Uh oh!
There was an error while loading. Please reload this page.
docs: harden the worktree recipe with --no-track; correct the stale no-mechanical-backstop claim - #6976
Merged
Merged
Conversation
…o-backstop claim Two instruction-file corrections on the same governed face. **The prescribed worktree recipe now specifies `--no-track`** (`CLAUDE.md`, `AGENTS.md`). Plain `-b` writes the new branch's upstream keys — `branch.NAME.remote` and `branch.NAME.merge` — into the one `.git/config` that every linked worktree of a repo shares. That write can fail *after* the branch is created, leaving a branch with no worktree: a half state in the very first step of the recipe, and one the error text does not name. Read as "the whole command failed", the retry hits `branch already exists` and reads as a second, unrelated problem; read as "the worktree exists", the agent starts editing the shared primary checkout — the one thing the worktree-first rule exists to prevent. Measured on git 2.43.0: `--no-track` removes the config write and still bases the worktree on `origin/main`. Explicit `git pull origin main` is unaffected (it uses the given refspec, never `branch.NAME.merge`), and `git push -u origin BRANCH` — already the prescribed first push — sets an upstream one command later. **The governed-surface section no longer claims this repo has no mechanical backstop.** The paragraph asserted that nothing mechanical covers the governed surface here, that the sibling repo's post-merge audit does not cover this repo, and — self-referentially — that "a backstop this paragraph does not name is a backstop that does not exist". Measured today, three of those claims are false: `.github/workflows/governed-surface-guard.yml` is live and reports on every pull request, and the sibling audit has covered this repo since objectstack#9619. The same file already named the guard 59 lines above, so the document contradicted itself. The replacement keeps what is still true (no CODEOWNERS, no hook, not yet a required check), names the guard and its two legs — the `pull_request` leg deliberately exits 0, so green does not mean ungoverned — records that it stays report-only until the ruleset toggle is flipped, and points coverage at the script's own list instead of restating a closed inventory that goes stale the next time a guard is added. Net 0 lines in both files; the changeset carries empty frontmatter because no published package's source changed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
This was referenced Aug 31, 2026
…ause One clause in the corrected backstop paragraph said the guard-versus-carve-out divergence on published `skills/**` was awaiting the maintainer. It is not: the ruling landed 2026-08-30 (director session, ruling batch 7, maintainer verbatim 「批 #7 同意」) taking Option A — published `skills/**` is governed, human merge, with the 2026-08-26 md-versus-code split written in alongside it. The earlier routing that described it as undecided was made from the card body alone and has been withdrawn on the card. The clause now states that the divergence is ruled, cites the ruling comment, and says the guard's reading is the decided one — while noting the carve-out text above has not yet been rewritten, so a reader must not act on it in the meantime. Rewriting that text is the separate implementation card's job, not this PR's. Word-level edit inside the existing line: the paragraph stays one line, both files keep their line totals (AGENTS.md 489, CLAUDE.md 51), and the carve-out sentences remain byte-identical to origin/main. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
os-zhuang
approved these changes
Aug 31, 2026
os-zhuang
marked this pull request as ready for review
August 31, 2026 07:17
Uh oh!
There was an error while loading. Please reload this page.
os-sam pushed a commit
that referenced
this pull request
Aug 31, 2026
Conflict resolution, one file, one hunk: the backstop paragraph. While this branch sat in the merge queue, the maintainer landed #6976 (ba55fb5), which rewrote the same paragraph under the title "correct the stale no-mechanical-backstop claim". That paragraph is authoritative and is taken VERBATIM; this branch's competing rewrite of it is discarded in full, not blended. Byte-checked: the whole paragraph up to its trailing caveat clause is identical to origin/main (sha256 of the 1393-byte prefix matches), including the CODEOWNERS sentence, the "尚未是 required context" sentence and "在翻转之前,那条拒绝腿只报告、不阻止队列". The branch's remaining edits auto-merged and are re-derived rather than replayed: the list heading 四项 -> 五项, the new repo-root `skills/**` row (`GOVERNED_SURFACES`'s `skills-catalog`), the docs/adr row's 上面三项 -> 上面四项 (verified: exactly 4 rows precede it), the⚠️ block flipped to "both skills trees are governed" while keeping `.agents/skills/` NOT governed, and the inverted-scolding paragraph, which still taught the retired ".claude/-prefix" criterion on main and now records it as the past error. One consequential edit beyond the branch: the maintainer's own trailing caveat said the script's set and the list above "并不一致 ... 落地仍挂在 #6866 上,在它落地前 ⛔ 不要照上面那条豁免行事". This commit IS that landing, so the clause is updated minimally to record the ruling as landed and the old exemption as void. Nothing else in the paragraph is touched. The ruling being implemented is the maintainer's 5th adjudication batch item #7, Option A, recorded on #6866 comment 5469339478. No ruling is made here. Verification (offline; both scripts import only node: builtins plus scripts/invoked-as.mjs, so no install is in their closure): node scripts/check-governed-queue-guard.mjs --self-test -> exit 0, "OK check-governed-queue-guard self-test: 132 cases pass" node scripts/check-governed-queue-guard.mjs --test AGENTS.md -> exit 3, "⛔ GOVERNED — 1 of 1 path(s) are on a governed surface" Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
huangyiirene pushed a commit
that referenced
this pull request
Aug 31, 2026
…diation text `.claude/hooks/guard-main-checkout.sh` and `.claude/hooks/guard-main-checkout-bash.sh` each end their block message with the worktree recipe to run instead, and both created the branch with a plain `-b`. PR #6976 hardened the prescribed form in `CLAUDE.md` and `AGENTS.md`; the hooks' copy was left behind — and it is the higher-leverage copy, delivered at the exact moment an agent is about to act, so it is the one most likely to be run verbatim. The hazard is the one #6976 established: plain `-b` writes the new branch's upstream keys (`branch.NAME.remote`, `branch.NAME.merge`) into the one `.git/config` that every linked worktree of a repo shares. That write can fail after the branch is created, leaving a branch with no worktree — a half state the error text does not name. Read as "the worktree exists", the agent starts editing the shared primary checkout, which is the one thing these two guards exist to prevent. Additive, not a recipe rewrite: this repo's hooks already emitted the fetch-hardened base (`git fetch origin main && … origin/main`, landed for ui#6208), so the missing flag was the only surviving divergence from the prescribed form. One word added per file, net ±0 lines in both. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EnE7G31tqbxN1rqpQmzurT
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 freeto 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.
Fixes#6880
Part of #6866 — its half 1 stays open (implementation tracked there) and is untouched here.
Two instruction-file corrections on the same governed face, folded into one PR because they
land in the same file and would otherwise be hard-serial.
1. The worktree recipe now specifies
--no-track(the anchor card)Byte-level insert into the two prescribed spellings, net 0 lines:
CLAUDE.md:16— the fenced recipe.AGENTS.md:234— the same recipe inline.(Placeholders written as words here; the files use angle-bracket placeholders.)
Plain
-bwrites the new branch's upstream keys —branch.NAME.remoteandbranch.NAME.merge— into the one.git/configthat every linked worktree of a reposhares. That write can fail after the branch is created, leaving a branch with no
worktree: a half state in the very first step of the recipe, and one the error text does not
name. Read as "the whole command failed", the retry hits
branch already existsand readsas a second, unrelated problem; read as "the worktree exists", the agent starts editing the
shared primary checkout — the single thing the worktree-first rule exists to prevent.
The measured basis is the anchor card's git 2.43.0 table, cited rather than re-derived:
--no-trackremoves the config write and still bases the worktree onorigin/main;explicit
git pull origin mainis unaffected (it uses the given refspec, neverbranch.NAME.merge), andgit push -u origin BRANCH— already the prescribed first push —sets an upstream one command later.
This PR ate its own dogfood: its worktree was created with the hardened recipe.
Scope pin honoured (anchor triage, comment 5473464940)
No shared-namespace prose was extended.
.git/configappears nowhere new in theinstruction text.
2. The "no mechanical backstop" paragraph, corrected in place (#6866 half 2)
Scope pin honoured (comment 5473466315)
The paragraph re-derived to
AGENTS.md:433(the card's:392had drifted). Claim by claim,measured on this branch's base:
Two of those were not in the card and turned up while reading: the audit-coverage sentence
is false for the same reason the headline claim is, and it sits in the same paragraph, so
leaving it would have meant knowingly shipping a corrected paragraph that still asserts a
measured-false absence.
⭐ The sharpest corroboration is internal: the same file already named the guard 59 lines
above, at
AGENTS.md:372-376, as the workflow a tree enumeration missed. The documentcontradicted itself, and the half asserting the absence was the half written to be trusted
absolutely.
The replacement keeps every claim that is still true, then names the guard
(
.github/workflows/governed-surface-guard.yml, checkGoverned Surface Queue Guard,predicate in
scripts/check-governed-queue-guard.mjs), states both legs — thepull_requestleg deliberately exits 0, so green does not mean ungoverned, which is themisread this paragraph would otherwise invite — records that the refusing
merge_grouplegonly reports until the ruleset toggle is flipped, and points coverage at the script's own
GOVERNED_SURFACESrather than restating a closed inventory that goes stale the next time aguard is added. That last part is the paragraph's own promise being kept in a form that
cannot rot the same way.
The divergence clause (amended at
623b713)The paragraph's closing clause originally described the guard-vs-carve-out divergence as an
open adjudication. That was stale on arrival: the maintainer had already ruled it on
2026-08-30 (第 5 场决裁批 #7, verbatim 「批 #7 同意」 — Option A, ui#6866 comment
5469339478). The clause now records the ruling itself — published
skills/**is governed,the guard's reading is the ruled one, implementation pending on #6866 — and forbids acting
on the carve-out until that lands. The carve-out sentences at
AGENTS.md:419/:421remainbyte-identical in this PR; their Option-A rewrite is #6866's follow-up implementation,
deliberately not folded in here.
Not in this PR
.git/configshared-namespace prose extension — deferred to objectstack#13597.(
.claude/hooks/guard-main-checkout.sh:57and.claude/hooks/guard-main-checkout-bash.sh:544). That is the text an agent reads at theexact moment it is about to run the command, so the hazard survives there. Carded as
[finding] guard-main-checkout hooks' remediation text still teaches the unhardened worktree recipe (no --no-track) — the copy an agent reads at the moment of the blocked action #6977 (this repo) and objectstack#13663 (the twins there, which also base on unfetched
local
main). The historical changeset.changeset/6208-worktree-recipe-fetch-base.mdquotes the old form and was deliberately left alone — it is a record of a past change,
not a prescription.
Validation
Round 1 at
64d6421, amend re-run at623b713; exit codes captured before any pipe.check:control-bytes✅ check-control-bytes: OK (scanned 5804 tracked text file(s); skipped 85 binary).check:doc-fences✅ check:doc-fences — every TypeScript block in 224 document(s) is fenced ts/tsx/typescriptcheck:governed-queue-guardOK check-governed-queue-guard self-test: 132 cases passcheck-changeset-presence.mjs✅ No source of a released package changed in this range, so no changeset is owed.check-doc-links.mjsLinks are valid across 17 scan roots.121 passed, 0 failed·41 passed, 0 failed·36 passed, 0 failedAnchored greps with positive controls (after the amend):
--no-track1 in each file;本仓没有任何机械兜底0;本段没点名的兜底工具0;这一分歧在 #6866 待维护者裁决0;批 #71; controls —受管面inAGENTS.md7;PreToolUse5;guard-shared-stash.shinCLAUDE.md1. Line totals unchanged:CLAUDE.md51,AGENTS.md489 — net 0 lines in both.The guard, run against this PR's own file list, agrees with what the new paragraph says
about it:
Landing
Governed surface ⇒ draft, human merge (
pm:awaiting-maintainerper 批 #7's executionnote). ⛔ Not flipped ready, not enqueued, no auto-merge. The changeset carries empty
frontmatter — this repo's measured form for a non-publishing change (precedent:
.changeset/6208-worktree-recipe-fetch-base.md, the same change class).Generated by Claude Code