story-086: A stage cannot edit the story that governs it - #84
Merged
Conversation
Implemented by the l5 harness story workflow.
The second verification found the same false claim it had already corrected in ARCHITECTURE.md still standing in this docstring, but the correction pass budget of 1 was spent, so it was recorded and left. Dropping the blocked_paths entry reddens three tests, not one: this assertion, the literal anchor in tests/test_planner_injection.py that pins the shipped list, and the resolved-path assertion below with its own control. The division the sentence describes is real; the word "only" was wrong. Prose only -- no assertion changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HkujNrgMcsRBFWNEKWYnmA
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 cannot edit the story that governs it.
.harness/stories/is blocked to every stage, so no stage of a run can rewrite the artifact its own work is judged against. This story asserts that guarantee — it does not build it.The entry was made by hand, and had to be
rules/execution-rules.jsongained.harness/stories/ind2ad537, committed before the run.rules/is blocked for every stage of every story, so no stage could have made the entry; the story asserts the deployment fact rather than creating it. This is the same shape story-081 used for the history directory.git diff main -- rules/on this branch is empty.The guarantee is now pinned three ways, and the division between them is the point:
test_this_repository_blocks_the_story_directory_to_every_stagereads the shipped file. The entry is spelled as the directory this repository configures its stories at, so the claim is that this deployment's story directory is blocked rather than that some string appears in a list.Supporting changes
test_the_workflow_defines_the_four_expected_stagesnames the shippedblocked_pathslist as a literal and now names the list the rule set carries. It stays a literal deliberately: it is the control the data-driven coverage assertions rest on, and a derived anchor would pass against an emptied rule set.test_workflow_context_and_build_context_render_blocked_paths_identicallyhad restated the rendered block as a second string literal, which was a maintenance site rather than part of its claim. The expectation is now derived from the same rules object both renders consume, guarded non-empty so an emptied rule set cannot make it vacuous. Thebuilt == injectedcomparison is untouched.test_the_workflow_fact_coverage_comes_from_the_injection_not_leftover_prosereddened on landing, for a reason unrelated to the injection:prompts/planner.mdnames.harness/stories/in its own prose, telling the planner where to look for the next story number. The repair keeps the assertion an exact equality and derives the exception rather than listing it — the placeholder-free template's own blocked paths must be a proper subset of the blocked list — so a collapse is still required to be real and a path leaking in from elsewhere still fails loudly.The new module is declared in
DECLARED_LIVE_ARTIFACT_READERSwith its reason: two reads remain and both have what is shipped as their subject.Evidence
suite-run-result.json, exit 0)clean-clone-result.json, exit 0)tests/test_planner_injection.py::test_the_workflow_defines_the_four_expected_stages— exit 1 reverted, exit 0 appliedtests/test_a_stage_cannot_edit_its_own_story.pyThe last commit is a hand correction, and why
The run's correction-pass budget of 1 was spent fixing a false exclusivity claim in
ARCHITECTURE.md: "drop the entry and that one test fails, and only that one". The second verification then found the same claim still standing in the new module's docstring — "Drop the entry and it fails here — and here only" — with the budget exhausted, so it was recorded inevents.logand left in the tree.The finding is correct. Dropping the
blocked_pathsentry reddens three assertions, not one: this one, the literal anchor intests/test_planner_injection.py, and the resolved-path assertion whose own control demonstrates that no other shipped prefix matches. The division the sentence describes is real; the word "only" was wrong.0ef748dapplies the replacement the verifier supplied. It is prose only — no assertion changed — and the module is green (10 passed). Committed by hand rather than left for a later story's documenter to inherit, since a false claim about the repository in a module whose subject is claims about the repository should not ship with no owner.🤖 Generated with Claude Code
https://claude.ai/code/session_01HkujNrgMcsRBFWNEKWYnmA