Repository navigation
Description
Priority: P1. Currently forces a human exception or a repeated full rereview for PR #392 (#389). No strict dependency.
Problem and rationale. restore_plan (scripts/cycle_history.py) restores a persisted plan only if every stored check has a currently authorized command binding. One unauthorized check makes it raise HistoryError: stored check has no currently authorized command binding for the whole plan. prepare_plan (scripts/cycle_plan.py) then takes the unrestored fallback, where commands are sha256: fingerprints and verification_resume stays false. A --from rereview --pr <n> after a verification_unverified stop therefore does not run cc-verify on the pending checks. It dispatches a full rereview of a head that is already approved, and the required checks stay unverified.
Observed on #389 / PR #392 (head 9b15fd9, latest plan record revision 6, stop verification_unverified, security stage COMPLETED):
- The stored plan has four required checks:
configured-test,quota-regressions,package-validationandconfiguration-invariant. - Three commands are authorized. The fourth,
configuration-invariant, isgit diff --exit-code <sha> -- .code-cycle.yml scripts/sandbox.py …, proposed by the implementer to prove that configuration and sandbox files are unchanged.git diffis not in the verify prefixes, so_is_verification_commandrejects it. - Reproduced read-only on a snapshot of the telemetry database:
restore_planwith the bindingsauthorized_bindings()builds raisesHistoryError. - Other conditions of the verification-only path were checked and hold: stop reason
verification_unverified, record HEAD equals the worktree HEAD, the last trusted receipt matches the record's plan, securityCOMPLETED, and the live issue criteria hash equals the stored one.
#385 (PR #387) fixed this for manual:* checks only. The same failure applies to any agent-proposed command the allowlist rejects.
Objective and scope. A plan containing an unauthorized check still resumes verification for the checks that are authorized and pending. The unauthorized check stays an unverified obligation with an explicit reason; it is never executed, never dropped, and the allowlist is not widened.
Smallest proposed implementation scope. In prepare_plan, when restore_plan fails on a binding, restore the authorized checks and retain the others as fingerprinted, unrunnable obligations. Then verification_resume is decided from the remaining conditions. Optionally, flag at proposal time that a proposed command cannot be authorized, so the implementer learns it before the plan freezes.
Acceptance criteria.
- A plan with one unauthorized and several authorized pending checks resumes through the verification-only path and runs only the authorized pending checks.
- The unauthorized check remains required and
unverified, with a stated cause; the conclusion stays capped atnot_verifieduntil it is satisfied. - Frozen check identities, historical results and criteria links are unchanged.
- No command outside the current authorization is ever executed, and
.code-cycle.ymland the allowlist rules are unchanged. - A plan whose every check is authorized behaves as today.
Regression tests. A fixture modelled on the PR #392 plan (four required checks, one with a rejected git diff --exit-code command): restore, verification-only dispatch of the three authorized checks, the fourth stays unverified and unexecuted; repeated resumes are stable; a fully authorized plan is unchanged.
Out of scope. Widening the verify allowlist or editing .code-cycle.yml, and host-attested evidence (#382). Related: #385, #388, #389.
Activity
docs(roadmap): add #394 and #395 to the M1 milestone row (#396)