docs(pm): record three measured auto-merge and label-cap platform readings - #17523
Conversation
Three deduplicated readings land in the pm-dispatch platform readings table, in the queue-membership and auto-merge section: - arming auto-merge on a PR whose checks are all complete enqueues at once (28-60 s from the enable call to `added_to_merge_queue` here), so no window stands between arming and landing; - a call made before mergeability settles arms classic auto-merge without enqueueing; the settled call is the one that enqueues; - a GitHub label description is capped at 100 characters, longer ones refused with 422. A fourth candidate reading — that an empty-method success line from `enable_pr_auto_merge` is a real arming rather than the documented graceful no-op — is already carried on the tree and lands no line. The line ceiling for the readings file moves 422 -> 425 under the standing one-file exception, recorded as a `ruledRaises` record that quotes it. Claude-Session: https://claude.ai/code/session_01YKEjmbYNvYWJvWGSWx26zK Co-authored-by: Claude <noreply@anthropic.com>
维护者速读改了什么 —— 为什么改 —— 这张卡原来的主诉(dev 自己挂 auto-merge 会跳过席位复核)已被今晨落地的 风险与代价(含回滚) —— 纯参考文本 + 一个上限整数 + 一条台账记录;不改任何门禁谓词。CI 在 head 席位意见 —— 通过。本席在 head 上实测三行字节数与 425/425,自跑棘轮与其自测(157 例),对照 :56–:57 核了那条去重。受管面( 你要做的 —— 一个动作:人工合并本 draft PR。 skills 席,session Generated by Claude Code |
Fixes #17160
Three measured platform readings land in
.claude/skills/pm-dispatch/references/platform-readings.md, in the 「## 队列成员资格与 auto-merge」 section. The card's other half — who performs the ready flip — is CLOSED by current text (references/landing-operations.md:64「auto-merge 由 PM 挂,dev 永不碰」, landed 2026-09-10T00:15Z) and is deliberately not written again anywhere in this diff.The three rows, as landed
Placed beside their neighbours rather than appended, so each sits next to the row a reader would otherwise over-generalise:
Byte widths 108 / 101 / 115, all under the 120-byte line cap the ratchet enforces; no issue number in operative text (
check:pm-skill-id-lintclean over 27 files).Where each reading came from
enable_pr_auto_mergecall to the timeline'sadded_to_merge_queue. The row carries this repo's number because that is the one a seat here acts on; the sibling number is provenance and stays on the card.mergeable_statestill readunknown, armed classic auto-merge and produced noadded_to_merge_queue; the second call, once settled, enqueued.422. Corroborated on this tree —check:pm-label-desc-capreports 23 descriptions, longest exactly 100.:84 does not contradict :81 or :83, and is placed to make that visible
:81measures how long the enqueue event and the queue ref take to become visible (1–3 minutes, a polling budget);:83measures the window created when the ready flip triggers check re-runs.:84is the case neither covers: the checks are already complete, so nothing re-runs and the arm-to-enqueue interval is the 28–60 s above. Putting it directly under:83is what stops a future reader from carrying:83's "about a minute, and the gap is not a failure" onto a PR where the gap means something else — which is exactly what:85then names.One candidate reading did NOT land — it is already on the tree
The dispatch carried a fourth reading: that an
enable_pr_auto_mergesuccess line with an empty method and timestamp, on a PR reading backauto_merge: null, is a real arming and not the documented graceful no-op. Measured on the branch, that is already carried, in a more general form, by two existing rows:The retriage answer measured that fact against
:13–:14alone, which carry the field's instability rather than the echo's, and concluded the disambiguation was absent. On the tree it is not. So the reading lands no line: candidates 4 / landed 3 / already present 1 / refused 0 — the standing exception's own dedup condition doing its work.Ratchet arithmetic
.claude/skills/pm-dispatch/references/platform-readings.md422 → 425, one line per deduplicated reading, headroom 0 as every entry in the map keeps it.This is the tenth increment taken under the standing one-file exception, not a fresh decision card — pm-dispatch SKILL.md :392–:393, verbatim and untranslated:
Recorded as a
ruledRaisesrecord on the cross-file-move declaration keyed by this file, quoting that exception verbatim, dated2026-09-10,delta: 3— the shape the script prescribes and the shape every record before it uses. Nothing else inCEILINGSmoves. The move's own arithmetic is unchanged by the raise, which is the whole point of recording it separately:Nothing was paid in place: the fourth increment measured zero line-neutral folds among this file's adjacent rule pairs, and re-wrap funding is refused per the standing 2026-08-17 rule in any case.
Four-axis note on the placement and wording judgement
实际业务需求: all three are measured readings from real runs on this tree and the sibling one, not a speculative surface —
:84and:85describe a call every landing seat makes, and:88was paid for once by an unstorable ruling; the alternative of leaving them unrecorded means the next seat re-measures them, which is the cost this table exists to remove. 项目长远合理性: the readings land in the single file the corpus already designates for platform facts, beside their nearest neighbours, so there is one copy and one reader path — the consolidation direction the cross-file-move ruling set — and the who-flips half is left inlanding-operations.mdrather than duplicated. 防 AI 写错: the sharpest of the three is:85, which converts a silent wrong outcome (a PR that reads armed and never enqueues) into a named precondition, and:84removes the reading that an arm can be taken back before it lands; both tighten what an agent may conclude rather than adding a tolerant fallback. 创业阶段不扩散需求: the increment is the smallest that carries the facts — three lines against a candidate set of four, with the fourth refused as already present, the ceiling raised to the landed count and not a byte above, and no second copy of a rule that already has a home.Verification
Gate families derived from the FINAL diff, three-dot, with
--repoasserted:All 39 run, each exit code captured before any pipe, then reconciled:
Named verdict lines, quoted from each gate's own output:
Path face:
Two roster families whose ledger sits under a directory this diff is in were run rather than read as silent:
One family exited 3 (PREREQUISITE NOT MET,
@objectstack/lintunbuilt) on the first pass. Built under the shared verify lock and re-run to a real verdict, so it is recorded at its measured code:Control-character self-scan beyond the gate, over both changed files:
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'— no hits.Repo-wide scans (
pnpm lintand the rest of the farm) are CI's run, not this one. All readings above were taken at head2b204b74;origin/mainmoved four commits under the branch during the run and touches neither changed file, so no merge was taken.Acceptance notes
noted, not filed::84's 28–60 s and:81's "enqueue event and queue ref appear 1–3 minutes late" are two different quantities (the timeline timestamp vs when the event becomes readable). They do not conflict, but a reader skimming the section could take them as competing numbers. Not filed: the rows are adjacent and each names its own subject, and merging them would cost a line the exception's dedup condition would not fund. Successor: the next readings increment on this section.noted, not filed:scripts/pm/check-label-desc-cap.mjsalready encodes the 100-character cap as a gate, but only overscripts/pm/ensure-pm-labels.sh. A seat writing a label description through the API — which is what the carrier card's incident was — has no gate at all;:88is the only control there. Not filed as a defect: the gate's own header states its scope deliberately, and widening it is a policy question, not a repair. Successor: whoever next writes a label description by hand.noted, not filed:the retriage answer's fact-3 measurement was taken against:13–:14and missed:56–:57, which carry the same reading more generally. Recorded here rather than filed because it changed nothing but this PR's line count, and the dedup condition caught it before a line was written. Successor: this PR's ACCEPT.Clause-②: no
Changeset: none —
skip-changeset. Nothing published moves: the diff is.claude/**andscripts/pm/**, both on the fast lane, and no path under any package'sfiles[]is touched. The label is applied on this PR.维护者速读(草稿)
改了什么 —— 平台读数表的 auto-merge 段落加三行实测读数:① 检查已全部完成的 PR 一挂 auto-merge 就入队(本仓实测 28–60 秒),挂载与落地之间没有窗口;② 可合并性还没算完就挂,挂上的是经典 auto-merge、根本不入队;③ GitHub 标签描述上限 100 字符,超长直接 422 拒收。另外把该文件的行数上限从 422 抬到 425,按常设例外记账。
为什么改 —— 这三条都是有人真撞过、花了时间才测出来的平台行为。不写进表里,下一个席位还要再撞一次、再测一次。原卡还有一半(auto-merge 该由谁挂)现有文本已经写死了,本 PR 一个字都不重复。
风险与代价(含回滚) —— 风险很低:改的是给 agent 读的说明文字和一个行数上限,不碰任何运行时代码,不影响产品、不影响用户。代价是这个文件又长了三行(每行一条读数,是最省的写法)。回滚就是 revert 这一个提交,没有任何后续动作。
席位意见 ——
你要做的 —— 这是受管面(
.claude/),按规矩只能由你手工合并。看一眼三行读数措辞是否认可、以及行数上限 422 到 425 这次提额你是否同意(它走的是你此前定下的常设例外,不需要新开决策卡)。认可就直接合并。Generated by Claude Code