Skip to content

Commit 5ed7ad9

Browse files
os-justinclaude
andauthored
docs(pm-skills): name the issue-state leg on the REST channel write side (#18580)
Fixes #18563 ## What changed One row added to the write side of `.claude/skills/pm-dispatch/references/rest-channel.md`, and one redundant line retired to pay for it. Net zero lines, so the file stays at its ceiling. **Added** (new `:42`, 115 B): ``` - ✓ 该 `PATCH` 带 `state` 关卡/重开,`state_reason` 交付 `completed`、撤单 `not_planned`,走裸 REST。 ``` Line `:41` is **unchanged** (120 B) and still names `PATCH .../issues/{n}` as 改正文; the new row sits directly beneath it and gives the same endpoint its state leg. **Payment — a genuine deletion, not a re-wrap.** The `issue transfer` item of the 不可迁移 list went from two lines to one: ``` -3. `issue transfer`:issues 端点表无 transfer 路由(核对文档,未实调)⇒ 同为 GraphQL-only。 105 B - 拿不到时当轮改走在目的仓重建配方,配方住 `platform-readings.md`。 87 B +3. `issue transfer`:issues 端点表无此路由(未实调)⇒ 同为 GraphQL-only;配方住 `platform-readings.md`。 118 B ``` Why the retired line was redundant: it restated a fallback instruction that `platform-readings.md` already owns in full — that file's `:147` reads 「`issue transfer` 因配额或权限拿不到 ⇒ 当轮改走多仓协调条款的在目的仓重建配方。」 and `:148` carries the recipe itself. Keeping a second copy here is exactly what this file's own rule forbids (「本表只指路,⛔ 不在两处各存一份」), and it is the same payment pattern the ratchet's own history records for this very file: the 红窗 restatement was retired under the content-ownership ruling 「红窗规则由 `platform-readings.md` 配额段独家持有,`rest-channel.md` 只留指路」. The pointer that rule permits is kept, folded into the numbered item at zero line cost. The provenance aside 「核对文档」 also goes, per the 2026-09-04 rules-only rewrite that took provenance narrative out of this corpus. **No live fact leaves the file.** ## The dispatched mechanism assumption did not hold The dispatch expected the leg could be folded into `:41` in place, on the reading that this file's ratchet pins table-row width and not bullet width. Measured on this branch, that is **false**: `check-skill-line-ratchet` enforces a per-line **120-byte max-line-length rule** on ordinary bullets, and `:41` is already **exactly 120 B**. The "widest table row is 0 bytes (pin 0)" reading is a separate pin, and it reads 0 only because this file contains no markdown table rows at all. Ablation, with the mutation and the restore each proved on disk. Injecting six bytes to take `:41` to 126 B turns the gate red: ``` ✗ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/rest-channel.md has 1 line(s) over the 120-byte budget: L41 (126B). ``` The restore leg was verified by blob hash, not by an exit code: `git checkout HEAD --` on the path, then `git hash-object` compared equal to the HEAD blob `a195fc4a47a49ab0b712d059d09a4e92a6707783`. So the in-place route was unavailable, and the other route the grading sanctioned — a new row paid by a genuine deletion — was taken instead. **One thing did not fit, and is flagged rather than quietly dropped.** A single row cannot carry every element the card lists: the fullest honest spelling measures about 129 B against the 120 B cap. The row keeps the endpoint, both directions (close and reopen), both payload keys, the reason mapping, and the corrective conclusion that the channel is a raw REST call. What did not fit is the parenthetical naming `post-stamped.mjs` and `label-write.mjs` as the two writers that lack the leg — lines `:38`-`:39` already tell the reader what those two scripts do. ## Ratchet on this head ``` ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/rest-channel.md: widest table row is 0 bytes (pin 0; headroom 0). ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/rest-channel.md is 82 lines (ceiling 82; headroom 0). ``` 82 / 82, headroom 0, unchanged. Every line in the file is at or under 120 B. ## Gates Derived from this worktree with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`, no paths passed so the script takes its own change set from the merge base. Re-derived after the `origin/main` merge and identical. Every exit code captured before any pipe. ``` node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 pnpm check:agent-test-spelling :: exit 0 pnpm check:doc-authoring :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:pm-governed-merges :: exit 0 pnpm check:pm-skill-id-lint :: exit 0 pnpm check:pm-skill-ratchet :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:skill-frame-sync :: exit 0 pnpm check:watch-hint-literal :: exit 0 ``` `dispatch-gates --ran` reconciliation: **15 derived, 15 run, 0 NOT-MEASURED, 0 UNRUN** — a derived zero, every family carrying a recorded exit code. Also run, beyond the derived list: ``` node scripts/pm/check-governed-merges.mjs --test .claude/...rest-channel.md :: exit 3 pnpm check:pm-settings-deny-roster :: exit 0 ``` Exit 3 there is the **expected GOVERNED verdict**, not a failure: this is a `.claude/**` path, so a human merge is the review record and no seat flips it ready, enqueues it, or arms auto-merge. The deny-roster gate was run because the derivation flagged its roster as living under `.claude/`, where silence is evidence in neither direction. One gate needed a second pass. `pnpm --filter @objectstack/lint run check:doc-formula-expressions` first returned **exit 3 PREREQUISITE NOT MET** — unbuilt workspace packages, and the gate says plainly that nothing was measured. After `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` through the shared verify lock (`VERDICT command-exit 0`, held 128 s), it re-ran at **exit 0**. Only the real reading is recorded above. ## Note for the reviewer The row now states a measured fact: the same `PATCH .../issues/{n}` that edits a card body also closes and reopens one, carrying `state` and `state_reason`, and it is reached as a raw REST call rather than through either sanctioned writer script. Two live measurements back it — card 16023, set to state closed with reason `completed` at 2026-09-17T01:42:37Z by the `domain:services` seat (record 5707137250), and card 17323, the same at 2026-09-17T02:45:08Z by the skills seat with body, `state` and `state_reason` in one PATCH (record 5707679383). `skip-changeset`: nothing under any package's `files[]` moves — `.claude/**` is not published. --- _Generated by [Claude Code](https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent a55646b commit 5ed7ad9

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
@@ -39,6 +39,7 @@
3939
-`post-stamped`/`label-write` 永不接进管道再 `&&`:拒收读成 0;看尾先落文件或 `set -o pipefail`
4040
- ⛔ 永不 MCP `issue_write`(锁 1 已拒);会话分类器拒改动 ⇒ 无通道,交有通道席位立卡。
4141
- ✓ 建卡带标签 `POST .../issues` · 改正文 `PATCH .../issues/{n}` · 认领 `POST .../issues/{n}/assignees`
42+
- ✓ 该 `PATCH``state` 关卡/重开,`state_reason` 交付 `completed`、撤单 `not_planned`,走裸 REST。
4243
- 请求体走文件(`-d @file`)或引号定界 heredoc(`<<'EOF'`),⛔ 永不内联双引号串。
4344
- 每个写请求必带 `Content-Type: application/json`;缺头的 415 与判别式见配额段。
4445
- ✓ 请求复审 `POST .../pulls/{n}/requested_reviewers` · 开 PR `POST .../pulls``draft=true`
@@ -58,8 +59,7 @@
5859
1. 语义搜索:`/search/*` 被出口代理按设计拒绝。退路 = REST 列表端点加本地 grep。
5960
REST 也被会话门关掉的席位 = 一次定向 MCP `search_issues`,⛔ 不宽表扫。
6061
2. Projects field_values:GraphQL-only —— 舰队并不需要它;MCP 服务器端无条件抓它才是漏点。
61-
3. `issue transfer`:issues 端点表无 transfer 路由(核对文档,未实调)⇒ 同为 GraphQL-only。
62-
拿不到时当轮改走在目的仓重建配方,配方住 `platform-readings.md`
62+
3. `issue transfer`:issues 端点表无此路由(未实调)⇒ 同为 GraphQL-only;配方住 `platform-readings.md`
6363

6464
## 第三桶 —— git 零配额等价物
6565

0 commit comments

Comments
 (0)