Skip to content

story-086: A stage cannot edit the story that governs it - #84

Merged
jerodw merged 2 commits into
mainfrom
story/story-086
Aug 29, 2026
Merged

story-086: A stage cannot edit the story that governs it#84
jerodw merged 2 commits into
mainfrom
story/story-086

Conversation

@jerodw

@jerodw jerodw commented Aug 29, 2026

Copy link
Copy Markdown
Owner

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.json gained .harness/stories/ in d2ad537, 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:

  • The behavioural cases — the escalation, its control and the predicate — run against this module's own fixture rule set, so they hold the mechanism and say nothing about what this repository declares.
  • The deployment facttest_this_repository_blocks_the_story_directory_to_every_stage reads 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.
  • The resolved path — the coordinator's own resolution is driven under this repository's configured stories directory and the path it returns is held against the shipped blocked list, with a control showing that with the stories entry withheld no other prefix matches. What is asserted is that the artifact a run is governed by is the artifact the rule covers, not that a directory sharing its name is.

Supporting changes

test_the_workflow_defines_the_four_expected_stages names the shipped blocked_paths list 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_identically had 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. The built == injected comparison is untouched.

test_the_workflow_fact_coverage_comes_from_the_injection_not_leftover_prose reddened on landing, for a reason unrelated to the injection: prompts/planner.md names .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_READERS with its reason: two reads remain and both have what is shipped as their subject.

Evidence

  • Suite on the working tree: 3870 passed, 1 skipped (suite-run-result.json, exit 0)
  • Suite in a fresh clone with the story committed: 3870 passed, 1 skipped (clean-clone-result.json, exit 0)
  • Verification: passed, no blocking issues, across two iterations
  • Revert-check nomination: tests/test_planner_injection.py::test_the_workflow_defines_the_four_expected_stages — exit 1 reverted, exit 0 applied
  • 10 tests written; new module tests/test_a_stage_cannot_edit_its_own_story.py
  • 0 retries, 0 self-routes

The 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 in events.log and left in the tree.

The finding is correct. Dropping the blocked_paths entry reddens three assertions, not one: this one, the literal anchor in tests/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.

0ef748d applies 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

jerodw and others added 2 commits August 28, 2026 21:34
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
@jerodw
jerodw merged commit fc1af2f into main Aug 29, 2026
3 checks passed
@jerodw
jerodw deleted the story/story-086 branch August 29, 2026 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant