Make the checkout form Phase 4's default Tests-fix revert and gate ladder rung 1 - #136
Conversation
…ng 1 The Tests-fix rubric item prescribed `git stash push` on a tree that Phase 3 has already committed and Phase 4 has already pushed, so the stash saved nothing, the check ran against the unmodified tree, and the no-op read as a false-negative in the test. The checkout form is now the default, stash is demoted to the genuinely-uncommitted case, and the revert must be confirmed to have changed the tree before either half is trusted. The fallback ladder loses its "retry with checkout first" preamble, since the retry is now the default, and rung 1 gains an entry condition: a headless or timeout-bounded dispatch must not push a head that undoes its own fix, because a killed session leaves nothing to restore it. Closes #116 Closes #132
Finding 1's entry covers both defects: a revert that silently does nothing returns Tests-fix to unanchored judgment while still reporting an anchor's verdict, and a ladder rung whose interruption leaves the head undoing its own fix damages the anchor it substitutes for. Finding 3's entry covers the consequence for the regression gate it motivated in PR #31 — manufactured evidence cannot distinguish a real fix from a coincidental patch.
Two self-review findings.
Substituting {{EXTERNAL_SIGNAL_LABEL}} into the ladder preamble and rung 1 was
wrong: rung 1 pushes a commit and reads a check result, so it is inherently
CI-specific and cannot be performed at all where the anchor is a manual
checklist. The literal wording is restored and a sentence now states that
unavailability outright.
The checkout form said `git checkout origin/<default> -- <src files>`, which
also pulls in anything that landed on the default branch since the branch was
cut. The merge base is named as the correct revert target.
Phase 4 self-reviewPosted as a plain comment rather than a formal review object: reviewer Universal rubric
Repo-specific rubric
Instruction-quality findings folded in from the diff readBoth were found by reading the first draft as a generated skill would receive it
Phase 7 — documentation accuracy checkEach row of the sources-of-truth table was checked against this PR's
A complete pass found nothing further to fix. Merge stateThe do-not-auto-merge path check was run: the modified paths are This review was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener). drafted by Claude on behalf of Daniel Stephenson |
Summary
Two defects in Phase 4's Tests-fix rubric item and its fallback ladder are
corrected in
create-dev-loop.md. Both were reported from generated instances,both live in the same paragraph pair, and neither is separable from the other
without leaving the surrounding text self-contradictory — so they are batched as
one coherent change.
instructed
git stash push -- <src files>to revert the fix. By the time thatitem is reached, Phase 3 has committed the fix and Phase 4 has pushed the
branch and opened the PR, so the working tree is clean and the stash saves
nothing. What follows is worse than a missing check: the subsequent run
executes against the unmodified (fixed) tree and passes,
git stash popthen fails with
No stash entries found, and the sequence is naturally scoredas "reverted, still passed → false negative in the test" when in fact nothing
was ever reverted. The checkout form —
git checkout origin/{{DEFAULT_BRANCH}} -- <src files>to revert,git checkout HEAD -- <src files>to restore — is now stated as the default,because it is correct in the state Phase 4 actually finds the tree in. Stash
is demoted to the rarer genuinely-uncommitted case, and a new instruction
requires the revert to be confirmed to have changed the tree
(
git status --porcelain/git diff --stat) before either half of theresult is trusted.
deliberately undoes the PR's own fix, waits for a red signal, then resets and
force-pushes. It is therefore only safe when the session is certain to survive
both round-trips. Under a headless or timeout-bounded dispatch there is no
human present and the run may be killed at any point, which produces exactly
the stuck-mid-revert state that Phase 1's orphaned-PR handling was added to
repair. An entry condition now forbids rung 1 in that situation and directs
the reader through to rung 2 or rung 3's hand-off.
The ladder's preamble is rewritten to match: its "before concluding the local
anchor cannot run, retry with a checkout-based revert" instruction is removed,
since that retry has become the default, and the entry condition is restated so
that a failure of one git mechanism is explicitly not the same as an
unavailable tool or interpreter. Two downstream references to the experiment
by its old name (the Phase 4 self-review comment example and Phase 8's
regression gate) are renamed from "stash-and-run" to "revert-and-run".
Two refinements beyond the two issues' literal scope
Disclosed rather than smuggled. Both were produced by the Phase 4 self-review of
this PR's own first draft and are recorded in the self-review comment.
draft replaced rung 1's hardcoded
CIwith{{EXTERNAL_SIGNAL_LABEL}}, onthe reasoning that a hardcoded anchor name is the defect PR Fix documentation drift across the three sources of truth #57 corrected
elsewhere. On review that was wrong and has been reverted: rung 1 pushes a
commit and reads a check result, so it is inherently CI-specific and cannot be
performed at all where the label names a manual checklist. The literal wording
is restored, and a sentence now says so outright rather than leaving a
generated skill to substitute its way into an instruction it cannot follow.
as first written said
git checkout origin/{{DEFAULT_BRANCH}} -- <src files>,which also pulls in anything that landed on the default branch since the
branch was cut, so the experiment would no longer isolate this PR's change.
The superseded ladder text had this precision (
<merge-base-with-…>) anddropping it would have been a regression;
git merge-baseis now named.Research grounding
confidence: high) covers both issues. §1's entry for PR Apply consolidated template-rule backlog (#36, #39–#51) #54 records that the
Tests-fix item exists specifically to ground regression scoring empirically
rather than by judgment; a revert that silently does nothing returns that item
to unanchored judgment while still reporting an anchor's verdict. §1's entry
for PR Add Tests-fix CI-revert fallback ladder and scratch-file guidance #67 records the ladder's addition for the case where the local anchor
cannot run; a rung whose interruption leaves the branch's head undoing its own
fix damages the anchor it was meant to substitute for. An Implementations
entry for this PR is added under §1.
is the source of the regression gate that Tests-fix feeds, quoted at Phase 8:
regression evidence is the only way to distinguish a real fix from a
coincidental patch. A no-op revert manufactures that evidence rather than
collecting it. An Implementations entry is added under §3 as well.
Doc sync check
{{placeholder}}added or changed has a corresponding Step 4substitution-table row —
{{DEFAULT_BRANCH}}and{{EXTERNAL_SIGNAL_LABEL}}were already used elsewhere in Phase 4 andalready carry rows;
python3 scripts/check_docs.pyconfirms parityRESEARCH.mdupdated with Implementations entries under §1 and §3README.md's "What it does" line is not listed: no Step was added, removed, orrenamed by this diff, so the 1:1 list is unchanged.
Test plan
python3 scripts/check_docs.py→Doc consistency check passed.python3 -m unittest discover -s tests -v→Ran 13 tests ... OKdoc-consistencygreen on the PR headthis diff, only edited within, so no new fence needed escaping
introduced into
create-dev-loop.mdgardener
the issue body: Phase 3's staging-hygiene rule ends at "before
committing", and Phase 4 opens with
git push -u origin ..., so the fixis committed before the rubric runs and the tree is clean
mechanism this PR promotes: with
create-dev-loop.mdchecked out fromorigin/main, the rubric item readsgit stash pushwith no checkoutalternative and rung 1 carries no entry condition; with the fix restored,
both are present.
scripts/check_docs.pypasses in both states, whichis the point of [self-audit] The repo's own validation anchor is structurally unrunnable in a headless dispatch, so template changes can never merge autonomously #109 — CI cannot observe this class of defect
anchor for a template change is a manual
/create-dev-looprun against areal target repository, per
CLAUDE.md's "Testing changes" section. Thatrun creates a GitHub repository in Step 6 and writes outside the checkout
in Steps 3 and 5, neither of which this dispatch is authorized to do, and
it is structurally unrunnable headlessly in any case ([self-audit] The repo's own validation anchor is structurally unrunnable in a headless dispatch, so template changes can never merge autonomously #109). This PR
changes
create-dev-loop.md, which is anchor-relevant, so per Phase 4'sscope gate it is handed to a human rather than merged autonomously. None
of the five checklist items in "Testing changes" was exercised
Retrofit note
Per
CLAUDE.md's "Promoting a rule into the template": both rules aretemplate-wide, so every generated skill predating this change keeps the old
git stashwording and the ungated rung 1 until it is regenerated. Retrofitpasses are likely needed on any existing
<slug>-dev-loopskill and are notopened here — this dispatch is path-restricted to this repository's own checkout
and cannot reach the other skill repositories, and only the person running those
skills can see which ones exist. Two are known by name:
create-dev-loop-dev-loop— this repository's own loop skill, generated fromtemplate
44756ec, which predates both rules. Its Tests-fix item namesgit stash push -- <src files>first and its rung 1 has no entry condition,which is why this very cycle used the checkout form manually.
medieval-factions-dev-loop— named in Tests-fix ladder rung 1 is unsafe under headless dispatch, and has no entry condition saying so #132 as the instance whose PR Phase 6: don't hardcode the Co-Authored-By model name; defer to the harness git rule #50propagated the ungated ladder.
Deferred this cycle
Recorded for auditability, per Phase 1's skip-reason rule. All open issues not
listed below were left untouched because this cycle was scoped to the two
Phase-4 Tests-fix defects above.
CLAUDE.mdisagent-loaded configuration, which Phase 1 classifies as requiring explicit,
separate authorization rather than a mid-cycle edit. Still unfixed and still
needing a human.
among offered remedies, not an implementable defect. Its consequence is
visible in this PR's UNVERIFIED line.
Closes #Nreferences but not forwardfollow-up promises) — also in Phase 4, but a different sub-area, and batching
it would have cost this PR its localization coherence.
resource outside this dispatch's own checkout (gardener's refresh path, the
tend allow-list, the attribution hook), which remains unavailable. Guessing
would put unverified claims into the template.
Closes #116
Closes #132
This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson