docs(pm-skills): adopt eight measured platform readings into the governed fact table, each paid in place - #18689
Conversation
…place
Six readings land in the governed fact table at zero headroom; each new row is
paid by a compression or a dedup in the same file, so the line count is
unchanged at 466/466 and every row stays under the 120-byte width rule.
New rows:
- zod v4 hangs parse methods per instance, so prototype spying throws; the
working seam is the barrel population, with its radius stated.
- os-verify-lock.sh lives only in objectstack; a sibling-repo seat running
this repo's copy reads a container-level lock, not that repo's depth.
- a label strip and a ready flip are both state writes that restart the
label-sensitive checks, so landing pre-check 3 is read after the last one.
- sending a whole footer block to an issue body trips the blank-line
normalisation, which post-stamped's body mode reports as `mutated`.
- grep -z treats a literal newline in the pattern as a separator, so a
wrapped phrase matches one side only -- a false positive, not a false zero.
- the issue create channel synthesises exactly one footer for a footerless
body (+58), folded into the existing create row at zero cost.
Payments: the conditional-request/payload row pair, the payload-staleness pair,
the created-order pagination pair, the missing-command pair, the MCP-truncation
pair and the usage-wall pair each compress two lines into one, losing no fact.
Claude-Session: https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu
Co-authored-by: Claude <noreply@anthropic.com>
The seat folded two more sibling cards onto this branch. Both land as one row
each, each paid by a compression in the same file, so the count stays 466/466.
New rows:
- mergeable_state `unstable` can be produced by a commit STATUS, which the
/check-runs enumeration cannot see, so landing pre-check 3 reads the
commit status too before calling a head green.
- the attribution footer has two spellings, so a "send no footer" strip that
matches only the bare one strands the session-URL one mid-body while the
58-byte read-back delta still looks exactly as documented.
Payments: the two CI-log reading rows compress into one, and the fence caveat
folds into the trap row beside it; no fact is dropped by either.
Claude-Session: https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu
Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Review of record on the PR thread — the same record the seat posted on the carrier card as 5716694216 at 2026-09-17T15:10:43Z; the merge-group leg of the Governed Surface Guard reads the PR thread, not the card, and dequeued this PR at 2026-09-17T15:36:18Z for want of it. In-seat review of PR #18689 (the seven-card platform-readings batch carried by #18426) by the dispatching ① Derived judgments
② Semver levelNone — no package is touched; ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
Part of #18426 — the carrier of a seven-card batch, all landing rows in one governed file.
Clause-②: noOne 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
:277+:278:172— the conditional-request row absorbs the payload-precedence row (its 「只有 body 精确」 is restated at:178–:179) ·:185— the payload-staleness pair:126–:132os-verify-lock.shis objectstack's and absent in objectui:393:207— thecreated-order pagination pair:374–:377and:430:250(cause at:164–:167):85:289— the missing-command pairgh-readonly-queue/*ref names embed the stacked-on sha ⇒ queue ORDER fromls-remote:70–:73:410+:357post-stamped'sbodymode reports asmutated:357(new row under it):318— the MCP-truncation pairPOST /issueswith a footerless body synthesises exactly one, +58:410, refined in placegrep -zwith a literal newline is an OR — a false POSITIVE;grep -Pzwith the backslash-n escape discriminates:291:451— the usage-wall pairunstablecan come from a commit STATUS the/check-runsenumeration cannot see:28:303— the two CI-log reading rows:347:331— the fence caveat folds into the trap row beside it8 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
:172304不计 core 池。」 + 「公开仓零配额读法两档,payload 档优先 —— 只有 body 精确。」:178–:179(assigneesstale, claim-bearing fields never read from this channel):185:207created序承重…」 + 「以两趟的重叠证覆盖…」:289:303get_check_run对本仓 CI job 回空output.text。」 + 「get_job_logs无论tail_lines只回占满日志尾部的 post-step service-container teardown。」:318:331:451limit reached, resets at HH:MM…」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.
REST writes」 lands on
:129(「类只认每次写回读的user.login/user.type」); a seat asking 「where is my PR inthe queue」 lands on
:70–:73, which carries the parent-tip chain recipe and a caution the card does nothave (
:72: the embedded parent is a presumed base, measured to reachmainten-plus minutes later). Adding asecond row would not add a reader path; it would add a second place to disagree.
copy is later corrected, the other stays, and the next seat reads whichever it reaches first. One row, one
reader path.
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.
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:
:126names both token classes (claude[bot]and the account),:127says the class is perClaude Code account and can flip mid-session,
:129says the class is only known by reading back each write,:132says never assumeclaude[bot].:128already lists two measured flips. The card's third measurement(
os-samvshotlong) confirms a rule the table states; it does not change it.:375records thegit push --deletedisconnect with the misleading tail,:374and:376record the consequence (probe branches accumulate), and
:430records the second form, the proxy 403, with thesame disposition and an explicit 「⛔ 不重试」.
:250is the reading: 「comments计数会多读:实测 1 而列表与 timeline 双 0 ⇒ 线程空否读那两条,⛔ 不读计数」. The cause is at
:164–:167.specifically for this one to be written in, and it already was.
:70gives the name form and says the embedded sha is the previous entry's tip;:71gives thewalk and says lexical order is meaningless;
:73says it is zero-quota and answers the position that thetimeline cannot.
:61keeps the positive-only caution the card asks to preserve.---+ footer BLOCK sent to an issue body through bare REST is RE-ANCHORED, not doubled — one newline moves, the net is zero bytes, and post-stamped reads the whitespace asmutated#18467 (main) —:410: 「issue 正文PATCH识别按整块:送全块或不送页脚都存回恰一条,已有页脚归一末尾不复制」 is the not-doubled half;
:357is the blank-line re-anchor and the instruction to compare by firstdiffering 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
grep -zwith a literal newline is an OR, not a wrapped-phrase match — the discipline line manufactures false confirmations #18498's restatement sweep. The dispatch asks where else the-zadvice is restated, so the same edit canride 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, hittingplatform-readings.md:290, andgrep -c grepon that file → 13.⇒ the
-zadvice is restated nowhere in this repo — it lives in the dispatching seat's own prose, handeddown 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.contract-review.md. That file is at 60 / 60. Its landingpre-check block
:40–:46runs 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
:85carriesthe sequence: 「③ 在入队前末次状态写之后读」.
contract-review.mdis untouched, still 60 / 60.both state writes.
:84already 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/objectstackderived the list from the tree(no hand-fed paths);
--ranreconciles: 18 derived, 18 run, 0 NOT-MEASURED, 0 UNRUN — a DERIVED zero, all 18carry an exit code and none of them is 3. Every code captured by redirect-then-
$?, never through a pipe.node scripts/check-closing-keyword-parity.mjsnode scripts/check-closing-keyword-parity.mjs --self-testnode scripts/check-comment-mask-corpus.mjsnode scripts/pm/check-governed-queue-guard.mjs --self-testnode scripts/pm/check-harness-current.mjs --self-testpnpm --filter @objectstack/lint run check:doc-formula-expressionspnpm check:agent-test-spellingpnpm check:doc-authoringpnpm check:driver-memory-censuspnpm check:nul-bytespnpm check:pm-governed-mergespnpm check:pm-half-statespnpm check:pm-skill-id-lintpnpm check:pm-skill-ratchetpnpm check:refd-timer-probepnpm check:required-contextspnpm check:skill-frame-syncpnpm check:watch-hint-literalNamed 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)andplatform-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 METon a fresh worktree with nonode_modules; that isnot a measurement, so
pnpm installran and every one was re-run.check:doc-formula-expressionsthen stillanswered 3 (
@objectstack/formulaand@objectstack/lintunbuilt); its own prescribed fix was run through theshared verify lock —
os-verify-lock: VERDICT command-exit 0— and the gate re-ran at 0.Manual byte discipline beyond the gates:
grep -naPfor control characters over the edited file → exit 1(none).
Acceptance notes
Noted while measuring, not filed, and not touched here:
platform-readings.md:412states the issue-bodyPATCHcell has two empties (MCP with a bare footer; asingle-field
issue_writeontitle/labels). Still true after this PR — the adopted create-channel cell isa 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 ISSUEBODY is unmeasured」, which [finding] a full
---+ footer BLOCK sent to an issue body through bare REST is RE-ANCHORED, not doubled — one newline moves, the net is zero bytes, and post-stamped reads the whitespace asmutated#18467 shows is stale prose — the table has carried that cell since PR docs(pm): eleven platform readings into the fact table — 23 rows, 3 in-place corrections, ceiling 425 to 448 #17746, andthis 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.merge#18461 is deliberately absent from this batch (its row ② contradicts [finding] the seat's arming channel forcesmerge_method: mergeand silently drops a requestedsquash— the readback says "merge" while the queue lands a 1-parent squash, and nothing tells a seat that #18421's reading; that decision is themaintainer's). Nothing here touches it.
维护者速读(草稿)
改了什么 —— 只改一个文件:PM 车道的平台读数事实表。八条今天实测出来的 GitHub/工具行为写进去,五条因为
表里已经有了而没写。文件行数一行没涨(466 / 466),每加一行都在同一个文件里删掉或压掉一行来付账。
为什么改 —— 这些读数原本只存在于各个 issue 的讨论里。没有载体的读数,下一个席位会从零重新推一遍;这次
的批次本身就是证据:五条里有五条已经在表里了,而填报席没查表就填了卡。
风险与代价(含回滚) —— 风险在八处压缩:两行合成一行,可能丢掉措辞。逐条列在正文的「Every payment」表里,
三处明确写了丢掉哪几个字以及那个事实在哪一行还能读到,其余五处无损。回滚是
git revert,单文件、无生成物、无下游消费者。
席位意见 —— (留空,由席位在复核时填)
你要做的 —— 不需要做什么。这是事实层(
references/**),按裁决 #17950 由技能席在自己的契约档复核后经队列落地;⛔ 没有席位把它翻 ready、入队或挂 auto-merge。
Closing lines
Part of #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 #18446
Part of #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 #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 #18498
Fixes #18521
Fixes #18522
Generated by Claude Code