Skip to content

Ground Phase 4's Docs score in a real pass and fix two Phase 3 rules - #138

Merged
dmccoystephenson merged 2 commits into
mainfrom
fix/template-instruction-corrections
Aug 29, 2026
Merged

Ground Phase 4's Docs score in a real pass and fix two Phase 3 rules#138
dmccoystephenson merged 2 commits into
mainfrom
fix/template-instruction-corrections

Conversation

@dmccoystephenson

@dmccoystephenson dmccoystephenson commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Three corrections to the generated-skill template, all in create-dev-loop.md.

Phase 4's Docs rubric item was scored three phases before its check was performed. The item names the Phase 7 documentation sources-of-truth table, but Phase 7 does not run until after the Phase 5 review wait and the Phase 6 comment pass. Scoring it at Phase 4 could therefore only be done from judgment — precisely what the rubric's own framing ("grounded in the diff or a command output — not in judgment") forbids — and a clean Phase 7 sweep left no artifact at all, so a later reader could not tell a completed pass from a skipped one. The table pass is now performed at Phase 4, where the score is taken, and Phase 7 is reduced to a re-check scoped to whatever Phases 5–6 changed, with an explicit instruction to record that the pass ran. The option chosen is the first of the two the issue proposed, which keeps the self-review a single artifact. A sentence was added to Phase 7 distinguishing this re-check from the intrinsic-critique re-run that Phase 4 step 6 caps, since a review comment that changed the implementation is an external signal. Closes #137

Phase 3's zero-tests rule described {{TEST_CMD}} as a substitution. After substitution a generated skill read "fall back to whatever the ./gradlew test substitution names as the real gate for this repo" — the substitution mechanism is the one context a generated child never has. The sentence now names an executed-test count from {{TEST_CMD}} as the gate, which reads correctly both in the template and in every generated instance. The rest of the template body was scanned for the same class of defect (a sentence referring to a {{TOKEN}} as a token rather than using it as a value); this was the only occurrence. Closes #126

Phase 3's scratch-file rule gains a third cleanup form. git clean -f <path> on a single untracked path inside the working tree succeeds where a bare rm <path> is blocked by the harness classifier, and is a more native fit than shelling out to Python whenever the scratch file already sits in a repo — which is the common case, since the canonical use is a body drafted with Write and passed to gh … --body-file. The preview step (git clean -n) and the single-path constraint are stated alongside it. Closes #134

One deviation from an issue's suggested text is worth flagging. #134 asks that the new rule defer to "the rule elsewhere in the template — never git reset --hard / git clean a path this run did not create". No such rule exists in create-dev-loop.md; the only git reset --hard in the template is Phase 1's stuck-mid-revert recovery, which is unrelated. Per the Phase 3 localization rule that the source wins over an issue's description, the constraint is stated directly and self-containedly instead of as a cross-reference to something that is not there.

Backlog skipped this cycle

Recorded here so deferral is auditable rather than silent. #106 (stale gardener owner link) is confined to CLAUDE.md, which is agent-loaded config and harness-blocked for autonomous editing — it needs explicit maintainer authorization and is surfaced rather than attempted. #109, #114, #120, #122, #123, #124, #125, #127, #128, #129, #130, #131, #133, and #135 were deferred as out of scope for a batch already coherent around three small instruction-text corrections; none is blocked, and each remains available for a later cycle.

Retrofit note

All three changes are rules in the generated-skill template, so the template only fixes them forward — every <slug>-dev-loop skill generated before this commit carries all three defects and will keep carrying them until its next MODE=update regeneration or self-audit cycle. Only the person running those skills can enumerate which exist, so the affected surfaces are named here rather than the skills:

  • Phase 4's Docs rubric item — every generated skill has one; each will keep scoring it before the check it names.
  • Phase 7 — every generated skill's Phase 7 still lacks both the re-check framing and the record-that-it-ran instruction.
  • Phase 3's zero-tests sentence — present only in skills generated after PR Require unique scratch filenames and define the structurally-red-anchor path #121 (2026-08-16), where the rule was introduced. Note that The new Phase 3 test-count rule refers to {{TEST_CMD}} as a substitution, so generated skills read as nonsense #126 reports a pass-2 retrofit having already propagated a variant wording ("treat {{TEST_CMD}} as this repo's real gate rather than the count-free banner") to the instance skills, so some instances may already read closer to this PR's wording than the template did; the wording adopted here is deliberately close to that variant to converge the two rather than introduce a third.
  • Phase 3's scratch-file rule — every generated skill has one, and none mentions the git clean -f form.

Research grounding

RESEARCH.md §1 (Self-critique without an external signal is unreliable, confidence: high) grounds the #137 change. A rubric item scored before the check it names has been performed is unanchored judgment wearing a rubric's clothes, which is the failure mode this finding's implementations have repeatedly corrected elsewhere in Phase 4 (PRs #54, #121, #136). An Implementations entry recording this PR has been added under that finding.

No finding applies to #126 or #134. #126 is a wording correction with no empirical claim behind it, and #134 records an observed harness-classifier behavior rather than a research result — consistent with how the two earlier rules from the same root cause (#62, #85) shipped without a RESEARCH.md entry. RESEARCH.md has no sandbox-behavior finding, and this change does not warrant creating one.

Doc sync check

The other two boxes are deleted as not applicable: no Step was added, removed, or renamed, and no {{placeholder}} was added or changed.

Test plan

The two gaps are stated plainly rather than papered over.

Behavioral validation. All three changes are to the generated-skill template body, which nothing in CI executes: check_docs.py verifies placeholder/substitution-table parity, README Step parity, and relative links, and none of those cover the semantics of a phase instruction. A green doc-consistency job is therefore not evidence that these instructions behave correctly. The validation run described in CLAUDE.md's "Testing changes" section was not performed because this cycle ran headlessly under a Gardener dispatch, where the side effects that run requires are not authorized: Step 6 creates a GitHub repository, and Steps 3 and 5 write outside the checkout to ~/local-skills/ and ~/.claude/commands/. None of the five checklist items were exercised. In place of the run, each changed instruction was hand-reviewed as a generated skill would receive it after substitution — which is how the #126 defect was confirmed and how the corrected wording was checked on both sides of substitution.

Regression evidence. The Phase 4 revert-and-run experiment was performed and is recorded in the self-review comment: the changed files were reverted to the merge base, the tree was confirmed to have actually changed, and both check_docs.py and the unit tests passed identically against the reverted tree. That is a real false-negative, not a scoring artifact — no automated check in this repo can reach the semantics of template prose. Neither fallback rung applies: rung 1 (CI-based temporary revert) would produce the same green on both sides and is in any case barred under a headless dispatch, and rung 2 requires a pre-existing test asserting the old behavior, of which there is none. The Tests-fix item is therefore scored FAIL, and this PR does not clear the Phase 8 regression gate autonomously.

The residual risk is bounded: no placeholder, Step, phase number, or fence was touched, so the mechanical failure modes CI does cover are not in play, and the changes are confined to instruction prose whose effect is visible on reading.

Closes #126
Closes #134
Closes #137

This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

dmccoystephenson and others added 2 commits August 29, 2026 02:07
Phase 4's Docs rubric item named a check that Phase 7 does not perform until
three phases later, so the item could only ever be scored from judgment — the
thing the rubric's own framing forbids — and a clean Phase 7 sweep left no
trace that would distinguish it from a skipped one. The table pass now happens
at Phase 4, where the score is taken; Phase 7 becomes a re-check scoped to
whatever Phases 5-6 changed, with an explicit instruction to record that it
ran.

Phase 3's zero-tests rule ended by describing {{TEST_CMD}} as a substitution,
which is the one context a generated child skill never has: after substitution
it read "fall back to whatever the ./gradlew test substitution names". It now
names the executed-test count as the gate, which reads correctly on both sides
of substitution. A scan of the rest of the template body found no other
sentence referring to a token as a token.

Phase 3's scratch-file rule gains a third cleanup form observed to work where
a bare rm is blocked: git clean -f on a single untracked path inside the
working tree, previewed with git clean -n.

Closes #126
Closes #134
Closes #137

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Docs rubric item was an anchor-shaped score with no anchor behind it,
because the check it named ran three phases later. That is the same defect as
finding 1's PR #121 entry, relocated from the signal to the schedule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dmccoystephenson

Copy link
Copy Markdown
Member Author

Phase 4 self-review

Posted as a plain comment, not a formal review — no independent reviewer is implied. This review was performed inline by the same session that authored the PR.

Universal rubric

  • Scope: PASS — two files touched. create-dev-loop.md carries all three fixes; RESEARCH.md carries the §1 Implementations entry that CLAUDE.md requires whenever a PR ships a finding. git diff --stat origin/main reports 7 insertions / 3 deletions in create-dev-loop.md and 1 insertion in RESEARCH.md — no reflowed prose, no renames, no comment churn.
  • Tests-new: not applicable — no public function was added. The repo's only executable code, scripts/check_docs.py, is untouched by this diff.
  • Tests-fix: FAIL — scored empirically, not from reasoning. git checkout fa50415 -- create-dev-loop.md RESEARCH.md was run against the merge base; git status --porcelain confirmed the tree had actually changed (both files listed as modified), so this was not the silent no-op the rule warns about. Against that reverted tree, python3 scripts/check_docs.py printed "Doc consistency check passed." and python3 -m unittest discover -s tests reported "Ran 13 tests ... OK" — identical to the fixed tree. git checkout HEAD -- create-dev-loop.md RESEARCH.md restored the fix and both were re-confirmed green. A check that passes identically on both sides measures nothing here: no automated check in this repo can reach the semantics of template prose. Neither fallback rung rescues it — rung 1 (CI-based temporary revert) would be green on both sides for the same reason, and is barred outright under a headless dispatch, while rung 2 needs a pre-existing test asserting the old behavior, of which there is none. Per rung 3 this PR does not clear the Phase 8 regression gate autonomously and is handed to a human.
  • Sibling structure: not applicable — no new file was created.
  • Sibling renames: PASS — no identifier, heading, or parallel-pair member was renamed.
  • Docs: PASS — Phase 7's table pass was performed here, at Phase 4, per the rule this very PR introduces. All nine rows were checked and none required correction: create-dev-loop.md (no Step, placeholder, or phase number changed; the cross-references added — "Phase 7's table pass", "Phase 4 step 6", "Phases 5–6" — were each verified to point at the right target, and check_docs.py confirms internal consistency); README.md (the "What it does" Step list is untouched, and line 35's one-word-per-phase summary still reads "doc check" accurately for a Phase 7 that re-checks); RESEARCH.md (the §1 entry names PR Ground Phase 4's Docs score in a real pass and fix two Phase 3 rules #138 and 2026-08-29 in the documented format); CONTRIBUTING.md (restates only "keep phase numbers stable", which holds); SECURITY.md (its trust model describes Step 2's read list and where COMPILE_CMD/TEST_CMD are executed — Step 2 is untouched and no execution site moved); .github/PULL_REQUEST_TEMPLATE.md (its checkboxes describe CI scope, unchanged); .github/ISSUE_TEMPLATE/*.md (restate Step and Phase names generically, none renamed); scripts/README.md (check_docs.py's role is unchanged); CLAUDE.md (its template conventions — stable phase numbers, placeholder rows, escaped fences, README 1:1, version comments below the H1 — all still hold; it is also harness-blocked for autonomous editing and needed no change).
  • Issue resolution: PASS — each closed issue's named surface is actually changed. Phase 4's Docs rubric item is scored three phases before Phase 7 performs the check it names #137 named create-dev-loop.md:367 (the Docs rubric item) and Phase 7; both are in the diff. The new Phase 3 test-count rule refers to {{TEST_CMD}} as a substitution, so generated skills read as nonsense #126 named the {{TEST_CMD}} sentence in Phase 3's zero-tests rule; it is in the diff. Scratch-file cleanup: 'git clean -f <path>' succeeds where 'rm <path>' is blocked #134 named Phase 3's scratch-file rule; it is in the diff. None is partially resolved while claiming closure.
  • CI: PASSdoc-consistency is green on head a863434, confirmed with gh pr checks 138 --watch. Its scope is check_docs.py plus the unit tests, which excludes everything this diff changes — so it is recorded as green, not as verification. See the Behavioral validation note in the PR body.

Repo-specific rubric

  • Placeholder parity: PASS — no {{placeholder}} was added, removed, or renamed; the two existing tokens in the touched lines ({{TEST_CMD}}, {{DOC_CHECK_TABLE}}) keep their Step 4 rows. python3 scripts/check_docs.py reports "Doc consistency check passed."
  • README Step parity: PASS — no Step was added, removed, or renamed, so the 1:1 list needed no change.
  • Fence escaping: PASS — this diff adds no fenced code block inside the template body. ^```` matches 28 lines in create-dev-loop.md`, all pre-existing outer fences, unchanged by this PR.
  • Phase numbering: PASS — no phase was renumbered. Phases 3, 4, 5, 6, and 7 are referenced by number in the added text and all resolve to the phases intended.
  • Version comments: PASS — the generated skill's header is outside this diff; template-version and generated-at remain directly below the H1.
  • Research grounding: PASS — the PR body cites RESEARCH.md §1 for Phase 4's Docs rubric item is scored three phases before Phase 7 performs the check it names #137 and states explicitly that no finding applies to The new Phase 3 test-count rule refers to {{TEST_CMD}} as a substitution, so generated skills read as nonsense #126 or Scratch-file cleanup: 'git clean -f <path>' succeeds where 'rm <path>' is blocked #134, with the reason. The §1 Implementations entry was added in commit a863434.
  • No back-ported specifics: PASS — the added text introduces no build command, reviewer name, or branch prefix belonging to this repo. git clean, gh --body-file, and "executed-test count" are all generic.
  • gardener interface: not applicable — Steps 3, 5, and 6 are untouched, so nothing changes about where a skill is written, what it is named, or what Step 6 creates. This is not a breaking change for gardener.
  • Retrofit note: PASS after fix — scored FAIL on the first pass: the PR description promoted three rules into the template without naming what needs a retrofit pass, which CLAUDE.md requires. Fixed by adding a Retrofit note section enumerating the four affected surfaces, including the observation that The new Phase 3 test-count rule refers to {{TEST_CMD}} as a substitution, so generated skills read as nonsense #126's pass-2 retrofit may already have propagated a variant wording to instance skills, and that this PR's wording was chosen to converge with that variant rather than introduce a third.
  • Behavioral validation: PASS as an honest UNVERIFIED — the PR body names no repo a /create-dev-loop run was validated against, states why (a headless dispatch is not authorized for the repo creation in Step 6 or the out-of-checkout writes in Steps 3 and 5), records that none of the five checklist items were exercised, and does not auto-merge.

Out-of-diff observations

Folded into this body rather than posted inline, since none of these lines is in a diff hunk.

  • create-dev-loop.md:621 — the TEST_CMD substitution-table row instructs "Substitute the same text everywhere {{TEST_CMD}} appears (Phase 3 verify block, Phase 8 rebase fence)", but the token also appears in Phase 3's zero-tests prose at line 297 — the very line this PR edits. The parenthetical has been incomplete since PR Require unique scratch filenames and define the structurally-red-anchor path #121 introduced that third occurrence; this PR preserves the occurrence rather than creating it, so correcting the row is out of scope here. A follow-up issue will be filed on this repo.
  • create-dev-loop.md:256 — the Phase 2 plan-summary example lists "no new placeholders without table rows, no fenced code blocks unescaped" as its illustrative invariants. Those are create-dev-loop's own invariants appearing in the generic template, which reads oddly for a child skill in an unrelated language, though the trailing hedge "(project-specific invariants from CLAUDE.md)" keeps it from being wrong. Noted, not changed.

Summary

Two FAILs found. The Retrofit note was mechanical and has been fixed in the PR description. Tests-fix is a genuine FAIL that cannot be repaired within this repo's tooling, and it — together with the absent behavioral validation run — is why this PR is handed to a human rather than merged: a template-prose fix has no reachable regression evidence, and the merge gate should not be satisfied by an anchor that measured nothing.

This review comment was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant