Repository navigation
Commit 1bc6ca1
docs(pm-skill): judge responsibility before dispatch, breaker on reopening security review (#21999)
Fixes #21929
Clause-②: no
## What changes
Five files under `.claude/skills/pm-dispatch/`, eight lines added or
rewritten, eight lines deleted, every file at its ratchet ceiling before
and after. The card's four rules land where the seat claims, dispatches,
grades and reviews; the dispatch prompt's ruling section is bound
through the claim template; the round report gains a per-PR breaker
line. No gate, workflow, hook or ratchet is added or moved, as the
triage grade asked. `.claude/agents/os-dev.md`, `skills/**`,
`scripts/**` and `.github/**` are untouched.
| Rule | File : line (after) | Action | Line (bytes) |
|:--|:--|:--|:--|
| 1 · responsibility check, the three questions | `SKILL.md` 〈模板与表〉
claim template, under `Clause-②` | new template field `Responsibility:`
— whose code produces the risk / the platform path that already covers
it, or none / who reaches it and whether anyone uses it today; `n/a —
not a defect card` otherwise; the parenthetical binds the dispatch
prompt's ruling section to repeat the three answers | fence (exempt) |
| 1 · the document-not-defend verdict | `SKILL.md` 〈升级与决策〉 :214 | new
escalation condition: `或责任三答齐指他人代码、已有正路、仅最高权限可达 ⇒ 只提文档或决策卡,⛔ 不派码。` | 120
|
| 1 · asked at first grade (triage) | `references/triage-duties.md` :74
| rewritten: `首触答责任三问:谁的代码出险/有正路否/谁可达且有人用否;据答改卡范围、域与路由。` | 117 |
| 2 · no security boundary on a heuristic | `SKILL.md` 〈升级与决策〉 :215 |
new escalation condition: `或修复以猜测(键名、值形状、模式表)定安全边界 ⇒ 决策卡先比对声明式方案。` | 108
|
| 3 · circuit breaker, consequence | `references/execution-duties.md`
〈复核〉 :182 | rewritten ESCALATE verdict: `判决
ESCALATE:见〈升级与决策〉;熔断任一命中亦判,PR 暂停,答复前 ⛔ 不派下一轮。` | 110 |
| 3 · circuit breaker, the three conditions |
`references/execution-duties.md` 〈复核〉 :183 | new: `熔断三条:独立安全复审连续 2
轮不过;diff 超首次复核规模 2 倍;上轮修复引入新 HIGH。` | 114 |
| 3 · round report records the hit | `references/seat-lifecycle.md`
〈轮次报告与节奏〉 :68 | rewritten: `报告加升级项、代裁清单(分诊)、awaiting a human merge 项、逐
PR 熔断命中项(无则 none)。` | 113 |
| 4 · price by reach, not by class | `references/filing-gate.md` 〈定级判据〉
:43 | new, directly under 「沿链继承只给上界」: `可达面定上界:\`security\`
标签不抬级;仅最高权限可达且无现用者至多 p3,可记录不修。` | 112 |
Reading the escalation enumeration after the edit (SKILL.md 213–216):
只在至少一条成立时升级 → the existing disagreement condition → rule 1's verdict →
rule 2's condition → the existing destructive/hard-to-roll-back
condition with its 「其余归 PM 裁量」 closer. The decision-frame block
(`**每个方案必须沿四条固定评估轴分析` … `交维护者拍板。`) is byte-identical; its md5 is
`abff5f852c8fd09b79ec0623439aa4f0` before and after.
Why these spellings:
- Rule 1's verdict sits in 〈升级与决策〉 rather than in `execution-duties.md`,
because both the triage seat and the execution seats read SKILL.md, and
the verdict is a "do not dispatch code" decision — the same class as the
enumeration it joins. ESCALATE already means a decision card with
options and a recommendation in the maintainer's inbox, and a
`needs-user-decision` card is never dispatched (红线), so "asks the
maintainer with a short summary and options" and "no further round until
the maintainer answers" ride on existing machinery; the ESCALATE line
still says `PR 暂停,答复前 ⛔ 不派下一轮` so the seat does not have to infer it.
- "at most low" is spelled `至多 p3`: p3 is this repo's lowest grade and
the grade `triage-duties.md` already assigns to a `reach:`-less finding
that is recorded without a dedicated fix. `可记录不修` is the "may be
recorded without a fix" half.
- `他人代码` stands for third-party or user-authored code (the first answer
is "someone else's code produces the risk"); the long spelling did not
fit in 120 bytes beside the other two answers.
## Line budget (headroom 0 on every file, net 0 on every file)
| File | Before | After | Ceiling |
|:--|--:|--:|--:|
| `.claude/skills/pm-dispatch/SKILL.md` | 319 | 319 | 319 |
| `references/execution-duties.md` | 183 | 183 | 183 |
| `references/dispatch-runbook.md` (not edited) | 241 | 241 | 241 |
| `references/seat-lifecycle.md` | 96 | 96 | 96 |
| `references/triage-duties.md` | 120 | 120 | 120 |
| `references/filing-gate.md` | 58 | 58 | 58 |
The dispatch budget was at most 8 added or rewritten lines across all
files: 8 were spent (5 new, 3 rewritten in place). Every new or
rewritten prose line is at or under 120 bytes (`LC_ALL=C awk`; the
figures are in the table above); the one template field is inside a
fence, which the rule exempts. No line was re-wrapped; each added line
is paid by deleting a line whose rule survives elsewhere, listed here
with its surviving home:
1. Deleted `SKILL.md` 〈报告契约〉: `- \`reach:\` 无实测 ⇒ ⛔ 不立卡,例外三种与定义见立卡门
①;同轮报告互读,同族只开一张。`
Survives in `references/filing-gate.md` 立卡门 ① (lines 12–14: the `reach:`
definition and the three exceptions; line 20: `⛔ 不是卡:三类外或无 \`reach:\` 的
\`finding\``), in `references/triage-duties.md` 47–48, and in the kept
SKILL.md line `同族发现并入收口卡(一卡覆盖全族位置,带枚举钉子),⛔ 不开单点卡;无则第二次即开。`; the kept
line 「席位读 PR … 经立卡门补立」 still points at 立卡门.
2. Deleted `SKILL.md` 〈机械守卫索引〉 row for `scripts/pm/git-history.mjs`.
Survives verbatim in `AGENTS.md` (Multi-agent working discipline: "A
windowed history question … goes through `scripts/pm/git-history.mjs` —
answer, or REFUSE … `historyHorizon()` is the read-only predicate"), and
the tool's use is still named in `references/seat-lifecycle.md` 19.
3. Deleted `SKILL.md` 〈机械守卫索引〉 row for the `guard-main-checkout` /
`guard-shared-stash` hooks.
Survives in `AGENTS.md` Prime Directive 11 and Multi-agent working
discipline (both hooks, their escape variables and the stash
replacements), and the rule itself in SKILL.md 红线 `⛔ 永不编辑共享检出,一任务一
worktree;⛔ 永不 \`git stash\`。`.
4. Deleted `references/execution-duties.md` 〈认领〉: `- \`Clause-②: yes\`
至少 \`minor\`:AGENTS.md Post-Task Checklist 第 3 条,本行在认领处复述。`
A self-declared restatement; survives in `AGENTS.md` Post-Task Checklist
step 3 (`yes` takes at least `minor`), which binds every seat, and is
enforced on the PR by the changeset gate that reads the body's
`Clause-②` line.
5. Deleted `references/filing-gate.md` 立卡门: `- 判例:自注「未测量」的 (b) 卡 ⇒
不立;\`reach:\` 记公开入口一次实测错误的 (b) 卡 ⇒ 立。`
A worked example of lines 12–13 and 20 in the same section, which stay;
both halves of the example are derivable from them.
Also rewritten rather than deleted: `triage-duties.md` 74
(`派发前按生产者的答案改卡的范围与域标签。`) keeps its content inside the new line
(`据答改卡范围、域与路由`, now at first touch), and line 73 keeps the
declared≠enforced producer question unchanged.
## Dispatch hypotheses, measured
- "Rule 2 can be appended to the 「只在至少一条成立时升级」 line or split into the
adjacent 「或修复需破坏性/难回滚动作」 line" — falsified by measurement: those lines
are 120 and 117 bytes, and the shortest self-contained spelling of the
condition is 108 bytes, so it lands as one line inside the same
enumeration (between the two), not as an independent rule line.
- "Rule 3 is an extension of the REWORK cap line" — the REWORK line is
118 bytes, so the breaker went into the adjacent ESCALATE verdict line
(rewritten, keeping its pointer) plus one conditions line, inside 〈复核〉;
no new section.
- "Rule 4 is mostly already in `filing-gate.md`" — confirmed for the
`reach:` requirement; the `security`-label and highest-privilege-only
sentences were absent (at `6befe19c`, `git grep -E
'熔断|责任三|Responsibility:|声明式方案|不派码|不抬级'` over
`.claude/skills/pm-dispatch/` exits 1; the control `升级与决策` hits 6
files), so one line landed, placed as the sibling of 「沿链继承只给上界」 so the
two upper-bound statements read together and neither conflicts with
清单项三态 ① inheritance.
- `dispatch-runbook.md` 〈派发词构造细则〉 was named as a landing spot for "the
dispatch prompt carries the three answers". Not edited: the claim
template line already says the dispatch prompt's ruling section repeats
the three answers, the PM writes the claim immediately before the
prompt, and a second sentence in the runbook would have cost a deletion
there for a line with the same reader. `execution-duties.md` 〈候选与批次〉
line 13 (維护者裁决 → 派发词裁决分区) was not rewritten for the same reason.
## Acceptance notes
- `references/lanes/hotcrm.md` 30 and `references/lanes/engine.md` 32
carry lane-local copies of the "ask where the producer is" question for
declared≠enforced cards; the new three-question line generalises them
for every card at first touch. Left as they are (lane files, not in this
card's surface; no conflict). carrier: none — noted, not filed.
- `AGENTS.md` lists `安全/权限边界` on the human floor for auto-adjudication
(triage-duties 95–96, SKILL.md 262) but the escalation enumeration had
no security-boundary trigger before this PR; rule 2 is that trigger,
narrowed to fixes that decide the boundary by guessing. Observation
only.
## Gates
Derived from this change set in the worktree with `node
scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at head `8cdefa6c`: 21 commands, the same 21
the dispatch named. All 21 ran on `8cdefa6c` (the tree was clean; the
gates read the committed files) with the exit code captured before any
pipe, and `--ran` reconciliation answered: "21 derived famil(ies)
accounted for — 21 run, 0 NOT-MEASURED (a DERIVED zero — all 21 recorded
an exit code and none of them is 3)". One first attempt was not a
measurement: `pnpm --filter @objectstack/lint run
check:doc-formula-expressions` exited 3 (`PREREQUISITE NOT MET`:
`@objectstack/formula` and `@objectstack/lint` were not built in the
fresh worktree); after `turbo run build --filter=@objectstack/formula
--filter=@objectstack/lint` under the shared verify lock (VERDICT
command-exit 0, held 133 s) the gate re-ran and exited 0 ("22
record-scoped formula example(s) across 461 files / 1384 TS blocks
judged clean"). Selected verdict lines:
- `pnpm check:pm-skill-ratchet`: "SKILL.md is 319 lines (ceiling 319;
headroom 0)", "execution-duties.md is 183 lines (ceiling 183; headroom
0)", "seat-lifecycle.md is 96 lines (ceiling 96; headroom 0)",
"triage-duties.md is 120 lines (ceiling 120; headroom 0)",
"filing-gate.md is 58 lines (ceiling 58; headroom 0)"; the
widest-table-row pin for SKILL.md stays at 342 bytes; no over-budget
line (that red prints only on failure).
- `pnpm check:pm-skill-id-lint`: "34 file(s) clean (pattern
/#[0-9]{3,}/g)".
- `pnpm check:skill-frame-sync`: "the one declared copy of the decision
frame is internally coherent (.claude/skills/pm-dispatch/SKILL.md) … 4
axes … binding sentence present".
- `pnpm check:pm-governed-prose`: "2 instruction surface(s) name all 6
registered governed surfaces … and claim no others".
- `pnpm check:nul-bytes`: "scanned 10023 text file(s) … no raw ASCII
control bytes".
- `pnpm check:doc-authoring`: "sibling-package prose ids hold the
baseline — 0 pinned site(s)".
`check:skill-frame-freshness` is not in the derived set; it compares
this tree's frame with `origin/main`, and the frame block is
byte-identical (md5 above). No package build, test or typecheck is owed:
the diff touches no package. Changeset: none — `.claude/**` publishes
nothing (fast lane), so the PR takes `skip-changeset`.
## Landing
Every path is under `.claude/**`, so this is Tier S: the PR stays draft
until the skills seat's contract-tier review record (`Served-tier:
CONTRACT_REVIEW_TIER`, PASS) is on the thread or the card; the seat then
lands it through the queue. No model identifier appears in this body or
in the commit trailer pair.
## 维护者速读(草稿)
**改了什么**:给 PM 派发技能加了四条规则,共改五个文件、八行,逐行用删掉的重复行付账,每个文件行数不变。① 认领模板多一行
`Responsibility:`,派发前先答三问:风险出自谁的代码、平台是否已有正路、谁能碰到且今天有没有人在用;派发词的裁决区照抄这三答。②
三答都指向「别人的代码、已有正路、只有最高权限能碰到」时,默认只补文档或开决策卡,不派代码修复。③
修复靠猜(字段名、值形状、模式表)来划安全边界的,先开决策卡、对照声明式方案,再谈派发。④
熔断三条:独立安全复审连续两轮不过、改动超过首次复核规模两倍、上一轮修复引出新的高危,任一命中即暂停
PR、升级问你,你答复前不派下一轮;轮次报告逐 PR 列出命中项。⑤ 定级按可达面:`security`
标签本身不抬优先级;只有最高权限能碰到、又没人在用的发现至多 p3,可以只记录不修。分诊首触也要先答这三问。
**为什么改**:上一次把一张只影响仓库里不存在的插件驱动、只有平台管理员能看到的卡当成安全漏洞派了开发,复审四轮都没收住,改动长到四千行,最后作废改成补一句文档。成本花在开工之前没人问「这是谁的问题」,和开工之后没有东西能停下循环。这五处改动把这两个问题各放在席位必经的那一行上。
**风险与代价(含回滚)**:风险是规则写得过短被误读 —— 每行不超过 120 字节,只能用缩略说法(如「他人代码」指第三方或用户代码,「至多
p3」对应「最多 low」)。代价是删了五行重复文本,每一行的规则都在 AGENTS.md 或同技能的另一处保留,PR
正文逐条列了归宿。回滚是单个 commit 的 revert,不涉及代码、门禁或 workflow。
**席位意见**:(留空,由席位填写)
**你要做的**:看一眼五段速读里的四条规则是否与你在 #21921 上的裁决一致;一致则由 skills 席按达档复核落地,不需要你合并。
---
_Generated by [Claude
Code](https://claude.ai/code/session_0181E4ZeZmWyknawnauxD2CE)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 21c804c commit 1bc6ca1
5 files changed
Lines changed: 8 additions & 8 deletions
File tree
- .claude/skills/pm-dispatch
- references
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
| 214 | + | |
| 215 | + | |
214 | 216 | | |
215 | 217 | | |
216 | 218 | | |
| |||
279 | 281 | | |
280 | 282 | | |
281 | 283 | | |
282 | | - | |
283 | 284 | | |
284 | 285 | | |
285 | 286 | | |
| |||
293 | 294 | | |
294 | 295 | | |
295 | 296 | | |
296 | | - | |
297 | 297 | | |
298 | 298 | | |
299 | 299 | | |
300 | | - | |
301 | 300 | | |
302 | 301 | | |
303 | 302 | | |
| |||
314 | 313 | | |
315 | 314 | | |
316 | 315 | | |
| 316 | + | |
317 | 317 | | |
318 | 318 | | |
319 | 319 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
72 | 71 | | |
73 | 72 | | |
74 | 73 | | |
| |||
180 | 179 | | |
181 | 180 | | |
182 | 181 | | |
183 | | - | |
| 182 | + | |
| 183 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | 15 | | |
17 | 16 | | |
18 | 17 | | |
| |||
41 | 40 | | |
42 | 41 | | |
43 | 42 | | |
| 43 | + | |
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
68 | | - | |
| 68 | + | |
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
74 | | - | |
| 74 | + | |
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
| |||
0 commit comments