Skip to content

Commit 22fb225

Browse files
pm(skills): rest-channel.md names the relay's release.yml refresh stroke (#23476)
Fixes #23410 Clause-②: no The seats' REST reference `.claude/skills/pm-dispatch/references/rest-channel.md` now 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 to `main`, the acting seat dispatches `Release` with `refresh_version_pr` through 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.mjs` line 246 at `9063727487` (blob `6d91b90d98`), `'release.yml': Object.freeze({ refresh_version_pr: true })`, with `WORKFLOW_DISPATCH_REF = 'main'` and the op row's `alone: true`. ## The rows, before and after Before (`main` at `9063727487`, lines 48 to 53): ```text - ✓ `origin/main` 合进 PR head:中继 op `pr_update_branch`(`pull` + 40 位 `expected_head_sha`),真合并提交。 - ⛔ 裸 `PUT .../pulls/{n}/update-branch` 落个人账号;短 SHA 派发前即拒;base 未动 422 = op 报 no-op。 - ✓ 落地经中继 `node scripts/pm/fleet-write/dispatch.mjs --repo O/N --actions-file F`;`--via dispatch` 同载。 - ✓ 启动 run 走 op `workflow_dispatch`:解锁物是白名单 run 才启;入表只经 workflow 自己的 PR。 - ⛔ 裸 `PATCH /pulls/{n}` 带 `{"draft": false}` 回 200 零改;状态码不作数,`GET /pulls/{n}` 才作数。 - 线程自己建:`POST .../pulls/{n}/comments` 带 `commit_id`·`path`·`line`,回读看 `review_threads`。 ``` After (head `42a0fd1006`, lines 48 to 53): ```text - ✓ `origin/main` 合进 PR head:中继 op `pr_update_branch`(`pull` + 40 位 `expected_head_sha`),真合并提交。 - ✓ 落地经中继 `node scripts/pm/fleet-write/dispatch.mjs --repo O/N --actions-file F`;`--via dispatch` 同载。 - ✓ 启动 run 走 op `workflow_dispatch`:解锁物是白名单 run 才启;入表只经 workflow 自己的 PR。 - F = `[{"op":"workflow_dispatch","workflow":"release.yml","ref":"main","inputs":{"refresh_version_pr":true}}]`。 - 该 F 刷版本 PR:单 op 成文件,发版路径修复入 `main` 即发;他 input、值、ref 或缺键按名拒。 - 线程自己建:`POST .../pulls/{n}/comments` 带 `commit_id`·`path`·`line`,回读看 `review_threads`。 ``` 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 to `main`, and any other input, value, ref or a missing key is refused by name. ## Line budget | | line | bytes | what it is | |---|---|---|---| | deleted | 49 (before) | 117 | the bare `update-branch` warning | | deleted | 52 (before) | 115 | the bare draft `PATCH` warning | | added | 51 (after) | 114 | the release refresh actions file | | added | 52 (after) | 117 | what it does, when it is sent, what is refused | File: 82 → 82 lines (ratchet `CEILINGS` row 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: - **Line 49 before**, 「⛔ 裸 `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.mjs` lines 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 bare `curl` / `fetch` / `gh api -X POST|PATCH|PUT|DELETE` write), 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`), and `ops.mjs` lines 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.mjs` lines 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, the `pr_update_branch` op, is unchanged. - **Line 52 before**, 「⛔ 裸 `PATCH /pulls/{n}` 带 `{"draft": false}` 回 200 零改;状态码不作数,`GET /pulls/{n}` 才作数。」. This is the queue-section reading of `references/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: `grep` over `.claude/skills/pm-dispatch/`, `.claude/agents/os-dev.md` and `AGENTS.md` finds it on line 57 only. Its other clauses are restated: the token-class readings in `platform-readings.md` lines 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-run` on head `42a0fd1006`. Dry runs send nothing. | actions file | exit | validator says | |---|---|---| | the added line's `F`, verbatim | 0 | DRY RUN, packs `workflow_dispatch` / `release.yml` / `main` / `{"refresh_version_pr":true}` | | `inputs` with `force: true` added | 2 | `actions[0].inputs.force is not an input the relay sends to release.yml` | | `refresh_version_pr: false` | 2 | `actions[0].inputs.refresh_version_pr must be true when workflow is "release.yml", got false` | | no `inputs` key | 2 | `actions[0].inputs is required when workflow is "release.yml"` | | `refresh_version_pr: "true"` (string) | 2 | `actions[0].inputs.refresh_version_pr must be a JSON boolean, got "true"` | | `ref: "next"` | 2 | `actions[0].ref must be one of "main", got "next"` | | the refresh plus a `comment` op | 2 | `a stroke carries exactly ONE workflow_dispatch and nothing else` | Every refusal printed `payload REFUSED ... ⛔ zero writes` and `nothing was sent`. `node scripts/pm/fleet-write/validate.mjs --self-test`: exit 0, 152 cases across 11 batteries (the release battery is at `validate.mjs` line 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.mjs` 0 · `--self-test` 0 - `node scripts/check-comment-mask-corpus.mjs` 0 - `node scripts/pm/check-harness-current.mjs --self-test` 0 - `pnpm --filter @objectstack/lint run check:doc-formula-expressions` 0. The first run exited 3 (PREREQUISITE NOT MET: `@objectstack/formula` and `@objectstack/lint` unbuilt). The gate measured nothing on that run. It passed after `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint`, built under the shared verify lock (VERDICT command-exit 0). - `pnpm check:agent-test-spelling` 0 · `check:cross-package-test-inputs` 0 · `check:doc-authoring` 0 · `check:driver-memory-census` 0 · `check:gitlink-declared` 0 · `check:nul-bytes` 0 · `check:pm-governed-merges` 0 · `check:pm-skill-id-lint` 0 · `check:pm-skill-ratchet` 0 · `check:refd-timer-probe` 0 · `check:skill-frame-sync` 0 · `check:watch-hint-literal` 0 - `--ran` reconciliation: 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-ratchet` 0: "rest-channel.md is 82 lines (ceiling 82; headroom 0)" - `node scripts/pm/check-skill-line-ratchet.mjs --self-test` 0 - `pnpm check:pm-skill-id-lint` 0: "87 file(s) clean" - `pnpm check:pm-governed-prose` 0 - `pnpm check:pm-settings-deny-roster` 0 (its roster is under `.claude`) - `node scripts/check-skills-token-ratchet.mjs` 0 · `node scripts/check-nul-bytes.mjs` 0 - The scripts whose prose names `rest-channel`, each `--self-test`: `board-snapshot.mjs` 0 · `check-settings-deny-roster.mjs` 0 · `label-write.mjs` 0 · `check-prior-rulings.mjs` 0 · `check-harness-current.mjs` 0 · `close-cards.mjs` 0. 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, so `skip-changeset` applies. 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 - **No ✓ on the added lines.** Line 8 of this file reserves ✓ for a route a seat has called successfully. On 2026-10-14 at 12:02Z, `release.yml` had 18 `workflow_dispatch` runs (`GET .../actions/workflows/release.yml/runs?event=workflow_dispatch`), and none was started by `objectstack-fleet[bot]`. The newest, run 38543943281 at 09:39:24Z, was started by a user account before PR #23209 merged at 10:06:34Z. The relay's own readings of the wire spelling are recorded in the `ops.mjs` header: runs 38351525685 and 38357219168, both started by a user account. A ✓ fits once a seat's relay stroke has run. - **The full refusal list stays with `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. - Noted, not filed (an observation about prose drift, no filing class; carrier: none): the docblock of `scripts/pm/check-settings-deny-roster.mjs`, lines 60 to 62, says this file's `PUT .../pulls/{n}/ccr/auto_merge` route "already serves every real enqueue". The table no longer carries that route. Auto-merge goes through the relay op `automerge_enable` (line 55), and `platform-readings.md` records 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](https://claude.ai/code/session_013zGKMG1cRedVzWtqGGGZW9)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0ecac96 commit 22fb225

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

‎.claude/skills/pm-dispatch/references/rest-channel.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@
4646
- 请求体走文件(`-d @file`)或引号定界 heredoc(`<<'EOF'`),⛔ 永不内联双引号串。
4747
- ✓ 请求复审 `POST .../pulls/{n}/requested_reviewers` · 开 PR `POST .../pulls` 带 `draft=true`。
4848
- ✓ `origin/main` 合进 PR head:中继 op `pr_update_branch`(`pull` + 40 位 `expected_head_sha`),真合并提交。
49-
- ⛔ 裸 `PUT .../pulls/{n}/update-branch` 落个人账号;短 SHA 派发前即拒;base 未动 422 = op 报 no-op。
5049
- ✓ 落地经中继 `node scripts/pm/fleet-write/dispatch.mjs --repo O/N --actions-file F`;`--via dispatch` 同载。
5150
- ✓ 启动 run 走 op `workflow_dispatch`:解锁物是白名单 run 才启;入表只经 workflow 自己的 PR。
52-
- ⛔ 裸 `PATCH /pulls/{n}` 带 `{"draft": false}` 回 200 零改;状态码不作数,`GET /pulls/{n}` 才作数。
51+
- F = `[{"op":"workflow_dispatch","workflow":"release.yml","ref":"main","inputs":{"refresh_version_pr":true}}]`。
52+
- 该 F 刷版本 PR:单 op 成文件,发版路径修复入 `main` 即发;他 input、值、ref 或缺键按名拒。
5353
- 线程自己建:`POST .../pulls/{n}/comments` 带 `commit_id`·`path`·`line`,回读看 `review_threads`。
5454
- ✓ `POST .../ccr/comments/{id}/resolve` · `/unresolve`;`{id}` 是评审评论 id,⛔ 只在自己 PR 上探。
5555
- ✓ F = `[{"op":"pr_ready","pull":N},{"op":"automerge_enable","pull":N}]`;反向 `pr_draft`/`automerge_disable`。

0 commit comments

Comments
 (0)