Skip to content

skills(pm-dispatch): needs:contract-review rides a reviewable increment — the carrier discipline restated where triage reads it - #16698

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-16625-carrier-discipline-triage
Sep 8, 2026
Merged

skills(pm-dispatch): needs:contract-review rides a reviewable increment — the carrier discipline restated where triage reads it#16698
os-zhuang merged 2 commits into
mainfrom
claude/issue-16625-carrier-discipline-triage

Conversation

@os-musk

@os-musk os-musk commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Fixes #16625

needs:contract-review was being hung at triage time as a routing state — on cards with no
pm:* state and no claim — so eleven cards sat in no queue at all (not dispatchable, not
decidable, not blocked), and of twenty open card-side carriers eleven had nothing to review. The
carrier discipline already forbids that: the label rides a reviewable increment and is never
pre-hung. The convention was inherited from neighbouring triage comments instead of from the rule
it claimed to implement, so this PR writes the rule where triage actually reads.

The ruling this PR executes

Director seat, summon #17, decision batch #3 (comment 5572349104); maintainer's reply, verbatim
and untranslated: 「同意」. The ruling, quoted verbatim:

Ruled. needs:contract-review is hung only with a reviewable increment — a draft PR, or the
card in the same stroke as a Clause-②: yes claim — and a triage verdict records the clause-②
direction in prose and gives the card one of the six states. The text already says so; it is
restated where triage reads it: one sentence in
.claude/skills/pm-dispatch/references/lanes/triage.md and one in SKILL.md's triage sweep
section, fold-paid, line count unchanged. Option B (a seventh "needs tier before dispatch"
parking state) is refused: the tier gate belongs at the review, where the compensating control
lives, not at dispatch. The sixteen carriers triage answered under the text as it stands
(5571816579) stand as written; nothing else waits on this card.

Execution, domain:skills lane: one XS draft PR, governed (.claude/**) ⇒ the terminal
four-step — draft, needs-user-decision, 「维护者速读」, review request — and the maintainer's
own merge. Clause-②: no; skip-changeset (nothing publishes).

Option B is not implemented here in any form: no state was added, no label was written on any
card, and the sixteen carriers triage already answered were not touched.

The two sentences added

Each is worded in its own file's register, and each is self-sufficient — a reader landing on one
never has to fetch the other.

.claude/skills/pm-dispatch/references/lanes/triage.md, appended as the fourth rule bullet —
115 bytes:

- ⛔ 分诊不挂 `needs:contract-review`:随 draft PR 或 `Clause-②: yes` 认领;写方向、给六态之一。

The charter names its seat in its other bullets (「分诊每 fire 只取一个仓…」), so this one names it
too and lets 分诊 carry as the subject through the second half.

.claude/skills/pm-dispatch/SKILL.md, inserted in the 分诊座位职责 section immediately after
L339 「分类动作每张三选一,外加一个修复通道。」 — 115 bytes:

- ⛔ 不挂 `needs:contract-review`:随 draft PR 或 `Clause-②: yes` 认领;裁定写方向、给六态之一。

The section supplies the seat, so this one drops the subject the way its neighbours do
(L378 「⛔ 写入前对每张卡现读当前状态…」) and spends the bytes on 裁定 instead — naming the act
that owes the direction and the state.

Both widths measured, not estimated: printf '%s' LINE | wc -c = 115 for each, against the
ratchet's 120-byte per-line cap. Placement is the verdict block, not the sweep enumeration
(L323–338), because what the ruling constrains is what a triage verdict does: the line sits
directly under the head of the three-way classification rule it qualifies.

The two folds

Fold 1 — triage.md, and the mechanism the dispatch proposed does not exist.

The dispatch named two ways to pay inside the seven lines: extend an existing line, or merge two
of the three rule bullets into one. Both were measured first and both fail, so a third
mechanism was used and is declared here rather than taken silently.

mechanism measurement verdict
extend an existing line the four content lines on origin/main are 119 / 113 / 110 / 101 bytes, so the whole file's headroom under the 120-byte cap is 37 bytes spread across four lines, and the largest single-line headroom is 19. The sentence is 115. impossible
merge two of the three rule bullets the three carry 324 bytes of content (113 + 110 + 101) over a 120-byte cap; any two of them sum to 179–223 bytes. git grep for each bullet's distinctive terms (轮替, 饥饿, 最旧优先, 第二分诊席, fire 频率) over the whole pm-dispatch corpus returns zero hits outside this file, so nothing in them is restated anywhere and no clause can be dropped to make a merge fit. impossible without losing a clause
used instead: spend the blank separator between the H1 and the pointer paragraph an ATX heading is a leaf block, so the paragraph following it needs no blank line. Proved rather than asserted: rendering the file before and after with micromark 4.0.2 (this repo's own installed CommonMark implementation), with the new rule stripped so the comparison isolates the blank-line removal, the two HTML outputs compare identical. The h1 / p / ul structure is unchanged; the only rendered difference in the full file is the added li. lossless — 7/7, and every existing byte of prose untouched

The ratchet ceiling was not raised, and no clause left the file. The whole diff on this file is
one deleted blank line and one added rule.

Fold 2 — SKILL.md, one restating line deleted, quoted byte-verbatim from origin/main:555:

- 条件性标准条款命中判据才抄:多实现面 ⇒ 共享一致性覆盖。
clause survives on origin/main at
「条件性标准条款命中判据才抄」 .claude/skills/pm-dispatch/references/dispatch-runbook.md:226 — 「条件性标准条款命中判据才抄,⛔ 不命中就省掉别硬套。」 — the same clause verbatim, plus what to do when the trigger does not fire
「多实现面 ⇒ 共享一致性覆盖」 .claude/skills/pm-dispatch/references/dispatch-runbook.md:227–228 — 「多实现面组件(同一契约 ≥2 个实现面)⇒ 测试放在未来的分叉会被抓住的地方。」 / 「即进共享一致性覆盖,不是独立测试文件。」 — the same rule with the definition of 多实现面 and the negative half the deleted line lacked

Two properties the dispatch required of a fold candidate, both checked rather than assumed:

  • Not mirrored in references/core-rules.md. A similarity scan of every SKILL.md bullet
    against the whole corpus, scoring each line's best twin outside core-rules.md against its best
    match inside it, puts this line at twin 0.43 / core-rules 0.05 — git grep for 条件性 and
    多实现面 over core-rules.md exits 1. The two stronger twins found (SKILL.md:586, whose
    twin sits at core-rules.md:120, and SKILL.md:600, which shares a clause with
    core-rules.md:122) were rejected on exactly this rule.
  • The section already delegates to the surviving copy. The deleted line's own neighbour,
    SKILL.md:554, ends 「原文见 runbook」, and SKILL.md:564 points at
    references/dispatch-runbook.md by name. Deleting it leaves L554 and L556 — two rules of the
    same class, about what a dispatch word must copy from the runbook — reading continuously.

Twins whose survival lives in .claude/agents/os-dev.md (SKILL.md:346–350) were also rejected:
that file is the dev's copy and SKILL.md is the PM's, so deleting one leaves its reader
without the rule. Survival has to be reachable by the same reader.

No untouched line was re-wrapped. The diff is exactly +2 / -2 across both files, and the
widest line in SKILL.md is unchanged (its widest table row is still 342 bytes, pin 342).

The five dispatched premises, each measured against the tree

# premise reading verdict
1 lanes/triage.md is 7 lines on origin/main, ratchet row ['.claude/skills/pm-dispatch/references/lanes/triage.md', 7] with widest-row pin 0, last touch 4a85d978f, and it contains no needs:contract-review and no Clause-② git show origin/main:PATH | wc -l = 7; ratchet map L798 = 7 and L1160 = 0; git log origin/main -1 --format=%h -- PATH = 4a85d978f2; grep -cE 'needs:contract-review|Clause-②' over that blob = 0 holds
2 the sentence must be paid inside those 7 lines, by extending a line or merging two of the three rule bullets measured in the Fold 1 table above: 37 bytes of total headroom, largest single-line headroom 19, against a 115-byte sentence; and 324 bytes of unique, nowhere-restated content across the three bullets FELL — both named mechanisms are arithmetically impossible. The ruling's own constraint (fold-paid, line count unchanged, no clause lost) is satisfied by a third mechanism, declared above and proved render-neutral. The ceiling was not raised
3 SKILL.md is 811/811 (widest-row pin 342); 分诊座位职责 runs L307–417 with the Backlog-sweep line at L323; the carrier rule already lives at L647–649 and in references/contract-review.md 〈载体纪律〉; the decision-frame block L734–752 has md5 22f2339f0acb64cdb50c7adc9db681c3 all re-read: 811 lines, ratchet rows L295 = 811 and L1137 = 342; L307 is ## 分诊座位职责 and L323 is 「Backlog sweep 是常设职责,每 fire 扫任一析取命中的卡。」; L647–649 carry 「…由 PR 创建者随可复审契约增量同笔挂…」 / 「Clause-②: yes 认领同笔在卡上挂标…」 / 「挂标后复核完成前短暂停靠;⛔ 不前瞻预挂。」; sed -n '734,752p' | md5sum = 22f2339f0acb64cdb50c7adc9db681c3 before the edit and unchanged after holds — the new lines point at that rule from where triage reads; they do not duplicate it, and the frame block is byte-identical
4 no label write on any card; references/core-rules.md, references/contract-review.md, .claude/agents/os-dev.md, AGENTS.md and content/docs/releases/** untouched git diff --name-only origin/main...HEAD lists exactly the two intended paths and nothing else; zero label writes were issued by this session on any card in either repo holds
5 SKILL.md's last touch is 4fe00b80e; no open PR names either file; take a merge-tree reading before opening the PR git log origin/main -1 --format=%h -- SKILL.md = 4fe00b80e7, as dispatched. main had already advanced past the dispatch tip when work started (4fe00b80e0f07b2c86) and advanced again during the run (→ 7797102139), so the open-PR check was re-run against the current set: all 16 open PRs fetched by refs/pull/N/head, and for each the blob at both paths compared to origin/main. Every triage.md blob is identical to origin/main. Ten SKILL.md blobs differ, and each differing value was resolved to a historical origin/main blob — fc5032c4 = 4fe00b80e^, 4a8302c7 = 905a1d2f5, 7d2c8d56 = 4a85d978f — i.e. an unmodified older copy carried by a stale base, not a modification. git diff --name-only MERGE_BASE origin/main -- .claude/skills/pm-dispatch/ is empty: main never touched either file holds, re-derived rather than inherited

Gates — derived, never hand-listed

Derived at final HEAD f305c7c9e5 with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack. The first
derivation, taken before merging main, printed a STALE TREE refusal — 15 commits behind, 14
of the files the families are derived from changed in that range — so origin/main was merged
(clean, zero conflicts) and the list was derived again from the merged tree. The second run's own
header:

dispatch-gates: gate list derived from the tree of 'objectstack-ai/objectstack' at commit f305c7c9e5
  --repo 'objectstack-ai/objectstack' checked against this checkout's 'origin' remote — it holds.
dispatch-gates: change set derived from git — 2 path(s) vs merge base 779710213 of 'origin/main' and HEAD
  · .claude/skills/pm-dispatch/SKILL.md
  · .claude/skills/pm-dispatch/references/lanes/triage.md

Every command ran with its exit captured to a file before any pipe (cmd > FILE 2>&1; ex=$?).

exit command
0 node scripts/check-closing-keyword-parity.mjs
0 node scripts/check-closing-keyword-parity.mjs --self-test
0 node scripts/check-comment-mask-corpus.mjs
0 node scripts/pm/check-governed-queue-guard.mjs --self-test
0 pnpm --filter @objectstack/lint run check:doc-formula-expressions (first run exited 3 = PREREQUISITE NOT MET, which is not a measurement; prerequisites built under the lock, then re-run)
0 pnpm check:agent-test-spelling
0 pnpm check:doc-authoring
0 pnpm check:driver-memory-census
0 pnpm check:nul-bytes
0 pnpm check:pm-governed-merges
0 pnpm check:pm-governed-prose
0 pnpm check:pm-skill-id-lint
0 pnpm check:pm-skill-ratchet
0 pnpm check:refd-timer-probe
0 pnpm check:skill-frame-sync
0 pnpm check:watch-hint-literal
3 node scripts/pm/check-governed-merges.mjs --test on both paths — expected: 3 = GOVERNED

Reconciliation, quoted from the tool's own verdict line:

Run reconciliation — 16 derived, 16 run, 0 NOT-MEASURED, 0 UNRUN.
✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.

Gate verdict lines that judge this diff, quoted as each gate printed them:

✓ 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/SKILL.md: widest table row is 342 bytes (pin 342; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/lanes/triage.md is 7 lines (ceiling 7; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/lanes/triage.md: widest table row is 0 bytes (pin 0; headroom 0).
✓ check-skill-id-lint: 26 file(s) clean (pattern /#[0-9]{3,}/g).
✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 files
  4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline
✓ 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.
check-nul-bytes: OK (scanned 8234 text file(s) -- 8234 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

check-governed-merges --test, exit 3:

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 (#9495 regime).
      .claude/** ×2 — the agent instruction tree (skills, agents, hooks, settings)
        - .claude/skills/pm-dispatch/SKILL.md
        - .claude/skills/pm-dispatch/references/lanes/triage.md

The prerequisite build ran through the shared lock (OS_VERIFY_LOCK_SLOT=issue-16625), which
printed: os-verify-lock: VERDICT command-exit 0 · held the lock 166s (2m46s) · waited 0s.

No changeset: this diff publishes nothing from any released package, so skip-changeset is the
correct disposition and is applied as a label. dispatch-gates names 13 further families that
「apply once this card's changeset exists」 — they stay out of scope for exactly that reason.

pnpm lint — a measured narrowing, with all three evidences

pnpm lint is eslint . --no-inline-config over the whole repo, a CI-owned run. It was narrowed
to the changed files, and the narrowing is a measurement, not a skip:

  1. Population read from eslint's own config, not guessed. Every files: selector in
    eslint.config.mjs is a JS/TS extension glob — L971 **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs},
    L1015, L1054, L1103, L1172, L1212 **/*.{ts,tsx,mts,cts}, plus COMMENT_SWALLOW_FILES at L785
    (['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}']). A grep for markdown|processor|**/*.md over the
    config exits 1: no markdown plugin, no processor, no .md selector exists.
  2. File count read from --format json. pnpm exec eslint on both changed paths with
    --no-inline-config --format json returned 2 results, 0 errors, 2 warnings, and each
    warning is eslint's own "File ignored because no matching configuration was supplied."
    0 linted files in this diff, stated by the instrument rather than inferred.
  3. Invariance over untouched files. Type-aware linting is not enabled anywhere: every config
    block's parserOptions is { ecmaVersion: 'latest', sourceType: 'module' }, and a grep for
    parserOptions.project|projectService|project: returns exactly one hit — L328, inside the
    config's own comment saying so: 「this repo runs one eslint.config.mjs, which never enables
    type-aware linting (no parserOptions.project, no typed @typescript-eslint rules) for ANY
    file, test or not」. With no cross-file type program, a markdown-only diff cannot move any
    verdict on any untouched file.

Merge-tree reading

Taken immediately before this PR was opened, at final HEAD f305c7c9e5:

git fetch origin main && git merge-tree --write-tree --name-only origin/main HEAD
  exit:             0
  tree:             1685828cdebebfc3b99d7863aa874f44056ca0fe
  conflicted paths: none (exit 0, tree oid only)
  origin/main:      7797102139

origin/main is also this branch's merge base — main was merged into the branch during the run
after the stale-tree refusal — so the reading is a clean fast-forward with no conflicted path.

验收备注

  • noted, not filed: the dispatch's two proposed fold mechanisms for triage.md are both
    arithmetically impossible against the file as it stands; the measurements are in the Fold 1
    table. This is a fact about the dispatch word, not a defect in the tree, so no card. It is
    surfaced here because the seat reviewing this PR is the one that wrote those mechanisms.
    承接者: the PM seat, at this PR's ACCEPT.
  • noted, not filed: triage.md is now the only lane charter whose H1 is not followed by a
    blank line. A future author who "tidies" that blank line back in pushes the file to 8 lines and
    reds check:pm-skill-ratchet — the failure is loud and immediate, not silent, so no guard is
    owed. 承接者: scripts/pm/check-skill-line-ratchet.mjs, mechanically.
  • noted, not filed: the corpus carries other near-duplicate pairs of the same shape as the
    line folded here — SKILL.md:600 against references/review-checklist.md:40 is the closest
    (they share every clause), and SKILL.md:349–350 against .claude/agents/os-dev.md:45–46 are
    near-verbatim across the PM/dev split. Neither is a defect and neither was touched; they are
    headroom for a future compression round, not work. 承接者:无.
  • noted, not filed: mcp__github__list_issues under-returning a single-label enumeration is
    recorded on this card's own thread (comment 5571816579) as a bound, not a total. Nothing in this
    PR depends on that reading. 承接者:无 — it is already stated where it was measured.

维护者速读(草稿)

改了什么

两个文件各加一句规则,各自用一次折叠付账,行数一动不动:references/lanes/triage.md 7/7,
SKILL.md 811/811,棘轮 headroom 都是 0。新规则说的是同一件事:needs:contract-review
这个标签只跟着能审的东西走 —— 一个 draft PR,或者认领时同笔写下的 Clause-②: yes;
分诊席自己不挂它,分诊的裁定要做的是把条款②的方向写进散文,并且把卡放进六个状态之一。
两句各 115 字节,都在棘轮的每行 120 字节上限之内。付账方式:SKILL.md 删掉一句纯重复的规则
(它的每个子句在 references/dispatch-runbook.md 里都活着,而且说得更全,上面逐条给了行号);
triage.md 花掉的是标题和指路段之间的那个空行 —— Markdown 的标题本来就不需要后面跟空行,
我用本仓自己装的 CommonMark 实现渲染前后对比过,渲染结果逐字节相同。

为什么改

不是补功能,是止住一个已经发生的损失。今天实测:十一张卡因为这个惯例卡在没有任何队列里 ——
不可派、不可裁、不阻塞 —— 其中一张是 p2 缺陷卡,后果是托管租户上传附件 404。规则本来就写着
「⛔ 不前瞻预挂」,只是没写在分诊席读的那份文件里,于是它被下一个分诊席从邻座的评论里
「继承」了八次。分诊席已经按现行文本把十六张卡全部放回队列/决策箱了,所以这张卡剩下的
只有文本这一半。第七个停车态(选项 B)按裁定不做:档位这道门按契约在复核,不在派发

风险与代价(含回滚)

代价:两行规则,两行折叠,零新文件,零 CI 成本,棘轮上限一格没抬。风险低但不是零 ——
SKILL.md 少了一句「条件性标准条款命中判据才抄」,读者要看全文得翻到 runbook;
它的邻居 L554 本来就以「原文见 runbook」结尾,所以这一跳是这一节原有的读法,不是新加的。
另一个可见变化是 triage.md 的标题后面没有空行了,这会让它和另外五份车道岗位说明看起来
略有出入 —— 渲染没有差别,而且真有人把空行加回去,棘轮会当场红,不会静默。
回滚就是 revert 这一个 commit:两个文件各回到原来的行数,被折的两处内容在别处完整存活,
revert 只会造成一次重复,不会造成缺失。没有生成物、没有基线、没有别的文件依赖它。

席位意见

(留空,待席位定稿)

你要做的

裁定已经做完了(A,您回的「同意」),这张 PR 只是执行它,没有留下任何要您再拍的岔路。
唯一值得您看一眼的是 triage.md 那个空行:裁定要求「行数不动」,而派发词提的两条付账办法
(拉长某一行、把三条规则合并成两条)我都量过,在每行 120 字节的上限下都办不到 ——
三条规则一共 324 字节,合并任意两条都要删掉一个子句,而它们的内容在整个语料里没有第二处。
所以我花掉了那个空行,并且证明了渲染没有变化。请回一个字:是(合并)或 否(要我换个付法)。


Generated by Claude Code

…s it

`needs:contract-review` was being hung at TRIAGE time as a routing state, on
cards with no `pm:*` state and no claim — a convention inherited from
neighbouring triage comments rather than from the rule it claimed to
implement. The carrier discipline already says the label rides a reviewable
increment (a draft PR, or the card in the same stroke as a `Clause-②: yes`
claim) and never gets pre-hung; it was just not written where triage reads.

Two sentences, both fold-paid, both files at their pinned line counts:

- `references/lanes/triage.md` (7/7): the new rule is paid by the blank
  separator between the H1 and the pointer paragraph. Proved render-neutral
  with micromark — an ATX heading is a leaf block, so the paragraph that
  follows it needs no blank line, and the rendered h1/p/ul structure is
  byte-identical to before. Merging two of the three existing rule bullets
  was measured first and would have cost a clause: the three carry 324 bytes
  of unique content over a 120-byte per-line cap, and nothing in them is
  restated anywhere else in the corpus.

- `SKILL.md` (811/811): paid by deleting one restating line whose every
  clause survives in fuller form in `references/dispatch-runbook.md`, which
  the same section already delegates to on the adjacent line.

Claude-Session: https://claude.ai/code/session_018dxq7YqsLDMeZDZ5AzsgJX
Co-authored-by: Claude <noreply@anthropic.com>
@os-musk os-musk added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/xs labels Sep 7, 2026 — with Claude
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 7, 2026
@os-musk
os-musk requested review from hotlong and os-zhuang September 7, 2026 22:50

os-musk commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

ACCEPT — flight N, PR #16698 at head f305c7c9e5 (#16625, ruling A: the carrier discipline restated where triage reads it), contract-tier review on the seat's own readings, 2026-09-07T22:51Z.

Own readings (review worktree detached at f305c7c9e5, origin/main = 7797102139 = merge base):

  • Diff: two files, +2/−2, one content commit plus a clean merge of main; SKILL.md 811 lines, lanes/triage.md 7 lines; both added lines measure 115 bytes; no control bytes; the decision-frame block's md5 is 22f2339f0acb64cdb50c7adc9db681c3 before and after.
  • Fold survivals read on the head: the deleted SKILL.md line 「条件性标准条款命中判据才抄:多实现面 ⇒ 共享一致性覆盖。」 is carried in full at references/dispatch-runbook.md:226–228 (the same clause plus the negative half and the definition of 多实现面), reachable by the same reader; core-rules.md does not mirror it. The triage.md payment is the blank line after the H1: the file's four content lines and the three rule bullets are byte-identical to origin/main, and an ATX heading needs no trailing blank — nothing folded, nothing lost.
  • Gates re-run here: check:pm-skill-ratchet (SKILL.md is 811 lines (ceiling 811; headroom 0), lanes/triage.md … widest table row is 0 bytes (pin 0)), check:pm-skill-id-lint (26 files clean), check:skill-frame-sync (2 copies isomorphic), all exit 0; check-governed-merges.mjs --test on both paths exit 3.
  • git merge-tree --write-tree --name-only origin/main HEAD exit 0, tree 1685828cd, no conflicted path.
  • CI: recorded by the dev once at 31 runs / 8 success / 15 skipped / 8 in progress / 0 failure; the seat reads it again at the next patrol. Not a landing condition on this surface.

Review checklist:

  • ① Derived judgments: the two sentences restate the L647–649 / 〈载体纪律〉 rule from the triage reader's side without duplicating it, in each file's register, and neither names an issue. Placement under the three-way classification head (not inside the sweep enumeration) is right: the ruling constrains what a triage verdict does. The seat's brief named two payment mechanisms for triage.md that the dev measured as impossible (37 bytes of headroom over four lines; 324 bytes of unique content in three bullets) — the seat's error, recorded here as the 承接者 the PR body names; the substitute payment is accepted (option A): whitespace-only, render-identical, every shared byte of the six charters untouched, and a future re-insertion reds the ratchet loudly.
  • ② semver: none — protocol prose, skip-changeset, nothing published moves.
  • ③ Boundary flags: governed surface (.claude/**). Draft kept; not readied, not enqueued, no auto-merge; reviewers os-zhuang + hotlong requested and needs-user-decision set on the PR in this same wake. Option B is implemented nowhere; no card label was written by the flight. The near-duplicate pairs the dev noted (SKILL.md:600 / review-checklist.md:40; SKILL.md:349–350 / os-dev.md:45–46) are compression headroom, not defects — 承接者:无.

Implemented-by: os-dev subagent abdd6500c35c7db3e (container & tier as recorded on the claim 5573139480 on #16625; resumed once after a model-window 429, state re-read from the tree)
Reviewed-by: domain:skills seat, session session_018dxq7YqsLDMeZDZ5AzsgJX, at CONTRACT_REVIEW_TIER (own get_session reading: session_context.model = last_served_model)

维护者速读

改了什么: 两个文件各加一句、各折一处,行数不动(lanes/triage.md 7/7,SKILL.md 811/811)。新规则:needs:contract-review 只跟着能审的东西走(draft PR,或认领同笔的 Clause-②: yes);分诊席不挂它,分诊裁定写方向、给卡六态之一。SKILL.md 折掉的一句在 dispatch-runbook.md 里说得更全;triage.md 花掉的是标题后的一个空行,渲染逐字节相同。

为什么改: 你 14:48Z 裁的 A 只剩文本这一半——十一张卡曾因这个惯例停在没有队列的地方,规则本来写着「不前瞻预挂」,只是不在分诊席读的那份文件里。选项 B(第七个停车态)按裁定不做。

风险与代价(含回滚): 两行规则、两处折叠,零新文件、零 CI 成本、棘轮不抬。回滚 = revert 一个提交。唯一可见的形式变化:triage.md 的标题后没有空行,与另外五份车道说明略有不同;有人加回去时棘轮当场变红,不会静默。

席位意见: 复核通过;派发词给的两种付账办法经量都办不到,空行付账是席位认可的替代,建议按现状合并。

你要做的: 手动合并本 PR(受管面,⛔ 不走队列、不挂 auto-merge);合并即关 #16625。是否合并?


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 8, 2026 00:30
@os-zhuang
os-zhuang enabled auto-merge September 8, 2026 00:30
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 8, 2026
Merged via the queue into main with commit 05374be Sep 8, 2026
38 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-16625-carrier-discipline-triage branch September 8, 2026 01:13
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 needs-user-decision skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants