Skip to content

docs(pm): record three measured auto-merge and label-cap platform readings - #17523

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-17160-platform-readings-arming-facts
Sep 11, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-17160-platform-readings-arming-facts

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

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:

:83  - ready 翻转触发检查重跑 ⇒ 入队落在翻转之后约一分钟,那段空窗不是挂载失败。   (existing)
:84  - 检查全部完成的 PR 挂 auto-merge 即入队,本仓 28–60 秒 ⇒ 挂载与落地之间无窗口。
:85  - `mergeable_state` 未落定时挂上的是经典 auto-merge、不入队,落定后再挂才入队。
:86  - `behind` 的 PR 照常入队:落后于 main 不是入队否决,⛔ 不为它先跑 update-branch。  (existing)
:87  - `check_suite.completed` 会命名过期 head ...                                    (existing)
:88  - 落地相邻的写侧一则:GitHub 标签描述上限 100 字符,超长写回 422,133 字的原文即不可存。

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-lint clean over 27 files).

Where each reading came from

row source of the reading
:84 arming an all-checks-complete PR enqueues at once the carrier card's own measurement on the sibling repo it was filed from (17–20 s enqueue to merge across a dozen PRs), plus this seat's measurement here today: 28–60 s from the enable_pr_auto_merge call to the timeline's added_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.
:85 a call before mergeability settles arms classic auto-merge without enqueueing this seat, on its own PR at 16:43Z today — the first call, seconds after the ready flip while mergeable_state still read unknown, armed classic auto-merge and produced no added_to_merge_queue; the second call, once settled, enqueued.
:88 label description capped at 100 characters the carrier card: a maintainer-confirmed ruling on the sibling repo was pinned verbatim at 133 characters and was unstorable, refused with 422. Corroborated on this tree — check:pm-label-desc-cap reports 23 descriptions, longest exactly 100.

:84 does not contradict :81 or :83, and is placed to make that visible

:81 measures how long the enqueue event and the queue ref take to become visible (1–3 minutes, a polling budget); :83 measures the window created when the ready flip triggers check re-runs. :84 is 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 :83 is 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 :85 then names.

One candidate reading did NOT land — it is already on the tree

The dispatch carried a fourth reading: that an enable_pr_auto_merge success line with an empty method and timestamp, on a PR reading back auto_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:

:56  - `enable_pr_auto_merge` 对已 `mergeable_state: clean` 的 PR 照样成功,与工具描述的优雅失败相反。
:57  - 回显两向不可靠,空回显不等于未挂上 ⇒ ⛔ 不拿它当任何方向的证据、不为它空转。

The retriage answer measured that fact against :13–:14 alone, 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.md 422 → 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:

「唯一例外:platform-readings.md 增量抬上限到落地行数,免决策卡,记 ruledRaises 引常设裁决。条件:席位验收评论逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排」

Recorded as a ruledRaises record on the cross-file-move declaration keyed by this file, quoting that exception verbatim, dated 2026-09-10, delta: 3 — the shape the script prescribes and the shape every record before it uses. Nothing else in CEILINGS moves. The move's own arithmetic is unchanged by the raise, which is the whole point of recording it separately:

+11 (314→425, less 100 lines of ordinary ruled raise) against a net source decrease of 20

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 — :84 and :85 describe a call every landing seat makes, and :88 was 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 in landing-operations.md rather 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 :84 removes 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 --repo asserted:

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack   :: exit 0
  change set: .claude/skills/pm-dispatch/references/platform-readings.md
              scripts/pm/check-skill-line-ratchet.mjs
  -> 39 command(s)

All 39 run, each exit code captured before any pipe, then reconciled:

node scripts/pm/dispatch-gates.mjs --ran ran.txt --repo objectstack-ai/objectstack   :: exit 0
✓ dispatch-gates --ran: 39 derived famil(ies) accounted for — 39 run, 0 NOT-MEASURED
  (a DERIVED zero — all 39 recorded an exit code and none of them is 3).

Named verdict lines, quoted from each gate's own output:

pnpm check:pm-skill-ratchet   :: exit 0
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/platform-readings.md is 425 lines (ceiling 425; headroom 0).
✓ check-skill-line-ratchet: cross-file move into .claude/skills/pm-dispatch/references/platform-readings.md: +11 (314→425, less 100 lines of ordinary ruled raise) against a net source decrease of 20 (...); authorised by #14685 item 5 (comment 5520452691).
✓ check-skill-line-ratchet: declared cross-file moves: 1, total ceilings down 9 lines.

node scripts/pm/check-skill-line-ratchet.mjs --self-test   :: exit 0
✓ check-skill-line-ratchet self-test: 157 cases pass.
  (includes: every live ruled-raise record quotes its ruling, dates it, and names a positive line count)

pnpm check:pm-skill-id-lint   :: exit 0
✓ check-skill-id-lint: 27 file(s) clean (pattern /#[0-9]{3,}/g).

pnpm check:pm-dispatch-gates   :: exit 0
✓ dispatch-gates self-test: 1678 cases pass.
  (run detached and waited for in the foreground with `tail --pid` — it exceeds the container's 600 s foreground cap)

pnpm check:nul-bytes   :: exit 0
✓ check-nul-bytes --self-test: 75 assertions over a temp git repo (real scan() path)

pnpm check:skill-frame-sync   :: exit 0
✓ check-skill-frame-sync: the one declared copy of the decision frame is internally coherent

pnpm check:pm-governed-merges   :: exit 0

Path face:

node scripts/pm/check-governed-merges.mjs --test .claude/skills/pm-dispatch/references/platform-readings.md scripts/pm/check-skill-line-ratchet.mjs   :: exit 3
⛔  GOVERNED — a human merge is the review record for this PR.
    .claude/** ×1 — the agent instruction tree (skills, agents, hooks, settings)

Two roster families whose ledger sits under a directory this diff is in were run rather than read as silent:

pnpm check:pm-label-desc-cap   :: exit 0
✓ check:pm-label-desc-cap: 23 label descriptions in scripts/pm/ensure-pm-labels.sh, all ≤100 characters (longest: 100, repo:objectui).

node scripts/check-skills-token-ratchet.mjs   :: exit 0
✓ check-skills-token-ratchet: 34 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted.

One family exited 3 (PREREQUISITE NOT MET, @objectstack/lint unbuilt) 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:

bash scripts/pm/os-verify-lock.sh -c 'pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2'
os-verify-lock: VERDICT command-exit 0 · held the lock 2s · waited 0s
pnpm --filter @objectstack/lint run check:doc-formula-expressions   :: exit 0

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 lint and the rest of the farm) are CI's run, not this one. All readings above were taken at head 2b204b74; origin/main moved 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.mjs already encodes the 100-character cap as a gate, but only over scripts/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; :88 is 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–:14 and 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/** and scripts/pm/**, both on the fast lane, and no path under any package's files[] 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

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>
@os-litant os-litant added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 10, 2026 — with Claude
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Sep 10, 2026

Copy link
Copy Markdown
Collaborator Author

维护者速读

改了什么 —— references/platform-readings.md 「## 队列成员资格与 auto-merge」 加三行实测平台读数:① 检查全部完成的 PR 挂 auto-merge 即入队(本仓 28–60 秒),挂载与落地之间没有窗口;② mergeable_state 未落定时挂上的是经典 auto-merge、不入队,落定后再挂才入队(本席今天在 PR #17468 上踩到的);③ GitHub 标签描述上限 100 字符,超长写回 422(hotcrm 一条 133 字的裁决原文存不进去)。三行各 108 / 101 / 115 字节,上限 120。文件 422 → 425 行,走 SKILL.md :392 那条「platform-readings.md 增量免决策卡」的常设例外,check-skill-line-ratchet.mjs 里记了一条 ruledRaises,逐字引用裁决。

为什么改 —— 这张卡原来的主诉(dev 自己挂 auto-merge 会跳过席位复核)已被今晨落地的 landing-operations.md:64「auto-merge 由 PM 挂,dev 永不碰」关掉,分诊席复核后降为 p3、落点改为平台读数;剩下的就是把三条实测记下来,让下一个席位不必再踩。候选本来有四条,第四条(空回显其实是挂上了)树上 :56–:57 已经写着,dev 查重后没写第二遍。

风险与代价(含回滚) —— 纯参考文本 + 一个上限整数 + 一条台账记录;不改任何门禁谓词。CI 在 head 2b204b74 上收敛中(3 项在跑)。回滚 = revert 两个文件,上限退回 422。

席位意见 —— 通过。本席在 head 上实测三行字节数与 425/425,自跑棘轮与其自测(157 例),对照 :56–:57 核了那条去重。受管面(.claude/**):本席不翻 ready、不入队、不批准。

你要做的 —— 一个动作:人工合并本 draft PR。

skills 席,session session_01YKEjmbYNvYWJvWGSWx26zK,2026-09-10T18:54Z。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 11, 2026 06:28
@os-zhuang
os-zhuang enabled auto-merge September 11, 2026 06:28
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 11, 2026
Merged via the queue into main with commit d8de599 Sep 11, 2026
40 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-17160-platform-readings-arming-facts branch September 11, 2026 06:54
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 needs-user-decision size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] The pm-dispatch landing rule lets a dev's auto-merge delete the seat's review entirely — arming on an already-green PR merges immediately

3 participants