Repository navigation
pm(skills): rest-channel.md names the relay's release.yml refresh stroke - #23476
objectstack-fleet[bot] merged 1 commit into
Conversation
…ml refresh stroke The write-side table's one sentence on starting a run named no workflow and no inputs. It now spells the actions file the relay accepts for the Version Packages PR refresh (workflow_dispatch on release.yml, ref main, inputs exactly refresh_version_pr true, alone in its file) and when a seat sends it (at once after a release-path fix merges to main). Paid in place, line count unchanged (82/82): two restatements leave the table. The bare update-branch line is carried by the relay's own docblocks (ops.mjs pr_update_branch header, execute.mjs base-sync header) and by the bare-write ban; the bare draft PATCH line is platform-readings.md's queue section reading, restated. Claude-Session: https://claude.ai/code/session_013zGKMG1cRedVzWtqGGGZW9 Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewed in seat by the dispatching skills seat (served tier read from ① Derived judgments
② Semver levelNone owed: ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
席位核对 · PR #23476 at
|
Fixes #23410
Clause-②: no
The seats' REST reference
.claude/skills/pm-dispatch/references/rest-channel.mdnow spells the relay's release refresh stroke in its write-side table, directly under the table's one sentence on starting a run (which names no workflow and no inputs). The stroke is the maintainer's ruling on #23177 (ruling B, item 5, 「同意」, comment 6139629628): after each release-path fix merges tomain, the acting seat dispatchesReleasewithrefresh_version_prthrough the relay at once rather than waiting for the 6-hourly refresh. The relay side landed as PR #23209 (parent card #23193); this card was filed under #23396's ruling A. File surface: that one file, write-side section only. Line count unchanged at 82/82: the two added lines are paid by deleting two lines of the same section that restate text held elsewhere.The spelling is read from the landed relay, not from the card:
scripts/pm/fleet-write/ops.mjsline 246 at9063727487(blob6d91b90d98),'release.yml': Object.freeze({ refresh_version_pr: true }), withWORKFLOW_DISPATCH_REF = 'main'and the op row'salone: true.The rows, before and after
Before (
mainat9063727487, lines 48 to 53):After (head
42a0fd1006, lines 48 to 53):The first added line is the actions file a seat pastes, in the house style of the table's existing
F = ...row (line 55 before, line 55 after). The second carries the rest: the stroke refreshes the Version Packages PR, the file holds that one op, it is sent at once when a release-path fix merges tomain, and any other input, value, ref or a missing key is refused by name.Line budget
update-branchwarningPATCHwarningFile: 82 → 82 lines (ratchet
CEILINGSrow 82, headroom 0, row untouched); 7305 → 7304 bytes; every line at or under the 120-byte cap. Two deletions were found, so the card's "two lines paid by two deletions" form is used.What each deleted line restates, and where the text still lives:
PUT .../pulls/{n}/update-branch落个人账号;短 SHA 派发前即拒;base 未动 422 = op 报 no-op。」. Each clause has another home. (1) "A bare PUT lands on the personal account": the relay's docblock,scripts/pm/fleet-write/ops.mjslines 41 to 47 ("as bare REST under a seat's session token, the seat's personal account, the identity exchange every other relay write already refuses"). AGENTS.md line 428 bans every bare write (⛔ never a barecurl/fetch/gh api -X POST|PATCH|PUT|DELETEwrite), and this file's line 10 names the relay as the write channel. (2) "A short SHA is refused before dispatch": line 48 of this file (40 位 expected_head_sha), andops.mjslines 51 to 53 ("a short or malformed sha is refused by the validator before the dispatch"). (3) "A 422 with the base unmoved is reported by the op as a no-op":scripts/pm/fleet-write/execute.mjslines 86 to 91 ("behind_by 0 means there was nothing to merge and the action LANDED as a no-op, the row saying so"), and the relay prints that row itself. Line 48, thepr_update_branchop, is unchanged.PATCH /pulls/{n}带{"draft": false}回 200 零改;状态码不作数,GET /pulls/{n}才作数。」. This is the queue-section reading ofreferences/platform-readings.md, line 51, with the same claim, the same endpoint and the same read-back: 「⛔ 裸PATCH /pulls/{n}传draft: false回 200 而无操作(2026-09-11);读回才作数:GET /pulls/{n}。」. The ready and draft flips go through the relay ops on line 55 of this file, and the bare write is banned by AGENTS.md line 428. After this PR the reading has one copy, in the readings file that dates it.The seat's two candidates were lines 57 and 49. Line 57 is not a pure restatement, so it stays. Its last clause, 「MCP 恒用户」 ("an MCP write is always the user"), appears nowhere else:
grepover.claude/skills/pm-dispatch/,.claude/agents/os-dev.mdandAGENTS.mdfinds it on line 57 only. Its other clauses are restated: the token-class readings inplatform-readings.mdlines 125 to 128, and the endpoint on line 73 of this file. Line 49 was used. Line 52, the second restatement, was found in the same section. Lines 48, 55, 56 and 57 are untouched.Measured: the line's payload against the landed relay
Every case below went through
node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file FILE --dry-runon head42a0fd1006. Dry runs send nothing.F, verbatimworkflow_dispatch/release.yml/main/{"refresh_version_pr":true}inputswithforce: trueaddedactions[0].inputs.force is not an input the relay sends to release.ymlrefresh_version_pr: falseactions[0].inputs.refresh_version_pr must be true when workflow is "release.yml", got falseinputskeyactions[0].inputs is required when workflow is "release.yml"refresh_version_pr: "true"(string)actions[0].inputs.refresh_version_pr must be a JSON boolean, got "true"ref: "next"actions[0].ref must be one of "main", got "next"commentopa stroke carries exactly ONE workflow_dispatch and nothing elseEvery refusal printed
payload REFUSED ... ⛔ zero writesandnothing was sent.node scripts/pm/fleet-write/validate.mjs --self-test: exit 0, 152 cases across 11 batteries (the release battery is atvalidate.mjsline 1097).Gates
These ran on head
42a0fd1006. Exit codes were captured before any pipe.Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 17 commands, all exit 0.node scripts/check-closing-keyword-parity.mjs0 ·--self-test0node scripts/check-comment-mask-corpus.mjs0node scripts/pm/check-harness-current.mjs --self-test0pnpm --filter @objectstack/lint run check:doc-formula-expressions0. The first run exited 3 (PREREQUISITE NOT MET:@objectstack/formulaand@objectstack/lintunbuilt). The gate measured nothing on that run. It passed afterpnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint, built under the shared verify lock (VERDICT command-exit 0).pnpm check:agent-test-spelling0 ·check:cross-package-test-inputs0 ·check:doc-authoring0 ·check:driver-memory-census0 ·check:gitlink-declared0 ·check:nul-bytes0 ·check:pm-governed-merges0 ·check:pm-skill-id-lint0 ·check:pm-skill-ratchet0 ·check:refd-timer-probe0 ·check:skill-frame-sync0 ·check:watch-hint-literal0--ranreconciliation: exit 0, "17 derived famil(ies) accounted for — 17 run, 0 NOT-MEASURED".Gates named by the acceptance criteria, and the file's readers:
pnpm -s check:pm-skill-ratchet0: "rest-channel.md is 82 lines (ceiling 82; headroom 0)"node scripts/pm/check-skill-line-ratchet.mjs --self-test0pnpm check:pm-skill-id-lint0: "87 file(s) clean"pnpm check:pm-governed-prose0pnpm check:pm-settings-deny-roster0 (its roster is under.claude)node scripts/check-skills-token-ratchet.mjs0 ·node scripts/check-nul-bytes.mjs0rest-channel, each--self-test:board-snapshot.mjs0 ·check-settings-deny-roster.mjs0 ·label-write.mjs0 ·check-prior-rulings.mjs0 ·check-harness-current.mjs0 ·close-cards.mjs0. None of them anchors on lines 49 or 52: their mentions cite the read-side page walk or write a fixture.No package is touched, so there is no build closure or package test.
.claude/**ships in no package, soskip-changesetapplies. CI's own families are read from this PR's check-runs. Governed surface:.claude/**, Tier S. The PR stays draft until the seat's contract-tier review of record.Acceptance notes
release.ymlhad 18workflow_dispatchruns (GET .../actions/workflows/release.yml/runs?event=workflow_dispatch), and none was started byobjectstack-fleet[bot]. The newest, run 38543943281 at 09:39:24Z, was started by a user account before PR tooling(pm): the fleet relay may start release.yml with refresh_version_pr true alone, so a seat refreshes the Version PR through the relay #23209 merged at 10:06:34Z. The relay's own readings of the wire spelling are recorded in theops.mjsheader: runs 38351525685 and 38357219168, both started by a user account. A ✓ fits once a seat's relay stroke has run.validate.mjs. The second added line names the refused classes in a few words. The validator's release battery (line 1097) pins each refusal and its exact message.scripts/pm/check-settings-deny-roster.mjs, lines 60 to 62, says this file'sPUT .../pulls/{n}/ccr/auto_mergeroute "already serves every real enqueue". The table no longer carries that route. Auto-merge goes through the relay opautomerge_enable(line 55), andplatform-readings.mdrecords the ccr route as retired.维护者速读(草稿)
改了什么:席位查的 REST 通道对照表(
rest-channel.md)写侧加了两行。第一行是经中继刷新 Version Packages PR 时可直接粘贴的载荷:release.yml、ref为main、inputs 只有refresh_version_pr: true,文件里只放这一个 op。第二行写明发版路径的修复合入main后立即发送,其它 input、值、ref 或缺键都会被中继按名拒绝。另删了两行在别处已有完整原文的复述,文件仍是 82 行。为什么改:维护者已裁定(#23177 裁决 B 第 5 条「同意」):修复合入后由当值席位立即经中继刷新版本 PR,不等六小时一次的定时刷新。中继能力已随 #23209 上线,但席位查的参考表没写这一笔,席位只能去脚本里自己推导,或像 #23193 实测的两次那样继续用个人账号刷新。
风险与代价(含回滚):只改给 agent 读的文档,不发布任何包,不动脚本。载荷写错时中继照样拒绝,不会产生任何写入。删掉的两行,原文仍在
platform-readings.md和中继脚本的注释里。回滚就是 revert 这一个提交。席位意见:
你要做的:无需操作。本 PR 只触及
.claude/**(Tier S),席位达档复核 PASS 后由席位落地。Generated by Claude Code