docs(pm): platform-readings retires the denied enqueue tool's rows and reads the REST token class per write, not per session - #18359
Conversation
…d reads the REST token class per write, not per session The four rows that taught a seat how to call MCP `enable_pr_auto_merge` / `disable_pr_auto_merge` describe a tool lock 1 denies. The live enqueue route is the REST ccr route, whose write-side recipe `rest-channel.md` already owns, so three rows retire and the two surviving truths are re-keyed tool-neutral. The token-class rows said the REST channel's class is fixed per session. Two measured flips inside one session, with no seat action and `GET /user` constant, falsify that: the class follows the Claude Code account and is read on every write's own read-back. One consequence row records what a user-class write costs — author-bound durability, and a 422 when the PR's author is requested as its reviewer. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
Contract reviewServed-tier: Reviewing seat: ① Derived judgments
② Semver levelNot applicable — nothing published moves; ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
Landing provenance — skills seat, session Generated by Claude Code |
Fixes #18320
Fixes #18334
ONE file, one fold:
.claude/skills/pm-dispatch/references/platform-readings.md.463 to 465 lines (ratchet ceiling 466, headroom 1); every edited and every added
line is at or under 120 bytes; the widest-table-row pin stays at 0.
Hunk A — the denied enqueue tool's rows (the first card): lines 41, 49, 50, 58, 60
Lock 1 denies MCP
enable_pr_auto_mergeanddisable_pr_auto_merge(PR #18317),and four rows still taught a seat how to call them. The live enqueue route is
REST
PUT .../pulls/{n}/ccr/auto_merge, whichrest-channel.mdowns.:49retired (themergeMethod: "SQUASH"calling convention). It is awrite-side recipe, and
:133of this same file rules that write-side recipeslive in
rest-channel.mdand are never restated here —「逐操作通道归属、写侧配方与队列路由三读法见
rest-channel.md,⛔ 不在本表复述」.rest-channel.md:50already carries the live spelling with{"merge_method":"SQUASH"}. Re-keying it here would have created the exactduplicate that row forbids.
:58retired (the tool succeeds on an already-mergeable_state: cleanPR,against its own description). Its entire content is a contradiction between one
MCP tool and that tool's description; nothing of it survives for the REST route.
:60retired (quota exhaustion returns success with no mount, so verify theeffect and not the echo). Its conclusion is carried for the live route by
rest-channel.md:52「⛔auto_merge与回显都不作数」, and inside this file bythe surviving row 「回显两向不可靠 … ⛔ 不拿它当任何方向的证据」, which now stands
directly above 「效果读数 = …」. The dispatch asked for no duplicate, so no
replacement row was written.
:41re-keyed TOOL-NEUTRAL, deliberately not keyed to the REST unload. Thesurviving truth (unloading auto-merge alone does not kick this repo's queue) was
measured on the MCP
disablecall. I could cite no measurement of that samebehaviour on
DELETE .../ccr/auto_merge:rest-channel.md:51measures only the422 an unmounted PR answers, which is a different question. Keying the row to the
REST route would have asserted an unmeasured platform fact, so it now reads
「补救:转 draft 与卸载 auto-merge 都做 —— 本仓卸载 auto-merge 单独不踢队。」
:50re-keyed in place, forced by retiring:49::50opened with 「它」 and:49was its antecedent. The reading is unchanged and the new subject isroute-neutral — 「挂上的 auto-merge 存的方法恒为
merge」. This is the one hunkoutside the four named lines, and it is declared as a deviation in the report.
After this hunk, zero rows in the file name either denied tool in any voice, so no
history row was needed either: the deny itself is already recorded for the
operation in
rest-channel.md:53, which is where:133says it belongs.Hunk B — the REST token class (the second card): lines 129-130 become 126-132
:129said the class is fixed per session — 「按会话定」. Two measured flips insideone session, each with no seat action and with
GET /userconstant, falsify that:claude[bot]at 15:54Z, thenos-samat 22:55Z;claude[bot]at 20:04Z, thenos-zhuangat 01:53Z.The rows now say: two classes, both at core 15,000/h; the class follows the Claude
Code account and NOT the session, and can flip between two writes of one session
with no seat action; both flips are named by date and account; the class is read
from EVERY write's own read-back (
user.loginplususer.type) and is nevercarried forward from the round-open marker, whose identity reading is dated rather
than standing; and
performed_via_github_app,GET /userand the core rate-limitheader all answer the same for both classes, so none of the three discriminates.
The consequence is split across two rows because it does not fit one 120-byte line:
a user-class write is author-bound — a suspended account 404s its comments and its
filed cards, while labels, state, titles and bodies survive — so the durability
calculus is re-run per class and never assumed to sign as
claude[bot]; and underthe user class the PR's author IS that user, so requesting them as reviewer answers
422. That 422 was measured on PR #18351 at 02:32Z. The second measurement table
comes from #18350, which the second card carries as its duplicate.
Verification
Reverse verification, before and after, on the one file:
1411cf2c)grep -n -E 'enable_pr_auto_merge|disable_pr_auto_merge':41 :49 :58 :60grep -n -E 'installation|user-to-server':129only:126only:129:127reads 「⛔ 不按会话定」:129「类只认每次写回读的 …」:131and:132wc -lFiring control —
rest-channel.mdis untouched and still carries the live route:grep -n 'ccr/auto_merge' .claude/skills/pm-dispatch/references/rest-channel.mdstill answers
:50and:51, byte-identical.git diff --statagainst the mergebase is the one file, 9 insertions and 7 deletions.
Ratchet, both readings, quoted from the gate itself:
node scripts/pm/dispatch-gates.mjs --commands THE-FILEderived 16 families; all16 were run, every one at exit 0, and reconciled with
--ran:✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.Outside that derivation I also ran
pnpm check:pm-settings-deny-roster(its roster sits under.claude/, so its silence would not have been evidence in either direction) andthe path face
node scripts/pm/check-governed-merges.mjs --test THE-FILE, whichanswers GOVERNED as expected.
No changeset: nothing versioned moves.
.claude/**ships in no packagefiles[].Landing
This diff touches
.claude/**, a governed surface (Prime Directive #14). Everygoverned path lies under
.claude/skills/pm-dispatch/references/, so the landingtier is the skills seat's in-seat review at
CONTRACT_REVIEW_TIERrather than themaintainer's word. This PR stays DRAFT. I requested no reviewers, touched no
ccr route, armed no auto-merge and flipped nothing.
维护者速读(草稿)
改了什么 — 派发座位的平台事实表改了两处。一是删掉三条、改写两条教座位去调一个已被
锁 1 禁掉的 MCP 入队工具的规则,活路线的写法本来就在
rest-channel.md。二是把「REST 写的身份按会话固定」这条改成实测的样子:身份跟 Claude Code 账号走,一次会话中间会变,每次
写都要自己回读一次。
为什么改 — 这两条都是写着的事实与实测不符。前者让座位学一个它调不到的工具;后者更贵:
座位的耐久性判断(评论和卡会不会随账号被封而 404)整个建立在「署名恒为
claude[bot]」上,而这一班里已经两次实测到写入落成了用户账号。四天内已经有两个分诊账号在班中被封并因此
丢掉全部书面记录,所以这条假设错的方向正是丢数据的方向。
风险与代价(含回滚) — 只动一个内部指令文件,不发布、不进任何包、无运行时影响。棘轮还
剩 1 行余量。回滚 = revert 这一个 commit。⛔ 本 PR 不改写入通道本身:换一个低权限账号或
改回 App installation token 是维护者的决定,这里只把事实表改成实测的样子。
席位意见 —
你要做的 — 目前不需要你做任何事。这是 references 层,按现行分层由技能席位在座评审后
自己落地;⛔ 不需要你的批准。若你希望把「写入身份」这件事本身处理掉(专用低权限账号,或
恢复 App installation token),那是另一张卡。
Generated by Claude Code