Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · GitHub
Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · GitHub
Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · GitHub
Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · GitHub
Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · GitHub
Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · GitHub
Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · GitHub
Skip to content

Base the worktree recipe on a fetched origin/main - #6449

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base
Aug 29, 2026
Merged

Base the worktree recipe on a fetched origin/main#6449
os-elon merged 1 commit into
mainfrom
claude/issue-6208-worktree-recipe-fetch-base

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#6208

Ports the repair landed upstream in objectstack#11934 (objectstack#11540), whose body notes this repo's copy was deliberately left to this card.

The defect

The documented worktree recipe branched off the localmain ref, which nothing in the recipe or its surrounding prose fetches. A worktree created by following it literally starts as far back as whoever last happened to update that ref — and on a long-lived shared checkout, nobody has a reason to.

Drift re-measured on THIS repo, not relayed

Measured on this repo's live shared checkout (/home/user/objectui) at claim time. The upstream card's numbers are its own snapshot of a different repo; these are this one's.

$ git -C /home/user/objectui rev-parse --short main origin/main
60d452ee0
c8ea8af9c
$ git -C /home/user/objectui log -1 --format='%ci' main
2026-08-21 03:27:52 +0000
$ git -C /home/user/objectui log -1 --format='%ci' origin/main
2026-08-26 00:13:35 +0000
$ git -C /home/user/objectui rev-list --count main..origin/main
473
$ git -C /home/user/objectui rev-list --count origin/main..main
0
readingvalue
local main60d452ee0 · 2026-08-21T03:27:52Z
origin/mainc8ea8af9c · 2026-08-26T00:13:35Z
local main behind origin/main473 commits
age gap116.8 hours (4.9 days)

The second rev-list is the positive control: 0 in the other direction, so this is a strict lag, not a divergence.

It is not an abstract lag for this PR in particular. Across that same range:

$ git -C /home/user/objectui diff --numstat main...origin/main -- AGENTS.md CLAUDE.md
109	1	AGENTS.md

Following the old recipe to fix the old recipe would have based this branch on a copy of AGENTS.md that is 109 lines out of date.

origin/main alone would have the same defect one layer down — it is a local ref only a fetch moves — so each fixed site begins with an explicit git fetch origin main &&. Measured here: that fetch moved origin/main0 commits, because another agent had fetched ten minutes earlier. Luck, not a guarantee, which is the point.

Sites enumerated and judged one by one

Enumerated independently (git grep -n 'worktree add' origin/main, plus a wider worktree sweep across the repo) rather than inherited from the card:

siteverdictwhy
CLAUDE.md:16inbare main base — the site the card named
AGENTS.md:234 (§9 多 agent 协作纪律)inbare main base, inside the fuller Chinese statement of the rule
.claude/hooks/guard-main-checkout.sh:57in⭐ the recipe the guard prints when it blocks an edit — same bare main base. Not named by the card. This is the copy an agent is most likely to run verbatim, because it arrives at the exact moment the agent needs it
.claude/hooks/guard-main-checkout-bash.sh:544in⭐ same recipe, same defect, in the Bash-side guard's block message
CLAUDE.md:40outthe -cmp comparison-tree line takes an explicit <ref> from the caller — correct as written
AGENTS.md:240outsame
.claude/hooks/guard-main-checkout-bash.selftest.sh:40outtest scaffolding: git worktree add -q "$WT" -b selftest-wt inside a throwaway temp repo. Not a recipe anyone follows, and it has no shared checkout to be stale against
content/docs/guide/ci-cd-pipeline.md:1592outprose that mentions the worktree-first rule; carries no recipe
scripts/pm/check-half-states.mjs:1494outa comment reading "fixed at git worktree add time"; not a recipe

After the change, grep -rn 'worktree add' --include='*.md' --include='*.sh' | grep -v origin/main returns exactly the three out sites and nothing else.

What the upstream template did differently, and why

  • Site set. objectstack#11934's three in-scope sites were all prose (AGENTS.md:173, AGENTS.md:203, CLAUDE.md:33); one of them had no base ref at all, which this repo has no equivalent of. Its .claude/ guards do not print the recipe in their block message, so it had no hook sites to judge. This repo's two guards do, so two sites are in here that had no counterpart upstream.
  • Second half not ported. #11934 also taught scripts/pm/dispatch-gates.mjs to announce a stale tree. That file does not exist in this repo (scripts/pm/ here holds only check-half-states.mjs), so there is nothing to port; the recipe half is the whole of this card.
  • Line-budget fence. Upstream both files sat at shrink-only ratchet ceilings with zero headroom and the repair had to be paid by reflowing a paragraph. This repo has no line ratchet on AGENTS.md / CLAUDE.md — no CEILINGS map covers them and no workflow measures their length. Checked rather than assumed. The repair was still spliced in place: net ±0 lines on all four files (CLAUDE.md 51, AGENTS.md 448, guard-main-checkout.sh 64, guard-main-checkout-bash.sh 561 — identical before and after).

The shape now landed

git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Gates — all run at 3e77bb6c3, the final commit

The whole scripts/__tests__ tree, not a subject-matter subset:

$ pnpm exec vitest run --project unit --maxWorkers=2 scripts/__tests__
Test Files 81 passed (81)
Tests 2318 passed (2318)
VITEST_EXIT=0

(That run prints a check-vi-mock-specifiers: the population COLLAPSED banner on stderr. It is a deliberate fixture — scripts/__tests__/check-vi-mock-specifiers.test.ts:371 asserts the gate emits exactly that text when fed an empty tree — not a failure.)

Every gate family the changed paths (AGENTS.md, CLAUDE.md, .claude/hooks/*.sh, .changeset/*.md) trigger, derived from this repo's own package.json and .github/workflows/, quoting each gate's own verdict line:

check:control-bytes ✅ check-control-bytes: OK (scanned 5327 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 13 fence(s); CLAUDE.md: 1 file(s), 2 fence(s); …)
check:doc-fences ✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript …
check:skills-paths ✅ check-skills-paths: OK (93/94 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-changeset-no-major ✅ No changeset declares a `major` bump.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
docs:check-links Links are valid across 17 scan roots.
guard-main-checkout-bash.selftest.sh 121 passed, 0 failed
guard-shared-stash.selftest.sh 41 passed, 0 failed

Both hook self-tests are re-run because .claude/hooks/*.sh changed; .github/workflows/hook-selftests.yml runs them in CI. Note guard-main-checkout.sh has no self-test of its own — its edited line is a message string, unpinned by any gate here.

Changeset added with empty frontmatter (.changeset/6208-worktree-recipe-fetch-base.md): instruction-file and hook prose only, no published package's src/ changed, so nothing ships. This repo has no skip-changeset label; the empty-frontmatter changeset is how that is declared here.

Governance

⛔ Governed surface (CLAUDE.md, AGENTS.md, .claude/**). This PR stays draft — not flipped ready, not armed, not queued. update_pull_request was deliberately not called: that endpoint sends draft: false alongside a reviewers-only update and published a governed-surface draft into the merge queue earlier today (PR #6183, recorded as objectstack#12200 and decision card #6325). No reviewer was requested through the API for the same reason.

Review requested from @os-zhuang by mention — a mention notifies without touching draft state. The hand-merge is the review record.

One declared deviation

The dispatch order said to create the worktree with the recipe as written (… -b <branch> main). It was created off a freshly fetched origin/main instead, and this is flagged rather than done quietly: the measurement above put local main 473 commits behind with AGENTS.md itself 109 lines out of date, so following the defective recipe would have written this repair on top of a stale copy of the very file it repairs. Base commit: c8ea8af9c, which is origin/main at claim time.

Generated by Claude Code


Generated by Claude Code

The documented worktree recipe branched off the local `main` ref, which
nothing in the recipe or its surrounding prose fetches. A worktree created
by following it literally starts as far back as whoever last happened to
update that ref -- and on a long-lived shared checkout, nobody has a reason
to. Measured on this repo's shared checkout at claim time: local `main` was
473 commits / 116.8 hours behind `origin/main`.
`origin/main` alone would carry the same defect one layer down, since it too
is a local ref only a fetch moves, so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base.
Four sites repaired: `CLAUDE.md`, `AGENTS.md` §9, and the recipe both
worktree guards print when they block an edit -- the copy an agent is most
likely to run verbatim. The two `-cmp` comparison-tree lines take an
explicit ref from the caller and are correct as written; they are unchanged.
Net ±0 lines on every file touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CZgmFFzqA9cX8tBMhvpFe
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 26, 2026
@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Reading note — the body's angle-bracket placeholders were eaten on write

GitHub's body sanitizer strips short <…> fragments, including inside backticks and fenced blocks. Three places in the PR body above are therefore missing their placeholders and read wrong:

body linewhat it says nowwhat it should say
"The shape now landed" fencegit worktree add ../- -b origin/maingit worktree add ../REPO-TASK -b BRANCH origin/main
the CLAUDE.md:40out row"takes an explicit `` from the caller"takes an explicit REF from the caller
the deviation section"the recipe as written (… -b main)"the recipe as written (… -b BRANCH main)

Restated with sanitizer-safe spellings — this is the shape now landed at all four in-scope sites (uppercase words stand in for the angle-bracket placeholders the files actually carry):

git fetch origin main && git worktree add ../REPO-TASK -b BRANCH origin/main && cd ../REPO-TASK && pnpm install

⛔ The body was not edited to repair this. update_pull_request sends draft: false alongside a body-only update, which is how a governed-surface draft reached the merge queue without human review earlier today (PR #6183). A comment carries the correction without touching draft state.

The diff itself is unaffected — the sanitizer only rewrites the PR body, never the committed files. Verified at 3e77bb6c3:

$ git show 3e77bb6c3:CLAUDE.md | sed -n '16p'
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install

Reviewer: @os-zhuang.

Generated by Claude Code


Generated by Claude Code

@os-warrenClaude

Copy link
Copy Markdown
CollaboratorAuthor

Correction to my own previous comment: its closing verification block was eaten by the same sanitizer it was describing, so it now shows the stripped form and appears to contradict the claim above it. Comments are not a safe channel for this either — only the uppercase substitutions in that comment's table survived.

Stated without any angle brackets, so nothing can be stripped: line 16 of the committed CLAUDE.md carries its angle-bracket placeholders intact. The mutation applies to PR/issue body and comment text only; it never touches committed file bytes. Confirmed against the rendered PR page rather than the API alone, per AGENTS.md's caution that a body reading short through the API may still be intact.

Review the diff, not any quotation of it in this thread. The Files-changed view is the authoritative rendering of what this PR does; every prose quotation of the recipe on this page is lossy by construction.

Generated by Claude Code


Generated by Claude Code

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

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The worktree recipe in CLAUDE.md / AGENTS.md branches off local main, a ref nothing in the recipe fetches — the objectui half of objectstack#11540

2 participants

@os-warren@claude