Skip to content

Commit a90a9f2

Browse files
claude[bot]claude
andauthored
docs(pm): platform-readings records the re-run channel split — REST 403 for the seat token, MCP rerun_failed_jobs 201 (#18025) (#18129)
Fixes #18025 One row in `.claude/skills/pm-dispatch/references/platform-readings.md`, in the Actions / re-run block, plus the ceiling increment it costs. No other file moves. Dev session `session_01DAcomhvR9kKizeYgg89Vo8` on branch `claude/issue-18025-platform-readings-rerun-channel` (worktree `objectstack-issue-18025`), off `origin/main` `ca788604`, BASE `ca7886047b27667122f9c2c44de3b6e67eb361fe`. No merge was needed: nothing landed on `main` under either path since the branch point. ## What landed `platform-readings.md` :285, placed immediately after the existing re-run pair (:283–:284): ```text - 读数 2026-09-13:席位 REST `/jobs/{id}/rerun` 403、MCP `rerun_failed_jobs` 201 ⇒ 重跑可做,锁 1 未禁。 ``` 117 bytes against the 120-byte line cap; one matter on the line; a dated 读数 in the file's own register voice. It records the CHANNEL split the card measured, and nothing else: - the seat's REST token (`GITHUB_TOKEN` through the session proxy) answers **403** `Resource not accessible by integration` on `POST /repos/objectstack-ai/objectstack/actions/jobs/103706765153/rerun`; - MCP `actions_run_trigger` with `method: rerun_failed_jobs`, `run_id: 34750740645`, answers **201** and re-queues the failed shards — attempt 2 visible on the run. The consequence rides the same line, which is why the row is worth a ceiling increment at all: **the one confirming re-run of a failure that is not this PR's is exercisable by the seat**, and lock 1 (PR #18072, `7ef05f997`) does not take it away — `actions_run_trigger` is state-shaped, so it is not on the write-identity deny list. The standing text that read 「re-run is 403 to this seat」 was true of ONE channel, which is the error the triage comment 5654613958 generalises: 「the seat cannot do X」 is a claim about a channel, ⛔ never about the seat. Two things the 120-byte cap did NOT buy, declared rather than quietly dropped: - **the 403's message text.** Error prose is not pinned unless a consumer parses its original words; nobody parses this one, and the operative discriminant is the status pair 403 / 201. The full text stays on the card. - **the `POST` verb and the `/actions` path segment.** The path `/jobs/{id}/rerun` exists only as a POST, and :291 already carries the sibling `GET /actions/jobs/{id}/logs` spelling, so the family is legible from the neighbourhood. Spelling both would have cost 8 bytes the line does not have. ## Ceiling 453 → 454 — the standing exception, no decision card `scripts/pm/check-skill-line-ratchet.mjs`: the `platform-readings.md` ceiling moves by exactly the landed delta, and the raise is recorded as the FOURTEENTH `ruledRaises` record on the cross-file-move declaration, in the same shape as the thirteenth (added by #18072 at `7ef05f997`) and quoting the same ruling verbatim and untranslated — pm-dispatch SKILL.md 〈分诊座位职责〉: > 唯一例外:`platform-readings.md` 增量抬上限到落地行数,免决策卡,记 `ruledRaises` 引常设裁决。条件:席位验收评论逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排 ⛔ No other ceiling moves. ⛔ No decision card, because the exception says none is owed. **Density was MEASURED, not assumed** — the exception's own precondition and the 2026-08-17 no-re-wrap-funding rule: - of the file's **427** adjacent bullet pairs, **ZERO** merge within the 120-byte cap; the smallest merged width is **134 B**. - the two neighbours the row joins offer **37** spare bytes (:283, 83 B) and **6** spare bytes (:284, 114 B), against the row's **115** bytes of content after the `- ` marker. Neither can absorb it, and folding it into :283 would put a second matter on a line — 一事一行. ⇒ the row could not be paid in place, so the increment is +1 and the landed count is 454. ## Premise readings — all four hold, none falsified Taken on this worktree at `BASE` `ca788604` unless noted. | # | premise | reading | verdict | |:--|:--|:--|:--| | P1 | the file is 453 lines at ceiling 453 | `node scripts/pm/check-skill-line-ratchet.mjs` at 2026-09-14T03:42Z, exit 0: `✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/platform-readings.md is 453 lines (ceiling 453; headroom 0).` | **holds** | | P2 | no row states the channel split | `git grep -n -i -E 'Resource not accessible|actions/jobs|rerun_failed_jobs'` on the file at 2026-09-14T03:40Z returns exactly TWO hits, quoted below | **holds** | | P3 | the #18085 footer fact is already on :333–:334 | quoted below, byte-for-byte from `BASE` | **holds — already present** | | P4 | no in-flight branch touches the file | scan at 2026-09-14T03:47Z, below | **holds** | **P2, every hit quoted:** ```text 283: - `rerun_failed_jobs` 复用原 run 的提交与合并 ref,不拿新 main 重算。 291: - ⇒ 两者都答不了到底挂在哪;`GET /actions/jobs/{id}/logs` 被出口代理拒绝,CONNECT 403。 ``` :283 states only that a re-run reuses the original run's commit and merge ref — a fact about WHICH TREE is re-run, silent on WHO may re-run it. :291 is a different endpoint (`GET .../logs`, not `POST .../rerun`) failing a different way (the egress proxy's CONNECT 403, not GitHub's `Resource not accessible by integration`). Neither says a re-run is unavailable, so the card's 「if the file already carries a row saying re-runs are unavailable, replace it rather than add」 branch does not fire: this is an ADD, and the two lit controls prove the grep was looking in the right place rather than returning a silent zero. **P3, already present, ⛔ not a second row:** ```text 333: - 裸 REST `PATCH /pulls` 追加一个裸页脚并保留既有 session-URL 页脚,差恰 58 字节。 334: - 同路送无页脚正文存回恰一条(平台裸形)⇒ 该格处方是不送页脚,⛔ 不是不重送正文。 ``` **P4:** `git ls-remote --heads origin` lists 1102 branches; a name grep for `reading|rerun|re-run|channel|18025` hits only `claude/issue-13326-platform-readings-family` (landed long ago), `claude/issue-10979-...`, `claude/issue-7018-...` and this branch. Every remote-tracking ref dated today (`2026-09-14`) was then checked directly — `#18074`, `#18037`, `#18085`, `#18061`, `#18055`, `#18060`, `#18047`, `#18069`, `#17959` — and `git log origin/main..origin/BRANCH -- the-file` returns **0** commits for each. ⚠️ Scope declared: that scan sees the refs this container has fetched, which is every in-flight seat branch in this shift but not a branch pushed from elsewhere and never fetched here. ## Verification counts for the seat's ACCEPT One matter per line, deduplicated, re-wraps not counted: | | count | what | |:--|--:|:--| | candidates | 2 | ① the re-run channel split (REST 403 / MCP 201); ② the PR-body footer reading from #18085's dev report | | landed | 1 | ① as :285, 117 B | | already present | 1 | ② — :333–:334 carry it verbatim; refused as a duplicate rather than restated | | refused | 0 | — | ⇒ landed 1 = the ceiling delta 1 = 453 → 454. ## Gates `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at `9303a7b7e` (no paths passed — the script derives its own change set: 2 paths vs merge base `ca7886047`, three-dot semantics): **39 families**. Every one run in the foreground with its exit code captured by redirect-then-capture BEFORE any pipe; **39 of 39 exit 0**. Reconciliation, `--ran` with the exit code recorded per family: ```text Run reconciliation — 39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN. ✓ 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). ``` One family needed a second pass: `pnpm --filter @objectstack/lint run check:doc-formula-expressions` first answered **exit 3 — PREREQUISITE NOT MET** (`@objectstack/lint` not built; nothing measured, ⛔ not a finding). Built under the shared verify lock (`OS_VERIFY_LOCK_SLOT=issue-18025`, `VERDICT command-exit 0 · held the lock 1s · waited 0s`) and re-run: **exit 0**. The reconciliation above is the post-fix record. Named explicitly by the dispatch, and the roster families whose baseline sits under a directory this diff is in — outside the derived 39, each run and each exit code captured the same way: ```text pnpm check:pm-governed-prose :: exit 0 node scripts/check-published-list-mirrors.mjs :: exit 0 node scripts/check-published-list-mirrors.mjs --self-test :: exit 0 node scripts/check-skills-token-ratchet.mjs :: exit 0 node scripts/check-skills-token-ratchet.mjs --self-test :: exit 0 ``` Rule ⑤ — this diff edits a gate script, so that script's own suite is owed beyond the derived families. `scripts/pm/check-skill-line-ratchet.mjs` has no `*.test.ts`: `git grep -l` over `*.test.ts` / `*.test.mts` / `*.test.mjs` / `*.spec.ts` returns nothing, and its suite IS its `--self-test`, wired into `pnpm check:pm-skill-ratchet` (in the 39, exit 0): `✓ check-skill-line-ratchet self-test: 157 cases pass.` Its siblings that read the same module — `check:ratchet-remedy-authority`, `check:pm-dispatch-gates` — are in the 39 and green. Line-ratchet verdict after the edit: ```text ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/platform-readings.md is 454 lines (ceiling 454; headroom 0). ✓ check-skill-line-ratchet: cross-file move into .claude/skills/pm-dispatch/references/platform-readings.md: +11 (314→454, less 129 lines of ordinary ruled raise) against a net source decrease of 20 … ``` The move's own arithmetic is unchanged at +11 against −20, which is what the `ruledRaises` record is for. Control characters: `grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'` over both changed files is empty, and `pnpm check:nul-bytes` is in the 39 at exit 0. Every added prose line is ≤ 120 B (the added row is 117 B; the added ratchet comment lines are JS source, outside that cap). ⛔ Not measured here, by design: whole-farm CI. The derivation itself names 52 artifact-roster families, 11 declared-wide families, 14 pending-changeset families and 1 path-scheduled CI job as outside the derived 39 — CI owns those. ## Changeset None owed, and `skip-changeset` is the declaration rather than a shortcut. There is no `check-changeset-presence.mjs` in this tree; the changeset gate is `changeset-check` in `.github/workflows/pr-automation.yml`, and it reads **no path filter at all** — its only two exemptions are the `skip-changeset` label (re-read live, because the event payload's label snapshot is stale by construction) and the `changeset-release/main` branch pushed by `github-actions[bot]`. So a docs/tooling PR cannot be exempted by its paths; it has to carry the label. Nothing here publishes: both paths — `.claude/skills/pm-dispatch/references/platform-readings.md` and `scripts/pm/check-skill-line-ratchet.mjs` — are on the fast-track non-publishing list (`.claude/**`, `scripts/pm/**`), inside no released package's `files[]`. ## Acceptance notes - noted, not filed (承接者: the skills seat reviewing this PR): the register now carries THREE `/actions/jobs/{id}/...` readings across :283–:291 — re-run tree reuse, the re-run channel split, and the logs endpoint's proxy CONNECT 403. They are three separate matters and each is one line, so no line merges; the observation is only that a future 段落 boundary there would read better if the endpoint family were contiguous. Not a defect, not a contract breach, not an authoring trap ⇒ ⛔ no card. - noted, not filed (承接者: 无): the card body's own budget line reads 「449/449 — pay inside the file」, measured when it was filed on 2026-09-13T12:28Z. The file was 453/453 by the time of dispatch. Nothing to act on — the card's instruction was the ceiling DISCIPLINE, not the number — and no PR or person will read that line again once this lands. Clause-②: no — the diff widens no declared contract; it records a reading and pays its line. ## 维护者速读(草稿) **改了什么**:事实表 `platform-readings.md` 加一行(453 → 454),记一条读数:CI 失败 job 的重跑,席位自己的 REST 令牌回 403,而 MCP 的 `rerun_failed_jobs` 回 201 并把失败分片重新排队。顺带把 `check-skill-line-ratchet.mjs` 里这个文件的行数上限抬 1,按常设例外记一条 `ruledRaises`,引用裁决原话。 **为什么改**:此前的记录只说「重跑对席位是 403」,那是一个**通道**的事实,被当成了**席位能力**的事实。结果是:一条本来能执行的规则(CI 红了先做一次确认性重跑)被当作做不到,#18010 那张卡直接把它写进了阻塞原因,还惊动维护者问「17990 你自己不能解决吗」。这一行把通道和能力分开,下次没人再为这件事找人点一下。 **风险与代价(含回滚)**:只动文档与一个门禁脚本的常量,不发布任何包,不改运行时行为。代价是事实表长 1 行(每个座位每次会话都要读它,这就是上限存在的理由);本次为此实测了密度——全文 427 对相邻条目没有一对能合并进 120 字节,所以省不出来。回滚 = revert 本 PR 的那一个 commit。 **席位意见**:(留空,定稿成评论) **你要做的**:这是受管面(`.claude/**` + `scripts/pm/**`),按 Prime Directive #14 只能由你手动合并 —— 席位不合、不进队列、不挂 auto-merge。你要确认的是两件事:① 这一行的读数属实(卡面 #18025 有原始测量表);② 抬 1 行的上限动作走常设例外、不另开决策卡,是否照你的意思。 --- _Generated by [Claude Code](https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent c667d8c commit a90a9f2

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

‎.claude/skills/pm-dispatch/references/platform-readings.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@
282282
- 判定跨天翻面 ⇒ ⛔ 一次拒绝不是能力边界;`permissions.allow` 条目才是仓库侧确定性通道。
283283
- `rerun_failed_jobs` 复用原 run 的提交与合并 ref,不拿新 main 重算。
284284
- ⇒ 基上缺已合修复时重跑无效,只能 `git merge origin/main` 推提交;判别看修复合并时间。
285+
- 读数 2026-09-13:席位 REST `/jobs/{id}/rerun` 403、MCP `rerun_failed_jobs` 201 ⇒ 重跑可做,锁 1 未禁。
285286
- 同一 head 上轻量兄弟 workflow `success` 加重量级载体 `cancelled` 是普通取代的预期签名。
286287
- 同名 `failure` 也会被带另一诊断的后一次 `failure` 取代 ⇒ 任何判定前先按名取最新一次。
287288
- cancel-in-progress 窗口只罩得住慢载体 ⇒ 先比对 run `head_sha` 与 PR 当前 head,不开调查。

‎scripts/pm/check-skill-line-ratchet.mjs‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,24 @@ export const CEILINGS = new Map([
888888
// / refused 0. Nothing paid in place: the two lines sit beside the
889889
// invalid-session pair they qualify. Landed count, headroom 0, same
890890
// convention.
891-
['.claude/skills/pm-dispatch/references/platform-readings.md', 453],
891+
// Raised 453 → 454 by the FOURTEENTH readings increment, again under the
892+
// STANDING one-file exception quoted above rather than a fresh decision
893+
// card, and again recorded as a `ruledRaises` record citing it. Spent at ONE
894+
// line for ONE deduplicated reading, written in this file's voice: a failed
895+
// CI job's re-run is a CHANNEL split rather than a seat capability limit —
896+
// the seat's REST token reads 403 on the job re-run endpoint while MCP
897+
// `rerun_failed_jobs` reads 201 and re-queues the failed shards, so the one
898+
// confirming re-run stays exercisable through the state-shaped tool the
899+
// write-identity deny list still allows (+1) = +1 exactly. Candidates 2 /
900+
// landed 1 / already present 1 / refused 0 — the second candidate, the PR-body
901+
// footer reading, is already carried by the two 裸 REST `PATCH /pulls` lines
902+
// and was refused as a duplicate rather than restated. Could not be paid in
903+
// place, and the slack was MEASURED rather than assumed: of this file's 427
904+
// adjacent bullet pairs ZERO merge under the 120-byte cap (smallest merged
905+
// width 134 B), and the two neighbours the row joins offer 37 and 6 spare
906+
// bytes against its 115 bytes of content; re-wrap funding is refused per the
907+
// 2026-08-17 rule in any case. Landed count, headroom 0, same convention.
908+
['.claude/skills/pm-dispatch/references/platform-readings.md', 454],
892909
// Per-operation REST/GraphQL/git channel mapping — which fleet operation has
893910
// a REST twin (each row executed in a real session, provenance date carried
894911
// per row), the handful that are GraphQL-only, and the queue-routing
@@ -1526,6 +1543,23 @@ export const CROSS_FILE_MOVES = new Map([
15261543
date: '2026-09-13',
15271544
delta: 2,
15281545
},
1546+
{
1547+
// The FOURTEENTH increment, under the same STANDING exception — the
1548+
// same words again, for the same reason: a record that quotes no
1549+
// ruling is RED and each record stands alone. The +1 is accounted for
1550+
// line by line beside this entry's ceiling above; the exception's
1551+
// conditions (per-item verification and the candidate / landed /
1552+
// already-present / refused counts) are carried by the raising PR's
1553+
// body and the seat's ACCEPT.
1554+
ruling:
1555+
'the standing one-file exception for'
1556+
+ ' `.claude/skills/pm-dispatch/references/platform-readings.md` — pm-dispatch'
1557+
+ ' SKILL.md, verbatim and untranslated: 「唯一例外:`platform-readings.md`'
1558+
+ ' 增量抬上限到落地行数,免决策卡,记 `ruledRaises` 引常设裁决。条件:席位验收评论'
1559+
+ '逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排」',
1560+
date: '2026-09-14',
1561+
delta: 1,
1562+
},
15291563
],
15301564
sources: [
15311565
['.claude/skills/pm-dispatch/references/lanes/cli.md', 35],

0 commit comments

Comments
 (0)