Skip to content

docs(pm-dispatch): SKILL.md discipline pack — six scoped protocol amendments in one file - #12086

Merged
hotlong merged 1 commit into
mainfrom
claude/issue-11578-skillmd-discipline-pack
Aug 25, 2026
Merged

docs(pm-dispatch): SKILL.md discipline pack — six scoped protocol amendments in one file#12086
hotlong merged 1 commit into
mainfrom
claude/issue-11578-skillmd-discipline-pack

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes#11578, closes#11901, closes#11936, closes#11944, closes#11604.
Part of #11923.

A folded pack: six scoped amendments from the skills-lane self-triage rulings, all in one
file — .claude/skills/pm-dispatch/SKILL.md. Each item below is the grading comment's
scope, nothing wider.

Scope notes on the two split cards:

Per-item checklist

card落点 (landing point)beforeafter
#11578派发词原则 — the dispatch-order conventionsOnly the zero-hit rule governed absence claims. A hazard claim ("this would destroy data") could be written into an order with no reading behind it.New clause, same register as the zero-hit rule: a hazard claim about the code needs a reading — call sites / paths / migration named. Unmeasurable from the PM seat ⇒ write it as a question for the dev, ⛔ never as a fence. The human-floor fence (decisions the maintainer owns) is exempt and needs no measurement. Carries the measured instance: a "would truncate data" fence over a path whose columns are all empty.
#11901标签纪律 — the write-back bullet正文/评论仅当含尖括号/HTML 注释才读回 — a read-back rule only; nothing stopped the PM from emitting the construct in the first place.New bullet, mechanical fix first: PM text written to GitHub never uses angle-bracket path placeholders — spell "后跟显式路径" in words. Records that backticks, fenced blocks and titles are all eaten, and that the damaged form reads as a complete command. Read-back demoted to backstop and narrowed to comments that must carry vulnerable fragments (orders and rulings, not routine markers).
#11936候选与批次 — the stale-premise checkTwo faces: 动作面 (actions) + 卡引用面 (card references). Completed work closed under another card number was invisible to both.Third face added — 工作项面: verify each work item against the tree (grep the named string, read the constant), ⛔ never against the card, because a comment re-read finds superseded rulings and not work already done elsewhere. Each work item enters the order as a premise the dev falsifies first, so the order carries its own stale-detector.
#11944派发词原则 — the dispatch-order conventionsThe order told the dev the card was claimed and not to touch the assignee; nothing required the dev's own claim comment, so both halves of the claim got suppressed together.New bullet: the order must require the dev's own claim comment — its own session ID + branch, in addition to the PM's, since the PM's identifies the PM session and not the one writing the code. "Don't touch the assignee" ⛔ narrowed to exactly that field; the one-line note that under a shared identity the comment is the load-bearing half is stated in the same bullet.
#11604 item 1座位 Routine — 开轮互斥读法Three readings; a session that does not use pm:dispatched is evidence-identical to an empty seat, and a stale seat post makes the pair a trap.Fourth reading: the lane's latest state=CLOSED card by updated_at, read its Claim: session ID. Immune to label conventions, one list + one read, and — like the third — it can only ADD self-retreat, never clear a seat.
#11604 item 3 + #11923 (SKILL.md half)收集 — the report-collection criterionThe marker was specified as the HTML comment only, so a sanitized report and a report that never arrived were indistinguishable.Both spellings count: the HTML comment and the plain-text first line os-dev-report. ⛔ An absent HTML-comment marker alone never reads as "report missing". The comment-first ordering (the card copy is the one that survives a mid-run death) is stated in the same paragraph.

Ceiling accounting — the ceiling was NOT raised

scripts/pm/check-skill-line-ratchet.mjs holds .claude/skills/pm-dispatch/SKILL.md at
1005 lines. The file was at that ceiling before this PR.

readingbeforeafter
lines1005 (headroom 0)999 (headroom 6)
bytes79,26081,320

⚠️Declared honestly, because the two readings point different ways. The six new rules
are ~2.1 KB of text. Payment came from two sources, and only the first is what the
ratchet's 2026-08-17 note calls payment:

  1. Word-level compression of the paragraphs the rules land in — redundant restatements
    removed, not rules: the duplicated "探的是「报告未达」不是「分支未出现」" clause, "有在飞
    即收紧" (already stated by the two intervals next to it), "基线之内的沉默不是证据"
    (already stated by "只有三类正当依据"), "这里是消费侧兜底", "Bug 优先只作用于队列卡",
    "(其真实解决路径)", "让任何座位可继承", the language clause in 决策箱勤务 (it repeats an
    invariant), and several parenthetical asides.
  2. Re-wrapping the touched paragraphs to the 120-byte budget. Those paragraphs were
    raggedly wrapped (~79 B/line against the 120 B budget), so re-flowing them recovered
    lines without removing content.

Source 2 is the one the ratchet note reserves for net-content-reducing PRs, so it is
flagged rather than buried. Mechanically constrained: the re-wrap tool refused to modify
any line present verbatim in origin/main, so no maintainer ruling quote was re-flowed
and no untouched paragraph was densified — the diff is confined to the six landing points
and their own paragraphs. If the reviewer wants the payment to be word-cuts only, the
remedy is a follow-up compression pass on this same file, not a ceiling change.

The ceiling constant itself is untouched (still 1005). It was deliberately not lowered
to 999: any sibling pack that lands in this file would then collide with a ratchet the same
round.

Gates

Run on the final commit 746c059, derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (change set taken
from the merge base by the script, not from a hand-written list). Verdict lines as the
gates printed them, exit codes captured before any pipe:

check:pm-skill-ratchet ✓ .claude/skills/pm-dispatch/SKILL.md is 999 lines (ceiling 1005; headroom 6).
check:skill-frame-sync ✓ 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness ✓ the decision frame in this tree is current with origin/main (fetched just now).
check:doc-authoring ✓ doc authoring guard: 389 files clean — no bare metadata literals.
check:pm-governed-prose ✓ 2 instruction surface(s) name all 5 registered governed surfaces … and claim no others.
check:pm-skill-id-lint ✓ 22 file(s) clean (pattern /#[0-9]{3,}/g).
check:nul-bytes OK (scanned 6704 text file(s); no raw ASCII control bytes).
check:agent-test-spelling ✓ 0 violations — 367 file(s) · 3683 bare `--` token(s) · 9 separator(s) JUDGED
check:pm-governed-merges self-test exit 0

Declared narrowing (one gate):pnpm --filter @objectstack/lint run check:doc-formula-expressions was not run locally — it imports typescript and this
worktree has no node_modules; the gate refuses loudly rather than answering. Its
population is formula expressions in docs and this diff adds no code fence of any kind. CI
runs it on this PR.

No changeset: .claude/** only, nothing published — skip-changeset applied.

Governed surface (.claude/**) ⇒ draft, human merge. Not marked ready, nothing armed.

Generated by Claude Code


Generated by Claude Code

…ndments
One file, six amendments, all from the skills-lane self-triage rulings on the
folded pack (hazard-claim readings, angle-bracket placeholders, work-item
staleness, the dev's own claim comment, the fourth mutex reading, and the
report-marker collection criterion).
The line ceiling was NOT raised: 1005 -> 999 lines (headroom 6). New rule text
is paid for by compressing existing prose in the paragraphs it lands in.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment