story-111: A stage records every file it touched - #151
Merged
Conversation
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.
Story
A stage records every file it touched.
story-101's tester modified a file and left it out of
tester-changed-files.json. Nothing caught it. The correction pass could not fix it — the record is another stage's output under a blocked path, and a documenter editing it would make the tester's account of its own work into something the documenter wrote. The verifier accepted that refusal, declined to re-raise it, and the run ended with a record known to be wrong and structurally unfixable.That matters more than one missing line. The changed-files records are what the governance layer reads: what a run touched, which stage created a governed path, what the revert check and the baseline merge turn on, and since story-100 what the post-story inspection takes into scope. A file missing from a record is a file no check considers governed and no reader can see was touched.
What changed
The coordinator takes a content signature of the tree before a stage runs and compares it afterwards, over tracked and untracked paths alike, so a stage that changed a file and did not record it is detected rather than trusted.
Two details are load-bearing. Blocked-path resolution is shared with the readers that already exist, so the check and the enforcement cannot disagree about which paths are governed. And paths are read
-z-delimited, so a filename containing a newline cannot corrupt the comparison.The remedy follows what story-101 established rather than working around it: only the stage that wrote a record may correct it. The omission routes back to that stage rather than being handed to another one or amended by the coordinator.
Evidence
story-108's split budget worked in the wild, first time out
This run took two self-routes: one a genuine suite failure, and one
stale-required-artifactsnaming bothtest-results.jsonandtester-changed-files.json.Under the single budget that existed until three stories ago, that is two of two spent, with nothing left for whatever came next. Under the split each came out of its own budget and neither touched the other, so the run kept its full failure allowance throughout. This is the first run since story-108 to spend a bookkeeping self-route, and it is also — pointedly — a run about stages failing to record what they did.
Notes for review
The correction pass caught a miscount. A paragraph presented itself as the account of the existing fixtures this story forced and enumerated four modules; the enumeration did not match. Same class as the count-versus-list rule the prose layer already carries.
One
unverifiednote, the routine one: the coordinator's whole-suite result was taken before the correction pass's edit, so the suite is green as of the tester's last turn rather than as of the final tree. The clean-clone check, which ran after everything, is exit 0.🤖 Generated with Claude Code
https://claude.ai/code/session_019WkxmJ5ArLEaC2RDPGkbRU