Skip to content

feat: verification plans, criteria gate and per-check results - #366

Merged
datacas merged 3 commits into
mainfrom
feat/290-verification-plan
Oct 30, 2026
Merged

datacas merged 3 commits into
mainfrom
feat/290-verification-plan

Conversation

@datacas

@datacas datacas commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Closes #290

Defines verification plans in ExecutionPlan version 3 and emits per-check results through tests.version=2. GitHub work items now require an explicit, parseable acceptance-criteria list before implementation, regardless of issue-review mode or difficulty. Plane and Jira criteria remain explicitly not evaluable until their readers exist.

The contract freezes check identity and obligations, retains result history, invalidates results from another HEAD, and deterministically caps conclusions for required failures, unverified checks and uncovered criteria. The one-release legacy adapter preserves unmatched executed evidence and never infers a missing required pass. Code-host checks remain separate.

Diagnosis

This is a feature request, so defect reproduction does not apply. The driver previously consumed stage-wide evidence without a structured criteria source or per-check states. The invariant is that project and criterion obligations cannot be removed, and missing or stale verification cannot become success. Related work was checked against the issue and owner decisions, with #288, #289, #327, #328 and #329 providing the relevant boundaries. The latest owner decisions defer persistence, plan execution, the final verification gate and verification-only resume to #329; CI substitution is also outside this change. No provisional store, new stop-reason schema or provider reader for Plane/Jira is introduced.

Work units

Unit Behaviour Files Tests Verification Rollback
WU-1 Runtime criteria gate, versioned plan/check contracts and conservative evidence normalization verification_plan.py, execution_plan.py, run_cycle.py, native_prerequisites.py, runtime/shard manifests, four emitting skills, issue template, owning documentation and regression tests Criteria grammar/provider status, mode/difficulty gate, immutable obligations, stale HEADs, compatibility, boundary results, telemetry/stats and process-boundary reader 190 targeted tests pass; package validation passes; full-suite verification remains limited by the nested Codex prerequisite dependent: revert with WU-2, whose follow-up uses this normalization contract
WU-2 Preserve a failed conclusion when follow-up evidence is malformed run_cycle.py, test_verification_plan.py Invalid-version follow-ups preserve agent failure and frozen required failure Included in the 190 passing targeted tests independent: reverting the follow-up restores WU-1 behaviour

Verification (agent-reported)

  • python3 -m unittest tests.test_execution_plan tests.test_verification_plan tests.test_cycle_outcomes tests.test_stage_dispatch tests.test_validate_workflow tests.test_fast_path: exit 0, 190 tests.
  • python3 scripts/validate-package.py: exit 0; 16 skills and shared sections validated.
  • python3 -m unittest discover -s tests: exit 1, 2,068 tests, 15 failures and 7 errors, all in test_dependency_setup under the known nested Codex socket limitation (Codex write stages fail: /tmp/codex-daemon-<uid> masked in the stage sandbox, and reroute stops on publication_changed #268). Some assertions see missing preparation outputs because the guard stops their mocked commands. Full-suite verification remains not_verified, rather than passed. The original command was rerun after fixing regressions; the follow-up cap case was then verified by the targeted suite. No isolation was disabled and no nested Codex launch was attempted as recovery.
  • BasedPyright CLI was run on affected Python files. The new verification module reports 0 errors and 90 warnings (exit 1 under its default warning policy); affected legacy files also retain diagnostics. This is not a clean project-wide type-check claim.

The targeted tests use controlled provider fixtures, disposable repositories and a real local child process for the criteria-reader boundary. They do not need live credentials or global Git identity. The full-suite prerequisite remains specific to this nested executor; CI is complementary evidence and is not reported as locally executed verification. Under the parallel CI policy this stage reads the pushed head's checks once without waiting.

Documentation and scope

The new behaviour was not previously documented. This change updates the owning pages, docs/execution-plan.md and docs/verification.md, plus the emitting skills and a new issue template. README has no entry-point changes. Durable plan/result persistence and the final gate/resume remain for #329; this PR does not implement CI substitution or claim merge readiness.

The final uploaded head is 9070ed2d332451f71151a2c1b6aec5490da8b475, confirmed through gh pr view. Its one CI read returned an empty statusCheckRollup: no checks were reported yet, and none is claimed passed. The parallel policy leaves the CI wait to the cycle gate.

@datacas

datacas commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner Author

Implemented #290 at 9070ed2d332451f71151a2c1b6aec5490da8b475; upload and PR head were confirmed through the publication helper and gh. The workspace is clean.

Agent-reported verification:

  • python3 -m unittest tests.test_execution_plan tests.test_verification_plan tests.test_cycle_outcomes tests.test_stage_dispatch tests.test_validate_workflow tests.test_fast_path: exit 0, 190 tests, including a real child-process criteria-reader test.
  • python3 scripts/validate-package.py: exit 0, package valid.
  • python3 -m unittest tests.test_verification_plan.CriteriaTests.test_reader_crosses_real_process_boundary_without_live_credentials: exit 0, 1 test, run separately on the final committed head as boundary verification.
  • python3 -m unittest discover -s tests: exit 1, 2,068 tests; 15 failures and 7 errors, all in dependency setup under the known nested Codex socket limitation. Full verification stays not_verified. The original command was rerun; the later cap-preservation follow-up is covered by the targeted suite. No isolation bypass was attempted.
  • BasedPyright CLI: the new module has 0 errors and 90 warnings; affected legacy files retain diagnostics. The CLI exits 1, so no clean type-check pass is claimed.

The one CI read for the final head returned no reported checks (statusCheckRollup: []). None is claimed passed. Under the parallel policy, the cycle's CI gate owns the wait.

Persistence, plan execution, the final verification gate/resume and CI substitution remain outside #290 as specified in the owner decisions. Updated owning docs: docs/execution-plan.md and docs/verification.md. This is an implementation handoff, without approval or merge.

@datacas

datacas commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

[CCR-20261029-001] · reviewer · anthropic/claude-sonnet-5-5→? · high · schema:2

Summary

Status: CHANGES_REQUESTED for head 9070ed2d332451f71151a2c1b6aec5490da8b475. I reviewed the complete accumulated diff (1384 lines, merge base ccc2f9d) for #290: the new scripts/verification_plan.py, ExecutionPlan v3, the driver criteria gate and normalization in run_cycle.py, the four skills, docs and tests. The contract is sound and fail-closed in the cases I traced (frozen obligations, stale HEADs, caps that never raise a conclusion). Two findings remain: one is a documented-behaviour gap with a misleading stop message, the other a likely false downgrade of reports from later stages.

Findings

[REV-001] · medium · open · - · blocks:yes — Plane/Jira cycles now stop before implementation; undocumented, with a misleading message

Paths: scripts/run_cycle.py:3965-3968, docs/verification.md:231

drive() stops with stop_reason="needs_refinement" for any criteria.status != "evaluable". That includes not_evaluable, which is what Plane and Jira always return (criteria reader unavailable). The stop text is acceptance criteria not_evaluable: criteria reader unavailable; refine the work item. Refining the work item cannot clear it, because no reader exists. Every Plane or Jira cycle halts before the first agent dispatch (CriteriaGateTests asserts this). docs/verification.md says only that these providers "return not_evaluable... neither counts as satisfied". It never says the cycle stops, and the PR description frames them as "explicitly not evaluable". AGENTS.md treats a visible behaviour change without its docs/ page as a finding. Either document the hard stop and give it an accurate message (a missing reader, not a work item to refine), or let not_evaluable proceed and rely on the not_verified cap. The second option fits the "not satisfied" wording better, but the owner decides.

[REV-002] · medium · open · - · blocks:no — configured-test identity is frozen to the first stage's executor and profile; later stages likely get capped to not_verified

Paths: scripts/run_cycle.py:3395-3403, scripts/verification_plan.py:210-217, skills/cc-resolve-comments/SKILL.md

The driver adds configured-test once, with the executor and profile of the stage that first reports. VerificationPlan.extend() raises "cannot rewrite frozen check identity" when a later report differs in executor or profile. The skills tell each agent to report "the dispatched executor/profile", and the runtime prompt (criteria_context) does not give the frozen values. In a normal cycle resolve and rereview run on other profiles, and often another vendor, than implement. Their honest reports then raise in normalize_tests. _normalize_test_payload swallows the error and records not_verified (or failed) for that stage. The result is fail-closed, so it never inflates a pass, but it understates good verification in the standard multi-profile flow and skews the new telemetry. No test covers a second stage with a different executor or profile. I could not run a probe, because the stage policy denies python3 -c and temporary scripts, so this comes from reading the code and is unverified by execution. Suggested direction: pass the frozen configured-test identity to later stages, or key identity on command, context and provenance and record the dispatched executor/profile per result.

Security triage

Not a sensitive change by the deterministic rule: no .code-cycle.yml security_review.always_when rule is declared. No path matches the mandatory minimum (.github/ISSUE_TEMPLATE/work-item.md is not under .github/workflows or .github/actions; the skills are not .claude/**). My own reading added a light inline audit, because the change reads a work-item body through a gh subprocess and injects it into an agent prompt. The call uses an argument list with no shell and a 30 s timeout. The body is passed as JSON-encoded data labelled "(data)", and provider failures stop the cycle (readiness_unconfirmed). I found no vulnerability. The residual point is that criteria text, which is untrusted, reaches the agent prompt. That is the same trust level as the work item the agent already reads. The delegated cc-security-review pass was not run as a separate skill; this was performed inline.

Commands executed (local)

Command Result
python3 scripts/validate-package.py exit 0: VALID: 16 skills (7 cycle, 9 supporting), shared sections in sync, cross-agent manifests aligned
python3 -m unittest discover -s tests exit 0: Ran 2069 tests in 191.651s, OK (all pass here; the PR text reports 22 failures in test_dependency_setup under the nested Codex limitation, which did not reproduce in this stage)
python3 -m unittest exit 0, but 0 tests ran (no discovery at the repo root). It gives no evidence
python3 /home/datacas/.code-cycle/runtime/cycle_journal.py ... permissions no permission decisions in force for this branch

Dependency preparation reported prepared (npm ci, scripts disabled). I did not count it as a test run.

Unverified

  • REV-002 is not reproduced by execution (the probe was denied by the command table); it rests on reading VerificationPlan.extend and the driver.
  • BasedPyright results in the PR description are agent-reported and were not rerun.

CI (parallel policy, read once, not waited on)

Head 9070ed2 has five checks from workflow "Validate package", all IN_PROGRESS: Skills, manifests, and Bash installer, Windows test shard (windows-1), (windows-2), (windows-3), (windows-4). None has passed yet, and none has failed. This is not a finding. The CI gate decides.

Residual risks

  • Resumes (--from resolve|rereview) and cycles with no work-item provider build a not_evaluable plan, so their verification is permanently capped at not_verified until Execute and replan native cycles under mandatory policy gates #329 persists plans. The docs record this as intended.
  • A standalone v2 report without a runtime plan (_tests with no plan) trusts the agent-supplied criteria list.
  • Documentation otherwise covers the change (docs/execution-plan.md, docs/verification.md, issue template).

Verdict

CHANGES_REQUESTED: REV-001 blocks approval. REV-002 does not block.

ORCHESTRATION_RESULT (JSON)

ORCHESTRATION_RESULT
{"skill": "cc-initial-review", "status": "CHANGES_REQUESTED", "issue_provider": "github", "issue_id": "290", "code_host": "github", "change_request_id": "366", "change_request_url": "#366", "pr_number": 366, "issue_number": 290, "head_sha": "9070ed2d332451f71151a2c1b6aec5490da8b475", "reviewed_head_sha": "9070ed2d332451f71151a2c1b6aec5490da8b475", "review_run_id": "CCR-20261029-001", "reviewer": {"profile": "reviewer", "provider": "anthropic", "model_requested": "claude-sonnet-5-5", "model_resolved": null, "effort": "high"}, "findings": [{"id": "REV-001", "severity": "medium", "status": "open", "disposition": "-", "blocks_approval": true, "category": "correctness", "path": "scripts/run_cycle.py", "line": 3965}, {"id": "REV-002", "severity": "medium", "status": "open", "disposition": "-", "blocks_approval": false, "category": "correctness", "path": "scripts/run_cycle.py", "line": 3395}], "blocking_findings": ["REV-001"], "checks": {"head_sha": "9070ed2d332451f71151a2c1b6aec5490da8b475", "passed": 0, "failed": 0, "pending": 5}, "blocking": false}
END_ORCHESTRATION_RESULT

@datacas

datacas commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

[CCR-20261029-002] · reviewer · anthropic/claude-sonnet-5-5→? · high · schema:2

Summary

Status: CHANGES_REQUESTED for head 9070ed2d332451f71151a2c1b6aec5490da8b475. This rerun re-verified the recovered review attempt-eb187c9f04c54c68b90dc7647c27ed0d on the same head. That attempt claimed no finding resolutions, so there was no claimed finding ID to verify. I read the complete accumulated diff (1384 lines, merge base ccc2f9d, line count confirmed) and re-checked the recovered findings against the code. REV-001 and REV-002 stay open. One new finding, REV-003, was added. The contract itself (frozen obligations, stale-HEAD invalidation, caps that never raise a conclusion) is fail-closed in the cases I traced.

Findings

[REV-001] · medium · open · - · blocks:yes — Plane/Jira cycles now stop before implementation; undocumented, with a misleading message

Paths: scripts/run_cycle.py:3965-3968, docs/verification.md:231

Recovered from the previous review and re-confirmed in the code. drive() stops with stop_reason="needs_refinement" for any criteria.status != "evaluable". That includes not_evaluable, which Plane and Jira always return (criteria reader unavailable). Refining the work item cannot clear that stop, because no reader exists. CriteriaGateTests asserts that every Plane/Jira cycle halts before the first agent dispatch. docs/verification.md says only that these providers "return not_evaluable... neither counts as satisfied", and never says the cycle stops. AGENTS.md treats a visible behaviour change without its docs/ page as a finding. Either document the hard stop and give it an accurate message (a missing reader, not a work item to refine), or let not_evaluable proceed and rely on the not_verified cap. The owner decides.

[REV-002] · medium · open · - · blocks:no — configured-test identity is frozen to the first stage's executor and profile; later stages likely get capped to not_verified

Paths: scripts/run_cycle.py:3395-3403, scripts/verification_plan.py:691-704

Recovered and re-confirmed by reading. The driver adds configured-test once, with the executor and profile of the first reporting stage. VerificationPlan.extend() raises "cannot rewrite frozen check identity" when a later report differs in executor or profile. The skills tell each agent to report "the dispatched executor/profile", and criteria_context does not pass the frozen values. In the standard multi-profile flow resolve and rereview run on other profiles than implement. Their honest reports then raise in normalize_tests, and _normalize_test_payload records not_verified (or failed) for that stage. Fail-closed, so it never inflates a pass, but it understates good verification and skews the new telemetry. No test covers a second stage with a different executor or profile. Not reproduced by execution: ad hoc Python is outside this stage's command table.

[REV-003] · medium · open · - · blocks:no — Stages that report no tests are now recorded as not_verified with tests_passed=false

Paths: scripts/run_cycle.py:3384-3413, scripts/verification_plan.py:760-841, scripts/run_cycle.py:4568-4570

Whenever a plan exists (every GitHub work item with a configured test command), resolve and rereview payloads go through normalize_tests. A payload with no tests object, or one with only tests.reason: no_code_change, defaults to version 1 and conclusion not_verified, and normalize_tests writes passed: false. _test_outcome then returns verification: not_verified and tests_passed: false, tests_basis: claimed. Before this change _test_outcome returned {} for such a stage, and the _legacy_tests docstring still says "a review, a blocked stage, and a no-code resolution record nothing". The recorder replaces the whole cycle-level test outcome whenever one of these fields is non-null (cycle.py:1219-1227). So a comment-only resolution or a review-style rereview overwrites the implementer's verified result with not_verified/false, which stats count as a failed test run. Likely fix: skip normalization when the stage reports no tests object, or when the reason is no_code_change. No regression test covers this. Not reproduced by execution (same command-table limit), so it rests on reading the code paths cited.

Security triage

Not a sensitive change: the security audit was skipped after triage. No security_review.always_when rule matched, and no changed path matches the mandatory minimum (.github/ISSUE_TEMPLATE/work-item.md is not under .github/workflows or .github/actions; the skills are not .claude/**). My own reading looked at the one trust boundary: the work-item body is read through a gh subprocess with an argument list, no shell and a 30 s timeout, and its criteria reach the agent prompt as JSON labelled "(data)". That has the same trust level as the work item the agent already reads. I found no vulnerability.

Commands executed (local)

Command Result
python3 -m unittest discover -s tests exit 0: Ran 2069 tests in 184.778s, OK
python3 scripts/validate-package.py exit 0: VALID: 16 skills (7 cycle, 9 supporting), shared sections in sync, cross-agent manifests aligned
python3 -m unittest exit 0, but 0 tests ran (no discovery at the repo root); it gives no evidence

Dependency preparation reported prepared (npm ci, scripts disabled); it was not counted as a test run.

Unverified

  • REV-002 and REV-003 are not reproduced by execution; they rest on reading the code.
  • BasedPyright results in the PR description are agent-reported and were not rerun.
  • The PR description reports 15 failures and 7 errors in test_dependency_setup under the nested Codex limitation. They did not reproduce here: the full suite passed.

CI (parallel policy, read once, not waited on)

Head 9070ed2 has six checks from workflow "Validate package", all SUCCESS: Skills, manifests, and Bash installer, Windows test shard (windows-1) to (windows-4), and PowerShell installer. None failed, pending or skipped. This is not a finding.

Residual risks

  • Resumes (--from resolve|rereview) and cycles with no work-item provider build a not_evaluable plan, so their verification is permanently capped at not_verified until Execute and replan native cycles under mandatory policy gates #329 persists plans. The docs record this as intended.
  • A standalone v2 report without a runtime plan (_tests with no plan) trusts the agent-supplied criteria list.
  • criteria_context is appended to the instruction of every stage, including reviewers, not only the code stages.
  • Criteria must be a flat list at column zero, so a wrapped or indented continuation line sends the work item to needs_refinement. This is documented.

Verdict

CHANGES_REQUESTED: REV-001 blocks approval. REV-002 and REV-003 do not block. All required checks of this head passed, but an open blocking finding remains.

@datacas

datacas commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

[CCR-20261029-001] · reviewer · anthropic/claude-sonnet-5-5→? · high · schema:2

[CCR-20261029-002] · reviewer · anthropic/claude-sonnet-5-5→? · high · schema:2

[CCT-20261029-001] · deep_coder · openai/gpt-6.1-sol→? · high · triaged:9070ed2d332451f71151a2c1b6aec5490da8b475 · schema:2

RESOLVED, with full-suite verification pending under the known nested Codex prerequisite. All three findings were classified as valid against the triaged head before source edits. Fix commit 77db5dc7c7639aafdccaf06b40d248110e852f1d was uploaded through the stage publication helper, and gh pr view confirmed that exact PR head. The worktree is clean. This is a resolution handoff, without approval or merge.

[REV-001] · medium · resolved · valid · blocks:yes — Plane/Jira stop needs accurate messaging and documentation

Preserved the conservative stop before implementation. An unavailable reader now produces BLOCKED / readiness_unconfirmed and explicitly says that a criteria reader is required; it no longer tells the user to refine an unreadable work item. docs/verification.md documents this hard stop and the Plane/Jira reader dependencies. Missing or malformed GitHub criteria still produce needs_refinement. The provider/mode/difficulty regression matrix verifies both paths before dispatch.

[REV-002] · medium · resolved · valid · blocks:no — Later stages need the frozen configured-test identity

The runtime now supplies existing frozen check identities to subsequent code stages. The four reporting skills instruct agents to retain the check's owning executor/profile when their dispatch differs, preserving the owner's identity contract. A check requiring a different context needs a new ID and cannot replace an existing obligation. The multi-stage regression verifies successful reports across different implement/rereview profiles and executors, without weakening identity validation.

[REV-003] · medium · resolved · valid · blocks:no — No-test stages must preserve earlier verification

Omitted tests and outcome-free no_code_change reports no longer manufacture not_verified / tests_passed:false telemetry. The regression runs implement → review → resolve → rereview and verifies that earlier passing cycle telemetry survives. Explicit reports still receive deterministic caps. The delegated delta review identified an overly broad first guard; it was narrowed and a further regression proves that no_code_change cannot hide an explicitly reported required failure.

Verification (agent-reported; commands executed in this stage):

  • python3 -m unittest tests.test_verification_plan: exit 0, 24 tests.
  • python3 -m unittest tests.test_execution_plan tests.test_verification_plan tests.test_cycle_outcomes tests.test_stage_dispatch tests.test_validate_workflow tests.test_fast_path: exit 0, 194 tests.
  • python3 scripts/validate-package.py: exit 0; 16 skills, shared sections and manifests valid.
  • python3 -m unittest discover -s tests: final rerun exit 1, 2,073 tests in 189.264 seconds; 15 failures and 7 errors, all in test_dependency_setup. The observed guard reports the known nested Codex app-server socket limitation (Codex write stages fail: /tmp/codex-daemon-<uid> masked in the stage sandbox, and reroute stops on publication_changed #268); related assertions then lack preparation outputs. The earlier run had the same 22 affected cases. Full-suite verification remains not_verified. No isolation bypass or direct nested executor launch was used as recovery.
  • python3 -m unittest: exit 0, 0 tests; this supplies no test coverage.
  • basedpyright scripts/run_cycle.py tests/test_verification_plan.py: exit 1, 101 errors and 1,757 warnings, including existing import-resolution and typing diagnostics. No clean type-check or complete baseline-equivalence claim is made.
  • git diff --check: exit 0. The affected regression tests use controlled provider fixtures and scripted adapters, with no live credentials or global Git identity required. No separate boundary run was required for these in-process normalization and prompt-composition fixes.

Post-change review used the complete fix delta from trusted review head 9070ed2d332451f71151a2c1b6aec5490da8b475, verified as an ancestor of the new head. The delegated cc-code-review pass found no remaining actionable findings after its follow-up review. Security triage found no configured or mandatory path/label trigger; frozen check data remains JSON-encoded data, with no new command execution or privilege boundary. No separate security audit was triggered.

CI was read once for 77db5dc7c7639aafdccaf06b40d248110e852f1d under the parallel policy. GitHub returned statusCheckRollup: []: zero reported passing, failing, pending, cancelled or skipped jobs. The two required gates documented in CONTRIBUTING.md, Skills, manifests, and Bash installer and PowerShell installer, are currently missing. In the structured counts these are two expected-but-missing failures, not observed failed executions. CI was not waited on, and no CI fix round ran; the cycle gate owns that decision.

Owning documentation was updated in this fix. Persistence and verification-only resume remain deferred to #329. Residual limitations are the unavailable full-suite prerequisite and non-clean type checking; none is represented as passed.

@datacas

datacas commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

[CCR-20261029-001] · reviewer · anthropic/claude-sonnet-5-5→? · high · schema:2

[CCR-20261029-002] · reviewer · anthropic/claude-sonnet-5-5→? · high · schema:2

[CCT-20261029-001] · deep_coder · openai/gpt-6.1-sol→? · high · triaged:9070ed2d332451f71151a2c1b6aec5490da8b475 · schema:2

[CCR-20261029-003] · reviewer · anthropic/claude-sonnet-5-5→? · high · schema:2

Summary

Status: REVIEW_PASSED_AWAITING_CI for head 77db5dc7c7639aafdccaf06b40d248110e852f1d. The review is complete for this head; it is not an approval. REV-001, REV-002 and REV-003 are resolved and verified by execution. I found no new finding. I read the complete accumulated diff (1523 lines, line count confirmed, merge base ccc2f9d) and the fix delta from the previously reviewed head 9070ed2 (7 files).

What changed since the previous review

Commit 77db5dc changes scripts/run_cycle.py, docs/verification.md, four skills and tests/test_verification_plan.py.

  • The Plane/Jira not_evaluable gate stops as BLOCKED / readiness_unconfirmed with a message that names the missing criteria reader.
  • The driver adds the frozen check identities to the prompt of later code stages.
  • _normalize_test_payload skips normalization when tests is omitted or is only reason: no_code_change.

Previous findings

[REV-001] · medium · resolved · valid · blocks:yes — Plane/Jira cycles now stop before implementation; undocumented, with a misleading message

Corrected and verified by execution. scripts/run_cycle.py:3977-3981 stops with BLOCKED / readiness_unconfirmed and the text "a criteria reader is required before implementation". The "refine the work item" text remains only for GitHub criteria that need refinement. docs/verification.md:235-239 documents the hard stop, that editing the work item cannot clear it, and the reader dependencies (#238-A for Plane, a Jira reader). CriteriaGateTests.test_gate_runs_for_every_issue_review_mode_and_difficulty_before_dispatch asserts the status, the stop reason, the message and that no agent was dispatched, for every provider, mode and difficulty. The test passes.

[REV-002] · medium · resolved · valid · blocks:no — configured-test identity is frozen to the first stage's executor and profile; later stages likely get capped to not_verified

Corrected and verified by execution. scripts/run_cycle.py:2891-2905 appends the frozen checks as JSON data to the prompt of implement, resolve and rereview stages, once the plan has checks. The four skills and docs/verification.md tell agents to copy the frozen executor/profile, and to use a new ID for a different context. test_later_profiles_receive_and_reuse_frozen_check_identity uses different implement and rereview profiles and executors, reads the frozen identity from the prompt, and checks that both later stages end verified / tests_passed. The test passes. The fix depends on the agent copying the identity. A deviation still fails closed in extend(), as before.

[REV-003] · medium · resolved · valid · blocks:no — Stages that report no tests are now recorded as not_verified with tests_passed=false

Corrected and verified by execution. scripts/run_cycle.py:4553-4557 returns the payload and plan unchanged when tests is omitted, or is no_code_change without checks, evidence, conclusion, passed or ran. _legacy_tests then returns {}, so the earlier cycle-level outcome survives. test_no_test_report_preserves_plan_and_does_not_invent_an_outcome and test_no_test_resolution_and_rereview_keep_implementation_outcome cover omitted and no_code_change reports through a full implement → review → resolve → rereview run. test_no_code_change_cannot_hide_an_explicit_required_failure shows that an explicit failed check with no_code_change still records failed. All three pass.

New findings

None.

Security triage

Not a sensitive change: the security audit was skipped after triage. No security_review.always_when rule matched, and no changed path matches the mandatory minimum (CI and automation, secrets and keys, agent and toolkit configuration). The fix delta adds frozen check data to the prompt as JSON-encoded data. That data comes from project policy and earlier agent reports, and it reaches only code stages. It adds no command execution and no new privilege boundary.

Commands executed (local)

Command Result
python3 -m unittest discover -s tests exit 0: Ran 2073 tests in 178.466s, OK
python3 scripts/validate-package.py exit 0: VALID: 16 skills (7 cycle, 9 supporting), shared sections in sync, cross-agent manifests aligned
python3 -m unittest tests.test_verification_plan -v exit 0: 24 tests OK, including the five regression tests above
python3 -m unittest exit 0, but 0 tests ran (no discovery at the repo root). It gives no evidence

The full suite passed in this stage. The implementer reported 22 test_dependency_setup failures under the nested Codex socket limitation (#268); they did not reproduce here. Dependency preparation reported prepared (npm ci, scripts disabled) and was not counted as a test run.

Unverified

CI (parallel policy, read once, not waited on)

Head 77db5dc has five reported checks from workflow "Validate package". Passed: Skills, manifests, and Bash installer, Windows test shard (windows-2). Pending: Windows test shard (windows-1), (windows-3), (windows-4). No failure is reported. PowerShell installer, a required gate in CONTRIBUTING.md, is not yet reported for this head; the earlier head had it. This is CI state, not a finding. The cycle's CI gate decides.

Residual risks

  • Resumes (--from resolve|rereview) and cycles with no work-item provider build a not_evaluable plan, so their verification stays capped at not_verified until Execute and replan native cycles under mandatory policy gates #329 persists plans. The docs record this as intended.
  • A standalone v2 report without a runtime plan trusts the agent-supplied criteria list.
  • Identity reuse across profiles relies on the agent following the prompt and skills.

Verdict

REVIEW_PASSED_AWAITING_CI: the head is completely rereviewed, every previous finding is resolved, and no open finding blocks approval. Required checks have not all passed yet, so this is not an approval.

@datacas
datacas merged commit 753e4ea into main Oct 30, 2026
6 checks passed
@datacas
datacas deleted the feat/290-verification-plan branch October 30, 2026 09:02
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.

Verification plan: map acceptance criteria to checks and record per-check results

1 participant