Skip to content

docs(pm-skill): record the PR-body rule-plus-footer eat, paid by two cuts - #13007

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-12909-prbody-sanitizer-fact
Aug 29, 2026
Merged

docs(pm-skill): record the PR-body rule-plus-footer eat, paid by two cuts#13007
os-zhuang merged 1 commit into
mainfrom
claude/issue-12909-prbody-sanitizer-fact

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes #12909

One fact row in .claude/skills/pm-dispatch/references/platform-readings.md, beside the
two existing write-side sanitizer entries. Net 0 lines at the 314/314 zero-headroom
ceiling: 14 insertions, 14 deletions.

The row as landed

Placed directly after the 写侧实测行为 · 评论 row, so the cluster now reads issue body /
comment / PR body. The 写侧实测行为 · naming is the cross-reference to the same silent
sanitizer class — it costs no line and it is the idiom the two siblings already established.

- **写侧实测行为 · PR 正文(尾部 `---` 与其后的署名页脚一并被吃)**:写调用照报成功;去掉横
  线只写页脚则原样存活(2026-08-28 两仓同轮、两张 PR 全文回读)。**评论不受影响**(两种拼法
  都活)⇒ 失效既**依拼写**又**依载体**:评论里验过页脚**对 PR 正文什么都没证明**。⇒ PR
  正文页脚**不带前置横线**、且**写后回读正文**(唯一检测手段);评论两形皆可。

Four lines, widest 120 bytes, at the cap and not over it.

Premise re-verified before writing, not inherited

The card grades another seat's measurement, so both cited bodies were read back on
origin/main before the row was written. Both end the same way — a ## Provenance
heading, the session URL as durable body prose, then the bare footer with no preceding
horizontal rule:

PR Body tail as it stands today
#12906 ## Provenance / Authoring session: ... / _Generated by [Claude Code](https://claude.ai/code)_
objectstack-ai/objectui#6641 same three-part tail, same bare footer, no rule

Both were created 2026-08-28 within one minute of each other, which is the "both repos,
same run" the card claims. Premise holds.

Boundary the row deliberately does not cross. The eat was observed on the create /
body-write path, and the surviving spelling was written by a later edit. The row therefore
says 写调用 rather than naming create and PATCH separately: a PATCH that still carries the
trailing rule was not measured, and the operative rule (bare footer plus read-back) covers
every path without needing that distinction.

A fourth measurement — this PR body itself

This body practises the row it lands: the attribution footer below carries no preceding
--- rule. The body was read back in full after creation and the result is recorded in the
dev report. Whatever it shows, it is a measurement either way; if the footer is missing when
you read this, that is the row failing open on its own remedy and worth a follow-up card.

Cut ledger — surviving homes, no re-wrap line-buying

Both cuts remove content that is stated in full somewhere else. Neither buys lines by
re-flowing; the re-wrapping visible in the diff is the consequence of deleting bytes from
the middle of a wrapped paragraph, and every resulting line is at or under 120 bytes.

Cut 1 — the 写侧 sanitizer 作者规则 row, 6 lines to 3 (saves 3).

The row restated the author rule. That rule's home is AGENTS.md, under GitHub mutates
body BYTES
, which already carries: poison-shaped tokens spelled out in words, fences do
NOT protect them, and read the body back after writing any less-than fragment. AGENTS.md
in the same breath delegates the measured shapes to this table — so the division is
already written down, and this table was holding a narrow copy of the other half.
.claude/agents/os-dev.md states the same division explicitly: 「一条规则一个家;此处不再
复制窄版」.

What was kept, because this table is its only home: the entity spelling for a literal
angle bracket, and bare identifiers surviving, which is what keeps the SKILL extraction
contract valid.

What was dropped, with its surviving home named:

Dropped clause Surviving home
改花括号占位符 / 整句用词描述 AGENTS.md ("or are described in words"); os-dev.md carries the placeholder spelling 「一律改占位词拼写」
⛔ 评论不豁免 the very next row in this table — the comment truncation measurement is the evidence — and the new PR-body row now states the surface-conditionality explicitly
⛔ 只回读标记不算验证 —— 要回读尾部 os-dev.md 干净收尾: 「写完读回那条评论到尾部」 and 「PR 正文同欠一次全文回读

Cut 2 — the credential-discrimination clause in the REST-availability row (saves 1).

references/rest-channel.md already carries it verbatim in its 通道边界 block: the
repo-scoped probe first, then 403 leads to a single /rate_limit call, 15000/hr means live
credentials refused by repo-scoping while 60/hr or an auth error means no credentials. That
file delegates only 按班矩阵 and 降级梯 back to this table, and both stay here untouched.
The clause is replaced by a pointer to it.

Genuinely lost, and stated rather than hidden: the parenthetical that one seat's token was
measured as a 14-byte placeholder string, and the phrase 两形同症不同治. The operative
discrimination they decorate survives in full at the named home.

No issue numbers were added to protocol prose — check:pm-skill-id-lint is green below.

Gates — union derived mechanically, run on 2e9ff3e2b

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack derived the change
set from git itself and matched 8 families. All were run under
scripts/pm/os-verify-lock.sh with slot issue-12909, after the final commit, on the head
quoted above. Exit codes were captured by redirecting each gate to its own file before
any pipe, so no tail status is being read as a gate verdict.

Gate Verdict line it printed Exit
check:pm-skill-ratchet (ceiling) ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/platform-readings.md is 314 lines (ceiling 314; headroom 0). 0
check:pm-skill-ratchet (max-line) ✓ check-skill-line-ratchet self-test: 111 cases pass. — includes ✓ budget is 120 bytes; widest line in the file measures 120 0
check:pm-skill-id-lint ✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). 0
check:pm-governed-prose ✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces (docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md) and claim no others. 0
check:skill-frame-sync ✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files 0
check:skill-frame-freshness ✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now). 0
check:pm-governed-merges ✓ check-governed-merges --self-test: 206 assertions ... 0
check:agent-test-spelling ✓ check-agent-test-spelling: 0 violations — 395 file(s) ... 0
check:doc-authoring ✓ doc authoring guard: 392 files clean — no bare metadata literals. 0
check:doc-formula-expressions ✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 425 files / 1453 TS blocks judged clean 0
check:nul-bytes (every-edit convention) check-nul-bytes: OK (scanned 7220 text file(s) ... no raw ASCII control bytes). 0

The ratchet verdict is quoted positively: the gate names this file and states 314 lines
against a ceiling of 314. The ceiling HOLDS and was not raised.

One derived family is NOT MEASURED rather than red — it refuses for want of CI-supplied
context and never reaches its predicate:

  • node scripts/pm/check-governed-queue-guard.mjs returns exit 1 with
    ⛔ Governed Surface Queue Guard: could not read GITHUB_EVENT_PATH — its own text says
    "could not look" must never exit 0 here. It runs with the event payload in CI.

check:doc-formula-expressions needs @objectstack/lint built; the dependency closure was
built inside the same locked run, and the verdict quoted above is the post-build reading.

Draft, and staying that way

This edits a governed surface (.claude/**), so: draft only. No ready flip, no
reviewers requested, no auto-merge, nothing approved — the PM runs the four-piece.

skip-changeset applies: the diff is one .claude/ markdown file and releases nothing from
any package. This seat's repo-scoped REST probe returned 403
(GitHub access is not enabled for this session), so the label goes on through the MCP
fallback — read current values, union, whole-group write, then a comparative read-back plus
a delayed second read, per the label discipline this very table carries.

Generated by Claude Code


Generated by Claude Code

…cuts

A PR body that ends with a `---` horizontal rule followed by the attribution
footer loses BOTH on write, while the write call reports success. Re-writing
the footer without the preceding rule survives intact. Issue comments are
unaffected in either spelling, so the failure is conditional on the spelling
(rule-then-footer at end of body) AND on the surface (PR body yes, comment no)
— which means a seat that verified the footer in a comment has proved nothing
about a PR body. The row carries the operative rule: write the footer bare in
PR bodies and read the body back, which is the only detection.

Net 0 at the 314-line ceiling, funded by two cuts with surviving homes: the
author-rule row is reduced to the two measurements this table alone carries
(the rule itself lives in AGENTS.md, which this table now points at instead of
restating), and the credential-discrimination clause in the REST-availability
row, which references/rest-channel.md already states in full.

Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Aug 28, 2026
@os-litant os-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Aug 28, 2026 — with Claude

Copy link
Copy Markdown
Collaborator Author

The fourth measurement — result

Recorded as a comment on purpose. Editing the body would destroy the very artifact the
measurement is about, so the create-time body stays untouched and the reading lands here.

The bare footer survived verbatim. This PR body was written with the attribution footer
and no preceding horizontal rule, and a full read-back after creation returns it intact
at the end of the authored text. That is the row's remedy working, on a third repo-write in
the same class.

And the platform then appended its own copy — rule and all. Beneath the surviving bare
footer, the read-back shows two blank lines, a horizontal rule, and a second footer in the
session-URL spelling that this seat never wrote:

_Generated by [Claude Code](https://claude.ai/code)_

This independently reproduces the corroboration the card mentioned, and it sharpens the fact
in a way worth writing down here even though it did not fit in the row:

  • The eat is not unconditional. A trailing rule followed by a footer can survive — the
    platform's own append did, in the same write. What was measured as eaten is the
    author-written rule-then-footer present in the payload at create time; the platform's
    append is added after whatever eats it has already run.
  • So the failure is not "trailing rules get eaten". It is narrower, and the row's operative
    rule is what actually covers both shapes: write the footer bare, and read the body
    back.
    A seat that reasons from "I saw a trailing rule survive" to "my rule is safe" is
    reading the platform's append as evidence about its own write, which it is not.
  • Practical consequence for anyone counting footers: a bare footer at the tail of a PR body
    with a rule above it is very likely the platform's, not yours downgraded — the same
    caution AGENTS.md already states for issue comments now has a PR-body instance.

The row as landed does not claim the platform's append is eaten, so nothing above
contradicts it and no re-edit is owed. Flagging it for the PM rather than spending a line:
the file is at 314/314 and this nuance would need its own cut to land.

Generated by Claude Code


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 29, 2026 01:42
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 29, 2026
Merged via the queue into main with commit 907eb04 Aug 29, 2026
32 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-12909-prbody-sanitizer-fact branch August 29, 2026 02:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants