Repository navigation
Description
Priority: P0. Effort: S–M. Currently blocked by this issue: #330 and its pull request #384 (REV-001 cannot be resolved through the runtime).
Problem and rationale. A cycle cannot resume a change request whose frozen verification plan holds a manual check. Two defects combine; observed on #330 / PR #384 (plan revision 2, readiness_unconfirmed).
- Manual checks can never be restored.
authorized_bindings()(scripts/cycle_plan.py) accepts journal-proposed commands only if_is_verification_commandallows them. A manual check such asmanual:orca-liveis not a runnable command and never passes, sorestore_plan(scripts/cycle_history.py) raisesHistoryError: stored check has no currently authorized command bindingfor the whole plan. Every resume then falls back to the unrestored plan, whose commands aresha256:fingerprints. - The fallback is not idempotent.
prepare_planlooks for a required check whose command equals the configured test command. Against fingerprints it finds none, so it derivesconfigured-test-<digest>and extends the plan. That id was already added by the previous resume, with the fingerprint as its command,provenance: runtimeandreason: runtime. The new spec carries the plain command,provenance: projectandreason: configured test command, andVerificationPlan.extendrejects it withcannot rewrite frozen check identity. The run stopsBLOCKEDbefore any agent runs, and every later resume stops the same way.
The frozen-identity invariant is correct and must stay as it is. A reproduction against a snapshot of the persisted state is described in the evidence below.
Objective and scope. A change request with a manual check resumes any number of times without losing obligations or evidence.
Smallest proposed implementation scope.
authorized_bindings()also binds journal-proposedmanual:*commands. A bound manual command grants no execution authority:_is_verification_commandis not changed and still rejects it, and a manual check is never treated as verified because it was restored.prepare_planrecognizes an existing configured check by its original command or by its canonical command digest (command_digest), and skips the extension when one is present. No frozen check is rewritten and no check is added twice.
Dependencies. None strict. Independent of #382 (host-attested evidence), which will build on manual checks being restorable. Unblocks #330 and PR #384.
Acceptance criteria.
- A persisted plan containing a
manual:*check restores without aHistoryErrorwhen its journal proposal exists. - Restoring a manual check neither marks it verified nor makes its command executable;
_is_verification_command("manual:…")stays false. - Consecutive resumes of the same change request (at least three) succeed and yield the same set of check identities: no
configured-test-<digest>duplicate appears and no frozen identity changes. - Historical results, frozen identities and required/criteria obligations are preserved across resumes.
- A plan whose check command is genuinely unauthorized (not a manual check) still fails restore as before.
.code-cycle.ymland the command allowlist rules are unchanged.docs/verification.mdstates that manual checks survive resume and that resume is idempotent.
Regression tests.
- Reproduce the revision-2 collision: a plan with
configured-test, agent-proposed checks,manual:orca-liveand a previously addedconfigured-test-<digest>entry whose command is a fingerprint; resume must not raise. - Three consecutive resumes of the same plan; identities and results are identical after each.
- Manual check restored but unexecuted: stays
unverified, never passes,cap()still lowers the conclusion. - Unauthorized non-manual command still raises
HistoryError. - A sanitized fixture of the persisted PR feat(orca): share execution plans in supervised cycles (#330) #384 state (check ids, fingerprints, results, digest) restores without loss of obligations or evidence.
Verification before the real cycle resumes. The fix is first run against a copy of the persisted state of PR #384, to show that the plan that is already blocked recovers without losing obligations or evidence, before any real cycle is started on it.
Risks. Binding manual:* must not widen what a verifier is allowed to run: verify_pending passes pending commands as verify prefixes, so manual commands must stay excluded from that list or be proven inert. The change must not mask a genuinely unauthorized command.
Out of scope. Host-attested evidence (#382), changing the allowlist or .code-cycle.yml, relaxing extend's frozen-identity rule, any change to PR #384 or its worktree.
Evidence. On a snapshot of the telemetry database, restore_plan with the bindings authorized_bindings() builds raises HistoryError; adding manual:orca-live to the bindings restores the plan. The unrestored plan's extension step then fails with cannot rewrite frozen check identity, differing in command (fingerprint vs plain), provenance (runtime vs project) and reason.
Activity
fix(verification): limit digest match to configured-test identities (#…
fix(verification): restore manual checks and make plan resume idempot…
docs(roadmap): add #382, #383 and #385 to the M1 milestone row (#386)