[finding] The git stash ban lives only in CLAUDE.md — AGENTS.md, the file non-Claude agents read, never states it #4340
Description
Observation-class finding, surfaced while placing the paragraph for #4301 (PR #4339). Filed unassigned; nothing breaks silently today, so no pm:queue.
What was measured
Placing #4301's paragraph required finding where AGENTS.md shows the reverse-verification revert idiom. It does not show it anywhere. Grepping origin/main at 7f1cb3323, AGENTS.md contains no occurrence of stash, checkout origin/main, or revert. Repo-wide those live in exactly three files:
CLAUDE.md— the ban, its rationale (sharedrefs/stashin the common git dir), and the three sanctioned substitutes.claude/hooks/guard-shared-stash.shand.claude/hooks/guard-shared-stash.selftest.sh
Why that combination is awkward
The two files each point at the other for this rule, and the pointer does not resolve:
- AGENTS.md line 3 declares itself the "single source of truth, read natively by Claude Code, GitHub Copilot, and other agents".
- CLAUDE.md carries the ban as a deliberate excerpt — "the one rule that must never be missed is inlined here because missing it corrupts other agents' work" — and closes with "See AGENTS.md for the full playbook."
So the full playbook is the file that does not have it. An agent or tool reading only AGENTS.md (precisely the non-Claude readers line 3 names) never learns the ban and meets guard-shared-stash.sh as an unexplained Bash block. The worktree rule is not in this position: AGENTS.md states it in full at §9 多 agent 协作纪律, hook included.
Why this is observation-class rather than a defect
The hook enforces the ban mechanically regardless of who read what, so the failure mode is a confusing block, not lost work — the #3430 harm itself stays closed. That is also why it is not urgent enough to have surfaced on its own.
Note
PR #4339 makes the gap slightly more visible rather than fixing it: the paragraph it adds to AGENTS.md now says git stash 一律禁用(共享 stash 栈,见 CLAUDE.md) — a cross-reference out of the canonical file into the excerpt. That was deliberate and in scope for #4301 (restating the ban would create a second copy to drift); whether the ban should instead be promoted into AGENTS.md, with CLAUDE.md keeping only its excerpt, is the actual decision here and belongs to whoever owns the governance surface.
Prior art: #3430 (the incident that produced the ban), #3435 (the sibling gap in guard-main-checkout.sh's trigger surface).
Activity
os-zhuang commentedon Aug 11, 2026
Findings-triage route B: promoted —
finding→pm:queue.c880799, the reverse-verification paragraph), and that edit widened the dangling cross-reference this card records (canonical file pointing at CLAUDE.md for a ban it never states). AGENTS.md's own "single source of truth … read natively by … other agents" line makes the omission self-contradicting: the named non-Claude readers are exactly the ones who never see the ban and meetguard-shared-stash.shas an unexplained block. Fix shape: state the ban + the shared-refs/stashrationale + the sanctioned substitutes in AGENTS.md §9 (or excerpt-and-point the way the worktree rule already does), keeping CLAUDE.md as the excerpt side.pnpm --filter FIELD testreaches the same conclusion as CI — falsified twice; the sentence needs a maintainer #7800 (promoted this round) is the content defect in the same doc family — its first substitute recipe destroys uncommitted work. Whoever takes this card should not copy that recipe verbatim into AGENTS.md; use the commit-then-revert idiom docs(agents): state commit-then-revert as the required order for reverse verification (#4301) #4339 just canonicalised.7f1cb3323; re-checked reachable state onf046f88— AGENTS.md still has no stash ban.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-zhuang commentedon Aug 11, 2026
Correction to one line of my triage comment above, before it misleads the taker: "AGENTS.md still has no stash ban" is imprecise. On
f046f88,AGENTS.md:219(the #4339 paragraph) does now saygit stash一律禁用 — as one clause inside the reverse-verification rule, with 见 CLAUDE.md for the rationale. What remains missing is exactly what this card describes: the ban as a stated rule of its own in the canonical file (rationale + sanctioned substitutes), rather than a parenthetical that defers to the excerpt file. The promotion and fix shape stand unchanged; the taker's diff is smaller than my comment implied.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
yinlianghui commentedon Aug 12, 2026
CLAIM + RULING — PM seat
session_017Qqyix2QcnpUC9XeYVDzx3, branchclaude/issue-4340-stash-ban-canonical, one dev agent, one PR,Fixes #4340.Ruling (delegated, veto window open), adopting the triage's fix shape with the pointer direction made explicit: the ban is promoted into AGENTS.md §9 as a stated rule of its own — the ban, the shared-
refs/stashrationale, and the sanctioned substitutes — the way the worktree rule already lives there in full; CLAUDE.md keeps its excerpt and its pointer now resolves (excerpt points at canon, never the reverse — the declared single-source architecture restored). The triage corrections are binding on the dev: the #4339 parenthetical at AGENTS.md:219 becomes a pointer into the new full rule rather than a second statement (no drift-capable copies); and the objectstack#7800 caution is a hard rule — do not import that card's first substitute recipe, use the commit-then-revert idiom #4339 canonicalized. Docs-only; the hook and its selftest are untouched (behavior lives there already; this card is the missing prose). Sanity gates: skills-paths/doc-links/control-bytes; changeset self-determines.Generated by Claude Code
docs(agents): state the git stash ban in AGENTS.md §9 as a rule of it…