Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

[finding] The git stash ban lives only in CLAUDE.md — AGENTS.md, the file non-Claude agents read, never states it #4340

Closed

Description

@yinlianghui

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 (shared refs/stash in the common git dir), and the three sanctioned substitutes
  • .claude/hooks/guard-shared-stash.sh and .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

  1. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings-triage route B: promoted — finding → pm:queue.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    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 say git 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

  3. self-assigned this
    on Aug 12, 2026
  4. yinlianghui commented on Aug 12, 2026

    @yinlianghui
    ContributorAuthor

    CLAIM + RULING — PM seat session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/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/stash rationale, 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

  5. added a commit that references this issue on Aug 17, 2026
    c7360f6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions