Repository navigation
Commit f7e836d
docs(pm-dispatch): let an execution seat accept a filer-labelled card when the lane fits the domain table and the body passes the filing gate; triage spot-checks after (#23751)
Fixes #23733
Clause-②: no
Relaxes the lane-label rule as the maintainer ruled on the card (filing
gate ③), verbatim and untranslated:
> 现在派,规则选 A;放宽:执行席可直接接收自贴标签的卡,只要车道按域表正确、正文有立卡门三件;分诊事后抽查
Scope pick B (「放宽(按我写的原文)」): the rule change only. The one-off dispatch
it also ordered is already done and is not touched here.
## What changed (three files, each at net 0 lines, no `CEILINGS` move)
**`.claude/skills/pm-dispatch/SKILL.md`** — 〈域车道〉 L171–172 (was L172):
- L171 keeps the rule and its tail clause, renumbering the one existing
exception: 「`domain:*` 只由分诊席产出,例外一:在飞卡衍生 sub-issue 承父卡域;无标签的卡 ⛔ 不得认领。」
(119 B)
- L172, new: 「例外二:立卡人自贴而车道合上表、正文齐立卡门三件 ⇒ 执行席直接认领,分诊事后抽查。」 (120 B). 「上表」
is the domain table directly above it; 「立卡门三件」 is
`references/filing-gate.md` L26, referred to and not restated.
- Payment: deleted L126, the `Unlock-action:` accepted-spellings line
(the two `re-check …` forms, others silently fall back). It survives at
its single source, `references/state-machine.md` L28–29 (both spellings,
then 「只认此二值,别的拼写静默回落重派」), and SKILL.md L124 already sends the reader
there for every hold/blocked line contract. The four-axis block is
untouched and still occupies L241–261 (md5
`abff5f852c8fd09b79ec0623439aa4f0`, identical before and after).
**`.claude/skills/pm-dispatch/references/execution-duties.md`** —
〈候选与批次〉:
- L11, new, directly under the candidate rule: 「自贴 `domain:*`
卡:车道合域表且正文齐 `filing-gate.md` 三件 ⇒ 候选;缺一 ⇒ 挂 `pm:retriage`。」 (118 B).
Either condition failing adds `pm:retriage`, and L10's candidate rule
(「无 `pm:retriage`」) then excludes the card, so it reaches triage instead
of waiting unseen.
- L42 (was L41): 「唯一绕过分诊」 → 「绕过分诊」. The sub-issue path is no longer the
only route past triage's first touch, so the word became false.
Same-line edit, −6 B.
- Payment: deleted L139 「dev 装不下预算 ⇒ 停手回报,⛔ 不自行扩写、不自行抬预算。」 It is a
developer obligation whose single source is `.claude/agents/os-dev.md`
L292 (「净增预算装不下 ⇒ 按 `blocked` 报缺口;⛔ 不自行扩写或抬预算:预算归 PM,抬它归维护者。」);
`references/dispatch-runbook.md` L188 already names SKILL.md and the dev
definition as the single source of dev duties. The PM-side duty on the
line above (set the budget) and the review rule (over-budget ⇒ REWORK)
both stay.
**`.claude/skills/pm-dispatch/references/triage-duties.md`** — the
Backlog sweep block:
- L17, new, right after the sweep's exclusion line: 「自贴卡抽查:窗内新派发且
`domain:*` 事件与建卡同分钟者,逐张核车道、三件;⛔ 不凭 actor。」 (120 B). 「窗内」 is the hourly
`since` window L8 defines (anchor = the seat post's last brief). The
discriminator and why it is not the actor are measured below.
- Payment: deleted L88 「retriage 维持或改判皆由分诊席同笔摘标;挂标归异议席。」 Its first
clause is L87 of the same file (「答后同笔摘标」) and
`references/state-machine.md` L40; its second is what the `pm:retriage`
row of SKILL.md's state table already defines (向分诊提问 … 异议评论写明所求).
## PM mechanism assumptions — measured
- (a) All readings held at `3b46855fb`: 319/319, 188/188, 120/120 lines;
L172, L10 and the sweep block read as quoted; table at L160–169.
- (b) No ruling comment id exists for a raise; each file stays at its
ceiling and no `CEILINGS` row moves.
- (c) Followed: the three items are referred to (`filing-gate.md`), not
restated; the lane condition points at the table.
- (d) Held, with one correction: the sub-issue exception stands
(SKILL.md L171, execution-duties L41–44), but execution-duties' 「唯一绕过分诊」
is no longer true and is edited.
- (e) Discriminator, measured on the public issue-page payload
(`LabeledEvent` items carry `createdAt` and `actor`) and the REST events
list, which agree:
- The card's suggestion (label event by the issue's creator in the
creation minute, no later triage-actor event) cannot stand as stated. On
#23720 all six label events have actor `objectstack-fleet[bot]` — the
filer's four at 20:01:15–16Z, seat 2's `pm:retriage` add at 20:53:44Z,
triage's `pm:retriage` removal at 21:53:18Z, the PM's `pm:dispatched` at
22:26:57Z — and that is also the issue's creator. The actor half
separates nothing; the timing half does (created 20:01:13Z,
`domain:devx` labelled 20:01:16Z).
- The PM's candidate (first `Claim:` with no earlier triage first-touch
comment opening `## Triage:` or `## First grade`) is roster-dependent.
On #23720 the only triage comment before the claim (22:27:26Z) opens
with `## Retriage answered: first touch · …` (21:52:42Z), so the literal
roster lists #23720 for the wrong reason, and a roster widened to that
opener drops it. `scripts/pm/check-half-states.mjs` L7809–7811 already
records six further opener spellings in the wild.
- Written: 「窗内新派发且 `domain:*` 事件与建卡同分钟者」. Reading on #23720:
`domain:devx` labelled 20:01:16Z against `created_at` 20:01:13Z (same
minute), `pm:dispatched` labelled 22:26:57Z — in a window covering that
hour it is LISTED. Reading on #23665: created 11:24:45Z, `domain:skills`
labelled 11:24:47Z (same minute, filer-labelled) but no `pm:dispatched`
and no `Claim:` — not listed, which is right: it sits at `pm:retriage`,
it was never accepted.
- (f) Confirmed: execution-duties L10 already lists 「无 `pm:retriage`」,
so the new line's failure outcome lands on an existing exclusion.
## Executable criterion (from the card)
- A card like #23720 (filer-applied lane, state and grade; lane correct
by the table; three items in the body): execution-duties L11 makes it a
candidate with no triage touch.
- A card missing either condition: L11 says it is not a candidate and
where it goes (`pm:retriage`).
- The triage text names a step that lists self-labelled cards accepted
in the window; #23720 appears in it (reading above).
- `pnpm check:pm-skill-ratchet` passes (below).
## Line ratchet — verdict lines before (`3b46855fb`) and after
(`5629c6ff6`)
Before:
```text
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 319 lines (ceiling 319; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/execution-duties.md is 188 lines (ceiling 188; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/triage-duties.md is 120 lines (ceiling 120; headroom 0).
```
After:
```text
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 319 lines (ceiling 319; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/execution-duties.md is 188 lines (ceiling 188; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/triage-duties.md is 120 lines (ceiling 120; headroom 0).
```
Widest line, in bytes, per file (prose lines; table rows are metered by
the separate table-row pin, unchanged at 342/0/0): SKILL.md 120 B (L175,
unchanged; the five edited or added lines measure 119, 120, 118, 106,
120 B), execution-duties.md 120 B (L22, unchanged), triage-duties.md 120
B (L10 and the new L17). Every line of the diff is ≤ 120 B; no `#`
followed by three or more digits enters any of the three files.
## Verification (local subset at `5629c6ff6`)
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` re-derived with no paths after the final
commit: 22 commands, identical to the dispatch order's list. Each ran
with its log redirected first and the exit code captured before any
pipe:
| # | command | exit |
|:--|:--|:--|
| 1 | `node scripts/check-closing-keyword-parity.mjs` | 0 |
| 2 | `node scripts/check-closing-keyword-parity.mjs --self-test` | 0 |
| 3 | `node scripts/check-comment-mask-corpus.mjs` | 0 |
| 4 | `node scripts/pm/check-governed-queue-guard.mjs --self-test` | 0 |
| 5 | `node scripts/pm/check-harness-current.mjs --self-test` | 0 |
| 6 | `pnpm --filter @objectstack/lint run
check:doc-formula-expressions` | 0 (re-run after the build; first run
was exit 3, see Acceptance notes) |
| 7 | `pnpm check:agent-test-spelling` | 0 |
| 8 | `pnpm check:cross-package-test-inputs` | 0 |
| 9 | `pnpm check:doc-authoring` | 0 |
| 10 | `pnpm check:driver-memory-census` | 0 |
| 11 | `pnpm check:gitlink-declared` | 0 |
| 12 | `pnpm check:nul-bytes` | 0 |
| 13 | `pnpm check:pm-expected-skips` | 0 |
| 14 | `pnpm check:pm-governed-merges` | 0 |
| 15 | `pnpm check:pm-governed-prose` | 0 |
| 16 | `pnpm check:pm-half-states` | 0 |
| 17 | `pnpm check:pm-label-write` | 0 |
| 18 | `pnpm check:pm-skill-id-lint` | 0 |
| 19 | `pnpm check:pm-skill-ratchet` | 0 |
| 20 | `pnpm check:refd-timer-probe` | 0 |
| 21 | `pnpm check:skill-frame-sync` | 0 |
| 22 | `pnpm check:watch-hint-literal` | 0 |
`node scripts/pm/dispatch-gates.mjs --ran ran.list --repo
objectstack-ai/objectstack` at `5629c6ff6`:
```text
Run reconciliation — 22 derived, 22 run, 0 NOT-MEASURED, 0 UNRUN.
✓ dispatch-gates --ran: 22 derived famil(ies) accounted for — 22 run, 0 NOT-MEASURED (a DERIVED zero — all 22 recorded an exit code and none of them is 3).
```
Not run locally, by design: the whole-tree families the derivation marks
as CI-owned (`pnpm lint`, the type-check lanes, `check-half-states
--format=markdown` with its workflow-supplied provenance) — CI's
check-runs on this PR are the reading for those. The two local-only
families (`check:dev-prereqs`, `check:skill-frame-freshness`) are not
named by the derivation for this diff and were not run.
## Acceptance notes
- The commit's author and committer name was set to
`objectstack-fleet[bot]` with a one-off `-c user.name` on the commit
command; the configured identity in this container is `Claude` at the
same address. Noted, not rewritten.
- Gate 6 first answered exit 3 (PREREQUISITE NOT MET:
`@objectstack/formula` and `@objectstack/lint` not built); the gate's
own prescribed build ran under the shared verify lock and the gate was
re-run — the table above carries the re-run.
- The new triage line names its window as 「窗内」 rather than spelling
`since` a second time: with the actor clause the line is at the 120-byte
cap. The window is the one L8 of the same file defines.
- No out-of-scope findings in the three filing classes. Observation
only, no card: triage first-touch comments open with at least eight
distinct spellings across the corpus and this week's threads, which is
why the spot-check keys on the label event's time and not on comment
openers.
## 维护者速读(草稿)
**改了什么**:执行席现在可以直接认领立卡人自己贴好车道标签的卡,条件两个都要满足:车道按 SKILL.md
的域表是对的、正文有立卡门三件(类别、动手的读者、查重查询与命中数)。任一不满足就挂 `pm:retriage`
交分诊,卡不会悬着没人看。分诊多一条事后抽查:看窗口内新派发、且 `domain:*`
标签是建卡同一分钟贴上的卡,逐张核车道与三件。三个文件各加一行、各删一行重复内容,行数上限一行不动。
**为什么改**:按您 2026-10-15 的原话放宽。此前自贴标签的卡要等分诊首触才能认领,而 sweep
看不到已经带齐标签的卡;量过的一张卡因此多等了约一个半小时,另一张近十二小时无人碰,靶是 `pm:retriage` 才到分诊。
**风险与代价(含回滚)**:风险是错车道的卡被执行席直接接下;抽查是补偿控制,抽查判据用标签事件的时间不用
actor(所有舰队写入都是同一个中继身份,actor 分不出立卡人与分诊)。代价为零行数增长。回滚 = revert 这一个
commit,三个文件回到原文。
**席位意见**:(留空,席位定稿时填)
**你要做的**:无需动作;本 PR 是 Tier S,席位做完契约复审 PASS 后自行落地。
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VqGhCg9wdsBXPz54uAEWg7)_
Co-authored-by: objectstack-fleet[bot] <noreply@anthropic.com>1 parent ae4dfaf commit f7e836d
3 files changed
Lines changed: 5 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
123 | 123 | | |
124 | 124 | | |
125 | 125 | | |
126 | | - | |
127 | 126 | | |
128 | 127 | | |
129 | 128 | | |
| |||
169 | 168 | | |
170 | 169 | | |
171 | 170 | | |
172 | | - | |
| 171 | + | |
| 172 | + | |
173 | 173 | | |
174 | 174 | | |
175 | 175 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
38 | 39 | | |
39 | 40 | | |
40 | 41 | | |
41 | | - | |
| 42 | + | |
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| |||
136 | 137 | | |
137 | 138 | | |
138 | 139 | | |
139 | | - | |
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
| |||
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
88 | | - | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| |||
0 commit comments