docs(pm): platform-readings records the re-run channel split — REST 403 for the seat token, MCP rerun_failed_jobs 201 (#18025) - #18129
Conversation
One row in the Actions / re-run block: the seat's REST token reads 403 on the job re-run endpoint while MCP `rerun_failed_jobs` reads 201 and re-queues the failed shards (2026-09-13), so the one confirming re-run of a not-this-PR failure stays exercisable through the state-shaped tool the write-identity deny list still allows. The ceiling moves 453 -> 454 under the standing one-file exception for `platform-readings.md`, recorded as the fourteenth `ruledRaises` record quoting that ruling. Density was measured, not assumed: zero of the file's 427 adjacent bullet pairs merge under the 120-byte cap. Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8 Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewHead: ① derived judgments (seat-measured on the fetched head
② semver: unchanged — nothing published. ③ boundary flags: the row's clause 「锁 1 未禁」 states that the state-shaped Implemented-by: Verdict: PASS — references tier ⇒ this seat lands: ready via the MCP 维护者速读(终稿)一行读数进 platform-readings.md 第 285 行:席位 REST 重跑 job 是 403、MCP Generated by Claude Code |
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_01DAcomhvR9kKizeYgg89Vo8on branchclaude/issue-18025-platform-readings-rerun-channel(worktreeobjectstack-issue-18025), offorigin/mainca788604, BASEca7886047b27667122f9c2c44de3b6e67eb361fe. No merge was needed: nothing landed onmainunder either path since the branch point.What landed
platform-readings.md:285, placed immediately after the existing re-run pair (:283–:284):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:
GITHUB_TOKENthrough the session proxy) answers 403Resource not accessible by integrationonPOST /repos/objectstack-ai/objectstack/actions/jobs/103706765153/rerun;actions_run_triggerwithmethod: 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_triggeris 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:
POSTverb and the/actionspath segment. The path/jobs/{id}/rerunexists only as a POST, and :291 already carries the siblingGET /actions/jobs/{id}/logsspelling, 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: theplatform-readings.mdceiling moves by exactly the landed delta, and the raise is recorded as the FOURTEENTHruledRaisesrecord on the cross-file-move declaration, in the same shape as the thirteenth (added by #18072 at7ef05f997) and quoting the same ruling verbatim and untranslated — pm-dispatch SKILL.md 〈分诊座位职责〉:⛔ 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:
-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
BASEca788604unless noted.node scripts/pm/check-skill-line-ratchet.mjsat 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).BASEP2, every hit quoted:
: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, notPOST .../rerun) failing a different way (the egress proxy's CONNECT 403, not GitHub'sResource 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:
P4:⚠️ 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.
git ls-remote --heads originlists 1102 branches; a name grep forreading|rerun|re-run|channel|18025hits onlyclaude/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— andgit log origin/main..origin/BRANCH -- the-filereturns 0 commits for each.Verification counts for the seat's ACCEPT
One matter per line, deduplicated, re-wraps not counted:
⇒ landed 1 = the ceiling delta 1 = 453 → 454.
Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat9303a7b7e(no paths passed — the script derives its own change set: 2 paths vs merge baseca7886047, 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,
--ranwith the exit code recorded per family:One family needed a second pass:
pnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst answered exit 3 — PREREQUISITE NOT MET (@objectstack/lintnot 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:
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.mjshas no*.test.ts:git grep -lover*.test.ts/*.test.mts/*.test.mjs/*.spec.tsreturns nothing, and its suite IS its--self-test, wired intopnpm 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:
The move's own arithmetic is unchanged at +11 against −20, which is what the
ruledRaisesrecord is for.Control characters:
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'over both changed files is empty, andpnpm check:nul-bytesis 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-changesetis the declaration rather than a shortcut. There is nocheck-changeset-presence.mjsin this tree; the changeset gate ischangeset-checkin.github/workflows/pr-automation.yml, and it reads no path filter at all — its only two exemptions are theskip-changesetlabel (re-read live, because the event payload's label snapshot is stale by construction) and thechangeset-release/mainbranch pushed bygithub-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.mdandscripts/pm/check-skill-line-ratchet.mjs— are on the fast-track non-publishing list (.claude/**,scripts/pm/**), inside no released package'sfiles[].Acceptance notes
/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.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