Skip to content

docs(agents): PR-body footer rule states channel/action dependence, not a form - #16771

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-16633-footer-rule-channel-dependence
Sep 8, 2026
Merged

docs(agents): PR-body footer rule states channel/action dependence, not a form#16771
os-zhuang merged 1 commit into
mainfrom
claude/issue-16633-footer-rule-channel-dependence

Conversation

@hotlong

@hotlong hotlong commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #16633

What changed

AGENTS.md's attribution-footer rule stops predicting a form. The PR-body sentences now state
the two axes the ledger states — the CHANNEL (the MCP wrapper vs a raw REST call) and the ACTION
(create vs edit) — say the cells disagree, ban generalising one cell to another, and keep the two
imperatives: send the footer you want stored, read the body back after every write. The
.claude/agents/os-dev.md twin (line 401) is corrected in the same register, in place.

Kept verbatim: the block-form heading and the two-form fence above it (lines 420-426), and
Durable attribution lives in body prose or a comment. ⛔ Untouched: the Issue comment and
Commit message sentences in the same paragraph (lines 433-444 are byte-identical).

file before after
AGENTS.md 428-432 create_pull_request keeps the session-URL form and rewrites bare into it. On EDIT (update_pull_request or a REST PATCH, measured in this repository) the session-URL footer survives verbatim and the platform APPENDS a bare footer block under whatever you send — so send an edited body with no footer of your own, read it back, and treat the appended block as the platform's; ⛔ never re-send … what a body write does to the footer depends on the CHANNEL (the MCP wrapper vs a raw REST call) and the ACTION (create vs edit) — measured in this repository, and the cells disagree, so ⛔ never generalise one to another; the readings live in pm-dispatch references/platform-readings.md. Send the footer you want stored, read the body back after every write, and ⛔ never re-send …
os-dev.md 401 session-URL 形创建用,编辑后原样存活;编辑时不带页脚发送、读回,平台在其下追加裸形块。 页脚形态随通道(MCP / REST)与动作(建 / 改)变,⛔ 不由一条推其余;发你要存的,写后必回读。

Why the create-side clause folded into the same sentence

The card scopes the edit-side sentence. It is folded because the rewrite's own subject is the
ACTION axis — a sentence that says "it depends on create vs edit" cannot sit beside a sentence
that asserts a fixed outcome for create without contradicting itself, and the create cell is the
one that has already produced a wrong write in this repo (PR #16694's duplicated footer came from
following an edit-side reading on another channel). No separate sentence was added for it: the
old create clause is deleted, not restated, which is also what pays for the new text.

Readings this rests on — recorded on the card and in the ledger, ⛔ none restated in AGENTS.md

channel action reading n
MCP update_pull_request edit, body sent with no footer reads back with no footer 4 (#16591, #16615, #16604, #16656)
MCP update_pull_request edit, body sent carrying footers both survive byte-identically 1 (ledger counterexample)
MCP issue_write by PR number edit nothing appended 1 (#16743)
raw REST PATCH /pulls edit appends a bare block every time, regardless of what the body carries 2 (#16694)
raw REST POST /pulls create appends a second same-form footer, 90 bytes, sent body a strict prefix ledger row
MCP create_pull_request create appended a second session-URL footer to a body that already had one 1 (#16764, unreviewed)

That last row is what the deleted create clause claimed the opposite of. This PR's own creation is
another sample of that cell; the reading is in the dev report on the card, ⛔ not folded back into
this body by a second write.

Line budget — no growth, paid by deletion

file before after ceiling ratchet verdict line
AGENTS.md 1067 1067 1068 ✓ check-skill-line-ratchet: AGENTS.md is 1067 lines (ceiling 1068; headroom 1).
.claude/agents/os-dev.md 403 403 403 ✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0).

Widest line written: 96 bytes in AGENTS.md (cap 120), 119 bytes in os-dev.md (cap 120 — the
replaced line was also 119). ⛔ No re-wrap was counted as payment: lines 433-444 of AGENTS.md
are byte-identical, so the whole diff is 5 replaced lines plus 1.

Gates — 19 derived, 19 run, all green

Derived in the worktree with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack
(no paths passed; change set read from the merge base) — identical to the 19 the dispatch named.
Exit codes captured by redirect before any pipe.

0  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-governed-queue-guard.mjs --self-test
3→0 pnpm --filter @objectstack/lint run check:doc-formula-expressions
0  pnpm check:agent-model-declared
0  pnpm check:agent-test-spelling
0  pnpm check:doc-authoring
0  pnpm check:docs-audit-scope
0  pnpm check:driver-memory-census
0  pnpm check:nul-bytes
0  pnpm check:pm-governed-merges
0  pnpm check:pm-governed-prose
0  pnpm check:pm-skill-id-lint
0  pnpm check:pm-skill-ratchet
0  pnpm check:refd-timer-probe
0  pnpm check:required-contexts
0  pnpm check:skill-frame-sync
0  pnpm check:watch-hint-literal
3  node scripts/pm/check-governed-merges.mjs --test AGENTS.md .claude/agents/os-dev.md
  • check:doc-formula-expressions first exited 3 — PREREQUISITE NOT MET (@objectstack/formula
    and @objectstack/lint not built): NOT a finding, nothing measured. After
    pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2
    under scripts/pm/os-verify-lock.sh (VERDICT command-exit 0 · held the lock 18s · waited 0s)
    it re-ran exit 0: ✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 434 files / 1372 TS blocks judged clean by @objectstack/formula.
  • Governed predicate: ⛔ GOVERNED — a human merge is the review record for this PR (#9495 regime).
    (exit 3, AGENTS.md ×1 + .claude/** ×1). Draft only; no ready flip, no queue, no auto-merge.
  • Reconciliation: ✓ dispatch-gates --ran: 19 derived famil(ies) accounted for — 19 run, 0 NOT-MEASURED.
  • The hypothesis the dispatch asked to test held: check:pm-governed-prose and
    check:skill-frame-sync do not read these two sentences — both green unchanged.

Local verification scope — a measured narrowing, not a skipped run

Whole-repo pnpm lint is CI's. The narrowing is proved, not assumed:

  1. Population, read from eslint's own config resolution (not from a guess): every files glob
    in eslint.config.mjs is **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs} or narrower. Asked directly,
    eslint answers for both changed paths: File ignored because no matching configuration was supplied.
  2. Count, read from --format json: pnpm exec eslint AGENTS.md .claude/agents/os-dev.md --no-inline-config --format json returns 2 results, errorCount: 0, and the only messages are
    those two ignore notices ⇒ 0 lint-checked files in this diff.
  3. Invariance for untouched files: no type-aware linting is configured (eslint.config.mjs
    line 328: no parserOptions.project, no typed @typescript-eslint rules), so a
    markdown-only diff cannot move any untouched file's verdict.

No package source changed, so no build closure, pnpm test or typecheck is owed: dispatch-gates
derives the change set as exactly AGENTS.md + .claude/agents/os-dev.md, neither inside a
workspace package.

Merge-tree reading

git merge-tree --write-tree origin/main HEAD at origin/main 8b37a0973 ⇒ exit 0, tree
8cc24592ed4ab2b5cebaf4f7350c2ab9373537fc, no conflict. No open PR carries either path
(seat listing 03:39Z, unchanged at push time).

skip-changeset

Nothing published moves: AGENTS.md and .claude/** are on the fast track (repo-root instruction
file and the agent instruction tree), shipped in no package's files[].

验收备注

  • noted, not filed: the ledger's PR-body sanitizer rows (platform-readings.md 296-299) say a PR
    body's footer should carry NO leading rule line, because the trailing rule and the footer under it
    are eaten together — while AGENTS.md 420-426 spells the block as blank line + rule + footer for
    every surface. The two are about different mechanisms (sanitizer vs the footer writer), and this
    card's scope is the channel/action sentence, so nothing here is changed for it. 承接者:the next
    card on the byte-mutation paragraph — no PR or person is queued on it today.

维护者速读(草稿)

改了什么

AGENTS.md 里关于「PR 正文署名页脚」的那句规则,不再预测平台会做什么,改为陈述它依赖什么:
依赖通道(MCP 包装器 / 裸 REST)与动作(建 / 改),并要求「发你要存的页脚 + 每次写后回读」。
.claude/agents/os-dev.md 的中文孪生句以同一 register 原地改写。两个文件行数都没变。

为什么改

这句话四个月里被改过四次,每次都是把「上一次在某一个通道上测到的形态」写成无条件规律,
下一次换个通道就又被推翻。昨晚它第一次造成了真实损害:一位 agent 照该句字面去改 PR #16694 的正文,
在 REST 通道上得到了该文件明令禁止的重复页脚。改成「依赖 + 回读」之后,这句话不会再随平台行为腐烂,
而具体读数留在 pm-dispatch 的读数账本里 —— 账本本来就是放读数的地方。

风险与代价(含回滚)

风险很小:规则变宽(不再断言具体形态),不会让任何原本合规的写法变违规。代价是读者想知道
「我这个通道会发生什么」时要多跳一层到账本;这正是我们要的分工。回滚 = revert 这一个提交,
两个文件各恢复一句,无生成物、无下游依赖。

席位意见

(留空,待席位 ACCEPT 时填)

你要做的

这是受管面(AGENTS.md + .claude/**),按 #9495 规矩需要人来合。请读上表两句的前后对照,
确认新句子说的是你要的规矩;同意就合并(或批准后入队)。⛔ 席位不会翻 ready、不会入队。


Generated by Claude Code

…ot a form

The edit-side sentence predicted one shape (session-URL survives, the platform
appends a bare block) that was measured on a raw REST PATCH and is false on the
MCP wrapper: an edit sent with no footer reads back with none (n=4). The
create-side sentence is folded into the same clause because the readings on
create disagree by channel too, so a rule that names only the edit action would
still invite the generalisation that produced a duplicated footer on #16694.

The sentence now states the two axes the ledger states — CHANNEL and ACTION —
keeps the imperative half, and points at
.claude/skills/pm-dispatch/references/platform-readings.md, which is where the
per-cell readings belong. The os-dev.md twin is corrected in the same register,
in place. Both files keep their line counts (AGENTS.md 1067/1068, os-dev.md
403/403); no reading is restated in either file.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY

hotlong commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)

席位复核记录:#16633 上的 ACCEPT 评论 5579457475(skills 席,hotlong,session session_01P58euzUXCVJNwmhuPC9DXY,2026-09-08T05:02Z)。head 45af323b6,base 8b37a0973

改了什么

两个文件各一句,行数不变。AGENTS.md 第 428–432 行:PR 正文署名页脚那条规则不再预言平台会做什么,改为陈述它取决于通道(MCP 包装器 / 裸 REST)与动作(建 / 改),各格读数不同,⛔ 不得由一格推另一格;读数住 pm-dispatch 的 references/platform-readings.md;保留两条祈使句(发你要存的页脚;每次写后回读)与「⛔ 永不重发已带追加页脚的正文」。.claude/agents/os-dev.md 第 401 行的中文孪生句同 register 原地改写,119 字节。

为什么改

这一句四个月改了四次(#12455#11273#15241#15246 → 本卡),每次把一个通道上测到的形态写成无条件规律,换个通道就被推翻;昨晚它第一次造成真实损害 —— 一个席照字面在 REST 通道上 PATCH PR #16694,得到了该文件明令禁止的重复页脚。改成「依赖 + 回读」后这句不再随平台行为腐烂,具体读数留在本来就放读数的账本里。

风险与代价(含回滚)

风险小:规则变宽(不再断言具体形态),不会让任何原本合规的写法变违规。代价:读者要多跳一层到账本查自己那一格。棘轮:AGENTS.md 1067/1068、os-dev.md 403/403,席位在分支上复测一致;付账方式是删掉旧的 create 侧子句(它断言的正是 dev 本次实测证伪的那一格),⛔ 未用 re-wrap 充数。回滚 = revert 这一个提交,两句各自恢复,无生成物、无下游依赖。

席位意见

同意合并。dev 折叠 create 侧子句进同一句是对的:一句说「取决于建/改」,旁边不能再放一句断言 create 固定结果。19/19 门禁族全绿并对账;check-governed-merges --test 对两路径 exit 3(受管);全部 check run 于 04:59Z 读到 success / skipped(Lint & Repo Gates 04:59:23Z success)。dev 顺手取到一个 n=1 读数(MCP create_pull_request 送出的正文带规则线时只存一个页脚;#16764 的正文没带规则线时被追加整块)—— 只记在 #16633 上,⛔ 没写进任何文件,留给第八次读数增量的载体卡。

你要做的

受管面(AGENTS.md + .claude/**),按 #9495 规矩由人合:读上面「改了什么」的两句前后对照(PR 正文首表逐字),同意就批准或直接合并;席位在授权批准落地且全绿时挂 auto-merge,⛔ 不翻 ready、不入队。只问一字:这句「依赖通道与动作 + 写后回读」是你要的规矩吗——


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 8, 2026 06:03
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 8, 2026
Merged via the queue into main with commit 87fad14 Sep 8, 2026
35 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-16633-footer-rule-channel-dependence branch September 8, 2026 06:26
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 needs-user-decision size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants