docs(pm-dispatch): three write-side lines of the REST channel table, and the pipeline trap in post-stamped - #18391
Merged
os-elon-musk merged 3 commits intoSep 16, 2026
Conversation
…re typed A pipeline's status is its last command's, so `post-stamped … | tail -N && label-write …` rewrites a refusal into the tail's 0: the audit comment is refused, the label lands, and the card carries a grade with nothing on it saying why — the half-state the comment-before-label ordering exists to prevent. The trap was written down in one lane's private wake-up text only, which is why it reached no seat before it was typed. It now sits in both places a seat passes through: the write-side block of `references/rest-channel.md`, beside the two tools it names, and the header of `scripts/pm/post-stamped.mjs`, which is the file opened before the idiom is typed. Neither restates the generic mechanism — that reading keeps its single home in `references/platform-readings.md`. Paid in place at the 82-line ceiling by retiring the 入队/落地 verification row: `added_to_merge_queue` is already on this file's own queue-routing block, and `git rev-list --parents` is a spelling this file's 第三桶 block already routes to `platform-readings.md`, where it lives verbatim. Claude-Session: https://claude.ai/code/session_01Bz6hxDBqK62NP2W1LATvnt Co-authored-by: Claude <noreply@anthropic.com>
…s consult `Content-Type: application/json` is required of every REST write through the egress proxy, and a request without it is refused 415 with not one byte written. The rule existed and was right; it lived only in `references/platform-readings.md`, while the table a seat opens before hand-rolling a curl — this file's write-side block, two of whose lines are about how the request body is spelled — carried no mention and no cross-reference of it. Six independent 415s across four endpoints in one shift are the behavioural evidence that the split placement did not reach the reader; each reads as a concurrent whole-set overwrite of the write, which is a distributed race that was never there. The rule is now stated where it is typed, and the reading it is measured from — the 415 and the discriminator that tells a proxy refusal from a GitHub one — keeps its single home, one hop away, named rather than copied. Paid in place at the 82-line ceiling by retiring the shell-expansion reading beside it: the backtick expansion, the broken-title-intact-body symptom and the quoted-delimiter requirement are all in `platform-readings.md` verbatim, and the prescription they belong to stays on the line above. Claude-Session: https://claude.ai/code/session_01Bz6hxDBqK62NP2W1LATvnt Co-authored-by: Claude <noreply@anthropic.com>
…t the session The row read 「REST 按会话为 `claude[bot]` 或用户」 — the premise the fact table retired: the REST channel's token class follows the Claude Code account, and it flipped inside a single session, with no seat action, twice in two days on two different seats. A seat recording a `merged_by` actor from this row records it on a premise its own read-back can contradict. Re-keyed in place: the actor is the token class, read from each write's own read-back rather than assumed from the session, with the measured rows named instead of copied. `MCP 恒用户` stays — it is this table's fact and has no other home. Claude-Session: https://claude.ai/code/session_01Bz6hxDBqK62NP2W1LATvnt Co-authored-by: Claude <noreply@anthropic.com>
Collaborator
Author
Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
This was referenced Sep 16, 2026
os-elon-musk
marked this pull request as ready for review
September 16, 2026 08:34
os-elon-musk
deleted the
claude/issue-18337-rest-channel-write-side-fold
branch
September 16, 2026 08:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18337
Fixes #18339
Fixes #18360
Three write-side lines of
.claude/skills/pm-dispatch/references/rest-channel.md— the table a seat opens before hand-rolling a REST write — plus the same pipeline trap in the header ofscripts/pm/post-stamped.mjs, which is the file opened before that idiom is typed. One commit per card.The file sits at its ratchet ceiling with zero headroom (82 / 82), so the two added rules are paid for by two retired rows, each declared below with the surviving home of every clause it carried. 82 lines before, 82 lines after. No re-wrap was used as currency, and
references/platform-readings.mdis untouched.Per card
#18337 — the pipeline-exit trap, beside the two tools it names
Landing point (by content): the write-side block, immediately after the
label-write.mjsrow.Before: no such line; the trap was written down only in one lane's private Routine prompt.
After (verbatim):
Second half — the tool's own header.
scripts/pm/post-stamped.mjsgains one section,## ⛔ Never pipe this tool, then && the write that follows, which names the half-state shape (refused audit comment, label landed anyway, card graded with nothing saying why), the redirect-then-capture spelling, andset -o pipefail. It states the shape rather than citing a card number, and it does not restate the generic mechanism: that reading keeps its single home inreferences/platform-readings.md.How this card reads independently: both places carry the trap — the write-side block (grep the table for
pipefail: was 0, is 1) and the tool header a seat opens before typing the idiom (grep -c 'set -o pipefail' scripts/pm/post-stamped.mjs).Paid by: retiring the write-side row
Every clause of it survives, twice over:
added_to_merge_queueis already a judgment row in this same file's queue-routing block;git rev-list --parentsis a spelling this file's own 第三桶 block declares to live inplatform-readings.md, where it is written with its-n1; and the auto_merge / echo-back unreliability is inplatform-readings.mdtwice plus this file's own queue-routing rule that the answer comes from the attempted action and not from the attribute field. It is the row this file's own line 「本表只指路,⛔ 不在两处各存一份」 refuses to keep.#18339 — the mandatory header, on the table seats consult
Landing point (by content): the write-side block, immediately after the request-body line 「请求体走文件…或引号定界 heredoc」, which is the hook the card names.
Before: the block carried zero mentions and zero cross-references of the header (
content-type, case-insensitive, over the whole table: 0 hits, withGETat 12 hits as the firing control).After (verbatim):
How this card reads independently: the reader path from the write-side block to the rule is now 0 hops — the rule is in the block — and the reading it is measured from (the 415, and the discriminator that tells a proxy refusal from a GitHub one) is 1 hop, named rather than copied. Was ∞. The two
platform-readings.mdrows are not copied and not edited; the pointer uses this table's existing spelling for that section, which its own opening line and its 不可迁移 heading already use.Paid by: retiring the reading beside it,
Both of its facts are in
platform-readings.mdverbatim: the backtick expansion with the broken-title-intact-body symptom, and the quoted-delimiter rule whose general form is 「请求体永不过会展开的 shell 上下文」, which is what covers$(...)and$VAR. The prescription those bytes explained — body via file or quoted heredoc, never an inline double-quoted string, with both spellings — stays untouched on the line above.#18360 — the direct-merge actor follows the token class, not the session
Landing point (by content): the write-side block's direct-merge row.
Before (verbatim):
After (verbatim):
How this card reads independently:
grep -c '按会话'on the file is 0 (was 1, that row); the row now says the actor is the token class, bound to the account and read back on each write; the fact-table rows landed by #18359 are pointed at, not copied;MCP 恒用户stays, because it is this table's own fact and has no other home. In place, 120 bytes, at the cap the ratchet sets.Line budget
rest-channel.mdbeforerest-channel.mdafterAdded 2 rules, retired 2 rows, re-keyed 1 row in place.
scripts/pm/post-stamped.mjscarries no ceiling (it is not in the ratchet's CEILINGS map — checked, not assumed). Every touched line is within the 120-byte cap; the two new rules measure 119 B and 98 B, the re-keyed row 120 B.Gates
All 39 commands derived by
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackagainst this branch's real change set were run, exit code captured before any pipe. 38 of 39 are green, includingpnpm check:pm-skill-ratchet(its own verdict line:rest-channel.md is 82 lines (ceiling 82; headroom 0)),pnpm check:pm-post-stamped(233 cases),pnpm check:nul-bytes,pnpm check:doc-authoring,pnpm check:pm-governed-mergesandpnpm check:pm-skill-id-lint.pnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst exited 3, PREREQUISITE NOT MET (unbuilt workspace packages, nothing measured); afterturbo run build --filter=@objectstack/formula --filter=@objectstack/lintit exits 0. The remaining command,pnpm check:pm-dispatch-gates(a 430–450 s battery), was still running when this PR was opened; its verdict is in the dev report on #18337.node scripts/pm/check-governed-merges.mjs --test .claude/skills/pm-dispatch/references/rest-channel.mdexits 3 — GOVERNED,.claude/**. ⛔ No seat flips this ready, enqueues it or arms auto-merge; it lands after the skills seat's contract-tier review.Acceptance notes
-d @fileflag and the quoted-heredoc delimiter spelling, the shell-expansion prescription, and every ✓ channel row are unchanged.scripts/pm/check-half-states.mjs): H64's header quotes this same retired premise as its rationale — 「REST 按会话为claude[bot]或用户,MCP 恒用户」, sourced torest-channel.md, with the surrounding prose reading "the write identity follows the CHANNEL rather than the account" and, further down, "the token class is handed to a session at start rather than chosen at write time". The landed fact table says the opposite in as many words: 「类按 Claude Code 账号定,⛔ 不按会话定」 and 「一会话内两次写之间可无席位动作地翻转」. The row's runtime message text carries the same sourcing. Prose only, no enforcement change; this PR's claim namesrest-channel.mdandpost-stamped.mjsand nothing else, so it is reported rather than fixed here. Dedup words:H64 按会话·check-half-states token class·write identity follows the channel·session-handed token.维护者速读(草稿)
改了什么 —— pm-dispatch 的 REST 通道对照表(席位手搓写请求前查的那张表)的写侧段,加了两条规则、改写了一条、退役了两条重复行;另外给
scripts/pm/post-stamped.mjs的文件头加了一段管道陷阱说明。表的总行数没变(82 行,正好在棘轮天花板上)。为什么改 —— 三张 p3 卡,同一个形状:规则存在,但不在读者动手时会看的那张表上。① 把写脚本接进管道再
&&,管道退出码取末端,于是审计评论被拒、标签照落,卡上留下「改了标、没理由」;这条陷阱原先只写在某条车道的私有唤醒提示词里。② REST 写必带Content-Type: application/json,缺了代理回 415、一个字节都不写 —— 规则写在事实表里,写侧段零提及,一个班次内六次独立踩中、四个端点,而失败长得像「别人并发把我的标签冲掉了」,会把一个加一个头就能修的问题误诊成分布式竞态。③ 直合的 actor 那行还写着「按会话」,而事实表已经改成「按 Claude Code 账号」,并记录了一个会话内无人操作就翻转两次的实测。风险与代价(含回滚) —— 纯文本面,无代码行为改动,无 changeset(
.claude/**与scripts/pm/**不发布)。代价是退役了两行:每一行的每个子句都在别处有家(逐条列在上面的 Paid by 里),这是天花板零余量下唯一合法的付账方式 —— 删内容,不是折行。若判定某条退役行不该退,回滚是一次 revert:三个 commit 逐卡独立,可以只回其中一个。席位意见 ——
你要做的 —— 复核两处:① 两行退役是否同意(它们的存续副本是否真的够用);② 三条新/改写的行文字是否准确 —— 尤其 #18360 那行为了压进 120 字节,把「按 Claude Code 账号」压成「按账号」,完整拼写留在它指向的配额段。这是受管面(
.claude/**),⛔ 不会有任何席位把它 ready 或入队。Generated by Claude Code