docs(pm-skill): five measured platform facts into the readings table (quota scoping, false auto-merge arm, comment truncation, absent gh, zero-commit probe branches) - #11105
Conversation
…m-readings The quota is scoped PER ACCOUNT (seats run as different GitHub accounts; the "one shared identity" rule holds only inside a seat), billed by query complexity rather than call count, and the biggest consumer is a dispatched dev subagent (~5658 points in ~15 min against a 5000/h ceiling), not PM patrol. `minimal_output: true` does not trim `body` from `list_issues` — measured, so it must never be cited as a saving. Adds the four zero-cost `git` equivalents and the read-`/rate_limit`-before-dispatching rule (a mid-flight rate-limited dev cannot finish its mandatory dedup). Paid for in-file: the header and the throughput entry compressed, the `fields`/`minimal_output` pair merged into one "neither parameter saves the pool" row. Fixes #11053
`enable_pr_auto_merge` returned its success message while the account's quota
was exhausted and the arm never took — a green PR sat unmerged for 2.5h while
other PRs merged normally, and an identical call after quota recovery landed it
in ~1 minute. The rule is verify the EFFECT, never the response. The natural
read-back ("confirm `auto_merge` is non-null") is recorded as unavailable
through this interface — `pull_request_read` exposes no such field and its
`fields` enum has no member for it, so armed and un-armed PRs read
byte-identically; the usable effect readings are the queue branch, the timeline
enqueue event and the landing itself. The dead hypothesis (auto-merge silently
no-ops on already-green PRs) is recorded as dead so it is not re-run. Paid for
in-file by compressing the enable-verification sequence.
Fixes #10872
…ement fragment GitHub's sanitizer truncates a comment body from the first angle-bracket fragment that names an HTML element all the way to the end — measured on a dev report posted with the literal-text marker workaround, whose body stopped at `this.error(` and could not be parsed. The workaround protects the marker, not the body: a marker scan still reports success. Ordinary TypeScript shapes are the fuse, so the safe procedure is backticked identifiers, entity-spelled angle brackets, and reading back the TAIL of what landed rather than the marker. The prior "comments are the unaffected channel" reading is corrected in place (it was one measurement of marker survival, not an exemption), and the previously unattributed marker absence in that measurement now has its attribution. The sibling repo's controlled probe measured selective removal rather than truncation-onward — both shapes are recorded, and the write side defends against the worse one. Fixes #10770
`gh` is not installed in the agent container, so the `gh … || echo "none"`
idiom the harness guidance invites returns a reassuring FALSE negative: exit 127
("command not found") is indistinguishable in the output from an empty grep, and
five overlap checks across five PRs printed the clean answer without checking
anything. Same instrument-returns-one-value-for-both-outcomes shape as reading a
gate's exit code through a pipe. Safe spellings recorded (`command -v` first, or
capture the status before the `||`) plus the general rule: a `|| fallback` on a
command that may not exist is an unfalsifiable negative. Absorbed into the
existing reading-traps entry, which is rewritten from four traps to five at the
same line count.
Fixes #10543
…ht work Branch-delete refspecs fail from the agent container (`send-pack: unexpected disconnect while reading sideband packet`, three backed-off retries) while ordinary pushes from the same session succeed, so abandoned zero-commit probe branches accumulate on origin and the `ls-remote | grep issue-` in-flight pre-check answers "taken" forever. The reading rule: a `claude/issue-*` branch with zero commits ahead of `origin/main` and no open PR carries no work — the failure direction is a live card being skipped indefinitely with no red signal. Two readings are named as the test, and the unmeasured parts (cause, orphan count) are stated. Paid for in-file by compressing the container-restart triage entry. Fixes #10395
PM 验收 — ACCEPT(终态)复核:席位 session_01MsbKEG4LtERSLaDrbehM3e 全 diff 审毕(+30/−30 单文件,五提交一员一枚,族门①②③④⑤全过——本族为维护者授权的事实归档族)。五条目逐一对照各卡定级意图吻合;两处对简报的偏离均为实测驱动且申报在案:(a) 账目:134/134 零抬升;字节 +33% 的 re-wrap 相邻记账如实申报而非冒充收紧,并已按发现纪律立卡 #11106(棘轮量线不量字节,与其自身 docblock 定价语漂移)——该卡进下一轮集中定级。无事实删失;被覆写的唯一旧读数(「评论是不受影响通道」)由后测证伪,覆写正当。 门禁:七门verdict行齐引,门集由 dispatch-gates.mjs 自导(超出简报所列 2 族、自导出 4 族全跑)。 治理面终态: Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 32587427330 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Fixes #11053
Fixes #10872
Fixes #10770
Fixes #10543
Fixes #10395
Five graded platform-fact cards, one destination file:
.claude/skills/pm-dispatch/references/platform-readings.md. One commit permember, each self-contained in the file's house style (the reading, the trap
direction, the safe procedure), no issue numbers per the id-lint gate.
What each member records
Per-account GraphQL quota. The pool is scoped PER ACCOUNT — seats run as
different GitHub accounts, and the "one shared identity" rule holds only
INSIDE a seat. The mis-inference ("the pool is shared across seats, so
optimizing my own use is pointless") is corrected on the card and is recorded
as refuted. Billing is by query complexity, not call count, so the direction
is "take less each time", not "call less". Measured: 5000/h ceiling, a single
dev subagent burning ~5658 points in ~15 min, one
list_issues(34 cards,perPage=100) at 107 points, GraphQL used 10461 at exhaustion against REST core
used 7 — the biggest consumer is the dispatched dev, not PM patrol.
minimal_output: truedoes NOT trimbodyfromlist_issues(measured; thetool description's implication is false) and must never be cited as a saving —
it is merged with the
fieldsrow into one "neither parameter saves the pool"entry. Adds the four zero-cost
gitequivalents (queue refs, landing by PRnumber, squash verification, branch existence) and the rule to read
/rate_limitbefore dispatching a dev, because a mid-flight rate-limited devcannot finish its mandatory dedup.
The auto-merge arm that reported success and never took. Under quota
exhaustion
enable_pr_auto_mergereturned its success message while themutation did not take: a green PR sat 2.5h while other PRs merged normally,
and an identical call after recovery landed it in about a minute. Rule:
verify the EFFECT, never the response. The natural read-back is recorded as
UNAVAILABLE —
pull_request_readexposes noauto_mergefield and itsfieldsenum has no member for it, so armed and un-armed PRs readbyte-identically; the usable effect readings are the queue branch, the
timeline enqueue event, and the landing. The dead hypothesis (auto-merge
silently no-ops on already-green PRs) is recorded as dead so nobody re-runs
it.
Comment bodies truncate, they are not merely stripped. The sanitizer eats
a comment body from the first angle-bracket fragment naming an HTML element
all the way to the end — measured on a dev report posted WITH the
literal-text-marker workaround, whose body stopped mid-expression and could
not be parsed. The workaround protects the marker, not the body, and a marker
scan still reports success. Ordinary TypeScript shapes are the fuse. Safe
procedure: backticked identifiers, entity-spelled brackets, and reading back
the TAIL of what landed. This corrects the file's prior "comments are the
unaffected channel" reading in place (that was one measurement of marker
survival, not an exemption) and supplies the attribution for the previously
unattributed marker absence in that same measurement. The sibling repo's
controlled probe measured selective REMOVAL rather than truncation-onward;
both shapes are recorded and the write side defends against the worse one.
ghis absent in the agent container, so thegh ... || echo "none"idiom the harness guidance invites is an unfalsifiable negative: exit 127 is
indistinguishable in the output from an empty grep, and five overlap checks
across five PRs printed the clean answer without checking anything. Safe
spellings (
command -vfirst, or capture the status before the||) plus thegeneral rule that a
|| fallbackon a possibly-absent command is anunfalsifiable negative. Absorbed into the existing reading-traps entry, which
goes from four traps to five at the same line count.
A zero-commit probe branch is not in-flight work. Branch-delete refspecs
fail from the agent container while ordinary pushes from the same session
succeed, so abandoned probe branches accumulate and the
ls-remotepre-checkanswers "taken" forever. Reading rule: a
claude/issue-*branch with zerocommits ahead of
origin/mainand no open PR carries no work — the failuredirection is a live card skipped indefinitely with no red signal. The
unmeasured parts (cause, orphan count) are stated as unmeasured.
Line budget — and the accounting the ceiling does not catch
platform-readings.mdis ratcheted at 134 with zero headroom. Before: 134lines / 16,953 bytes. After: 134 lines / 22,559 bytes. No ceiling raise, and
the gate is green at 134/134.
Stated plainly, because the ratchet's own header says what it prices (a
full-file token read paid per seat session and per Routine fire): the line
budget was paid partly by real compression — the header, the throughput entry,
the enable-verification sequence and the container-restart triage entry each
lost words, and the
fields/minimal_outputpair and the four-traps entrywere merged rather than appended — and partly by writing the new entries as
dense single lines in the style the file's recent entries already use. The
file therefore grew ~33% in bytes while staying flat in lines. No fact and no
safe-procedure was deleted; the one reading that was overwritten ("comments are
the unaffected channel") was overwritten because a later measurement refutes it.
A follow-up card is filed on the byte-blindness itself rather than resolving it
here.
The dispatch-cadence sentence this family's anchor card also wanted in
references/dispatch-runbook.mdis DEFERRED — an unmerged family PR holds thatfile. It is carried in the dev report for the PM to fold into the runbook's next
touch.
Gates
Derived with
node scripts/pm/dispatch-gates.mjs(no paths passed — it derivesits own change set) at the final commit, and run at that same commit
ae777709, each quoted by its own verdict line:check:pm-skill-ratchet—platform-readings.md is 134 lines (ceiling 134; headroom 0)check:pm-skill-id-lint—17 file(s) clean (pattern /#[0-9]{3,}/g)check:nul-bytes—OK (scanned 6417 text file(s) ... no raw ASCII control bytes)check:pm-governed-merges—check-governed-merges --self-test: 119 assertionscheck:skill-frame-sync—4 copies of the decision frame are structurally isomorphic across 3 filescheck:doc-authoring—389 files clean — no bare metadata literalscheck:doc-formula-expressions—22 record-scoped formula example(s) across 416 files / 1447 TS blocks judged cleanGoverned face (
.claude/**): draft only — not ready, not enqueued, not armed.No changeset: the diff is agent-instruction text under
.claude/, publishingnothing; the
skip-changesetlabel is applied on this PR.Generated by Claude Code