Skip to content

docs(pm-dispatch): dispatch token economics — sonnet tier for S-class cards, scoped local gates, slimmed prompts (#6863) - #6871

Draft
os-project-manager wants to merge 1 commit into
mainfrom
claude/issue-6863-dispatch-token-economics
Draft

docs(pm-dispatch): dispatch token economics — sonnet tier for S-class cards, scoped local gates, slimmed prompts (#6863)#6871
os-project-manager wants to merge 1 commit into
mainfrom
claude/issue-6863-dispatch-token-economics

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #6863

Three coupled changes to the dispatch machinery, all in .claude/. Nothing ships to
users; this PR releases nothing and writes no changeset.

Maintainer authorization

Per the Guardrails exception for .claude/ internal tooling PRs (#5925-6, precedents
#5597 / #5872 / #6650), the authorization is quoted here verbatim and untranslated.
Maintainer, in-session, 2026-08-09:

全部同意,先开任务

Approving the domain:spec seat's token-economics assessment (session
session_011sGk4SKHqGRgmmqUok1P8M). Review stays with another seat or a maintainer
walkthrough — this PR is a draft, auto-merge is not armed, and the seat that
implemented it will not merge it.

Item 1 — model tiering, and the precedence finding the card asked for

The finding first, because the card flagged it as the one thing that could make item 1
inert: it does not. The per-dispatch argument wins.

Claude Code resolves a subagent's model in four steps, verified 2026-08-09 against the
subagent documentation rather than inferred from the repo's own prose:

  1. the CLAUDE_CODE_SUBAGENT_MODEL environment variable, when set
  2. the per-invocation model parameter on the Agent call
  3. the agent definition's model: frontmatter
  4. the main conversation's model

So .claude/agents/os-dev.md's frontmatter model: opus (#6688, guarded by #6836's
check:agent-model-declared) does not defeat a dispatch that passes
model: "sonnet" — step 2 outranks step 3. The pin governs only the case where the
dispatcher passes nothing, which is exactly the #6686 incident it was written for. Item 1
takes effect as written.

Two adjacent traps are recorded next to it, because both are silent:

  • CLAUDE_CODE_SUBAGENT_MODEL outranks both the argument and the frontmatter. It is
    not set in the dispatch container (checked 2026-08-09), but if it ever is, it
    overrides every tier decision the PM makes and nothing in this repo would show it.
  • A tier blocked by the org's availableModels allowlist does not fall back to the
    frontmatter pin — it falls back to the inherited model, i.e. straight back into the
    silent-inheritance failure the pin exists to stop.

On the contradiction the card named. The old rule existed in two places: step 5's
「Model split (maintainer policy): pass model: "opus" on every dev dispatch」 and the
08-08 handover's 「所有派发至少 opus」. The second is a handover note, not a file — grep
finds no copy of it in the tree — so only the first was editable. Rather than quietly
swapping the sentence, the new §5 names the old wording, quotes it, and declares it
废止
, and instructs the reader to override any 「一律/至少 opus」 they meet elsewhere
(old handover notes, seat stickers, second-hand retellings). A reader cannot come away
holding both.

Tiering itself: S-class mechanical cards go to sonnet, where the criterion is "the
gate farm decides correctness mechanically", not "the diff is small"; M/L, ruling
implementations, multi-face semantic cards and anything with design judgment stay on
opus; ties round up. model is passed explicitly on every dispatch rather than
leaning on the pin, so the tier is a property of the dispatch and not of a file's current
state. The claim comment's container-assessment line now carries the tier beside the
size, since both come from one reading — with an explicit warning that "S-class" does not
imply sonnet on its own.

Item 2 — local gate scoping, with the safety half kept mandatory

os-dev.md gains a Local verification scope section: build closure, the affected
packages' suites, and the gate families touching the card's surface — instead of
enumerating all 55+ check:* steps out of lint.yml. The dispatch template now names
the relevant families per card.

The card accepts an occasional extra push-fix lap as the cost, so the rule states that
cost and then pins the half that makes it safe. Written into os-dev.md verbatim:

This is not licence to report before CI converges — it is the opposite: the local farm
was the thing that could be dropped precisely because the CI wait cannot be.

And reconciled on the PM side at step 7: the CI-convergence check moves from "the second
of two safety nets" to the only one, so a non-obvious gate reddening in CI is now the
expected shape rather than an anomaly, the extra lap is a price already paid rather
than grounds for REWORK, and "local green" in a report covers a smaller surface than it
used to. Kept intact per the card: build-first, prefix-direction consumer sweep, reverse
verification, and CI convergence before reporting.

Item 3 — slimmed prompts, boilerplate sunk to the producer

  • The template no longer pastes the issue body. It instructs the dev to read the full
    body and all comments on GitHub, which premise-first already forced. It still
    pastes what GitHub reading cannot supply: ruling quotes verbatim (Chinese
    untranslated), the 裁决 / PM-机制假设 partition, card-specific clauses and same-day
    churn.
  • Mitigation for the notes-12 truncation risk is written as the price of the risk
    transfer
    , not a courtesy: pasting made truncation the PM's risk, self-reading makes
    it the dev's, so the prompt requires a completeness self-check and a double-read on
    suspicion. Precedent [移交自 objectui] ComponentPropsMap 未声明 objectui 渲染器实读的 5 个顶层 prop(page:header ×3 / page:tabs.tabStyle / page:accordion.variant)—— #5775 的清点未完 #6776 is cited.
  • The unconditional non-negotiables move into .claude/agents/os-dev.md once
    (producer-side fix, the PD#12 instinct the SKILL itself cites): build-first ordering,
    filter direction, cross-package reverse verification, the authorable-surface anchor
    rules with the gen:schema MERGE-state ban, and the Fixes vs Part of judgment.
    Worktree discipline, ADR-0112 rejection assertions, foreground posture, English policy
    and the report contract were already there and were not duplicated.
  • Conditional standard clauses — the ones carrying 适用判据 (multi-face shared
    conformance coverage, rejection-case code+status, the filter compile-face
    inventory) — deliberately stay in the SKILL and are still pasted per card. They are not
    universal, so sinking them would attach them to cards they do not apply to.
  • os-dev.md says plainly that a prompt's silence about a standard clause is the
    expected shape and never permission.

Overlap with PR #6799

#6799 is mergedcd704cc43, 2026-08-09T01:50:17Z — so the card's premise that it
is open and being held for a human merge had already expired by dispatch time. I branched
from origin/main with #6799 in it rather than composing around it.

Region overlap: none. Hunk ranges do not intersect at any point:

regions touched
#6799 1820-1855, 1846-1875, 1927-1957, 2090-2099, 2101-2131, 2539-2568
this PR 1302-1310, 1368-1394, 1395-1441, 1453-1459, 1685-1693, 1999-2005

Verified by content, not by line arithmetic: every line #6799 added is still present
verbatim in the file, checked by replaying its added lines through grep -qF
(zero missing). All four of its additions are untouched — the ADR merge prohibition in
Guardrails, the step-7 ACCEPT path fork, probe-and-revive as the standing backstop, and
the replay-wake identity check. My nearest edit (the step-7 CI-convergence bullet, in the
review checklist) sits above the ACCEPT verdict section where #6799's fork lives.

Deliberately NOT done

  • ⛔ No docs/adr/**, no content/docs/releases/, no code, no AGENTS.md.
  • The card's "Already in effect (seat practice)" list is explicitly marked
    "no file change needed" — batched seat-post refreshes, terse ACCEPT comments,
    thread-tail race re-reads, sweep-first S-card batching. Not written.
  • Kept untouched per the card, each carrying incident receipts: claim protocol, race
    checks, premise-first verification, write-after-read, serial landing relay, and the
    45-minute patrol cadence. The claim comment gained one line and lost nothing; the
    「最后一行」 back-reference that the [skill] pm-dispatch:services 车道 08-05/06 班次交接沉淀的 10 条 SKILL 更新建议(28 PR / 两次 CI 红 / 三次前提证伪) #5885 serial-constraints sentence depends on was
    preserved by inserting the new line above it, not below.
  • scripts/check-agent-model-declared.mjs's header describes the resolution as "three
    steps" and omits CLAUDE_CODE_SUBAGENT_MODEL. Accurate in effect today (the variable
    is unset) and outside this card's declared file surface, so it was not edited — filed
    separately as an observation.

Verification

No package code changed, so pnpm test / pnpm typecheck are not meaningful here —
saying so beats manufacturing template-shaped evidence. What was run, serialized under
the shared verification lock with the capped heap, is every gate whose scan surface
includes .claude/ (found by grepping scripts/*.mjs for the path rather than from
memory), plus the repo-wide prose and changeset gates. 8 gates, all green, each with
EXIT=0:

  • check:agent-model-declared — 18 self-test cases pass; os-dev.md → opus, 0 justified inherits
  • check:skill-frame-sync — 12 self-test cases; 4 copies isomorphic across 3 files, 3 axes, 42 files scanned
  • check:skill-frame-freshness — 12 self-test cases; frame current with origin/main
  • check:skill-compatibility — 18 self-test cases; 11 SKILL.md reconciled against 77 packages
  • check:nul-bytes — 56 assertions; 6403 tracked text files, no raw ASCII control bytes
  • check:doc-authoring — 373 files clean
  • check:role-word — 44 baselined files, no new occurrences
  • check:empty-changeset — no empty-frontmatter changeset introduced

Byte discipline: a manual control-byte self-scan beyond the gate's surface
(grep -naP over the two edited files, the full 0x00-0x1f plus 0x7f range) returned
no matches. This PR is dogfooding its own item 2 — the gates above are the families
touching its surface, not the whole farm.


Generated by Claude Code

… cards, scoped local gates, slimmed prompts (#6863)

Three coupled changes to the dispatch machinery, maintainer-approved
2026-08-09 (「全部同意,先开任务」).

1. Model tiering. Step 5's absolute "pass model: opus on every dev dispatch"
   is replaced by a tiered policy: S-class mechanical cards dispatch on
   sonnet, everything with design judgment stays on opus. The old absolute is
   named and retired in place so a reader cannot come away with both. The
   claim comment's container-assessment line now carries the tier too.

2. Local gate scoping. The "enumerate every check:* from lint.yml and run all
   55+ locally" rule is replaced by build closure + affected-package suites +
   the gate families touching the card's surface. The CI-convergence wait is
   restated as the load-bearing safety half, in os-dev.md and again in the PM's
   step-7 reconciliation.

3. Slimmed dispatch prompts. The template no longer pastes the issue body; the
   dev reads it on GitHub and must verify completeness (notes-12 truncation
   risk moves with the read). The unconditional non-negotiables sink into
   .claude/agents/os-dev.md once; prompts carry only deltas. Conditional
   standard clauses (those with 适用判据) stay in the SKILL, pasted per card.

Every line PR #6799 added is present verbatim; zero hunk overlap.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn
@vercel

vercel Bot commented Aug 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 9, 2026 2:06am

Request Review

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 size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants