story-020: Resume an escalated run, and commit its work when it escalates - #18
Merged
Conversation
…ates Implemented by the l5 harness story workflow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An escalated run's work lived only in the working tree, surviving exactly until someone checked out another branch — which is a normal thing to do while deciding what to do about the escalation.
_completeends a successful run with a commit;_escalatecommitted nothing. The one terminal state a developer most needs to inspect was the one the harness did not preserve.This story fixes both halves: escalation commits its work, and an escalated run can be resumed rather than restarted.
Changes
orchestration/story_coordinator.py—_escalatecommits the run's work before returning.state.jsongains fields recording the escalation commit, the story artifact digest and the harness revision, each with a default so astate.jsonwritten before this story still loads. Resume re-enters at the recorded stage, carryingretry_countandverification_iterationsforward.scripts/l5-run— gains--stage, refusing a stage the loaded workflow does not define.tests/test_story_020_validation.py(new, tester stage) — 49 tests.Testing
930 passedin the working tree and930 passedin a fresh clone with the story committed, on Python 3.10.20 (clean-clone-result.json,exit_code: 0). Verification passed on the second iteration with zero blocking issues.Notes for review
git checkout mainthen failed outright with "Your local changes would be overwritten." The developer is stranded on the story branch. As the verifier put it, that is a stronger failure than work being carried across: the act the story exists to make safe is refused outright, and a test that only inspected the other branch afterwards would not have seen it. The same root cause meant the unchanged-since-escalation guard could never fire.state.jsonrecords the sha of the commit containing it, and a commit cannot carry its own sha. The verifier recorded this as a consequence, not a defect.unchanged_since_escalationcompares the recorded commit againstHEAD~1, which the criterion's wording does not settle either way.A defect this run exposed, which is not this story's
The shipped
test-results.jsonsays the suite failed. It reportsstatus: "failed", 927 run, 923 passed, with four named failures — while the verifier and the clean-clone check both independently report 930 passed, 0 failed.The record is attempt 1's, never replaced. Write times settle it:
Attempt 2's tester ran and did not rewrite its own declared output. The coordinator's post-stage check asks only whether a required artifact exists, not whether the stage that just ran produced it, so a stale artifact from a superseded attempt satisfies it silently.
This is not introduced by story-020 — it is a gap in the coordinator's output check that any retried run can hit. story-012 retried and its record is current, so it does not always happen; that makes it a silent, intermittent hazard rather than a consistent one. The verifier ran the suite itself and the clean-clone check ran it again, so the work here is verified twice over by evidence that is fresh. What is stale is one artifact, and it is the one a reader would most reasonably trust.
Filed separately; flagged here because a reviewer opening this run's artifacts will see a failing test record on a passing run.
🤖 Generated with Claude Code