Skip to content

Commit 802a91b

Browse files
os-justinclaude
andauthored
skills(pm-dispatch): a ruling's file/symbol/line/call-shape clause carries its reading or is marked 未验证 — the 派发令 evidentiary duty extended to 裁决 (#18679)
Fixes #18506 Clause-②: no `skip-changeset` — the only touched path is `.claude/skills/pm-dispatch/SKILL.md` (governed `.claude/**`, internal agent tooling; it ships in no package's `files[]`). ## The defect, in one paragraph A ruling is consumed exactly like a dispatch order — quoted verbatim into the brief, ⛔ not re-litigable, treated by the dev as settled — yet the charter's evidentiary discipline binds dispatch orders only: 「派发令里关于代码的危害断言必须有读数(点名 call site / 路径 / 迁移)」, 「搬自任何工件(含己文)本轮未亲测计数/零命中/文件面:重测或注「未验证」点名来源」, 「PM 测不了的危害 ⇒ 写成给 dev 的问题,⛔ 不写成栅栏」. Nothing required a ruling's code-level assertions to carry a reading, and nothing marked them unverified when they did not. The artefact with more authority had fewer evidentiary requirements than the one that merely relays it — the asymmetry is the defect. This PR extends the same two options (carry the reading, or mark that clause 「未验证」) to 裁决, so the dev reading a ruling knows which clause to falsify first. ⛔ It is not 「measure before ruling」, adds no gate or script, and re-grades no ruling. ## The evidence: six for six on one split (card comment 5701534399) | ruling | kind of claim | outcome | |:--|:--|:--| | objectui#8938 | asserted a code fact (「every one folds in the restrictive direction」) | broke — `_packageId` presence admits an affordance at 14 of 38 read sites | | objectui#8826 | asserted a code location (`ObjectKanban.tsx`'s `handleDragEnd`) | broke — it lives in `KanbanImpl.tsx` | | objectui#8209 | asserted a call shape (`field.format ?? 'compact'`) | broke — `temporalText(type, value, locale)` takes no `field`; no `format` key on the published type | | objectui#8167 | asserted a mount topology (「each host mount supplies it」) | broke — zero mount sites; registry-resolved | | objectui#7771 | cited standing rules (「一个标签存在当且仅当有具名读者」) | held | | objectui#9537 | cited standing rules (「门禁内部参数与扫描器盲区修复(加强,非削弱)」; ADR-0049) | held — every code fact it named had been READ; its one slip (`:866-870` for `:878`) was inherited from the card body | The rulings that reasoned from rules held; the four that asserted implementation facts broke. The exposure is confined to the moment a ruling names a file, a symbol, a line or a call shape — the same boundary the charter already draws for dispatch orders, which is why the line below carries a rule-citing exemption rather than a measurement duty. ## The change — one line in, one line out, SKILL.md 812 / 812 **In** — `.claude/skills/pm-dispatch/SKILL.md` :731 (work tree), section 升级与决策, between 「卡上裁决评论是详注,仍是执行与复核的第一落点。」 and 「出决策箱须引同趟取回过的裁决 id …」: ```text - 裁决点名文件/符号/行/调用形状的条款,逐条带读数或注「未验证」;只引规则的条款免。 ``` 118 B (cap 120). Reads: a ruling clause that names a file, a symbol, a line or a call shape carries, per clause, the reading behind it or is marked 「未验证」; a clause that only cites rules owes nothing. 读数 is the corpus's defined term (:166–:167: UTC 取数时刻 + ref/tip; AGENTS.md: a count plus the tree it was taken against), and 「未验证」 is the dispatch-order rule's own mark, so the mark travels verbatim with the clause when the ruling is quoted into a 派发令. **Out** — the 分诊座位职责 line at origin/main :309, 95 B: ```text - 代裁只由维护者召唤的总监席产出,⛔ 永不凭自述、⛔ 无子代理裁决。 ``` Every clause of it is already stated in the ruling section this PR adds to: 「总监席是唯一裁决者:决策箱、代裁与一类自裁只出自本席,⛔ 无子代理无自述。」 (:769) covers 代裁 ⊂ {决策箱、代裁、一类自裁}, 只出自本席, 无自述, 无子代理; 「项目总监席:维护者在所在仓召唤 …」 (:765) covers 维护者召唤; :75 「裁决不在本席,归维护者召唤的总监席」 and the red line :30 「唯一例外是已裁的代裁通道」 still tell the triage seat the same thing in its own sections. Deleting the second spelling is the corpus discipline (one rule per line, no rule stated twice), not a weakening — a control grep for the deleted spelling returns 0 and each restating line returns its line. Why no cheaper payment existed: measured on this tree, of SKILL.md's 598 adjacent bullet pairs ZERO merge under the 120-byte cap (smallest 124 B), and in the 升级与决策 section ZERO of 40 (smallest 158 B); re-wrap funding is refused by the ratchet rule. The whole-file diff vs `origin/main` is exactly these two hunks (`1 insertion(+), 1 deletion(-)`). ## Placement — SKILL.md, not core-rules.md, along the four axes - **实际业务需求** — the consumers are the seat writing a ruling and the dev reading it quoted into a brief; both read SKILL.md in full every session. core-rules.md :3 says 「本文不新增规则」 and :43 makes it 「本文的子集」, so it cannot be the sole home; a twin there would cost a second line in a file at 151 / 151 where ZERO of 122 adjacent pairs merge under the cap (smallest 175 B, measured on this tree) and no line restates another — an unrelated compression to fund it, which the ratchet's own precedent refuses. - **项目长远合理性** — the line sits in the block that defines the ruling record (:729 权威载体, :730 卡上裁决评论, :732 出决策箱须引裁决 id), where 裁决 is the generic term — maintainer ruling, 代裁, 一类自裁, PM 裁量, retriage 改判 — so it binds every seat that rules without naming one. :44 (一条规则在本文与核心条款一处改动,另一处同 PR 同改) is not triggered: the new line is new, and the three dispatch-order lines whose twin is core-rules :116 are byte-untouched. - **防 AI 写错** — the mark is mechanical (a clause either has a 读数 or the literal 「未验证」), per clause, and rides verbatim into the 派发令 under the existing 「裁决不可重裁 / 机制假设须实测」 partition; no seat has to judge whether it is a nice-to-have, and a 「不 expected」 built on an unread function is no longer a legal spelling. - **创业阶段不扩散** — one line, zero net lines, no gate, no script, no new label, no re-grade; the rule-citing exemption keeps the cheap reading and forecloses the expensive one. ## Measured: the neighbours do not contradict it, and the quoted lines are untouched Neighbouring text (work tree): :715 「② 把裁决挂在具名、可证伪的前提上,派发令要求 dev 先验前提再动手。」 (a premise-bearing ruling names its premise — compatible: the new line says which clauses of any ruling are the premises); :180 「裁决明令的动作实施中测出对向事实 ⇒ 照字面执行 …」 (what happens when a measurement contradicts a ruled action — unchanged); :427–:432 (the PM's pre-dispatch staleness re-read of a ruling's 动作面/卡引用面 — about the re-read, not about what the ruling carries); :401 「① 既有裁定/在案类规则/成文纪律机械决定方向,裁决评论点名所用权威」 (the class-1 gate is rule-citing by construction — the exemption agrees with it); `references/lanes/director.md` :11 (the ruling comment's fixed first line — unaffected). Byte-identity against `origin/main` `7f7b8557d` (diff of the extracted lines, empty): the three quoted dispatch-order lines (:541–:543 there, :540–:542 here); PR #18656's :91; PR #18666's :198–:209, :536–:542 (now :535–:541), :625–:631 (now :624–:630), :642–:648 (now :641–:647). The set of over-120 B lines is unchanged (23, all table rows plus the claim-template line); widest row 342 B, pin 342. Line numbers shift by −1 between the deleted line and the inserted one; no hunk overlaps either PR's hunks. ## Readings Head `cb1a949d0` (`origin/main` `f6c2eb7c8` merged — one unrelated driver-sql commit; the SKILL.md delta unchanged). Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` from the worktree (change set from the merge base, no hand-fed paths): 18 commands, list identical before and after the merge. Exit codes captured redirect-then-`$?`, reconciled with `--ran`: 「18 derived, 18 run, 0 NOT-MEASURED (a DERIVED zero — all 18 recorded an exit code and none of them is 3)」. | command | exit | |:--|--:| | `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 | | `node scripts/pm/check-harness-current.mjs --self-test` | 0 | | `pnpm --filter @objectstack/lint run check:doc-formula-expressions` | 0 — first run exit 3 = PREREQUISITE NOT MET (unbuilt `@objectstack/formula` / `@objectstack/lint`, 「Nothing was measured」); built both under `os-verify-lock.sh` (VERDICT command-exit 0, held 165 s, waited 0 s), then rerun | | `pnpm check:agent-test-spelling` | 0 | | `pnpm check:doc-authoring` | 0 | | `pnpm check:driver-memory-census` | 0 | | `pnpm check:nul-bytes` | 0 — 「OK (scanned 8798 text file(s) … no raw ASCII control bytes)」 | | `pnpm check:pm-governed-merges` | 0 | | `pnpm check:pm-governed-prose` | 0 | | `pnpm check:pm-half-states` | 0 | | `pnpm check:pm-skill-id-lint` | 0 | | `pnpm check:pm-skill-ratchet` | 0 — 「.claude/skills/pm-dispatch/SKILL.md is 812 lines (ceiling 812; headroom 0)」 · 「widest table row is 342 bytes (pin 342; headroom 0)」; core-rules.md untouched at 151 / 151 | | `pnpm check:refd-timer-probe` | 0 | | `pnpm check:skill-frame-sync` | 0 — 「the one declared copy of the decision frame is internally coherent (.claude/skills/pm-dispatch/SKILL.md …)」 | | `pnpm check:watch-hint-literal` | 0 | | `pnpm check:pm-expected-skips` (explicit, not derived; its self-test pins the `check-expected-skips.mjs` literal on the enqueue-bar line, untouched) | 0 — 「99 cases pass」 | | `pnpm check:skill-frame-freshness` (explicit, outside the derivation) | 0 — 「the decision frame in this tree is current with origin/main (fetched just now)」 | `node scripts/pm/check-governed-merges.mjs --test .claude/skills/pm-dispatch/SKILL.md` → exit 3, 「GOVERNED — a human merge is the review record for this PR」 — recorded as the expected answer, not a failure. CI-owned and not run locally: the 52 artifact-roster families, the 11 wide-population families and `pnpm lint` (the derivation names them as outside the 18; none reads this file's content). No package build is owed by the diff (no package touched); the one build above was that gate's own prerequisite. ## Acceptance notes - noted, not filed: `references/lanes/director.md` :9 「裁决只存在于本卡:聊天原话、台账行、他卡引述 ⛔ 都不是裁决」 and SKILL.md :729 「一条裁决已记录的权威载体 = 总监席每场收工的摘要台账」 name different carriers as authoritative for a ruling. Observed only; not a defect class (a)–(c), and outside this card. 承接者:无. - noted, not filed: core-rules.md carries no twin of the new line (reasons above). If the maintainer wants one, it is one core-rules line at 151 / 151 with no duplicate to pay — a ruled raise or a compression of another rule, both the maintainer's call. 承接者:the `domain:skills` seat, at the maintainer's word. ## 维护者速读(草稿) **改了什么** — `pm-dispatch` 技能文件加一行、删一行,行数不变(812 / 812):裁决里凡点名文件、符号、行号或调用形状的条款,要么带上得出它的读数,要么该条注「未验证」;只引规则的条款不欠。删掉的是分诊节里一条与总监席节完全重复的「代裁只出自总监席」拼写。 **为什么改** — 派发令早有这条纪律(代码危害断言必须有读数,未亲测就注「未验证」),但裁决没有。裁决被 dev 当作已定事实照抄进派发令,不可重裁。一轮六张卡实测:引规则的两条裁决全对,断言实现事实的四条全错(文件位置、调用形状、挂载拓扑、折叠方向),每次都靠 dev 自己重新测量才发现。权威更高的工件反而举证要求更低,这是结构性缺口,不是三次失误。 **风险与代价(含回滚)** — 零新增门禁、零脚本、零标签;只约束裁决的写法,不要求先测再裁(引规则免费,只有点名代码事实的条款才欠读数或标记)。代价是出裁决的席位多写几个字。回滚 = revert 这一个 commit,两行原样回来。 **席位意见** — (留空,由席位填写) **你要做的(一个动作)** — 批准这个 PR(受管面 `.claude/**`,需要你的 approve 或亲手合并)。 --- _Generated by [Claude Code](https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu)_ Co-authored-by: os-dev <noreply@anthropic.com>
1 parent 18cc3b1 commit 802a91b

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,6 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
306306

307307
- sweep 与首触定级只对多车道仓,单车道仓机械三务自理。
308308
- 发版板(无板仓跳过)、查重/shadow 检查与代裁通道全仓照跑。
309-
- 代裁只由维护者召唤的总监席产出,⛔ 永不凭自述、⛔ 无子代理裁决。
310309
- fire 开局只按名加载互斥检查所需工具,`ToolSearch` 用 `select:`;判定本轮有活才加载其余。
311310
- ⛔ 分诊 fresh session 开局不做泛关键词 ToolSearch;可验判据:空转轮 ~4 万 token 以内。
312311
- 工具加载纪律只约束分诊 fresh session 的开局;执行座位与 dev 不受约束。
@@ -729,6 +728,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
729728
- 鲜度门 = 录前重读晚于正文最后编辑的评论;案例与机械两旗见 `references/dispatch-runbook.md`。
730729
- 一条裁决已记录的权威载体 = 总监席每场收工的摘要台账(卡、权威、方向、状态转移)。
731730
- 卡上裁决评论是详注,仍是执行与复核的第一落点。
731+
- 裁决点名文件/符号/行/调用形状的条款,逐条带读数或注「未验证」;只引规则的条款免。
732732
- 出决策箱须引同趟取回过的裁决 id 与 `Governing text:` 项,⛔ 时间戳加回忆不算引用。
733733
**每个方案必须沿四条固定评估轴分析,这是决策分析的核心原则,不是可选项:**
734734

0 commit comments

Comments
 (0)