Skip to content

docs(pm-dispatch): pm:retriage is a question for the triage seat, answered every fire - #15732

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-15404-retriage-is-a-question-for-triage
Sep 5, 2026
Merged

docs(pm-dispatch): pm:retriage is a question for the triage seat, answered every fire#15732
os-zhuang merged 1 commit into
mainfrom
claude/issue-15404-retriage-is-a-question-for-triage

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #15404

What changes

pm:retriage was documented as "awaiting a re-grade", yet four of the first five cards measured under it were asking the triage seat for something the label had no vocabulary for — a lane designation for a cross-domain PR, a re-route, a split, a disposition fork left by a dev report — so those cards were skipped by every dispatcher and actionable by no sweep. The card's own doctrine ranks a new label worst (a label exists only with a named reader) and the triage seat IS the named reader of pm:retriage, so the repair is the label's documented meaning and the triage sweep's answer set: no new label, no new state, no new query.

Three sites, each reworded in place, line-neutral (four physical lines; the state-machine section carries two):

site before (bytes) after (bytes)
.claude/skills/pm-dispatch/SKILL.md line 115 — the pm:retriage row of the label table (table row; pin 342) 121 232
.claude/skills/pm-dispatch/SKILL.md line 382 — the triage duty line 95 112
.claude/skills/pm-dispatch/references/state-machine.md line 40 — the applier line (挂标者) 112 115
.claude/skills/pm-dispatch/references/state-machine.md line 41 — the remover line (摘标者) 100 112

Before → after, verbatim:

  • SKILL.md 115: | pm:retriage | 等分诊改判:与现行 pm:* 并存、⛔ 不摘原标;带本标签的 pm:queue 卡跳过派发 || pm:retriage | 向分诊提问(改判、跨域 PR 指定车道、改路由、拆卡、裁 dev 报告留下的分叉),异议评论写明所求;与现行 pm:* 并存、⛔ 不摘原标;带本标签的 pm:queue 卡跳过派发 | (backticks inside the row omitted here for readability; the file keeps them)
  • SKILL.md 382: - pm:retriage 重判每 fire 高优先处理:按异议评论的证据与建议定级重裁。- pm:retriage 每 fire 先答异议评论所求,答后同笔摘标;须维护者答的进收件箱,标照摘。
  • state-machine.md 40: - 挂标者 = 提出异议的席位,挂标与异议评论(证据 + 建议定级)同笔;⛔ 裸挂标不合法。- 挂标者 = 提出异议的席位,挂标与异议评论(证据 + 所求的答案)同笔;⛔ 裸挂标不合法。
  • state-machine.md 41: - 摘标者 = 分诊 Routine,每 fire 高优先重判、重判后摘标;老化兜底归巡查 H18。- 摘标者 = 分诊 Routine,每 fire 先答异议评论所求、答后同笔摘标;老化兜底归巡查 H18。

The answer set (re-grade · lane designation for a cross-domain PR · re-route · split · fork ruling) is enumerated once, in the label-table row, where the 342-byte table-row pin has room for it. On the two 120-byte prose lines (SKILL.md 382, state-machine.md 40) the example list did not fit beside the rule — the 382 line with both the list and the maintainer clause measures 136 bytes — so, per the dispatch ruling, those lines keep the clause naming the answer sought and drop the example list, never the rule: 382 still carries first-every-fire, answer-then-remove-in-the-same-stroke, and the maintainer-needed answer going to the inbox with the label still removed. Every non-table line of both files is at or under 120 bytes (measured with LC_ALL=C awk); the widest table row of SKILL.md is unchanged at 342 (line 250, not this row).

No other line moved: git diff --stat reads 2 files changed, 4 insertions, 4 deletions; SKILL.md lines 29, 107, 226, 424 and the digest's two lines already carry this meaning (a pm:retriage card is never a dispatch candidate) and are untouched. Line 383 (retriage 维持或改判皆由分诊席同笔摘标;挂标归异议席) is outside the ruled sites and untouched; it is not contradicted by the new 382 (an answer of either kind still ends in the same-stroke removal).

Ratchet lines (verbatim, at d88cfa4)

✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md: widest table row is 342 bytes (pin 342; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 811 lines (ceiling 811; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/state-machine.md is 42 lines (ceiling 42; headroom 0).

Gate verdicts (all at git rev-parse --short HEAD = d88cfa4, exit codes captured before any pipe)

Derived family — node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (16 commands; --ran reconciliation: ✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.):

  • node scripts/check-closing-keyword-parity.mjs — exit 0 — check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 7601 tracked file(s), all registered).
  • node scripts/check-closing-keyword-parity.mjs --self-test — exit 0 — ✓ check-closing-keyword-parity --self-test: 24 assertions, 5 mutations of the shipped parsers each driven to red.
  • node scripts/check-comment-mask-corpus.mjs — exit 0 — ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 5974 files, 0 disagree, 0 unparseable, 75.1s
  • node scripts/pm/check-governed-queue-guard.mjs --self-test — exit 0 — ✓ check-governed-queue-guard self-test: 144 cases pass
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions — first run exit 3 PREREQUISITE NOT MET (@objectstack/formula then @objectstack/lint unbuilt; NOT MEASURED); after building both closures under the verify lock, exit 0 — ✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 428 files / 1370 TS blocks judged clean by @objectstack/formula.
  • pnpm check:agent-test-spelling — exit 0
  • pnpm check:doc-authoring — exit 0 — ✓ doc authoring guard: 46 published skill files clean — no internal issue-id references.
  • pnpm check:driver-memory-census — exit 0 — check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live
  • pnpm check:nul-bytes — exit 0 — check-nul-bytes: OK (scanned 7594 text file(s) -- 7594 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).
  • pnpm check:pm-governed-merges — exit 0 — ✓ check-governed-merges --self-test: 274 assertions / live: the real generator declared 9 output(s) and certified this tree
  • pnpm check:pm-governed-prose — exit 0 — ✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces (docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md) and claim no others.
  • pnpm check:pm-skill-id-lint — exit 0 — ✓ check-skill-id-lint: 24 file(s) clean (pattern /#[0-9]{3,}/g).
  • pnpm check:pm-skill-ratchet — exit 0 — the three lines quoted above
  • pnpm check:refd-timer-probe — exit 0 — OK check-refd-timer-probe: 5969 source file(s) swept
  • pnpm check:skill-frame-sync — exit 0 — ✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 files / 73 markdown files scanned for undeclared copies.
  • pnpm check:watch-hint-literal — exit 0 — ✓ check-watch-hint-literal: 60 declaration(s) across 4 rostered name(s)

Beyond the derived family:

  • node scripts/pm/check-governed-merges.mjs --test .claude/skills/pm-dispatch/SKILL.md .claude/skills/pm-dispatch/references/state-machine.md — exit 3 (expected) — governed-surface predicate: 2 of 2 path(s) hit the register (5 surfaces, repo-agnostic). / ⛔ GOVERNED — a human merge is the review record for this PR
  • pnpm check:pm-half-states — exit 0 — ✓ check-half-states self-test: 2223 cases pass. (this gate reads pm:retriage as a label spelling only; no sentence of the two edited files is pinned there)
  • pnpm lint (full tree, through scripts/pm/os-verify-lock.sh, sharing one hold with the formula build) — os-verify-lock: VERDICT command-exit 0 · held the lock 300s (5m00s) · waited 0s; eslint printed no findings. Note the two edited files are outside eslint's population anyway (eslint --print-config on SKILL.md answers undefined).

Governed

Both paths are on the .claude/** governed surface: draft PR, human merge only. Nothing here flips it ready, enqueues it, arms auto-merge, or approves. skip-changeset: nothing publishes from any package.

Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox

Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox


Generated by Claude Code

…wered every fire

The label's documented meaning was "awaiting a re-grade", yet four of the first
five cards measured under it were asking triage for something else — a lane
designation for a cross-domain PR, a re-route, a split, a disposition fork left
by a dev report — so they were skipped by every dispatcher and actionable by no
sweep. No new label, no new state: the label's row in the table, the triage duty
line, and the state-machine's applier/remover lines are reworded in place so the
label means "a question for the triage seat", the disagreement comment states the
answer sought, and triage answers it first every fire and removes the label in the
same stroke (an answer that needs the maintainer goes to the inbox, label still
removed). Line-neutral: 811 of 811 and 42 of 42; no other line moved.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox

os-steve commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

ACCEPT — contract-tier in-seat review of PR #15732, head d88cfa48b (skills seat, 2026-09-05T05:2xZ).

Implemented-by: claude/issue-15404-retriage-is-a-question-for-triage (os-dev subagent)
Reviewed-by: session_019RfFHiRCSs3JXLK4cwcfox (skills seat)

Verified in a detached compare worktree at the PR head against merge-base a5cef3769, not from the report: two files, +4 / −4, the three ruled sites and nothing else. SKILL.md line 115 (the pm:retriage label row) now says the label is a question for the triage seat, enumerates the five shapes the card measured (a re-grade, a lane designation for a cross-domain PR, a re-route, a split, a disposition fork a dev report left open), requires the objection comment to state what is sought, and keeps the coexistence, never-strip and skip-dispatch clauses — 232 bytes under the 342-byte pin. Line 382 (the triage duty line) says triage answers what the comment asks first every fire and removes the label in the same stroke, and an answer that needs the maintainer goes to the inbox with the label still removed — 112 bytes. state-machine.md lines 40–41 carry the same two facts on the applier and the remover — 115 and 112 bytes. Line-neutral: 811 / 811 and 42 / 42; no other line moved; the widest table row is still line 250 at 342 bytes. No issue number in any changed line; no model name in the diff (the commit's ruled trailer aside) or in the PR body; no new label, state or query. Governed on both paths (check-governed-merges --test exit 3).

Seat gate runs on this head in the compare worktree: skill-line-ratchet exit 0 (both ceilings at headroom 0, as ruled), skill-id-lint 24 files clean, half-states self-test 2223 cases, token ratchet exit 0, tier read MANDATORY from the SKILL.md path. The frame-sync gate could not resolve its module there (no installed tree) and is recorded as NOT MEASURED locally; the evidence is the dev's run (two copies structurally isomorphic, 73 markdown files scanned for undeclared copies) and CI on d88cfa48b: 29 check runs, 17 success, 12 skipped, none failing, Lint & Repo Gates among the successes; the dev's derived family reconciled 16 of 16 with the formula and lint packages built under the lock.

The open question — line 383 still speaks in re-grade vocabulary — is ruled A: the ruling fixed the edit set at three sites, the line stays consistent with the new 382 (every answer ends in the same-stroke removal), and it is a candidate for the next density pass, not a second governed flight. The out-of-scope finding (H18's JSDoc citation and finding sentence, and the pm:retriage description in ensure-pm-labels.sh and on the five repos, all still re-grade vocabulary) is filed by the seat as #15744, pm:blocked behind #15702 on the same file, pure code.

Landing regime: governed surface ⇒ this PR stays a draft; reviewers os-zhuang and hotlong requested by the seat at 05:24Z; the human merge is the review record; no seat flips it ready, enqueues it, or arms auto-merge. Fixes #15404 closes the card on merge.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 5, 2026 06:10
@os-zhuang
os-zhuang enabled auto-merge September 5, 2026 06:10
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 5, 2026
Merged via the queue into main with commit d21ddbb Sep 5, 2026
31 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-15404-retriage-is-a-question-for-triage branch September 5, 2026 06:36
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/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants