docs(pm): runbook step that pastes the decision frame into every dispatch prompt - #15057
Draft
os-steve wants to merge 1 commit into
Draft
docs(pm): runbook step that pastes the decision frame into every dispatch prompt#15057os-steve wants to merge 1 commit into
os-steve wants to merge 1 commit into
Conversation
…atch prompt The internal dispatch runbook constructed the dispatch prompt without ever naming the four-axis decision frame. After the batch-3 item-4 ruling (option B, 2026-09-03) the dev definition expects the frame to arrive in the prompt from the PM's own copy and stops and asks when it does not, so the runbook was an instruction surface promising a behaviour it no longer produced -- one round-trip per dispatch until the step is written down. Adds one bullet to the clause list of the dispatch-prompt construction section, beside the "two readings handed down at dispatch" clause it belongs with: the internal-pm frame section is taken fresh and pasted verbatim per card, from `.claude/skills/pm-dispatch/SKILL.md`, delimited by its two anchor sentences; never retyped; the brief records the copy's commit and md5; the os-dev definition stops and asks when the frame is missing. The frame text itself is NOT copied -- the bullet points at the existing copy by its anchors, so `check:skill-frame-sync` keeps watching exactly two copies. Line ratchet: 276 -> 280 of the 280 ceiling; no ceiling edit, no re-wrap, no cross-file move needed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
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 #14869
The internal dispatch runbook constructed the dispatch prompt without ever naming the four-axis decision frame. After the batch-3 item-4 ruling (option B, recorded 2026-09-03 on #14685, comment 5520452691) the frame keeps two copies, both PM-side, and the dev definition expects it to arrive in the prompt from the PM's own copy —
.claude/agents/os-dev.md:398-401, verbatim and untranslated:That clause is unchanged by this PR — it is quoted here only because the new bullet is the PM-side half it was waiting for. Until now the runbook was an instruction surface promising a behaviour it no longer produced: the failure is loud rather than silent, but it costs one round-trip per dispatch.
The change — one bullet, one file, +4 lines, nothing else
.claude/skills/pm-dispatch/references/dispatch-runbook.md, § 派发词构造细则, inserted into the clause list immediately after the 两份读数 clause (the other "what every brief carries at dispatch time" entry) and before 文件面两句原文:Conventions matched against the file it lands in: Chinese prose, English machine identifiers in backticks, ASCII
(/)/:/,/;(the file uses ASCII 115/115/96/158/101 times against 9/9/0/0/0 full-width), the ideographic、and。, the bare U+26D4 no-entry glyph with no variation selector (44 occurrences, 0 VS16), and the(维护者 2026-0x-xx 裁)date-citation form its neighbour at:246uses. No issue numbers —check:pm-skill-id-lintscans this directory with/#[0-9]{3,}/.Line widths, bytes: 109 · 100 · 119 · 110, all inside the file's 120-byte budget (its widest pre-existing line is exactly 120).
The frame text is NOT copied — the bullet points at it
Anchor measurement, re-taken on this branch rather than trusted from the brief:
.claude/skills/pm-dispatch/SKILL.md:868—每个方案必须沿四条固定评估轴分析,这是决策分析的核心原则,不是可选项:.claude/skills/pm-dispatch/SKILL.md:885—推荐意见必须基于这四条轴给出理由;四轴冲突时如实呈现权衡,grep -creturns 1 and 1sed -n 868,885p .claude/skills/pm-dispatch/SKILL.md | md5sum=b9a0de17880c39e412055e656a953222(matches the brief's number)Frame-sync reading — why quoting both anchors in full is safe here, and the caveat that comes with it. The anti-dormancy scan detects a copy by FINGERPRINTS (
/fixed axes/i,/固定评估轴/,/条评估轴/, and an EnglishN-axis frameshape) over the populationwalkMarkdownbuilds fromSCAN_ROOTS = ['.claude', 'skills']. That walk skipsSCAN_SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'references']), and this file lives in.claude/skills/pm-dispatch/references/— so the runbook is not in the scanned population at all and cannot read as a third copy. Recomputed independently before editing: 40 files, runbook absent; the gate's own pass line then reported the same 40. Neither anchor had to be truncated.That blind spot is larger than this PR and is not this PR's to fix — filed separately and unassigned as #15056 (32 of 72 hand-written markdown files under the two scan roots are invisible, including all 12 published skill reference pages). It is called out here because the two interact: this bullet's first anchor contains
四条固定评估轴, which would match FINGERPRINTS, so whoever narrows that skip set has to distinguish a deliberate anchor pointer from a copy in the same stroke.Line ratchet — paid from existing headroom, no ceiling edit
origin/maind5b330dc(git show origin/main:… | wc -l)cce4a1ebGate's own verdict line:
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/dispatch-runbook.md is 280 lines (ceiling 280; headroom 0).No ceiling was edited, no other bullet was re-wrapped, and no cross-file move was declared or needed — the four lines fit the headroom exactly.
Gates
Family list re-derived from the real change set after the commit, not from the brief:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no paths passed — the script takes the change set from the merge base itself), which reportedchange set derived from git — 1 path(s) vs merge base d5b330dc6andReconciliation — 12 famil(ies). Identical to the 12 the brief carried; nothing added, nothing dropped.All twelve run at head
cce4a1eb, working tree clean. Each exit code captured by redirect before any pipe; each row quotes the gate's own verdict line, never a bare$?.check:pm-skill-ratchet✓ check-skill-line-ratchet: … dispatch-runbook.md is 280 lines (ceiling 280; headroom 0).check:skill-frame-sync✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 filescheck:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).check:doc-authoring✓ doc authoring guard: 46 published skill files clean — no internal issue-id references.check:agent-test-spelling✓ check-agent-test-spelling: 0 violations — 432 file(s) · 5851 bare … token(s) …check:pm-governed-merges✓ check-governed-merges --self-test: 245 assertions …check:nul-bytescheck-nul-bytes: OK (scanned 8180 text file(s) … no raw ASCII control bytes).check:refd-timer-probeOK check-refd-timer-probe: 5832 source file(s) swept; …check:watch-hint-literal✓ check-watch-hint-literal: 48 declaration(s) across 4 rostered name(s) …check:doc-formula-expressions✓ check:doc-formula-expressions (field-level …): 14 predicate(s) … judged clean; 6 skipped as undeterminable.scripts/check-closing-keyword-parity.mjscheck-closing-keyword-parity: OK (3 parsers agree on all 9 keywords …).scripts/check-comment-mask-corpus.mjs✓ comment-mask corpus sweep …: 5837 files, 0 disagree, 0 unparseable …One honest note on the tenth row: its first run exited 3, and 3 is this gate's PREREQUISITE NOT MET code, in the gate's own words "Nothing was measured: this gate exited before running a single check, so this result says NOTHING about what it gates." It named two unbuilt workspace packages in turn (
@objectstack/formula, then@objectstack/lint); both were built and the gate re-run to the exit 0 above. The exit 3 is recorded as NOT MEASURED, never as a failure.Beyond the twelve:
grep -naPfor raw ASCII control bytes over the edited file returned no hits, and the diff is1 file changed, 4 insertions(+).Governed surface
.claude/**— opened as a draft, no ready flip, no auto-merge, no reviewers requested from this seat; the dispatching seat reviews in-seat and requests the approvers.skip-changesetapplies: nothing here publishes from any released package.Generated by Claude Code