From 04cbdb817219d479d7c7cd6d2b296ee0273e380b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 03:40:23 +0000 Subject: [PATCH 1/5] =?UTF-8?q?docs(pm-skill):=20the=20seventh=20readings?= =?UTF-8?q?=20increment=20=E2=80=94=20six=20deduplicated=20readings,=20two?= =?UTF-8?q?=20in-place=20corrections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ledger 395 -> 401 under the standing one-file exception; ceiling row and a `ruledRaises` record updated to match. Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY Co-authored-by: Claude Co-Authored-By: Claude Fable 5.1 --- .../references/platform-readings.md | 10 ++++- scripts/pm/check-skill-line-ratchet.mjs | 38 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index ea126ec9bb..586774816c 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -12,6 +12,7 @@ - 它分得开从未入队与入队后被踢;`pull_request.enqueued` webhook 推送式不可重读,只作旁证。 - `auto_merge` 字段不只是空,是不稳定:同一 PR 一分钟内先 set 后 None,入队后又回落 off。 - ⛔ 永不据它判没挂上而重挂 —— 重挂踢队重排。 +- 推送重折已挂 auto-merge 的 PR 可静默掉挂,无字段说明 ⇒ 重折后重发,再按队列 ref 探。 - 成功序列读间隔不读事件名:`removed_from_merge_queue` 后 ~1 秒内跟 `merged` 是落地不是被踢。 - 真被踢是其后无 `merged`、几分钟后 PR 仍 open。 - 不在 `origin/main` 上是二义读数:在队列里等 / 没入队,两者处置相反。 @@ -19,6 +20,7 @@ - `origin/main` 按内容读(grep 本 PR 的产物),⛔ 不按 head sha 祖先性、不按 `merged` 布尔。 - 队列落的是另一个提交:`git merge-base --is-ancestor origin/main` 对已完全合入的 PR 答 NO。 - 同 PR 的 `list_pull_requests` 会回 `merged: false` 与 `merged_at` 并存 ⇒ 只读布尔即读成没合。 +- `list_pull_requests` 的 `fields` 请求 `merged_by` 不返回该字段 ⇒ 字段缺席不是值读数。 - `mergeable_state` 惰性计算,`unknown` 不是读数 —— 挂 unknown 等于挂在可能脏的头上。 - `dirty` 即队列入口否决(冲突对象是当前 main);draft PR 恒回 `draft`。 - 判头脏走零配额本地试合并:fetch PR ref 后 `git merge-tree --write-tree origin/main `。 @@ -49,6 +51,7 @@ - 设方法的 GraphQL mutation 不服务 agent 会话 ⇒ 席位既设不了也纠不了。 - 它在本仓无实效:`main` 的合并队列规则带 `merge_method: SQUASH`,合并由队列执行。 - ⇒ 落地方法读分支规则,⛔ 永不读 auto-merge 请求;树上每 PR 一个 squash 提交。 +- `enable_pr_auto_merge` 对已 `mergeable_state: clean` 的 PR 照样成功,与工具描述的优雅失败相反。 - 回显两向不可靠,空回显不等于未挂上 ⇒ ⛔ 不拿它当任何方向的证据、不为它空转。 - 配额枯竭时 `enable_pr_auto_merge` 回成功而挂载根本没发生 ⇒ 验效果,不验回应。 - 回读 `auto_merge` 非空本接口给不了:`pull_request_read` 与 `fields` 枚举都无该成员。 @@ -201,12 +204,14 @@ - `issue_write` 还清空每个未传字段(assignees 在内)⇒ 单字段更新必须把现值带齐重写。 - 追加端点同样先过探针:403 会话没有真追加通道,只能整组替换。 - 摘标签也没有加法端点:`finding` 定级这类只能整组写,carve-out 保留;写后照纪律回读。 -- PR 标签的三条读腿全盲、两条静默。 +- PR 标签走 issue 形通道的三条读腿全盲、两条静默,PR 原生端点见腿 ④。 - 腿 ①:`issue_read get_labels` 传 PR 号回 Could not resolve to an Issue。 - REST 的 PR 也是 issue 惯例在此方法不成立;响亮失败即路由信号,改走腿 ③。 - 腿 ②:`pull_request_read get` 的 `labels` 时缺时滞,可整字段缺席;连盲都不稳定,更险。 - 腿 ③:payload 档 —— issue 页的 `href` 锚点 grep(`/labels/NAME`)在 PR 页命中零。 - PR 侧拼写是 `data-name="NAME"`,片链到 `issues?q=…label%3A…`。 +- 腿 ④:`list_pull_requests` 与 `search_pull_requests` 传 PR 号回完整 `labels`,是可用读腿。 +- 反向不对称:`issue_write update` 传 PR 号写 `labels` 与 `assignees` 生效,而读腿 ① 拒 PR 号。 - ⇒ ⛔ 读成功而标签空或缺席不读作没有标签:按 `data-name=` 确认,否则整集作 UNKNOWN。 - 可达时优先加法端点;⛔ 单读与单次即时读回都不决断。 - ⇒ union-write 欠一次延迟确认;必需标签(如 `skip-changeset`)其后每次触碰重核。 @@ -215,7 +220,7 @@ - 可指派性是仓+账号属性且会话中可变:`GET /repos/{o}/{r}/assignees/USER` 204/404,指派后回读。 - MCP `issue_read` 的 body 实体转义是纯读侧伪影,撇号与引号与尖括号成数字实体,comments 原样。 - 存储体是明文,先解码实体再写回往返安全;腐蚀 body 的恰是把转义读数原样回写。 -- 读侧并非一律可逆:行内反引号里的尖括号片段被 MCP 读路径整个丢弃,非转义,无从解码。 +- 读侧并非一律可逆:丢弃亦及标题,自首个 tag 形跨度截到尾,凭标题计数只是下界。 - 写侧剥除是真实存储损耗,⛔ 两类不并成一条,写后回读必做;实体归属与 `&` 类未实测。 - 评论里独立成行的标记同被读路径吃掉留空行 ⇒ 缺失不证写侧剥除,先读 payload 原体。 - `Blocked-by:` 行归 BODY,是单通道反向索引:追加按解码后写回执行。 @@ -357,6 +362,7 @@ - 落地探针除命名代码形外,还必须在落地前的 tip 上读出不同值,否则它分不开两棵树。 - `check-governed-merges` 浅克隆上拒答而非少报,并报未审计仓数;补救 `git fetch --shallow-since=`。 - 前台 `sleep` 被 harness 拒 ⇒ 等待写成带 until 条件的前台阻塞等待,⛔ 不写 sleep 轮询循环。 +- `check:pm-dispatch-gates` ≈13 分钟超 600 秒前台上限 ⇒ detach 加 `tail --pid` 等;超时不是读数。 - 分支删除被拒有第二形态:代理回 403,与既有 send-pack 断连同处置 ⇒ 不可删,⛔ 不重试。 ## 闭合关键词解析(PR 正文写侧) diff --git a/scripts/pm/check-skill-line-ratchet.mjs b/scripts/pm/check-skill-line-ratchet.mjs index 3e61eeba7f..3ac511bdff 100644 --- a/scripts/pm/check-skill-line-ratchet.mjs +++ b/scripts/pm/check-skill-line-ratchet.mjs @@ -599,7 +599,29 @@ export const CEILINGS = new Map([ // pairs, and re-wrap funding is refused per the 2026-08-17 rule in any case. // The same-PR correction of the footer-mechanism row is line-neutral and buys // nothing. Landed count, headroom 0, same convention. - ['.claude/skills/pm-dispatch/references/platform-readings.md', 395], + // Raised 395 → 401 by the SEVENTH readings increment, again under the STANDING + // one-file exception quoted above rather than a fresh decision card, and again + // recorded as a `ruledRaises` record citing it. Spent at ONE line per + // deduplicated reading, each written in this file's voice: the dispatch-gates + // self-test runs past the container's 600 s foreground cap, so a timeout is not + // a verdict (+1); a push that re-folds an armed PR can drop the arm with no + // field saying so (+1); `enable_pr_auto_merge` succeeds on a PR already reading + // `mergeable_state: clean`, against its own tool description (+1); a `merged_by` + // named in `list_pull_requests`'s `fields` comes back absent, so an absent field + // is not a value reading (+1); PR labels ARE readable after all — leg ④, the two + // PR-native MCP endpoints (+1); and the write side's mirror asymmetry, where + // `issue_write update` takes a PR number that read leg ① refuses (+1) = +6 + // exactly. TWO corrections are paid in place and buy nothing: the read-side + // truncation row (the loss reaches TITLES and cuts from the first tag-shaped + // span to the END, so a title-derived count is a lower bound) and the PR-label + // block's opening row, which said three blind legs where leg ④ now answers. + // The single-label omission this increment's carrier card was opened for did + // NOT reproduce, so it lands NO line — the negative reading is on the card. + // Nothing else 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 2026-08-17 rule in any case. Landed count, headroom 0, + // same convention. + ['.claude/skills/pm-dispatch/references/platform-readings.md', 401], // Per-operation REST/GraphQL/git channel mapping — which fleet operation has // a REST twin (each row executed in a real session, provenance date carried // per row), the handful that are GraphQL-only, and the queue-routing @@ -1067,6 +1089,20 @@ export const CROSS_FILE_MOVES = new Map([ date: '2026-09-07', delta: 7, }, + { + // The SEVENTH increment, under the same STANDING exception — the same + // words, quoted again rather than cross-referenced, because a record + // that quotes no ruling is RED and each record stands alone. The +6 is + // accounted for line by line beside this entry's ceiling above. + ruling: + 'the standing one-file exception for' + + ' `.claude/skills/pm-dispatch/references/platform-readings.md` — pm-dispatch' + + ' SKILL.md, verbatim and untranslated: 「唯一例外:`platform-readings.md`' + + ' 增量抬上限到落地行数,免决策卡,记 `ruledRaises` 引常设裁决。条件:席位验收评论' + + '逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排」', + date: '2026-09-08', + delta: 6, + }, ], sources: [ ['.claude/skills/pm-dispatch/references/lanes/cli.md', 35], From ff2bd708ae54a6e6243d61638da700bb24dc99dc Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 03:59:04 +0000 Subject: [PATCH 2/5] docs(pm-skill): pin the dispatch-gates row to its case count, not a drifting minute figure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-measured in this container: 1534 cases, exit 0, 705 s wall — past the 600 s foreground cap either way, which is the load-bearing half. Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY Co-authored-by: Claude Co-Authored-By: Claude Fable 5.1 --- .claude/skills/pm-dispatch/references/platform-readings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index 586774816c..e35c185e76 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -362,7 +362,7 @@ - 落地探针除命名代码形外,还必须在落地前的 tip 上读出不同值,否则它分不开两棵树。 - `check-governed-merges` 浅克隆上拒答而非少报,并报未审计仓数;补救 `git fetch --shallow-since=`。 - 前台 `sleep` 被 harness 拒 ⇒ 等待写成带 until 条件的前台阻塞等待,⛔ 不写 sleep 轮询循环。 -- `check:pm-dispatch-gates` ≈13 分钟超 600 秒前台上限 ⇒ detach 加 `tail --pid` 等;超时不是读数。 +- `check:pm-dispatch-gates`(1534 例)逾 600 秒前台上限 ⇒ detach 加 `tail --pid` 等;超时不是读数。 - 分支删除被拒有第二形态:代理回 403,与既有 send-pack 断连同处置 ⇒ 不可删,⛔ 不重试。 ## 闭合关键词解析(PR 正文写侧) From 2695ba835cef0d82710fb515691c50ef04832364 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 04:20:03 +0000 Subject: [PATCH 3/5] docs(pm-skill): restore the read-side row's subject; the title truncation pays for its own line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review finding: replacing the 「读侧并非一律可逆」 row in place cost it the subject of 丢弃 — the original names WHAT is discarded (an angle-bracketed span inside inline backticks, whole, unescaped, undecodable), which is the contrast with the reversible entity-escaping row above it, and no other row carries it. The row is restored byte-identical to origin/main and the title fact lands as its own adjacent row. Ceiling 401 -> 402, ruledRaises delta 6 -> 7. Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY Co-authored-by: Claude Co-Authored-By: Claude Fable 5.1 --- .../references/platform-readings.md | 3 +- scripts/pm/check-skill-line-ratchet.mjs | 31 +++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index e35c185e76..d33f63117e 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -220,7 +220,8 @@ - 可指派性是仓+账号属性且会话中可变:`GET /repos/{o}/{r}/assignees/USER` 204/404,指派后回读。 - MCP `issue_read` 的 body 实体转义是纯读侧伪影,撇号与引号与尖括号成数字实体,comments 原样。 - 存储体是明文,先解码实体再写回往返安全;腐蚀 body 的恰是把转义读数原样回写。 -- 读侧并非一律可逆:丢弃亦及标题,自首个 tag 形跨度截到尾,凭标题计数只是下界。 +- 读侧并非一律可逆:行内反引号里的尖括号片段被 MCP 读路径整个丢弃,非转义,无从解码。 +- 该丢弃亦及标题:自首个 tag 形跨度截到尾,是切不是洞 ⇒ 凭标题的总体计数只是下界。 - 写侧剥除是真实存储损耗,⛔ 两类不并成一条,写后回读必做;实体归属与 `&` 类未实测。 - 评论里独立成行的标记同被读路径吃掉留空行 ⇒ 缺失不证写侧剥除,先读 payload 原体。 - `Blocked-by:` 行归 BODY,是单通道反向索引:追加按解码后写回执行。 diff --git a/scripts/pm/check-skill-line-ratchet.mjs b/scripts/pm/check-skill-line-ratchet.mjs index 3ac511bdff..b156ae8d7c 100644 --- a/scripts/pm/check-skill-line-ratchet.mjs +++ b/scripts/pm/check-skill-line-ratchet.mjs @@ -599,7 +599,7 @@ export const CEILINGS = new Map([ // pairs, and re-wrap funding is refused per the 2026-08-17 rule in any case. // The same-PR correction of the footer-mechanism row is line-neutral and buys // nothing. Landed count, headroom 0, same convention. - // Raised 395 → 401 by the SEVENTH readings increment, again under the STANDING + // Raised 395 → 402 by the SEVENTH readings increment, again under the STANDING // one-file exception quoted above rather than a fresh decision card, and again // recorded as a `ruledRaises` record citing it. Spent at ONE line per // deduplicated reading, each written in this file's voice: the dispatch-gates @@ -609,19 +609,32 @@ export const CEILINGS = new Map([ // `mergeable_state: clean`, against its own tool description (+1); a `merged_by` // named in `list_pull_requests`'s `fields` comes back absent, so an absent field // is not a value reading (+1); PR labels ARE readable after all — leg ④, the two - // PR-native MCP endpoints (+1); and the write side's mirror asymmetry, where - // `issue_write update` takes a PR number that read leg ① refuses (+1) = +6 - // exactly. TWO corrections are paid in place and buy nothing: the read-side - // truncation row (the loss reaches TITLES and cuts from the first tag-shaped - // span to the END, so a title-derived count is a lower bound) and the PR-label - // block's opening row, which said three blind legs where leg ④ now answers. + // PR-native MCP endpoints (+1); the write side's mirror asymmetry, where + // `issue_write update` takes a PR number that read leg ① refuses (+1); and the + // TITLE truncation — the same read-side discard reaches titles, where it cuts + // from the first tag-shaped span to the END rather than leaving a hole, so a + // title-derived population count is only a lower bound (+1) = +7 exactly. + // + // ⚠️ That last line is a NEW ROW, not a rewrite, and the distinction was a + // review finding rather than the author's first instinct. It was first written + // as an in-place replacement of the read-side row above it, which silently cost + // that row its SUBJECT: the original names WHAT is discarded (an angle-bracketed + // span inside inline backticks, discarded whole, unescaped, undecodable), and + // that is the load-bearing contrast with the entity-escaping row before it, + // which IS reversible. The replacement left 「丢弃」 with no antecedent anywhere + // in the file. The read-side row is therefore restored BYTE-IDENTICAL to + // `origin/main` (blob c242297575d3c04205e47d9628ff0545e5d63da4) and the title + // fact pays for its own line. + // + // ONE correction is paid in place and buys nothing: the PR-label block's + // opening row, which said three blind legs where leg ④ now answers. // The single-label omission this increment's carrier card was opened for did // NOT reproduce, so it lands NO line — the negative reading is on the card. // Nothing else 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 2026-08-17 rule in any case. Landed count, headroom 0, // same convention. - ['.claude/skills/pm-dispatch/references/platform-readings.md', 401], + ['.claude/skills/pm-dispatch/references/platform-readings.md', 402], // Per-operation REST/GraphQL/git channel mapping — which fleet operation has // a REST twin (each row executed in a real session, provenance date carried // per row), the handful that are GraphQL-only, and the queue-routing @@ -1101,7 +1114,7 @@ export const CROSS_FILE_MOVES = new Map([ + ' 增量抬上限到落地行数,免决策卡,记 `ruledRaises` 引常设裁决。条件:席位验收评论' + '逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排」', date: '2026-09-08', - delta: 6, + delta: 7, }, ], sources: [ From aa3e58bf6f0207b858a50cf87dccb1c8d7765d08 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 04:33:10 +0000 Subject: [PATCH 4/5] =?UTF-8?q?docs(pm-skill):=20drop=20the=20dispatch-gat?= =?UTF-8?q?es=20case=20count=20=E2=80=94=20a=20merge=20moved=20it=201534?= =?UTF-8?q?=20to=201552=20within=20the=20hour?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The load-bearing half is the 600 s foreground cap, which does not drift. Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY Co-authored-by: Claude Co-Authored-By: Claude Fable 5.1 --- .claude/skills/pm-dispatch/references/platform-readings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index d33f63117e..8535638731 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -363,7 +363,7 @@ - 落地探针除命名代码形外,还必须在落地前的 tip 上读出不同值,否则它分不开两棵树。 - `check-governed-merges` 浅克隆上拒答而非少报,并报未审计仓数;补救 `git fetch --shallow-since=`。 - 前台 `sleep` 被 harness 拒 ⇒ 等待写成带 until 条件的前台阻塞等待,⛔ 不写 sleep 轮询循环。 -- `check:pm-dispatch-gates`(1534 例)逾 600 秒前台上限 ⇒ detach 加 `tail --pid` 等;超时不是读数。 +- `check:pm-dispatch-gates` 逾容器 600 秒前台上限 ⇒ detach 加 `tail --pid` 前台等;超时不是读数。 - 分支删除被拒有第二形态:代理回 403,与既有 send-pack 断连同处置 ⇒ 不可删,⛔ 不重试。 ## 闭合关键词解析(PR 正文写侧) From 29557972384e80d926a7a4e1b3112f022fcbad36 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 04:53:00 +0000 Subject: [PATCH 5/5] docs(pm-skill): the seventh increment's ruledRaises comment says +7, matching its delta Comment-only. The record's delta is 7 and the CEILINGS comment above it tallies "+7 exactly"; this one sentence still read +6 from before the title row landed. Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY Co-authored-by: Claude Co-Authored-By: Claude Fable 5.1 --- scripts/pm/check-skill-line-ratchet.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pm/check-skill-line-ratchet.mjs b/scripts/pm/check-skill-line-ratchet.mjs index b156ae8d7c..db59425314 100644 --- a/scripts/pm/check-skill-line-ratchet.mjs +++ b/scripts/pm/check-skill-line-ratchet.mjs @@ -1105,7 +1105,7 @@ export const CROSS_FILE_MOVES = new Map([ { // The SEVENTH increment, under the same STANDING exception — the same // words, quoted again rather than cross-referenced, because a record - // that quotes no ruling is RED and each record stands alone. The +6 is + // that quotes no ruling is RED and each record stands alone. The +7 is // accounted for line by line beside this entry's ceiling above. ruling: 'the standing one-file exception for'