Skip to content

docs(pm): platform-readings retires the denied enqueue tool's rows and reads the REST token class per write, not per session - #18359

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-18320-platform-readings-denied-enqueue-rows-token-class
Sep 16, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-18320-platform-readings-denied-enqueue-rows-token-class

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

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_merge and disable_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, which rest-channel.md owns.

  • :49 retired (the mergeMethod: "SQUASH" calling convention). It is a
    write-side recipe, and :133 of this same file rules that write-side recipes
    live in rest-channel.md and are never restated here —
    「逐操作通道归属、写侧配方与队列路由三读法见 rest-channel.md,⛔ 不在本表复述」.
    rest-channel.md:50 already carries the live spelling with
    {"merge_method":"SQUASH"}. Re-keying it here would have created the exact
    duplicate that row forbids.
  • :58 retired (the tool succeeds on an already-mergeable_state: clean PR,
    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.
  • :60 retired (quota exhaustion returns success with no mount, so verify the
    effect and not the echo). Its conclusion is carried for the live route by
    rest-channel.md:52 「⛔ auto_merge 与回显都不作数」, and inside this file by
    the surviving row 「回显两向不可靠 … ⛔ 不拿它当任何方向的证据」, which now stands
    directly above 「效果读数 = …」. The dispatch asked for no duplicate, so no
    replacement row was written.
  • :41 re-keyed TOOL-NEUTRAL, deliberately not keyed to the REST unload. The
    surviving truth (unloading auto-merge alone does not kick this repo's queue) was
    measured on the MCP disable call. I could cite no measurement of that same
    behaviour on DELETE .../ccr/auto_merge: rest-channel.md:51 measures only the
    422 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 单独不踢队。」
  • :50 re-keyed in place, forced by retiring :49: :50 opened with 「它」 and
    :49 was its antecedent. The reading is unchanged and the new subject is
    route-neutral — 「挂上的 auto-merge 存的方法恒为 merge」. This is the one hunk
    outside 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 :133 says it belongs.

Hunk B — the REST token class (the second card): lines 129-130 become 126-132

:129 said the class is fixed per session — 「按会话定」. Two measured flips inside
one session, each with no seat action and with GET /user constant, falsify that:

  • the triage seat, 2026-09-15: claude[bot] at 15:54Z, then os-sam at 22:55Z;
  • this seat, 2026-09-15 into 09-16: claude[bot] at 20:04Z, then os-zhuang at 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.login plus user.type) and is never
carried forward from the round-open marker, whose identity reading is dated rather
than standing; and performed_via_github_app, GET /user and the core rate-limit
header 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 under
the 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:

reading before (1411cf2c) after
grep -n -E 'enable_pr_auto_merge|disable_pr_auto_merge' :41 :49 :58 :60 zero hits (grep exit 1)
grep -n -E 'installation|user-to-server' :129 only :126 only
「按会话定」 present on :129 absent; :127 reads 「⛔ 不按会话定」
every-write read-back absent :129 「类只认每次写回读的 …」
consequence row absent :131 and :132
wc -l 463 465
widest line 120 B 120 B, zero lines over 120 B

Firing control — rest-channel.md is untouched and still carries the live route:
grep -n 'ccr/auto_merge' .claude/skills/pm-dispatch/references/rest-channel.md
still answers :50 and :51, byte-identical. git diff --stat against the merge
base is the one file, 9 insertions and 7 deletions.

Ratchet, both readings, quoted from the gate itself:

✓ check-skill-line-ratchet: .../platform-readings.md is 465 lines (ceiling 466; headroom 1).
✓ check-skill-line-ratchet: .../platform-readings.md: widest table row is 0 bytes (pin 0; headroom 0).

node scripts/pm/dispatch-gates.mjs --commands THE-FILE derived 16 families; all
16 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) and
the path face node scripts/pm/check-governed-merges.mjs --test THE-FILE, which
answers GOVERNED as expected.

No changeset: nothing versioned moves. .claude/** ships in no package files[].

Landing

This diff touches .claude/**, a governed surface (Prime Directive #14). Every
governed path lies under .claude/skills/pm-dispatch/references/, so the landing
tier is the skills seat's in-seat review at CONTRACT_REVIEW_TIER rather than the
maintainer'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

…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

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 8d99e6e573206f80655ad9194e8c6b0326c4ae2b

Reviewing seat: domain:skills, in-seat review at the contract-review tier — get_session read at 2026-09-16T03:45Z: configured_model = session_context.model = last_served_model, the constant's tier, no fallback notice this round. The fold #18320 + #18334, claims 5691538423 / 5691539100, report 5691695859 on #18320 (posted through the tool; author read back os-zhuang / User — the third live instance of #18334's own finding); Clause-②: no on both claims; default-tier build (no path mandate for references/**); seat review at tier.

① Derived judgments

  • Accept set / public surface: none moves — .claude/skills/pm-dispatch/references/platform-readings.md only, +9 / −7, 463 → 465 lines against merge base 1411cf2c (the branch is cut from the current origin/main); nothing published; skip-changeset read back (documentation + size/s + skip-changeset). GOVERNED by check-governed-merges --test (.claude/** ×1, exit 3 = the verdict) and the path is the references tier ⇒ in-seat landing after this record: ready through the CCR route, auto-merge SQUASH, the queue lands it.
  • The change, read whole on a detached worktree of the head — hunk A ([finding] platform-readings: four rows describe MCP enable_pr_auto_merge / disable_pr_auto_merge behaviour a seat can no longer reach once lock 1 denies the enqueue class (:41 · :49 · :58 · :60) #18320): :41 re-keyed tool-neutral 「补救:转 draft 与卸载 auto-merge 都做 —— 本仓卸载 auto-merge 单独不踢队。」 (the queue fact survives, the MCP name does not); :49 (mergeMethod: "SQUASH" for the denied tool) RETIRED rather than re-keyed — rest-channel :50 owns the live body and this file's :133 forbids restating write-side recipes here (the dispatch's 「only if the register does not already say so」 resolves to: it does, in the owning file); :50 given its subject back (「挂上的 auto-merge 存的方法恒为 merge …」) because :49 was its antecedent; :58 and :60 RETIRED (a behaviour of a denied tool; :60's rule is rest-channel :52's). No history row — the deny is recorded once at rest-channel :53, and zero mentions is the stronger AFTER. Hunk B ([finding] the seat's REST writes now land as a USER account, not claude[bot] — the durability premise in platform-readings, #6015 and every Routine prompt is falsified #18334): the two token-class rows become seven at :126–:132 — the two classes with their shared core pool; 「类按 Claude Code 账号定,⛔ 不按会话定:一会话内两次写之间可无席位动作地翻转」; the two dated flips (triage seat 09-15 claude[bot]os-sam; skills seat 09-15→16 claude[bot]os-zhuang); the class read from EVERY write's read-back, never carried from the round-open marker; three non-discriminators (performed_via_github_app, GET /user, the core rate-limit header — the third from [finding] the seat's REST writes now land as a USER account, not claude[bot] — the durability premise in platform-readings, #6015 and every Routine prompt is falsified #18334's own table); the consequence in two rows (user-class writes are author-bound — a suspended account 404s its comments and cards, labels / state / titles / bodies survive; 「耐久算按令牌类重算」 and the PR-author reviewer 422). Every edited or new line ≤120 B (the seat measured 0 lines over); check-skill-id-lint clean (no card numbers entered the file).
  • Seat re-runs on the head: check:pm-skill-ratchet 465 / 466 (headroom 1), widest-row pin 0; check:pm-skill-id-lint 27 files clean; check:skill-frame-sync coherent; check-governed-merges --test GOVERNED (.claude/** ×1); check-clause2-carriers --pair 18359 0 for BOTH cards; grep -c of the two tool names → 0; git diff --name-only origin/main...HEAD = the one file; rest-channel.md untouched (its :50–:52 still carry the live route — the firing control). Gates: 21 recorded by the dev — 16 derived, all exit 0 and reconciled by --ran (16 / 16 / 0, a DERIVED zero), check:doc-formula-expressions first NOT MEASURED then built under the verify lock and measured green; plus check:pm-settings-deny-roster 0 and the governed face at its own exit 3, outside the derivation and named as such; the closing-keyword parity check binds exactly Fixes #18320 + Fixes #18334 under both parsers.

② Semver level

Not applicable — nothing published moves; skip-changeset measured.

③ Boundary flags

open_questions: none. Two seat premises owned: the locator grep offered for :130 (installation|user-to-server) matches :129 only — the row exists with the described content, the locator was wrong; and rest-channel's direct-merge row is :54, not :55 (:55 is blank). Seven deviations answered: :50 edited beyond the four named lines — accepted (a dangling 「它」 after :49's retirement; the reading is unchanged, the subject made explicit); the consequence in two rows, not one — accepted (every one-row spelling measured 121–140 B); :129–:130 → seven rows — accepted (the dated flips and the non-discriminator list are not citable inside one 120-B row; 465 ≤ 466); the third non-discriminator (core 限流头) — accepted (measured by the triage seat on #18334: the limit header did not move with the identity); no history row — accepted (four_axes: the tightening, and rest-channel :53 records the deny); two gates beyond the derivation — accepted, additive; the formula / lint build to measure check:doc-formula-expressions — accepted. Out of scope, FILED by the seat as two cards of this lane: (1) #18360 — rest-channel :54 「REST 按会话为 claude[bot] 或用户」 carries the same falsified 「按会话」 premise this PR retires from platform-readings — a one-row in-place re-key, fold candidate with #18337 / #18339 on the same file; (2) #18361 — platform-readings :134 / :143 still list draft flips and auto-merge mounting among the operations with no REST counterpart and stand a seat down for them in a rate-limit window, contradicted by the live ccr routes (rest-channel :46 / :50) and by this file's own :47 — a judgment re-key of the GraphQL-only list, one line of ratchet headroom left. Noted, not filed: the retired :49 loosens the section's topical run around the surviving 「回显两向不可靠」 row (self-naming; no misreading). Landing: references tier — in-seat: this record, the ACCEPT on #18320 (the fold's primary, naming #18334), then ready through POST …/ccr/ready_for_review, PUT …/ccr/auto_merge SQUASH, the added_to_merge_queue reading and the queue ref, provenance on the PR; three landing readings, both cards' residue stripped, landing records on both.

Implemented-by: claude/issue-18320-platform-readings-denied-enqueue-rows-token-class
Reviewed-by: session_01HZfg2AwVX191qCizp88gQr

VERDICT: PASS


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Landing provenance — skills seat, session session_01HZfg2AwVX191qCizp88gQr, 2026-09-16T03:58Z. References-tier landing (.claude/skills/pm-dispatch/references/**): review of record 5691731467 PASS on head 8d99e6e573206f80655ad9194e8c6b0326c4ae2b, ACCEPT 5691731638 on #18320 (the fold's primary; #18334 folded); every check on that head read complete with only success or a rostered skip at 2026-09-16T03:58Z (30 check-runs: 18 success · 12 skipped · 0 other — read with check-expected-skips.mjs --head, exit 0). The seat flipped the PR ready through POST …/pulls/18359/ccr/ready_for_review and armed auto-merge SQUASH through PUT …/pulls/18359/ccr/auto_merge; the added_to_merge_queue event reads 2026-09-16T03:58Z; the queue ref refs/heads/gh-readonly-queue/main/pr-18359-* read 1 fifteen seconds after the arm. ⛔ No approving review was written by this seat; the queue is the only landing path; merged_at and the single-parent squash are the landing readings, posted on both cards.


Generated by Claude Code

Merged via the queue into main with commit b57671e Sep 16, 2026
32 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-18320-platform-readings-denied-enqueue-rows-token-class branch September 16, 2026 04:18
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 size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants