Skip to content

docs(pm-dispatch): pin the shared checkout to a detached origin/main before a subagent batch - #24685

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24585-detached-main-checkout
Oct 20, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24585-detached-main-checkout

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #24585
Clause-②: no

What changed

One section of .claude/skills/pm-dispatch/references/dispatch-runbook.md, the pre-dispatch step for a subagent batch (lines 137-141). The PM seat no longer fast-forwards its session branch on the shared checkout. It fetches main and checks out origin/main detached:

git -C REPO-ROOT fetch origin main && git -C REPO-ROOT checkout --detach origin/main

(REPO-ROOT stands for the file's existing placeholder spelling, which is unchanged in the file.)

  • L137, the heading: "先快进本地检出" becomes "先把本地检出钉到 main".
  • L139: the old 139 and the reason half of the old 141 merge into one line. Subagents read agent definitions and skill text from the local checkout, so a stale checkout gives the whole batch stale definitions.
  • L140: the command above replaces pull --ff-only origin main.
  • L141: states the properties the new form actually has. On a detached HEAD the stop hook skips its branch block, and the session branch is never fast-forwarded. Only dirty changes that conflict with the switch are refused, and divergence is not refused. This replaces the old promise that --ff-only makes "a dirty or diverged checkout fail loudly". The measurements below show that half of that promise was never true for dirty changes, and that the new form drops the divergence half.

Ruling of record: the maintainer's 「技能侧可选改法,立skills卡片」, recorded verbatim in the card body. The carded option is implemented exactly as written. The two items in the card's "Not in this card" section are untouched: the hook's own counting, and the stale local ref.

Line budget

  • File: 241 lines before, 241 after. The ceiling is 241 (check:pm-skill-ratchet: "is 241 lines (ceiling 241; headroom 0)").
  • Lines changed: 4 replaced in place. Nothing was re-wrapped to make room.
  • Bytes per changed line, without the newline, against MAX_LINE_BYTES = 120: L137 49 to 57; L139 100 to 113; L140 87 to 111; L141 117 to 120.
  • The dispatch's premise quoted L140 and L141 as 88 and 118 bytes. Those figures include the newline. The gate counts without it, so its numbers are 87 and 117.

The three measurements the card asks for

All readings were taken on origin/main eadea5720 (this branch's base). The git-behaviour probe ran in a throwaway repository under the session scratchpad: a bare origin, an author clone, and a "shared" clone on a session branch whose origin/SESSION-BRANCH ref was written locally and never pushed. The probe never touched the shared checkout, and it was deleted before this PR. The stop hook script itself was read only: it was not executed and not modified. The probe ran the same git commands the hook runs.

1. Every reader of the shared checkout's branch name

git grep -nE "abbrev-ref|show-current|symbolic-ref|symbolic-full-name|@\{u\}|..." HEAD -- .claude/ scripts/pm/ .githooks/ returns 11 hits. Three of them read a branch name. The others are prose about detached processes or clones.

Reader What it does with the name On a detached HEAD
.claude/hooks/guard-main-checkout.sh:120 rev-parse --abbrev-ref HEAD, printed in the refusal text at L132 only. Whether to block is decided structurally (git-dir vs common-dir, L114-117). Prints HEAD (probe E). The block decision is unchanged.
.claude/hooks/guard-main-checkout-bash.sh Reads no branch name: zero hits. Same structural git-dir vs common-dir test (L347-350). Unaffected.
scripts/pm/os-regen-merge.sh:891 (mode_run) Refuses main and HEAD. Refuses to run on the shared checkout, with exit 1. That is stricter than today: on the session branch it would proceed. :729 writes the name into its record only after mode_run passed, so only in a dev worktree.
scripts/pm/check-harness-current.mjs Reads rev-parse HEAD as a sha (L124, L139, L141, L157) and no name. Unaffected.
.githooks/pre-commit, .githooks/pre-push Zero branch-name reads. The seat never commits or pushes from the shared checkout. Unaffected.

2. Other fast-forwards in the skill or os-dev.md that assume a branch

git grep -nE "git pull|pull --|快进|fast-forward|--ff\b|ff-only|共享检出|shared checkout|本地检出|primary checkout" HEAD -- .claude/skills/pm-dispatch/ .claude/agents/os-dev.md returns 11 hits. The only fast-forward is the one this PR replaces (old L140-141). The rest are:

  • SKILL.md:31 and os-dev.md:28 say never edit the shared checkout. Compatible.
  • reading-discipline.md:8 says do not verify main from the shared checkout's tree. Compatible.
  • seat-lifecycle.md:21 is the harness-current reading, which works by sha. Compatible.
  • platform-readings.md:59 uses 快进 for squash committer dates. Unrelated.

Outside the skill, scripts/check-skill-frame-freshness.mjs:136 prints the remedy git fetch origin main && git merge --ff-only origin/main. It runs in whatever checkout invokes it; os-dev.md:151 lists it as a dev-worktree local family. Probe D: on a detached HEAD, that merge fast-forwards HEAD with exit 0, and branch --show-current stays empty, so it is compatible.

3. The stop hook's control flow, and whether it stays silent across rounds

Source: /root/.claude/stop-hook-git-check.sh, md5 d36da5d989abb71904a379c7de566b95, read only.

  • L6-24: recursion guard, not a git repo, or no remote, then exit 0.
  • L27-37: uncommitted or untracked changes, then exit 2. This runs before any branch read, so it still fires on a dirty detached checkout. That is correct, and this change does not alter it.
  • L39-40: current_branch=$(git branch --show-current), then if [[ -n "$current_branch" ]]. Everything else lives inside that block: the signing check (L77-114) and the $upstream..HEAD count (L116-124).
  • L127: exit 0.
  • Reading: on a detached HEAD, git branch --show-current prints an empty string. The whole branch block is skipped and the hook exits 0. The card's claim is confirmed.

Probe readings, using the hook's own commands:

Step branch --show-current Hook branch block rev-list origin/BRANCH..HEAD HEAD ^origin/main
A1, old recipe, after 3 commits land on main claude/sess entered 3 (the reported symptom) 0
A2, new recipe, round 1 empty skipped n/a 0
A3, new recipe, round 2 empty skipped n/a 0
A4, new recipe, round 3 empty skipped n/a 0

After A2 the session branch ref is still present and unmoved. NOT MEASURED: a live seat session's stop hook across several real dispatch rounds. That needs this text landed and a seat running it, and the hook belongs to the harness, which this run must not execute. The seat can confirm it on its first rounds after landing.

Live reading of the shared checkout at this PR's open (read only): it is on claude/eloquent-curie-6slepw at 3a931fca1. Its remote branch exists at the same sha, a zero-diff mirror of main pushed by the seat. This is the cost the card names. origin/main is already 2 commits ahead, so the next fast-forward under the old text would show 2 "unpushed" commits.

The refusal surface, old vs new (probe B and C)

Case pull --ff-only (old) checkout --detach origin/main (new)
B1: dirty tracked file the incoming commits do not touch exit 0, change carried along exit 0, change carried along (M b.txt)
B2: dirty tracked file the incoming commits touch exit 1, "would be overwritten by merge" exit 1, "would be overwritten by checkout"
B3: untracked file colliding with an incoming file not run exit 1, "untracked working tree files would be overwritten"
C1: local commit on the session branch exit 128, "Not possible to fast-forward" exit 0; the commit stays on the session branch
C2: local commit on the detached HEAD not applicable exit 0 with "you are leaving 1 commit behind"; the commit is reachable from no ref

So the old line's "dirty fails loudly" held only for B2 under either form. Its "diverged fails loudly" is lost: C1 and C2 both exit 0. The new L141 says this ("不拒分叉") instead of carrying the old promise forward. Divergence on the shared checkout already breaks the never-edit rule (SKILL.md:31, plus the two PreToolUse guards). In C1 the commit survives on its branch; in C2 it survives only in the reflog.

Gates

All 17 derived families exit 0 at ee7b8181e (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, change set derived from git: 1 path, +4/-4). Each exit code was captured before any pipe:

  • node scripts/check-closing-keyword-parity.mjs: 0
  • node scripts/check-closing-keyword-parity.mjs --self-test: 0
  • node scripts/check-comment-mask-corpus.mjs: 0
  • node scripts/pm/check-harness-current.mjs --self-test: 0
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions: the first attempt exited 3 (PREREQUISITE NOT MET: formula and lint not built), so nothing was measured. After turbo run build --filter=@objectstack/formula --filter=@objectstack/lint under the verify lock, it exits 0.
  • pnpm check:agent-test-spelling: 0
  • pnpm check:cross-package-test-inputs: 0
  • pnpm check:doc-authoring: 0
  • pnpm check:driver-memory-census: 0
  • pnpm check:gitlink-declared: 0
  • pnpm check:nul-bytes: 0
  • pnpm check:pm-governed-merges: 0
  • pnpm check:pm-skill-id-lint: 0 ("87 file(s) clean")
  • pnpm check:pm-skill-ratchet: 0 ("dispatch-runbook.md is 241 lines (ceiling 241; headroom 0)"; the 120-byte line check prints only on failure)
  • pnpm check:refd-timer-probe: 0
  • pnpm check:skill-frame-sync: 0
  • pnpm check:watch-hint-literal: 0

Reconciliation with --ran (each line annotated with its exit code): "17 derived, 17 run, 0 NOT-MEASURED, 0 UNRUN", and "a DERIVED zero — all 17 recorded an exit code and none of them is 3".

No package is touched, so there is no dependency-closure build and no package test or typecheck. .claude/** publishes nothing, so this PR carries skip-changeset.

Acceptance notes

  • The header of scripts/pm/check-harness-current.mjs says "the primary checkout is not advanced in place (worktree-first)". The runbook has advanced it in place before every batch, both before this PR (fast-forward) and after it (detached checkout). This is comment drift and nothing reads it. Carrier: none.
  • os-regen-merge.sh will now refuse on the shared checkout (HEAD), where before it would have run on the session branch. This is a side effect in the safe direction, noted only.
  • One instance of the card's cost, taken from the dispatch as an example and not as a ruling: the environment pre-created origin/claude/eloquent-curie-6slepw, and the seat pushed the shared checkout there twice as a zero-diff mirror of main.

维护者速读(草稿)

改了什么 —— PM 席位每批派发子代理前,不再在会话分支上快进本地检出,改为取回 main 后以游离 HEAD 钉在 origin/main。只改技能手册的一节,4 行原位替换,行数不变。

为什么改 —— 云端停止钩子按会话分支计未推送提交。快进让 main 的提交挂到会话分支上,钩子每轮提示推送。照做会推出与 main 零差异的分支,本席位已推过两次。游离 HEAD 下钩子跳过分支检查,提示消失。子代理读到的仍是最新定义。

风险与代价(含回滚) —— 新写法不再拒绝分叉,共享检出上若有本地提交会被丢下或留在原分支。但共享检出本就禁止编辑,有两道钩子把守。与切换冲突的脏改动仍被拒。回滚即还原这 4 行。

席位意见 ——

你要做的 ——


Generated by Claude Code

…before a subagent batch

The pre-dispatch step fast-forwarded the session branch, so the cloud
stop hook counted main's commits against a never-pushed origin ref of
that branch and asked the seat to push a zero-diff mirror of main.
Fetch, then check out origin/main detached: the hook reads an empty
current branch and skips its branch block. State the real refusal
surface of the new form (only dirty changes that conflict with the
switch; divergence is not refused). Line-neutral: 241/241.

Claude-Session: https://claude.ai/code/session_01HEdP5tPhqQfzwRmKDxwn85
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review — 2026-10-19T23:41Z

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: ee7b8181e87eb58bd945ef6fb379189d65621537
Local-runs: none
Scope: .claude/skills/pm-dispatch/references/dispatch-runbook.md + .claude/hooks/guard-main-checkout.sh, .claude/hooks/guard-main-checkout-bash.sh, scripts/pm/os-regen-merge.sh, scripts/pm/check-harness-current.mjs, scripts/check-skill-frame-freshness.mjs, and the container stop hook at /root/.claude/stop-hook-git-check.sh (outside the repo, read only)

Inputs read: card #24585 body and all three comments (triage 6270321855, claim 6279366886, os-dev-report 6279634704); PR #24685 body, file list (1 file, +4/-4) and the net diff against main; 38 check-runs on the head, all completed: 26 success, 12 skipped, 0 failure (Governed Surface Queue Guard, Lint · PM dispatch-gates, Check Changeset, and the three claim/closing guards are among the successes). Cited files read at origin/main (92ce3af at review time); every cited file and the runbook are byte-identical between the PR's merge base eadea57 and that main, so the premise reads the same on today's main. Nothing was built, run or re-run; the stop hook was read, never executed.

① Derived judgments

  1. Ruling fidelity — RIGHT. The maintainer's 「技能侧可选改法,立skills卡片」 is implemented on the skill side only, and the carded option's command appears verbatim in the new L140: fetch origin main, then checkout --detach origin/main, both through git -C REPO-ROOT (the file's existing placeholder spelling, unchanged). The two items in the card's "Not in this card" section are untouched: the diff is the one file.
  2. The rule's refusal set narrows, and the text says so — RIGHT. The old L141 promised that a dirty or diverged checkout fails loudly. By git semantics, pull --ff-only refused a dirty tree only when the incoming commits touched the dirty paths, so the dirty half was over-claimed under both forms; checkout --detach keeps exactly that refusal (would be overwritten by checkout). The diverged half is genuinely lost: a local commit on the session branch stays there with exit 0, and one on an already-detached HEAD is left behind with git's own warning. Judged acceptable: a commit on the shared checkout is already a breach of SKILL.md:31 and os-dev.md:28, guarded by the two PreToolUse hooks, and the stop hook's dirty and untracked checks (its lines 27-37) run before any branch read and still fire. The step's purpose — a batch reading current definitions — is better served: HEAD equals origin/main after the step whatever the session branch holds, where the old form left the batch stale on refusal. The new L141 states the property the command has instead of carrying the old promise forward; that is the honest surface.
  3. The stop-hook claim — CONFIRMED on the file itself (md5 d36da5d989abb71904a379c7de566b95, the PR body's reading). L27-37 are the dirty and untracked checks; L39 reads git branch --show-current and L40 opens the branch block only on a non-empty value; the signing check (L77-114) and the upstream..HEAD count (L116-124) both live inside that block; L127 exits 0. A detached HEAD prints an empty string there, so the block is skipped. Live reading in this container, read only: the shared checkout is already detached at origin/main with commit.gpgsign true and a stale local origin/SESSION-BRANCH ref present — the exact shape the new rule prescribes — and the remote's fetch refspec is the full wildcard, so fetch origin main does update origin/main here.
  4. Branch-name readers, re-read in the cited code — RIGHT as the PR tabulates. guard-main-checkout.sh decides structurally at L114-117 (git-dir against git-common-dir) and reads rev-parse --abbrev-ref HEAD at L120 only for the refusal text at L132, which prints HEAD when detached. guard-main-checkout-bash.sh carries the same predicate at L347-350 and no branch read; its write roster is redirections, sed -i, perl -i, tee, cp, mv, rm, touch, so neither it nor guard-shared-stash, guard-process-kill or guard-tree-enum (the Bash matcher in .claude/settings.json) treats git fetch or git checkout as a guarded write: the new command passes the guards exactly as the old pull did. os-regen-merge.sh:891 refuses main and HEAD in mode_run, so it now refuses on the shared checkout — stricter, and correct, since its header requires the feature branch's worktree; :729 writes the name into its record only inside the sequence. check-harness-current.mjs reads HEAD as a sha only (rev-parse L139, log L141, merge-base --is-ancestor L157, diff HEAD against the ref L124). check-skill-frame-freshness.mjs:136's remedy, fetch then merge --ff-only origin/main, fast-forwards a detached HEAD without error. A grep of .claude/, scripts/, .githooks/ and .github/ at origin/main for abbrev-ref, show-current, symbolic-ref and upstream shorthand finds no other reader outside self-tests.
  5. Other fast-forwards and the heading — RIGHT. The replaced L140 was the only fast-forward in .claude/skills/pm-dispatch/** and os-dev.md; platform-readings.md:59's 快进 is about squash committer dates. The renamed heading is referenced nowhere else in the tree (a grep for the old heading text hits only the file itself), so no anchor breaks, and the claim's section name 〈subagent 批派发前置〉 is still the heading's prefix.
  6. Dev worktrees — unaffected, as the card premised: os-dev.md:26 and both guards' refusal recipes create them from origin/main with --no-track, and a detached primary checkout holds no branch that a worktree could collide with.
  7. Line budget — RIGHT. 241 lines before and after against the 241 ceiling; the four changed lines measure 57, 113, 111 and 120 utf8 bytes without the newline against MAX_LINE_BYTES 120, which the gate compares less-or-equal on newline-split lines, so L141 sits at the budget, not over it. The dispatch premise's 88 and 118 counted the newline; the dev's 87 and 117 are the gate's numbers. Nothing else moved.
  8. Text discipline and public surface — RIGHT. No tracker number in the new lines (check:pm-skill-id-lint is inside the green Lint · PM dispatch-gates run); naming the harness stop hook's branch block is the operative reason for the detach, not incident narrative. Public surface: none — .claude/** is harness text and publishes nothing.

② Semver level

  • The diff touches only .claude/skills/pm-dispatch/references/dispatch-runbook.md; no released package is in the tree and nothing publishes. The skip-changeset label is present and the Check Changeset run on the head is success — matches: RIGHT.
  • Clause-②: the PR body reads Clause-②: no with no arm, the form AGENTS.md prescribes for a diff that publishes nothing (no widening, no narrowing of a published surface). RIGHT. The served tier is read off the governed path (rules face), not off that line.
  • The commit carries the model-free trailer pair; title, body and this record name no model.

③ Boundary flags

  • open_questions: empty — nothing to answer.
  • Deviation, base eadea57 instead of the dispatch's 3a931fc — answered: the merge base is eadea57; the runbook and every cited file are identical between it and today's origin/main, and the PR is mergeable clean.
  • Deviation, L139 rewritten too — answered: inside the claimed surface (L137-141); the stale-batch rationale survives there within the byte budget; no line outside the section moved.
  • Deviation, probe in a synthetic throwaway repo — answered: acceptable; the readings are git semantics independent of this repo, the shared checkout was not touched, and the hook was read, not run — the card's constraint that the hook belongs to the harness holds.
  • Deviation, trailers follow AGENTS.md rather than the harness reminder — answered: correct precedence; the model-free pair is what the pre-push hook enforces.
  • NOT MEASURED, a live seat's stop hook across real dispatch rounds — answered, not escalated: unmeasurable from a dev run by the card's own constraint; the control-flow reading (L39-40 gates the whole branch block) decides the text, and this container's shared checkout already runs in the prescribed shape. The seat confirms silence over its first rounds after landing and notes it on the card if the hook speaks.
  • Out-of-scope 1, the check-harness-current.mjs header sentence "the primary checkout is not advanced in place" — answered: pre-existing drift (the old pull --ff-only already advanced it), not widened by this diff, and nothing reads the sentence; carrier none is within the runbook's own routing (L29: the three filing thresholds, else acceptance notes). Not escalated.
  • Out-of-scope 2, os-regen-merge.sh now refuses on the shared checkout — answered: the safe direction; its header requires a feature branch's worktree, and landing-operations.md:36-40 invokes it on the PR's branch, never on the shared checkout.
  • Reviewer's flag, not the dev's: the narrowed refusal set (divergence no longer refused) is named in L141 and judged in ①.2; no escalation. Should the maintainer want divergence kept loud, a one-line pre-check (refuse when HEAD is not an ancestor of origin/main) is a follow-up card, not a blocker on this text.
  • Landing: the PR is a draft on a Tier S surface; it lands by the owning seat on this record once the required checks stay green, per AGENTS.md Prime Directive 14.

Implemented-by: claude/issue-24585-detached-main-checkout
Reviewed-by: session_01HEdP5tPhqQfzwRmKDxwn85

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)· PR #24685 · domain:skills seat 1 · os-justin · session_01HEdP5tPhqQfzwRmKDxwn85 · 2026-10-19T23:42Z

  • 改了什么: PM 席位每批派发子代理前,不再在会话分支上 pull --ff-only,改为取回 main 后 checkout --detach origin/main。只改技能手册〈subagent 批派发前置〉一节,4 行原位替换,文件仍 241 行。
  • 为什么改: 您对 domain:cli 席说「技能侧可选改法,立skills卡片」。云端停止钩子按会话分支计未推送提交,快进让 main 的提交挂到会话分支上,钩子每轮要求推送;照做就推出与 main 零差异的分支(本席今天已推过两次)。游离 HEAD 下钩子跳过分支块,提示消失;子代理读到的仍是最新定义。
  • 风险与代价(含回滚): 新写法不再拒分叉:共享检出上若有本地提交,会留在原分支或只剩 reflog。但共享检出本就禁止编辑,两道 PreToolUse 钩子把守;与切换冲突的脏改动仍被拒。副作用一处、方向更安全:os-regen-merge.sh 在游离 HEAD 上拒跑,它本就只该在 dev worktree 里跑。回滚 = revert 一个提交。
  • 席位意见: 接受。dev 没有沿用旧行「脏或分叉都大声失败」的承诺,而是实测后写了真实性质(脏改动只拒冲突、不拒分叉),这比照抄更诚实。第 141 行恰 120 字节,无余量。本席落地后即按新写法派发,首轮实测停止钩子是否安静,记座位贴。
  • 你要做的: 无。Tier S,席位在达档复核 PASS 后入队。

席位核对

  • 形态: draft、base main、首行 Fixes #24585、第 2 行行首 Clause-②: no、assignee os-justin、skip-changeset 随创建同笔;1 文件 +4/−4;正文无尖括号、闭合关键词只有首行一处。
  • 前提实测(席位,origin/main 3a931fca1→dev 基点 eadea5720): 第 140–141 行原文如卡所引;文件 241/241;分支名读者 grep 与 dev 清单一致(guard-main-checkout.sh:120 只印名、guard-main-checkout-bash.sh 零读、os-regen-merge.sh:891 拒 HEAD、check-harness-current.mjs 只读 sha);停止钩子 /root/.claude/stop-hook-git-check.sh:39-40 以非空 current_branch 包住分支块 —— 本席自读相同。dev 报的字节 87/117 与本席的 88/118 差一个换行,以门禁口径(不含换行)为准。
  • 门禁 check-runs(head ee7b8181e): 2026-10-19T23:35Z 38 条,26 success、12 skipped、0 failed、0 in_progress;check-expected-skips --pr 24685:OK,12 skipped 全在名单;check-governed-merges --pr 24685:GOVERNED,Tier S,8 行。dev 本地 17 条派生门禁全 0,--ran 17/17。
  • 接受的偏差: 基点 eadea5720(派发令写 3a931fca1,中间两提交不碰本面);第 137、139 行也重写(在认领的 137–141 节内);探针用 scratchpad 下一次性合成仓,未碰共享检出,报告前已删;doc-formula-expressions 首跑 exit 3 为前置未建,补建后 0。
  • 范围外去向: check-harness-current.mjs 头注「primary checkout is not advanced in place」与手册不符 —— 注释漂移、无读者,记座位贴 Carried pointers,不立卡;os-regen-merge.sh 在游离 HEAD 拒跑 —— 方向更安全,只记。本席现场实例(2026-10-19T23:37Z):共享检出在 claude/eloquent-curie-6slepw 上 pull --ff-only 后,停止钩子报「3 unpushed commit(s)」并要求推送;实测 HEAD ^origin/main = 0、工作树干净,三个「未推送」提交是 main 自己的合并(fix(plugin-approvals,plugin-audit,plugin-sharing): list views drop the target object's API name column beside a record pointer #24600、fix(console): the injection assertion reads the plain runs inside long or escaped describe literals, so a .objectstack-sha pin gets a real witness #24672、fix(service-automation)!: a runAs:'user' hook fired by a user-triggered runAs:'system' flow's write runs on that user's own grants #24658)。本席拒推,随后按卡上口径把共享检出 checkout --detach origin/main(2026-10-19T23:38Z,92ce3af40):branch --show-current 为空,check-harness-current.mjs 在游离 HEAD 上照常读 CURRENT。新写法下真实席位跨轮的钩子行为由本席后续停止时实测,结果记座位贴。
  • 落地条款: Tier S;达档复核记录 PASS 在案(6279791956)后由本席 pr_ready + automerge_enable 入队。

ACCEPT


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 19, 2026 23:43
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 19, 2026 23:43
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit c663245 Oct 20, 2026
39 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-24585-detached-main-checkout branch October 20, 2026 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants