Skip to content

docs(pm): eleven platform readings into the fact table — 23 rows, 3 in-place corrections, ceiling 425 to 448 - #17746

Merged
os-zhuang merged 5 commits into
mainfrom
claude/issue-17680-platform-readings-rows
Sep 12, 2026
Merged

os-zhuang merged 5 commits into
mainfrom
claude/issue-17680-platform-readings-rows

Conversation

@claude

@claude claude Bot commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #17680
Fixes #17239
Fixes #17563
Fixes #17677
Fixes #17710
Fixes #17754

One folded family plus one review-round rider, one file. Twenty-four new rows and four in-place
corrections in .claude/skills/pm-dispatch/references/platform-readings.md, plus the one
CEILINGS entry the standing one-file exception prescribes. Nothing else moves — not
rest-channel.md, not SKILL.md, not check-clause2-carriers.mjs, not check-half-states.mjs.

Dedupe counts (the standing exception's own condition)

Candidates 33 / landed 26 readings / already present 7 (no edit) / refused 0.

Landed 26 readings = 24 new lines + 4 in-place corrections. Two readings needed two lines each
under the 120-byte per-line cap, which is why 26 readings are 28 line-level changes.

card candidate dedupe verdict
17680 PR-body Check Changeset gate reads the clause-2 declaration tolerantly landed, 1 new row
17680 claim-comment limb's axis is line-initial PLACEMENT landed, 2 new rows (tolerance · breakers + the import authority)
17680 the claim marker's own spelling, absent from the table landed, 2 new rows (spelling · the invisibility it causes)
17239 PATCH /pulls appends a bare footer, +58 B, keeping the sent one already present
17239 a footerless body on that same cell stores exactly one landed, 1 new row
17239 POST /pulls create leg, +90 B when the tail is not the block already present, in a stronger form (both directions, both channels)
17239 comment PATCH and issue-body PATCH carry a full block through already present (comment); issue half corrected in place below
17563 every REST write through the egress proxy needs Content-Type: application/json landed, 1 new row
17563 the tell: the refusal's documentation_url is Claude Code's, not GitHub's landed, 1 new row
17677 MCP issue_write UPDATE eats a trailing rule+footer block and reports success landed, 1 new row
17677 bare REST PATCH /issues recognition is BLOCK-shaped landed, 1 in-place correction
17677 a bare footer with no rule line is not a footer, so a block is appended (two) landed, 1 new row
17677 the two unmeasured cells named as unmeasured landed, 1 new row
17710 A1 needs:contract-review is a merge gate in its own right landed, 1 new row
17710 A2 the two mergeable_state sequences across a ready flip landed, 1 new row
17710 A3 the echoed merge_method is inert already present
17710 A4 a failure superseded by a later failure with a different diagnosis landed, 1 new row
17710 A5 an exit code is a field literal; the reading is the printed verdict line landed, 1 new row
17710 A5 the measured instance inside check-governed-merges landed, 1 new row
17710 A6 check-half-states.mjs does full-repo I/O even for --help landed, 1 new row
17710 A6 nohup inside a backgrounded tool call reports a false exit 0 landed, 1 new row
17710 A7 an unquoted heredoc delimiter expands every backtick in the body landed, 1 new row
17710 A7 a piped command's exit code is the pipe's last stage landed, 1 new row
17710 A8 exactly one footer, idempotent on its own form, a different spelling yields more already present (the three-block reading covers the different-spelling half)
17710 A8 comment creation appends +58 B already present
17710 A9 queue progress is read from the event=merge_group runs; a quiet tip lags already present
17710 A9 the queue branch name embeds the SPECULATIVE base landed, 1 new row
17710 A9 the removal and the merge event arrive in no fixed order landed, 1 in-place correction
17710 c2 HTML entities do not decode inside an inline code span landed, 1 in-place correction
17710 c2 a bracketed placeholder inside a code span survives landed, 1 new row
17710 c6 the wake relay escapes its own rendering; judge the stored body from a GET landed, 1 new row
17754 labels and type in ONE bare-REST issue PATCH answers 500 and writes nothing; the same two fields as two writes both answer 200 landed, 1 new row (rider, admitted in this PR's own review)
review a draft PR's mergeable_state is not the literal draft landed, 1 in-place correction (reviewer-authorised)

The four in-place corrections, each because a new cell contradicts the row rather than
extending it: the success-sequence row that keyed on the removal event being followed by the
merge event within about a second; the issue-body PATCH row whose "always exactly one" is
true of a full block and of no footer but false for a bare footer with no rule line; the
write-entities prescription, true of body prose and false inside an inline code span; and the
row asserting a draft PR always answers draft for mergeable_state, which seven draft PRs
across two repos falsify — they answer clean, blocked or unknown like any other PR.

Line budget

quantity before after
platform-readings.md lines 425 449
CEILINGS entry for that file 425 449
net +24

Every new or changed line measures at or under the 120-byte per-line cap (measured with awk
over the file: zero lines exceed 120 bytes). The raise is recorded as ONE ruledRaises record
on the cross-file-move declaration, quoting the standing one-file exception verbatim, dated
2026-09-12, delta 24 — the rider raised that record's delta rather than adding a second, since
this is one increment. The declaration's ordinary-ruled-raise total moves 100 to 124 while its
own was stays at 314. No other ceiling moves; no re-wrap was used as payment.

Gates

39 commands derived on the final diff with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (the derivation's own stderr names the repo and the commit,
and derives the change set three-dot from the merge base). Every one captured its exit code
before any pipe. All green, and the reconciliation confirms it:

  • dispatch-gates --ran — 39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN, and the zero is a
    DERIVED one: all 39 recorded an exit code and none of them is 3.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3 —
    PREREQUISITE NOT MET
    (two workspace packages unbuilt). That is NOT a finding and not a
    measurement; after turbo run build --filter=@objectstack/formula --filter=@objectstack/lint
    under the shared verify lock it exits 0. It is also a live instance of the A5 reading
    this PR lands.
  • pnpm check:pm-dispatch-gates exceeds the container's 600 s foreground cap and was run
    detached with a recorded PID, waited on in the foreground; verdict dispatch-gates self-test: 1678 cases pass, exit 0.
  • pnpm check:pm-skill-ratchet — platform-readings.md is 449 lines (ceiling 449; headroom 0).

Path face: node scripts/pm/check-governed-merges.mjs --pr 17746 prints GOVERNED — a human merge is the review record for this PR and exits 3 — the expected verdict, and itself the
measured instance behind one of the landed rows.

维护者速读(草稿)

改了什么。 只动两个文件。platform-readings.md 加 24 行读数、就地更正 4 行;棘轮脚本里
只改这一个文件的 CEILINGS 数(425 → 449)并按脚本头部规定的形状补一条 ruledRaises 记录。
没有别的天花板移动,没有别的 skills 文件被碰。

为什么改。 六张卡都是同一类:平台行为被实测到了,而事实表里没有、或写得比代码窄。
写得比代码窄比缺席更险 —— 上一轮就有席位据一条过窄的规则去修一个本来没坏的东西。
其中三条跨席位后果最重:认领标记的拼写决定后继席位能不能看见本车道已被占;
REST 写侧少一个 header 就整个静默不写;标签与类型挤进同一次写会 500 且零落库。

风险与代价(含回滚)。 只是参考事实表,没有运行时代码、没有发布物,故挂 skip-changeset。
风险面是「写进去的读数是不是真的」,这由每行自带的实测标注与本 PR 的去重表承担。
回滚成本一个 revert:天花板与表的行数是同一笔提交里的一对,revert 后仍自洽。

席位意见。 (待席位定稿)

你要做的。 这是治理面(.claude/**),⛔ 没有任何 agent 席位可以合它。
请人工确认后手合;若不同意某一行的措辞,指出行号即可,不必整体退回。

Authored in Claude Code session session_01MCLBsUgfykL74aU716rzVK — durable attribution kept
in prose here, because this body is re-sent footerless on purpose (see the landed row on that
cell) and the block below is the platform's own.


Generated by Claude Code

… in-place corrections)

Claude-Session: https://claude.ai/code/session_01MCLBsUgfykL74aU716rzVK
Co-authored-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…r the standing exception

Claude-Session: https://claude.ai/code/session_01MCLBsUgfykL74aU716rzVK
Co-authored-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCLBsUgfykL74aU716rzVK
Co-authored-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 12, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 12, 2026
…he labels-and-type rider row

Claude-Session: https://claude.ai/code/session_01MCLBsUgfykL74aU716rzVK
Co-authored-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)

改了什么 — 给 PM 派发技能的平台事实表 references/platform-readings.md 加 24 行、原地改 4 行(425 → 449 行),同 PR 把行数棘轮的上限抬到 449 并按常设例外记一条 ruledRaises。六张卡一次付清:#17680(claim 评论与 clause-② 声明的行首位置规则、Claim: 标记的可见性)、#17239 / #17677(REST 与 MCP 写 issue/PR 正文时署名页脚的存留形状)、#17563(经出口代理的 REST 写必须带 Content-Type: application/json,否则 415 零写入)、#17710(队列/门禁/shell 的 12 条读数陷阱)、#17754(issue PATCH 同体带 labels+type 回 500)。四处原地改正:合并队列成功序列的次序、issue 正文 PATCH 页脚计数的边界、行内代码跨度里实体不解码、以及「draft PR 恒回 draft」这条本席实测为假的旧行。

为什么改 — 这些都是各席位这两天实测踩到的平台事实,写进表后下一个席位不用再踩一次;抬上限走的是 SKILL.md 里唯一的常设例外(该文件增量抬上限免决策卡),条件——逐条核实、去重计数、一事一行、不计重排——本席在 ACCEPT 评论里逐条对过。

风险与代价(含回滚) — 纯参考文本,不改任何门禁行为;每行 ≤ 120 字节,棘轮、id-lint、nul-bytes、dispatch-gates 全家族 39 条本席按 dev 报告与自身读数核过全绿;本 head 上 CI 还有 1 个 job 在跑,合并前等它绿。回滚 = revert 本 PR。

席位意见 — 席内按契约复审档复核通过,建议合并。去重计数:候选 33 / 落地 26 / 已有 7 / 拒收 0。

你要做的 — 受管面:请人工合并 PR #17746(本席不翻 ready、不入队、不挂 auto-merge)。


Generated by Claude Code

@claude
claude Bot requested review from hotlong and os-zhuang September 12, 2026 02:55
os-justin pushed a commit that referenced this pull request Sep 17, 2026
…ape its own clean class

The header declared the issue-body footer cell UNMEASURED and held the
body-mode append in `mutated` on that ground, while the governed fact
table has carried the measurement since PR #17746 and the skills seat
re-measures it on every seat-post refresh. Since PR #18758 `$?` already
answered 0 for both footer shapes, so the tool said two things about one
set of bytes: "everything sent is on the platform" in `$?` and "MUTATED"
on stderr, with `--json` reporting `body_mutated: true` beside
`body_landed: true`.

`footerReAnchoring`'s two measured shapes are now two declared classes —
`footer-appended` and the new `footer-re-anchored` — for either act, so
`classifyReadBack` takes no `mode`: the comparison is exact bytes, which
cannot tell one act's write from another's, and the gate existed only
for the cell that is now measured. `sentBodyLanded` reads the class
alone. Every exit-4 control is unchanged: a byte lost before the rule, a
byte changed at equal length, a chewed footer, a rewritten link, a
newline from nowhere, a truncation ending in the block.

What is unmeasured is named instead: the WRITE CHANNEL. Two `--body`
refreshes of the same shape on the same endpoint the same day read +58
on this seat's channel and IDENTICAL on the triage seat's, and no act
here can vary that.

Claude-Session: https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu
Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 28, 2026
…rned fact table, each paid in place (objectstack-ai#18689)

Part of objectstack-ai#18426 — the carrier of a seven-card batch, all landing rows in
one governed file.

`Clause-②: no`

One file: `.claude/skills/pm-dispatch/references/platform-readings.md`,
held at **466 / 466** (headroom 0,
widest line 120 B). No ceiling was raised. Every adopted row is paid by
a compression or a dedup **in the same
file**, listed beside the sentence it shortened. Rows :10–:12, :212 and
:431 are untouched — verified by content,
and none of them appears in any hunk of the diff.

Each reading was adopted or rejected **on its own**, as the cards ask.

## Verdicts

| card | reading | verdict | row line | bytes | paid by |
|---|---|---|---|---|---|
| objectstack-ai#18426 ① | zod v4 defines the parse methods per INSTANCE, so prototype
spying throws; the seam is the barrel population | **ADOPTED** | `:277`
+ `:278` | 97 B + 116 B | `:172` — the conditional-request row absorbs
the payload-precedence row (its 「只有 body 精确」 is restated at
`:178`–`:179`) · `:185` — the payload-staleness pair |
| objectstack-ai#18426 ② | the REST write identity is per-TOKEN, not per-channel; read
back your own write | **REJECTED** | already at `:126`–`:132` | — | — |
| objectstack-ai#18426 ③ | `os-verify-lock.sh` is objectstack's and absent in objectui
| **ADOPTED** | `:393` | 112 B | `:207` — the `created`-order pagination
pair |
| objectstack-ai#18426 ④ (comment) | ref deletion is refused while every other write
on the token succeeds | **REJECTED** | already at `:374`–`:377` and
`:430` | — | — |
| objectstack-ai#18426 ⑤ (comment) | a suspended author's comment is counted but not
served | **REJECTED** | already at `:250` (cause at `:164`–`:167`) | — |
— |
| objectstack-ai#18446 | a label strip re-triggers the label-sensitive checks ⇒
pre-check ③ is read after the last state write | **ADOPTED** | `:85` |
118 B | `:289` — the missing-command pair |
| objectstack-ai#18458 | `gh-readonly-queue/*` ref names embed the stacked-on sha ⇒
queue ORDER from `ls-remote` | **REJECTED** | already at `:70`–`:73` | —
| — |
| objectstack-ai#18467 (main) | a full rule-plus-footer BLOCK to an issue body is
re-anchored, not doubled | **REJECTED** | already at `:410` + `:357` | —
| — |
| objectstack-ai#18467 (operating half) | that re-anchor is what `post-stamped`'s
`body` mode reports as `mutated` | **ADOPTED** | `:357` (new row under
it) | 119 B | `:318` — the MCP-truncation pair |
| objectstack-ai#18467 (addendum) | bare REST `POST /issues` with a footerless body
synthesises exactly one, +58 | **ADOPTED** | `:410`, refined in place |
120 B | **zero** — folded into the existing create row |
| objectstack-ai#18498 row 1 | `grep -z` with a literal newline is an OR — a false
POSITIVE; `grep -Pz` with the backslash-n escape discriminates |
**ADOPTED** | `:291` | 118 B | `:451` — the usage-wall pair |
| objectstack-ai#18498 row 2 | (withdrawn on the card as a duplicate) | not adopted |
— | — | — |
| objectstack-ai#18521 | `unstable` can come from a commit STATUS the `/check-runs`
enumeration cannot see | **ADOPTED** | `:28` | 115 B | `:303` — the two
CI-log reading rows |
| objectstack-ai#18522 | the footer has two spellings, so a bare-only strip strands
the session-URL one mid-body | **ADOPTED** | `:347` | 106 B | `:331` —
the fence caveat folds into the trap row beside it |

**8 readings adopted, 9 lines, 8 payments** (the create-channel cell
costs nothing — it refines a row that was
already there). Net line change: **0**.

### Every payment, and what it shortened

| payment | before | after | fact lost |
|---|---|---|---|
| `:172` | 「文档载明未实测:条件请求答 `304` 不计 core 池。」 + 「公开仓零配额读法两档,payload 档优先 ——
只有 body 精确。」 | one row | 「只有 body 精确」 — restated in full at
`:178`–`:179` (`assignees` stale, claim-bearing fields never read from
this channel) |
| `:185` | 「⇒ 前 15 项那条判别式…」 + 「失效方向是据它对别人的工作下没有认领的判词。」 | one row | none
|
| `:207` | 「`created` 序承重…」 + 「以两趟的重叠证覆盖…」 | one row | none |
| `:289` | 「⛔ 一般规则:任何可能不存在的命令…」 + 「PR 与查重类核验改走 MCP GitHub 工具或 git。」 |
one row | none |
| `:303` | 「`get_check_run` 对本仓 CI job 回空 `output.text`。」 +
「`get_job_logs` 无论 `tail_lines` 只回占满日志尾部的 post-step service-container
teardown。」 | one row | 「post-step」 and 「占满」 — the position is still
given by 「尾部的」 |
| `:318` | 「GitHub 存储字节完好,raw REST 取回一字不差。」 + 「⇒ ⛔ 永不单凭 MCP 读判截断…」 | one
row | none |
| `:331` | 「⛔ 围栏不防护:照删、留空围栏。」 + 「另一坑:感叹号紧跟左方括号即触发(TS 非空断言下标),无需尖括号。」 |
one row | 「TS」 and 「下标」 from the parenthetical — the mechanism is
already spelled out by 「感叹号紧跟左方括号」 |
| `:451` | 「盲区:窗口起点是本地推断的近似值。」 + 「撞墙报文形如 `limit reached, resets at
HH:MM`…」 | one row | none |

## Why the five rejections — the four axes

All five reject for **one** reason: the reading is **already in the fact
table**, measured and phrased. That makes
this a single class, so the axes are argued once and the per-card
evidence follows.

- **实际业务需求** — the need each card names is real, and it is already
served. A seat asking 「who authors my
REST writes」 lands on `:129` (「类只认每次写回读的 `user.login`/`user.type`」); a
seat asking 「where is my PR in
the queue」 lands on `:70`–`:73`, which carries the parent-tip chain
recipe **and** a caution the card does not
have (`:72`: the embedded parent is a presumed base, measured to reach
`main` ten-plus minutes later). Adding a
second row would not add a reader path; it would add a second place to
disagree.
- **项目长远合理性** — a fact table with two rows for one fact is the
workaround shape this repo refuses. When one
copy is later corrected, the other stays, and the next seat reads
whichever it reaches first. One row, one
  reader path.
- **防 AI 写代码犯错** — this is the axis that decides it. A duplicated row is
a **lenient** surface: it lets a
future edit narrow one copy while the other keeps the old claim, and
nothing goes red. The strict form is one
row, which the ratchet already prices. Note the direction of the
rejection: none of the five loses a fact —
  each is being kept, in the line that already carries it.
- **创业阶段不扩散需求** — at 466 / 466 every row is paid by deleting or
compressing another. Paying real
compression for a fact that is already written down spends the budget
twice and shrinks the table's coverage by
  exactly the sentence that was compressed to make room.

Per-card evidence:

- **objectstack-ai#18426 ②** — `:126` names both token classes (`claude[bot]` and the
account), `:127` says the class is per
Claude Code account and can flip mid-session, `:129` says the class is
only known by reading back each write,
`:132` says never assume `claude[bot]`. `:128` already lists two
measured flips. The card's third measurement
(`os-sam` vs `hotlong`) confirms a rule the table states; it does not
change it.
- **objectstack-ai#18426 ④** — `:375` records the `git push --delete` disconnect with
the misleading tail, `:374` and `:376`
record the consequence (probe branches accumulate), and `:430` records
the second form, the proxy 403, with the
  same disposition and an explicit 「⛔ 不重试」.
- **objectstack-ai#18426 ⑤** — `:250` is the reading: 「`comments` 计数会多读:实测 1 而列表与
timeline 双 0 ⇒ 线程空否读那两条,
⛔ 不读计数」. The cause is at `:164`–`:167`. ⚠️ Worth the seat's eye: the
triage grading on objectstack-ai#18426 asked
  specifically for this one to be written in, and it already was.
- **objectstack-ai#18458** — `:70` gives the name form and says the embedded sha is
the previous entry's tip; `:71` gives the
walk and says lexical order is meaningless; `:73` says it is zero-quota
and answers the position that the
timeline cannot. `:61` keeps the positive-only caution the card asks to
preserve.
- **objectstack-ai#18467 (main)** — `:410`: 「issue 正文 `PATCH`
识别按整块:送全块或不送页脚都存回恰一条,已有页脚归一末尾不
复制」 is the not-doubled half; `:357` is the blank-line re-anchor and the
instruction to compare by first
differing offset rather than by length. What was **missing** is the
operating consequence, and that is the row
  adopted at `:357`.

## Measurements taken for this PR

- **objectstack-ai#18498's restatement sweep.** The dispatch asks where else the `-z`
advice is restated, so the same edit can
ride the same PR. Measured repo-wide, exit code captured before any
pipe: `git grep -F 'grep -z'` → **exit 1**,
`git grep -F -- '-Pz'` → **exit 1**, `git grep -F '行向'` → **exit 1**.
Lit control in the same batch:
`git grep -F '拼接后'` → **exit 0**, hitting `platform-readings.md:290`,
and `grep -c grep` on that file → 13.
⇒ **the `-z` advice is restated nowhere in this repo** — it lives in the
dispatching seat's own prose, handed
down per round. Nothing in SKILL.md or core-rules needed the co-edit, so
nothing is reported for re-scoping.
The row is placed under pit ⑥ (`:290`), which is where this repo's
wrapped-phrase discipline actually lives.
- **objectstack-ai#18446's second half is NOT line-neutral in `contract-review.md`.**
That file is at 60 / 60. Its landing
pre-check block `:40`–`:46` runs 99–120 B per line, and the cheapest
adjacent merge inside it is **213 B** —
no insertion fits without a raise. ⇒ per the dispatch's own instruction
for that case, the row at `:85` carries
the sequence: 「③ 在入队前末次状态写之后读」. `contract-review.md` is untouched, still
60 / 60.
- **objectstack-ai#18446 is recorded in its generalised form**, per the card's own
addendum: a label strip and a ready flip are
both state writes. `:84` already recorded the ready-flip re-run with a
different consequence (enqueue timing);
  the new row states the consequence for pre-check ③.

## Gates

`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived the list from the tree
(no hand-fed paths); `--ran` reconciles: **18 derived, 18 run, 0
NOT-MEASURED, 0 UNRUN — a DERIVED zero, all 18
carry an exit code and none of them is 3.** Every code captured by
redirect-then-`$?`, never through a pipe.

| command | exit |
|---|---|
| `node scripts/check-closing-keyword-parity.mjs` | 0 |
| `node scripts/check-closing-keyword-parity.mjs --self-test` | 0 |
| `node scripts/check-comment-mask-corpus.mjs` | 0 |
| `node scripts/pm/check-governed-queue-guard.mjs --self-test` | 0 |
| `node scripts/pm/check-harness-current.mjs --self-test` | 0 |
| `pnpm --filter @objectstack/lint run check:doc-formula-expressions` |
0 |
| `pnpm check:agent-test-spelling` | 0 |
| `pnpm check:doc-authoring` | 0 |
| `pnpm check:driver-memory-census` | 0 |
| `pnpm check:nul-bytes` | 0 |
| `pnpm check:pm-governed-merges` | 0 |
| `pnpm check:pm-half-states` | 0 |
| `pnpm check:pm-skill-id-lint` | 0 |
| `pnpm check:pm-skill-ratchet` | 0 |
| `pnpm check:refd-timer-probe` | 0 |
| `pnpm check:required-contexts` | 0 |
| `pnpm check:skill-frame-sync` | 0 |
| `pnpm check:watch-hint-literal` | 0 |

Named explicitly by the dispatch, both inside that list:

- `pnpm check:pm-skill-ratchet` → **exit 0**; its own verdict lines:
  `platform-readings.md is 466 lines (ceiling 466; headroom 0)` and
`platform-readings.md: widest table row is 0 bytes (pin 0; headroom 0)`;
  `contract-review.md is 60 lines (ceiling 60; headroom 0)`.
- `pnpm check:skill-frame-sync` → **exit 0**: `the one declared copy of
the decision frame is internally coherent`,
  4 axes, 74 markdown files scanned for undeclared copies.

Governed-surface predicate, as the dispatch asks it be recorded:

- `node scripts/pm/check-governed-merges.mjs --test
.claude/skills/pm-dispatch/references/platform-readings.md`
→ **exit 3 = GOVERNED** (not a failure): `1 of 1 path(s) hit the
register`, `.claude/** ×1`.

First eight of those ran at exit 3 = `PREREQUISITE NOT MET` on a fresh
worktree with no `node_modules`; that is
not a measurement, so `pnpm install` ran and every one was re-run.
`check:doc-formula-expressions` then still
answered 3 (`@objectstack/formula` and `@objectstack/lint` unbuilt); its
own prescribed fix was run through the
shared verify lock — `os-verify-lock: VERDICT command-exit 0` — and the
gate re-ran at 0.

Manual byte discipline beyond the gates: `grep -naP` for control
characters over the edited file → **exit 1**
(none).

## Acceptance notes

Noted while measuring, not filed, and not touched here:

- `platform-readings.md:412` states the issue-body `PATCH` cell has two
empties (MCP with a bare footer; a
single-field `issue_write` on `title`/`labels`). Still true after this
PR — the adopted create-channel cell is
a different verb. Successor: the next seat that writes an issue body
through MCP.
- `scripts/pm/post-stamped.mjs`'s docblock says 「whether the platform
synthesises a footer for a footer-less ISSUE
BODY is unmeasured」, which objectstack-ai#18467 shows is stale prose — the table has
carried that cell since PR objectstack-ai#17746, and
this PR adds the create half. The tool and the table now disagree in
writing. ⛔ Out of scope here: the file is
not on this PR's declared surface, and the card itself declines to judge
whether one observation is enough to
extend the tool's declared normalisation set. Successor: whoever next
touches `post-stamped.mjs`.
- objectstack-ai#18461 is deliberately absent from this batch (its row ② contradicts
objectstack-ai#18421's reading; that decision is the
  maintainer's). Nothing here touches it.

## 维护者速读(草稿)

**改了什么** —— 只改一个文件:PM 车道的平台读数事实表。八条今天实测出来的 GitHub/工具行为写进去,五条因为
表里已经有了而没写。文件行数一行没涨(466 / 466),每加一行都在同一个文件里删掉或压掉一行来付账。

**为什么改** —— 这些读数原本只存在于各个 issue 的讨论里。没有载体的读数,下一个席位会从零重新推一遍;这次
的批次本身就是证据:五条里有五条已经在表里了,而填报席没查表就填了卡。

**风险与代价(含回滚)** —— 风险在八处压缩:两行合成一行,可能丢掉措辞。逐条列在正文的「Every payment」表里,
三处明确写了丢掉哪几个字以及那个事实在哪一行还能读到,其余五处无损。回滚是 `git revert`,单文件、无生成物、
无下游消费者。

**席位意见** —— (留空,由席位在复核时填)

**你要做的** —— 不需要做什么。这是事实层(`references/**`),按裁决 objectstack-ai#17950 由技能席在自己的契约档复核后经队列
落地;⛔ 没有席位把它翻 ready、入队或挂 auto-merge。

## Closing lines

Part of objectstack-ai#18426 — readings ① and ③ adopted; readings ②, ④ and ⑤ rejected
as already recorded, so the card stays
open for the seat to confirm those three duplication claims before it is
retired.
Fixes objectstack-ai#18446
Part of objectstack-ai#18458 — the entire reading is already recorded at the queue-ref
rows; no row was added, and the card
stays open for the seat to confirm that before it is retired.
Part of objectstack-ai#18467 — the operating consequence and the create-channel cell
are adopted; the re-anchor itself is
rejected as already recorded, so the card stays open for the seat to
confirm that one.
Fixes objectstack-ai#18498
Fixes objectstack-ai#18521
Fixes objectstack-ai#18522

---
_Generated by [Claude
Code](https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-user-decision size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants