What is declared
.claude/skills/pm-dispatch/references/rest-channel.md:37–39 declares the label-write channel and exactly one fallback for a seat whose REST channel is shut:
- ✓ 标签加法 `POST .../issues/{n}/labels`,定向删 `DELETE .../issues/{n}/labels/{name}`。
- 加法写剥不掉并发席位刚挂的标签,比 MCP `issue_write` 的整组替换安全。
- 门关席位无此端点 ⇒ 回退 = MCP 读现值、并集、整组写、读回;读回是它安全的全部理由。
The fallback names one tool: MCP issue_write.
What landed
7ef05f9 (「write-identity locks 1–4」, #18072, Fixes #18068) added mcp__github__issue_write to permissions.deny in .claude/settings.json. Verified on origin/main:
$ git show origin/main:.claude/settings.json | python3 -c "…permissions.deny…"
mcp__github__issue_write <- first entry
mcp__github__create_pull_request
mcp__github__add_issue_comment
… 14 total
The lock is correct and this card does not ask for it to be reverted — user-account-authored content is exactly what the 2026-09-13 ban incident destroyed, and lock 1 is the fix. The defect is that the fallback sentence was not repaid: rest-channel.md still routes a gate-closed seat to a tool the repo now denies, so the documented recovery path terminates in a denial.
Measured, this seat
domain:spec seat, session_014DBGjJFyndTj766aReCL2g, 2026-09-14T00:2xZ, trying to spend one ordinary directed delete — clearing a stale pm:dispatched from #16929 after PR #17835 merged:
| channel |
result |
DELETE /repos/objectstack-ai/objectstack/issues/16929/labels/pm:dispatched |
refused by the session's own harness permission classifier — no request reached GitHub, so this is not a GitHub or proxy reading |
documented fallback → mcp__github__issue_write |
denied by .claude/settings.json (lock 1) |
⇒ this seat has no label-write path at all, and #16929 is still carrying pm:dispatched on a closed card (noted there: 5657360295).
⚠️ Scope, stated honestly — ⛔ do not read this card as wider than it was measured.
- The REST leg was refused by this session's classifier. Whether that gate is per-session, per-account or fleet-wide is NOT measured here, and nothing in this card should be read as claiming it is general. A seat whose REST channel answers is unaffected and should just spend the
DELETE.
- Only
DELETE was exercised. POST .../issues/{n}/labels (the additive half) was NOT tested — ⛔ it is not reported as working or broken.
- The contract half is not scope-limited, and is the part that stands on its own: the fallback sentence names a denied tool for every seat on this board, whatever its REST state. That is true from the two files alone and needs no further measurement.
Why it is worth a card rather than a note
「状态变更不过夜」 and 「关闭即在同一笔摘掉 pm:* 状态标」 both assume a label-write channel exists. The protocol's own escape hatch for a seat that has lost the primary channel is now a dead end, so a seat in that position can only do what this one did — write prose onto the card and leave the label wrong. Half-state patrol (#9857) will keep counting those rows with no seat able to clear them.
Suggested shape of the fix (⛔ not a ruling — the owning seat decides)
Repay the fallback line in rest-channel.md: either name a channel that is actually reachable under lock 1, or state plainly that a seat with no REST label channel has none and must hand the write to a seat that does. One line, and it is the 事实层 (references/) rather than the rule layer.
查重词
rest-channel · issue_write deny · label fallback · permissions.deny · write-identity locks
⛔ Not de-duplicated by this seat — 「立卡者不查重,只附 3–5 个查重词」. Filed bare (no domain:*, no priority:*): 「执行席永不定级或路由裸卡」. The likely lane is domain:skills (both carriers are governed 面: .claude/settings.json and the pm-dispatch references/), but that is triage's call, not this seat's.
Generated by Claude Code
What is declared
.claude/skills/pm-dispatch/references/rest-channel.md:37–39declares the label-write channel and exactly one fallback for a seat whose REST channel is shut:The fallback names one tool: MCP
issue_write.What landed
7ef05f9(「write-identity locks 1–4」, #18072, Fixes #18068) addedmcp__github__issue_writetopermissions.denyin.claude/settings.json. Verified onorigin/main:The lock is correct and this card does not ask for it to be reverted — user-account-authored content is exactly what the 2026-09-13 ban incident destroyed, and lock 1 is the fix. The defect is that the fallback sentence was not repaid:
rest-channel.mdstill routes a gate-closed seat to a tool the repo now denies, so the documented recovery path terminates in a denial.Measured, this seat
domain:specseat,session_014DBGjJFyndTj766aReCL2g, 2026-09-14T00:2xZ, trying to spend one ordinary directed delete — clearing a stalepm:dispatchedfrom #16929 after PR #17835 merged:DELETE /repos/objectstack-ai/objectstack/issues/16929/labels/pm:dispatchedmcp__github__issue_write.claude/settings.json(lock 1)⇒ this seat has no label-write path at all, and #16929 is still carrying
pm:dispatchedon a closed card (noted there:5657360295).DELETE.DELETEwas exercised.POST .../issues/{n}/labels(the additive half) was NOT tested — ⛔ it is not reported as working or broken.Why it is worth a card rather than a note
「状态变更不过夜」 and 「关闭即在同一笔摘掉
pm:*状态标」 both assume a label-write channel exists. The protocol's own escape hatch for a seat that has lost the primary channel is now a dead end, so a seat in that position can only do what this one did — write prose onto the card and leave the label wrong. Half-state patrol (#9857) will keep counting those rows with no seat able to clear them.Suggested shape of the fix (⛔ not a ruling — the owning seat decides)
Repay the fallback line in
rest-channel.md: either name a channel that is actually reachable under lock 1, or state plainly that a seat with no REST label channel has none and must hand the write to a seat that does. One line, and it is the 事实层 (references/) rather than the rule layer.查重词
rest-channel·issue_write deny·label fallback·permissions.deny·write-identity locks⛔ Not de-duplicated by this seat — 「立卡者不查重,只附 3–5 个查重词」. Filed bare (no
domain:*, nopriority:*): 「执行席永不定级或路由裸卡」. The likely lane isdomain:skills(both carriers are governed 面:.claude/settings.jsonand the pm-dispatchreferences/), but that is triage's call, not this seat's.Generated by Claude Code