Skip to content

docs(pm-skill): three review-chain protocol rows, paid by compression - #12083

Merged
hotlong merged 1 commit into
mainfrom
claude/issue-11399-review-chain-rows
Aug 25, 2026
Merged

docs(pm-skill): three review-chain protocol rows, paid by compression#12083
hotlong merged 1 commit into
mainfrom
claude/issue-11399-review-chain-rows

Conversation

@claude

@claudeclaudeBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Closes#11399, closes#11994, closes#11220

A folded pack of three one-line protocol rows across the two pm-dispatch
reference files. Both files sit at zero ratchet headroom, so every row is
paid in place — no ceiling is raised, and no ceiling row in
scripts/pm/check-skill-line-ratchet.mjs is touched.

Ceilings read from the gate (not recalled): contract-review.md48,
state-machine.md43. Note the #11399 card body says "ceiling 44" for
contract-review.md — that is stale; the script is authoritative.

Per-item

1. #11399 — re-hang guard

落点references/contract-review.md, tail of 载体纪律(挂与清).

before — nothing in the file told a would-be re-hanger where the
distinguishing evidence lives; 「被剥不是红灯是放行」 (in state-machine.md)
covers only the reverse direction.

after — new bullet:

重挂前先查裁决:闸门标签缺失 ⇒ 先 grep 卡片评论找现行复审结论 —— PASS 评论 + 标签缺失 + PR head 自复审后未动 = 已复审清标,不是被剥;仅当 head 在结论之后移动、或根本无结论时才重挂(复审载体是卡上一行结论,get_reviews 读空不是「未复审」的证据)。

2. #11994 — the handoff IS the label

落点references/state-machine.md, the 通则 needs:contract-review
dual-carrier bullet (its natural home, per the grading comment).

before…卡侧先挂而 PR 尚不存在是合法中间态,不是半写。

after — same bullet, extended:

…不是半写;交接即标签 —— 只写交接评论而不同笔挂标 = 空交接,收件箱只认标签。

The read-back half of the graded row is deliberately not re-stated: the same
bullet already opens with 「挂与清各一笔、两向都读回」, so adding it again would
have been duplication bought at a line of a zero-headroom file.

Per the grading comment, the prose-matching patrol heuristic is declined
only the protocol row is implemented here.

3. #11220 — Blocked-by discipline (option 3 only)

落点references/state-machine.md, the pm:blocked 正典标记 bullet.

before…句中提及**刻意拒收** —— 指令是行,提及是散文。

after — same bullet, extended:

…指令是行,提及是散文。等「PR 合并」或「发布且 pin 覆盖」的卡同理:指一张在该刻关闭的卡(等发布 = pin-bump 杂事卡),⛔ 不扩词表;Part of 型 PR 的跟踪卡不在该刻关闭,不可用。

Scope is option 3 as the discipline row only. Options 1/2 (a !PR form, a
release/lockfile form) stay unmechanized, per the maintainer ruling recorded on
the card (2026-08-23, verbatim and untranslated:
「10950 不考虑存量,其他接受你的建议」).

The live precedent that motivates the row is cited on the card, not in the file:
.claude/skills/pm-dispatch/** is scanned by check:pm-skill-id-lint
(/#[0-9]{3,}/), so the row is written as a self-contained lesson with no issue
IDs. The Part of clause is the third instance recorded on the card: when the
blocking PR carries Part of rather than a closing keyword, its tracking issue
cannot close when that PR lands, so naming it over-waits by construction.

How each file paid

contract-review.md — 48 → 48, paid by canonical re-wrap (no content change)

Three bullets were re-wrapped using the gate's own exported wrapLine, so
the result is canonical by construction rather than by hand:

bulletlines
复审资格与归属 · 资格8 → 7
降档保险丝 · 子轮开场 get_session4 → 3
降档保险丝 · 保险丝只对座位自会话有效7 → 6

That frees exactly the 3 lines the new row costs. Proof this moved no
content
: both versions were folded back to their logical blocks (line breaks
removed per the CSS segment-break rule the wrapper documents — a break between
two wide characters
is removed, any other break renders as a space) and the
block lists compared:

folded blocks: 19 -> 20
blocks byte-identical after folding: 19
[+ ADDED] - **重挂前先查裁决**:…

All 19 pre-existing blocks are byte-identical; the only delta is the added row.
Every 「…」 verbatim ruling survives intact — the wrapper treats a corner-bracket
quotation as a single atom, so no ruling is re-flowed. A side effect worth
naming: the 资格 bullet previously wrapped as …免复审 / / 放,…, a
one-character line; it now reads 免复审直放.

state-machine.md — 43 → 43, paid by two compressions

This file had no re-wrap slack (a canonical re-wrap of the whole file yields
43 → 43), so its 2 lines came from real cuts. Both are rationale/duplication;
every rule, every mechanical step and every ⛔ prohibition survives.

放行双查 (3 → 2) — dropped the rationale story
—— 已放行过的条件是花掉的,再点火就把过期前提立成现行, plus
所载 and 该转换评论之后该评论之后. Both checks, both ⛔, and
「两查皆机械、零判断」 are kept verbatim. The rule is fully mechanical on its
own; the ratchet's own header is explicit that stories live on cards, not in
operational text.

完工停放 (4 → 3) — dropped the parenthetical
回队前提检查见到已完工的 open PR 即按落地工作处理, which re-states the same
sentence's own main clause from the 回队 side, and the trailing rationale
让链路两端可读; also 据此. ⛔ 永不给完工卡重派 dev,
Unlock-action: re-check PR #M and 停放 PR 正文须点名门禁卡 are kept.

Fold-level diff: 22 of 26 blocks byte-identical, 4 changed — the two rows
above and these two compressions, nothing else.

Gates

Derived from the real change set with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths
passed — the script reads the change set itself). The derivation added four
families the dispatch did not name: check:agent-test-spelling,
check:doc-formula-expressions, check:pm-governed-merges,
check:pm-skill-id-lint.

Union re-run after the final commit, at 7f6f25ba5. Exit codes captured
before any pipe; the verdict lines below are the gates' own:

✓ check-skill-line-ratchet: …/state-machine.md is 43 lines (ceiling 43; headroom 0).
✓ check-skill-line-ratchet: …/contract-review.md is 48 lines (ceiling 48; headroom 0).
✓ check-skill-id-lint: 22 file(s) clean (pattern /#[0-9]{3,}/g).
✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
✓ doc authoring guard: 389 files clean — no bare metadata literals.
✓ doc authoring guard: 38 published skill files clean — no internal issue-id references.
check-nul-bytes: OK (scanned 6704 text file(s); no raw ASCII control bytes).
✓ check-agent-test-spelling: 0 violations — 367 file(s) …
✓ check-governed-merges --self-test: 129 assertions …
✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 421 files / 1449 TS blocks judged clean.

check:doc-formula-expressions needed pnpm install plus a build of
@objectstack/lint and its dependency closure in this fresh worktree — its first
two runs were prerequisite failures that measured nothing, not findings, and
the numbers above come from the run after the build.

Notes

  • No changeset: .claude/ internal agent tooling publishes nothing. The
    skip-changeset label is applied on this PR via the additive labels endpoint
    and read back.
  • No published-skills diff, so the published-catalog line-budget reading does not
    apply — this is the internal, never-published surface.
  • Governed surface ⇒ draft, human merge. Not marked ready.

Generated by Claude Code

Folded pack of three one-line protocol rows across the two pm-dispatch
reference files, both at zero ratchet headroom — every row paid in place,
no ceiling raised.
contract-review.md (48 -> 48, ceiling 48): a re-hang guard on the gate
label — grep the card thread for a standing verdict before re-hanging;
PASS comment + label absence + unchanged PR head reads as CLEARED, not
dropped. Paid by canonically re-wrapping three bullets; folded content is
byte-identical, only line breaks moved.
state-machine.md (43 -> 43, ceiling 43): the handoff IS the label — a
handoff comment without the same-stroke label write is a null handoff;
and a card waiting on a PR merging or a release landing names an issue
that closes at the right moment, the vocabulary staying issue-only. Paid
by dropping one rationale story and one same-sentence restatement; every
rule and every prohibition survives.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment