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

AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(<<'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150

Closed

Description

@os-zhuang

由 PM 座席在 PR #5135(卡 #4994)合并之后的事后核查中发现 —— 那个 PR 未经报告、未经人工核验就入队合并,19 秒落地。这是那次未核验合并的唯一实质代价。

缺陷

AGENTS.md §9 新增的共享 scratchpad 条款里,「首选机制」那条的代码示例在 origin/main 上的真实字节是:

  git commit -F - <<'"'"'EOF'"'"'
  fix(scope): 一句话主题

  正文……
  EOF

'"'"' 是在单引号 shell 字符串里嵌入一个单引号的转义写法。写文件的那次调用本身套在单引号里,转义序列漏进了文件内容。应有的字节是:

  git commit -F - <<'EOF'

实测确认过是文件内容而非渲染问题(git show origin/main:AGENTS.md | sed -n '222,245p' | cat -A 明确显示 git commit -F - <<'"'"'EOF'"'"'$),不是 diff 视图的转义。

为什么值得单开一卡而不是顺手改

照抄这条示例得不到一条能用的命令。 heredoc 的终止符不再是 EOF:<< 后面那个词经 shell 引号消除后不是 EOF,所以下面那行 EOF 匹配不上,heredoc 不终止 —— 命令要么吞掉后续输入,要么等在那里。

失败形状和这条规则自己描述的那一族同类:没有报错可看。作者以为自己照做了「让内容不落共享盘」,拿到的是一条卡住的命令,于是最可能的反应是退回第 2 条(临时文件 + 前缀),也就是这条规则明确说「能用形式解决的,就别退回到纪律」的那一条。一个教你用机制替代纪律的示例,坏掉之后恰好把人推回纪律。

这也是 agent 面文本特有的放大:AGENTS.md 是之后每一个会话都要读的东西,坏示例不是被一个人踩一次,是被每一个读到它的座席各踩一次。

修复

一行,把那行的字节改成 git commit -F - <<'EOF'。周围的散文、编号、排序(机制在前、纪律在后)与那段说明为什么机制优于纪律的论证都是对的,不要动 —— 事后核查逐条对过 #4994 的裁定,三点全部成立:机制半边在场且排在纪律半边之前、被推迟的 PreToolUse 钩子没有被建、#4016 的历史标注已发(评论 5323653819)。这一条是那次落地里唯一坏掉的东西。

⚠️ 改的时候注意别重蹈覆辙:不要用套在单引号里的 shell heredoc 去写这个文件。用编辑工具直接改那一行,或者用不需要嵌套引号的写法,改完 git show HEAD:AGENTS.md | cat -A 把那两行的字节读回来确认。

复核命令

git show origin/main:AGENTS.md | grep -n "commit -F -"
git show origin/main:AGENTS.md | cat -A | grep -n "EOF"

关联:#4994(落地本条规则的卡,裁定内容正确)、PR #5135(带着这个缺陷合并的 PR)、#4016 / PR #4988(这条规则要防的那次实际损伤)。

Activity

  1. self-assigned this
    on Aug 18, 2026
  2. os-zhuang commented on Aug 18, 2026

    @os-zhuang
    ContributorAuthor

    Claiming this card.

    • session: session_01NYgmGheCzM6NrHZN436Cxf
    • branch: claude/issue-5150-agents-heredoc-escape
    • worktree: /home/user/objectui-5150

    Scope is the single line in AGENTS.md §9; surrounding prose, ordering and the mechanism-over-discipline argument stay untouched per the card.


    Generated by Claude Code

  3. os-zhuang commented on Aug 18, 2026

    @os-zhuang
    ContributorAuthor
    {
      "issue": 5150,
      "status": "done",
      "branch": "claude/issue-5150-agents-heredoc-escape",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5152",
      "premise_still_valid": true,
      "summary": "Restored the intended bytes of the AGENTS.md 9 heredoc example: the shared-scratchpad clause's mechanism half now reads `git commit -F - <<'EOF'` instead of the leaked single-quote-in-single-quote escape. One line, 1 insertion / 1 deletion, applied with an editing tool rather than a nested-quoted shell heredoc (the write path that caused the defect). Surrounding prose, numbered ordering and the mechanism-over-discipline argument untouched, as the card required. Draft PR #5152 open; not marked ready, no auto-merge, not enqueued.",
      "tests": "All gates run at final commit 55ab4c9 (git rev-parse --short HEAD), after the last commit. Derived union by inspecting each script's real scan set, not recall: check-control-bytes EXIT=0; check-doc-links EXIT=0; check-changeset-presence EXIT=0; check-changeset-no-major EXIT=0. Byte verification from the committed object: `git show HEAD:AGENTS.md | cat -A | grep -n EOF` -> `230:  git commit -F - <<'EOF'$` and `234:  EOF$`; `git show HEAD:AGENTS.md | grep -n 'commit -F -'` -> line 230 `  git commit -F - <<'EOF'` (plus prose lines 227/239, unchanged). Residue grep for the escape sequence over the committed blob: exit 1 (no match). No pnpm install was needed - every derived gate is a plain-node script using builtins only; no build/test ran, so the shared heavy-verify lock was never taken. Reverse verification: predicted BEFORE running that nothing would go red; observed exactly that - re-introducing the corrupted bytes left all four gates at exit 0. The re-introduction was byte-identical to origin/main, independently proven by check-changeset-presence then reporting '0 file(s) changed' against the merge-base. Restored via git checkout of the committed fix; working tree clean, worktree removed unforced.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #5151: no gate anywhere validates the executability of fenced shell examples in markdown - measured, all four derived gates stay exit 0 with the corrupted heredoc present; generalizes to AGENTS.md / CLAUDE.md / skills/** / content/docs/**. Unassigned, unlabeled for PM triage.",
        "dispatch-prompt correction (no code change): the prompt said `skip-changeset` applies and to state its precedent. That label mechanism does not exist in objectui - content/docs/guide/ci-cd-pipeline.md records it explicitly ('None of it existed'), matching the standing dev-contract clause. No label was created or applied. No changeset is owed either, and check-changeset-presence certifies that itself: its guarded surface is a released package's src/**, which a root AGENTS.md edit is outside.",
        "attribution footer: used the session-URL form per the standing dev contract (the bare https://claude.ai/code form is stripped from a PR body on every later edit), rather than the bare form the dispatch prompt spelled out."
      ]
    }

    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdocumentationImprovements or additions to documentationpm:queue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions