Skip to content

pm-dispatch: reserve the contract-review tier for the skills seat and the spec seat’s clause-② review; default tier elsewhere; the director’s tier is the maintainer’s per-summon choice - #17294

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-17285-tier-policy
Sep 10, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/issue-17285-tier-policy

Conversation

@os-justin

Copy link
Copy Markdown
Collaborator

Fixes #17285

Model-tier policy after this PR: the contract-review tier is reserved for the skills seat (the three clause-① protocol files plus the published skills/** catalogs) and for the spec seat's clause-② review; the triage seat and every other execution seat run the default tier and spawn no contract-review-tier subagent; adjudication (decision inbox, 代裁, 一类自裁) belongs to the maintainer-summoned director seat alone, at whatever tier the maintainer summons it — no tier hard gate. The seat's own prose uses the tier names the skill text already uses (契约复审档 = CONTRACT_REVIEW_TIER, 默认判断档 = TIER_DEFAULT); no model name enters any skill file, and scripts/pm/dispatch-gates.mjs stays the single value site of the constant (self-test pinned).

裁决 — the maintainer's words, verbatim and untranslated (chat, 2026-09-10)

  1. 「现在所有车道都会派 fable 任务,没有fable就等契约复审,你综合评估一下,我们哪些车道实际需要fable级别的开发的。哪些只用opus就够了」
  2. 「必须 fable的还包括对外发布的skills」
  3. 「按照你的新建议,只有 spec 和 skills 车道需要fable 对吧。」 — the seat answered 对 with the split in the table below, and the maintainer built rulings 4 and 5 on that answer.
  4. 「分诊席现在也是opus,裁决统一由我以总监的身份召唤。比如我在 hotcrm 或其他元数据项目中可以召唤总监裁决。」
  5. 「现有的卡片如果写了要求fable的,也要让相关的项目经理知道,opus就够了。」
  6. 「裁决(决策箱、代裁、一类自裁)是人工召唤,不需要fable,简单的元数据项目opus就可以,这个我人工判断。」 — added 2026-09-10T03:16Z (card comment 5612109163) while this branch was already in flight; the coordinator relayed it the same minute and the branch carries the amended shape (details under Acceptance notes).

What the rule text says after this PR

seat / channel build review contract-review tier used
triage seat, incl. its emergency-triage subagent never
engine / services / cli / devx / ui / hotcrm execution seats default tier the lane seat's own default-tier review + the gates never
spec seat default tier clause-② PRs: contract-review-tier review (in-seat subagent; fuse unchanged) review only
skills seat contract-review tier for the clause-① files AND the published skills/** catalogs; default tier for references/** and other governed one-liners as today skills-seat self-review at the contract-review tier build + review
adjudication: decision inbox, 代裁, 一类自裁 the maintainer-summoned director seat, and only it, at the tier the maintainer chooses per summon (ruling 6); no tier hard gate, no 免档整理 state

Seat reading recorded for veto: 「分诊席现在也是opus」 is read as covering the whole triage seat including its emergency-triage subagent (SKILL.md :332 below). If the maintainer meant the direct session only, that one line reverts.

Every changed line, before → after, next to the ruling it implements

Line numbers are on origin/main at ebf9a489; identical to the card's d64bcb63 on this surface (git log d64bcb63..ebf9a489 over the five files is empty). Every rewritten line was measured at ≤120 bytes, the ratchet's line cap.

.claude/skills/pm-dispatch/SKILL.md — 812 → 812 (ceiling 812)

  • :75 — ruling 4 (「分诊席现在也是opus,裁决统一由我以总监的身份召唤」)
    • before 「- 分诊席跑普通直连会话、默认判断档;达档职责改派显式传 model 的契约复审档子代理。」
    • after 「- 分诊席跑普通直连会话、默认判断档;裁决不在本席,归维护者召唤的总监席。」
  • :310 — rulings 4 and 6 (代裁 is the summoned director's, no subagent)
    • before 「- 代裁只由达档者产出,⛔ 永不凭自述。」
    • after 「- 代裁只由维护者召唤的总监席产出,⛔ 永不凭自述、⛔ 无子代理裁决。」
  • :311 — rulings 4 and 6 — DELETED (the transcript-verified contract-review-tier subagent is no longer an adjudicator; the director's tier is unqualified)
    • before 「- 达档者 = 显式传 model 的契约复审档子代理(逐份过转录核验),或达档总监席。」
  • :332 — ruling 4 (seat reading above)
    • before 「- 紧急卡直接分诊:维护者点名或 p0 嫌疑 ⇒ 立即起契约复审档分诊子代理,不等定时轮。」
    • after 「- 紧急卡直接分诊:维护者点名或 p0 嫌疑 ⇒ 立即起默认判断档分诊子代理,不等定时轮。」
  • :397 — ruling 6 (置信门 is four gates)
    • before 「- 置信门五条全立才可代裁:① 四棱同向;② 不在人工地板;③ 不推翻既有维护者裁决。」
    • after 「- 置信门四条全立才可代裁:① 四棱同向;② 不在人工地板;③ 不推翻既有维护者裁决。」
  • :398 — ruling 6 (gate ⑤ 档位硬门 deleted outright, not moved)
    • before 「- ④ 执行是否决窗口不是许可门;⑤ 档位硬门达标。」
    • after 「- ④ 执行是否决窗口不是许可门。」
  • :399 — ruling 6 — DELETED (no tier gate on adjudication ⇒ no 「档位未达 ⇒ 整体跳过」 consequence anywhere)
    • before 「- 档位未达 ⇒ 本 fire 代裁整体跳过,卡原样留在决策箱走维护者路径。」
  • :509 — ruling 2 (「必须 fable的还包括对外发布的skills」)
    • before 「- 协议语义面 = 本 SKILL.md 主文件、决策框架拷贝所在文件与 .claude/agents/os-dev.md。」
    • after 「- 协议语义面 = 本 SKILL.md、决策框架拷贝所在文件、.claude/agents/os-dev.mdskills/**。」
  • :510 — unchanged; NEW line inserted directly after it — ruling 2 (必须 ⇒ no one-line exemption for the published catalog)
    • new 「- 发布的 skills/** 整根随 npx skills add 发运,⛔ 无一行级豁免,逐行判机械不作数。」
  • :513 — rulings 1 and 3 (clause-② contract-review-tier review only in the spec seat)
    • before 「- 强制条款②:凡放宽接受集或扩大公开面的卡默认判断档施工、契约复审档复核。」
    • after 「- 强制条款②:放宽接受集或扩大公开面的卡默认判断档施工;契约复审档复核只在 spec 席。」
  • :523 — rulings 3, 4 and 6 (the reservation names skills + spec clause-② review; nobody else spawns the tier)
    • before 「- 契约复审档留给裁决/复审子代理、skills 席与条款②复核。」
    • after 「- 契约复审档留给 skills 席与 spec 席的条款②复核,其余席位 ⛔ 永不起该档子代理。」
  • :522 — unchanged, still true: 「- 席位档策略:skills 车道外的执行席与分诊席默认判断档会话。」
  • :639 — rulings 1 and 3 (twin of core-rules :123; the enqueue gate reads the in-seat clause-② review, whose tier is the seat's)
    • before 「- --tier 嫌疑行是提示非裁定;双肢命中任一 ⇒ 无席内契约复审档 PASS 在案 ⛔ 禁止入队。」
    • after 「- --tier 嫌疑行是提示非裁定;双肢命中任一 ⇒ 无席内条款②复核 PASS 在案 ⛔ 禁止入队。」
  • :642 — rulings 1 and 3 (twin of contract-review :29/:34; other seats self-review at the default tier plus gates)
    • before 「- 交付后复核由派发席在席内完成:达档 PM 自审,或派契约复审档复核子任务。」
    • after 「- 交付后复核由派发席席内完成:spec 席达档自审或派该档子任务,余席默认档自审加门禁。」
  • :767 — ruling 4 (「比如我在 hotcrm 或其他元数据项目中可以召唤总监裁决」)
    • before 「- 项目总监席:人工召唤,入口 /pm-dispatch director;⛔ 无 Routine 无 cron。」
    • after 「- 项目总监席:维护者在所在仓召唤,入口 /pm-dispatch director;⛔ 无 Routine 无 cron。」
  • :769 — ruling 6 (「不需要fable,简单的元数据项目opus就可以,这个我人工判断」)
    • before 「- 总监席档位硬门 = CONTRACT_REVIEW_TIER,不达档只做免档整理并停放四职。」
    • after 「- 总监席档位由维护者按项目人工定,每场记入摘要台账;⛔ 无档位硬门、无免档整理态。」
  • NEW line inserted directly after :769 — rulings 4 and 6 (the director is the only adjudicator)
    • new 「- 总监席是唯一裁决者:决策箱、代裁与一类自裁只出自本席,⛔ 无子代理无自述。」
  • The decision-frame block (:735–:753) is byte-identical: md5 22f2339f0acb64cdb50c7adc9db681c3 before and after.

.claude/skills/pm-dispatch/references/core-rules.md — 151 → 151 (ceiling 151), twins of the above per SKILL.md :44

  • :18 (twin of SKILL.md :75) — ruling 4
    • before 「- 分诊席跑普通直连会话,达档职责改派显式传档位的子代理;自排下次唤醒不超过 55 分钟。」
    • after 「- 分诊席跑普通直连会话、默认判断档,裁决归总监席;自排下次唤醒不超过 55 分钟。」
  • :94 (twin of SKILL.md :310/:769) — rulings 4 and 6
    • before 「- 代裁只由达档者产出 ⛔ 永不凭自述,不达档则通道整体跳过、卡走维护者路径。」
    • after 「- 代裁只出自维护者召唤的总监席 ⛔ 永不凭自述;其档位由维护者按项目定,⛔ 无硬门。」
  • :98 (twin of SKILL.md :397–:398) — ruling 6
    • before 「- 置信门五条全立才可代裁:四棱同向、不在地板、不推翻既有裁决、否决窗口执行、达档。」
    • after 「- 置信门四条全立才可代裁:四棱同向、不在地板、不推翻既有裁决、否决窗口执行。」
  • :112 (twin of SKILL.md :508–:513) — rulings 1, 2 and 3
    • before 「- 一单一次派发调用,档位逐卡显式传参;语义面卡恒契约复审档施工,契约变更卡恒其复核。」
    • after 「- 一单一次派发,档位逐卡显式传参;语义面卡恒契约复审档施工,契约卡达档复核归 spec 席。」
  • :123 (twin of SKILL.md :639) — rulings 1 and 3
    • before 「- 受管面 PR 留 draft 并向两个授权批准账户请审;无达档复核 PASS 的契约卡 ⛔ 禁止入队。」
    • after 「- 受管面 PR 留 draft 并向两个授权批准账户请审;无席内复核 PASS 的契约卡 ⛔ 禁止入队。」
  • :147 — unchanged (names no tier), per the ruling-6 amendment.

.claude/skills/pm-dispatch/references/contract-review.md — 60 → 60 (ceiling 60)

  • :10 — rulings 1 and 3 (the declaration routes to the in-seat contract review; its tier is the seat's)
    • before 「- Clause-②: yes | no 按设计临时:只定是否必过契约复审档复核的保守方向,⛔ 非终审。」
    • after 「- Clause-②: yes | no 按设计临时:只定是否必过席内契约复核的保守方向,⛔ 非终审。」
  • :12 — rulings 1 and 3 (names the spec seat as the at-tier reviewing seat)
    • before 「- 真闸门在 PR 或报告时点的档位复核;声明被档位推翻 ⛔ 不作席位过失。」
    • after 「- 真闸门在 PR 或报告时点的席内复核,达档只在 spec 席;声明被复核推翻 ⛔ 不作席位过失。」
  • :13 — rulings 1 and 3
    • before 「- 机械地板 claim 时可查树:新导出符号或已发布载荷上的新键恒 yes,锁契约复审档复核。」
    • after 「- 机械地板 claim 时可查树:新导出符号或已发布载荷上的新键恒 yes,锁席内契约复核。」
  • :15 — rulings 1 and 3
    • before 「- claim 拿不准 ⇒ 按 yes 挂标走契约复审档复核;⛔ 不建全量分类学与 claim 时决策程序。」
    • after 「- claim 拿不准 ⇒ 按 yes 挂标走席内契约复核;⛔ 不建全量分类学与 claim 时决策程序。」
  • :19 merged into :20 (ceiling budget for the new fuse-population line below; both rules kept verbatim)
    • before 「- 开着的载体恒 = 真实待审。」 + 「- 载体不迁移:⛔ 不迁 PR review 或 Request Changes,⛔ 不为迁移留门。」
    • after 「- 开着的载体恒 = 真实待审;载体不迁移:⛔ 不迁 PR review 或 Request Changes,⛔ 不为迁移留门。」
  • :29 — rulings 1 and 3 (the review-subagent language is the spec seat's)
    • before 「- 审的是低档实现者的契约增量,非自身产物。」
    • after 「- spec 席审低档实现者的契约增量,非自身产物;余席条款②复核 = 默认判断档自审加门禁。」
  • :34 — rulings 1 and 3
    • before 「- 独立性件:契约判断真分叉、或 dev 挂旗待裁 ⇒ 起上下文隔离的复核子代理出第二意见。」
    • after 「- 独立性件,spec 席:契约判断真分叉或 dev 挂旗 ⇒ 起上下文隔离的达档复核子代理。」
  • :42 — rulings 1 and 3 (the landing precheck reads the seat's own review PASS; only the spec seat's is at-tier)
    • before 「- 落地前检三条:① 席内契约档 PASS 在案,即卡上的达档裁决评论。」
    • after 「- 落地前检三条:① 席内条款②复核 PASS 在案,即卡上的复核裁决评论(spec 席达档)。」
  • :50 — rulings 3 and 6 (the fuse population is the spec seat's clause-② review and the skills seat, only)
    • before 「- 席内复核与审计每场前必读一次服役档,读法与陷阱见 platform-readings.md。」
    • after 「- 保险丝只管 spec 席条款②复核与 skills 席,每场前必读服役档,读法见 platform-readings.md。」
  • NEW line inserted directly after :50 — rulings 1, 3 and 6 (other seats' reviews and the director's adjudications are not at-tier verdicts and are not gated by the fuse)
    • new 「- 余席条款②复核与总监席裁决非达档裁决,⛔ 不受本丝;总监席档位由维护者逐场定。」
  • :51–:60 — unchanged: the fuse itself (自述档位不是读数, transcript verification, the quota-exemption refusal) stays for the two seats that still produce at-tier verdicts.

.claude/skills/pm-dispatch/references/lanes/director.md — 72 → 72 (ceiling 72)

  • :12 — ruling 6
    • before 「- 档位 = CONTRACT_REVIEW_TIER,dispatch-gates 常量单源,⛔ 本文不写模型名。」
    • after 「- 档位由维护者逐场按项目人工定,⛔ 无档位硬门、无免档整理态;本文不写模型名。」
  • :13 — ruling 6 (the tier is recorded from the harness reading, never a refusal)
    • before 「- 每场开场按降档保险丝机读认定,细则见 ../contract-review.md。」
    • after 「- 开场读一次服役档记入会话审计行,读法见 ../platform-readings.md;⛔ 不因档位拒裁停四职。」
  • :14 — rulings 4 and 6 (the one clause the card asks for: only adjudicator, summoned in whichever repo the maintainer works in)
    • before 「- 不达档只做免档整理(载体盘点、批次拟稿、待您清单归集),四职停放,⛔ 不裁不清标。」
    • after 「- 唯一裁决者:决策箱、代裁与一类自裁只出自本席;维护者在哪个仓工作就在哪个仓召唤。」
  • :47 — rulings 4 and 6 (the 代裁 channel is no longer 「分诊席或本席」 and has no 硬门)
    • before 「- 代裁通道(分诊席或本席)的硬门、置信门与人工地板见 SKILL.md 分诊座位职责,⛔ 不另抄。」
    • after 「- 代裁通道的置信门与人工地板见 SKILL.md 分诊座位职责,⛔ 不另抄。」
  • :72 — rulings 3 and 6 (the fuse's population, stated on the director's side of the boundary)
    • before 「- 机读保险丝照旧,不可协商。」
    • after 「- 机读保险丝照旧管 spec 席条款②复核与 skills 席,不可协商;本席不在其内。」
  • Nothing about a published-skill director role (separate card, per the card's out-of-scope section).

scripts/pm/dispatch-gates.mjs — tier constants, their docblock, the tier rendering, the self-test

  • MANDATORY_TIER_GLOBS gains { glob: 'skills/**', tier: CONTRACT_REVIEW_TIER, why: 'clause ① (2026-09-10 ruling, verbatim 「必须 fable的还包括对外发布的skills」): the published catalog ships verbatim to third parties by npx skills add objectstack-ai/objectstack/skills and npm create objectstack, so a wrong edit is installed elsewhere before anyone here reads it — and no one-line exemption applies under this root', oneLineExit: false } — ruling 2. oneLineExit: false is the one path-shaped exit the ruling closes (a closed enumeration beats a per-line "is this mechanical" call); every other entry carries no flag (self-test pinned as an opt-out).
  • Docblock: the clause-① set now names the published skills/** catalog (ruling 2); the clause-② paragraph says default-tier build, contract-review-tier REVIEW in the spec seat only, other lanes' review = own default-tier review plus gates, triage and director spawn no contract-review-tier subagent (rulings 1, 3, 4, 6); the sanctioned-exits paragraph states the encoded skills/** exception; the measured-side-effect paragraph adds the re-measured count (47 tracked files under skills/ on ebf9a489, one already covered); the authority paragraph cites the 2026-09-10 widening.
  • deriveTier copies oneLineExit onto each hit; tierLines renders the exits line without the one-line-class exit when any hit carries oneLineExit: false (「⛔ NOT available for this surface … carries no one-line exemption」), and otherwise exactly as before. The two clause-② sentences of the rendering now say 「owes a contract-review-tier REVIEW too (spec seat; default-tier build)」 instead of 「is fable-mandatory too」 — the stale wording would have restated the superseded review scope in every claim comment.
  • Self-test: 15 new cases — the pure derivation (skills/objectstack-data/SKILL.md, skills/objectstack-ai/SKILL.md, a generated references/_index.md under a published skill, the published PM skill covered by two entries at ONE tier, skills/** not reaching .claude/skills/**, the flag as data, the rendering with and without the exit, a mixed surface losing the exit for the whole card) and the CLI end to end (--tier skills/objectstack-data/SKILL.md and --tier skills/objectstack-ai/SKILL.md print the mandate naming 'skills/**' and refuse the exit; --tier .claude/skills/pm-dispatch/references/core-rules.md prints no mandate).
  • ⛔ Not touched: how dispatch-gates resolves a literal or a base (STAGE-THEN-RUN, dispatch-gates: STAGE-THEN-RUN reaches a program by an edge neither follow traverses — check:objectui-changeset inherits nothing from scripts/bump-objectui.sh #14290 is not addressed here — see Acceptance notes), SUSPECT_TIER_GLOBS, TIER_FLOOR/TIER_DEFAULT, the constant's value.

维护者速读(草稿)

改了什么

把「谁用契约复审档」从「所有车道都派、没有就等复审」收窄为两处:skills 席(三个协议文件加对外发布的 skills/**,施工与复核都用)与 spec 席的条款②复核。分诊席、engine/services/cli/devx/ui/hotcrm 执行席全部默认判断档,不再起契约复审档子代理。裁决(决策箱、代裁、一类自裁)只由您召唤的总监席出,档位由您逐场按项目定,不设档位硬门、不再有「不达档只整理不裁」的状态;分诊席不再有每 fire 代裁通道,置信门由五条改四条。dispatch-gates.mjs--tier 推导把 skills/** 整根列入强制档,并明确对它没有一行级豁免。

为什么改

您 2026-09-10 的六条指示(正文顶部逐字引用):fable 只留给 spec 与 skills 车道,对外发布的 skills 必须 fable,分诊席用 opus,裁决由您以总监身份人工召唤且不需要 fable、简单元数据项目 opus 即可。现行规则文本与这六条冲突的每一行都在本 PR 一并改掉,主文件与核心条款、章程、细则四处同改,无一处留旧口径。

风险与代价(含回滚)

  • 代价:spec 席以外的条款②卡不再有契约复审档复核,靠该席默认档自审加 check-clause2-carriers / check-widening-tells 门禁兜底;错误码新码等「恒 yes」的机械地板不变。
  • 风险:总监席若在低档召唤,裁决质量由您人工判断承担(第六条指示的明示选择);分诊紧急子代理改默认档是本席对「分诊席现在也是opus」的整体读法,如与您本意不符只回滚 :332 一行。
  • 回滚:整个 PR 是五个文件的文本改动加一条常量,git revert 一次即回到旧口径;无发布物、无数据迁移。

席位意见

(留空,由席位定稿时填写)

你要做的

人工合并本 draft PR(受管面:.claude/**scripts/pm/**,席位不翻 ready、不入队、不批准);若对 :332 的读法有异议,在 PR 上说一句,本席回滚该行后再合。

Acceptance notes

  • Governed terminal: .claude/** and scripts/pm/** are governed ⇒ draft only; no seat flips it ready, queues it, arms auto-merge or approves it. Changeset: none — neither .claude/** nor scripts/pm/** is in any package's published files[] (fast-track class per the os-dev clause); the PM applies skip-changeset.
  • Ruling-6 amendment: received 2026-09-10T03:16Z from the coordinator and verified on the card (comment 5612109163, body amended in place); folded in before the first push of the skill-file half. Versus the original dispatch: :398–:399 deleted outright (not moved to :769); :769 rewritten to the maintainer's per-summon tier with no hard gate; director.md :12–:14 rewritten accordingly; the fuse population in contract-review.md is spec clause-② review + skills seat only; core-rules :94 carries no tier gate and :98 four gates; 「达档者」 replaced by 「裁决者」/「总监席」 wherever the line no longer speaks of a tier.
  • Ratchet arithmetic (every file at its ceiling, headroom 0 before and after): SKILL.md −2 (:311 and :399 deleted) +2 (the skills/** no-exemption row after :510, the 唯一裁决者 row after :769) = 812/812; core-rules.md 151/151, all in place; contract-review.md −1 (:19 merged into :20) +1 (the fuse-population row after :50) = 60/60; director.md 72/72, all in place. No ceiling raised, none lowered. Every rewritten line measured ≤120 bytes (max seen 119 B) — the cap check-skill-line-ratchet enforces on these files.
  • No issue number and no ruling date enters any skill .md (check:pm-skill-id-lint green; the corpus convention — AGENTS.md header and the id-lint header — is that rules carry no ruling dates, so the 2026-09-10 date lives in the dispatch-gates docblock and why strings and in this PR, not in the rule lines; the dispatch's suggested wordings carried none either).
  • Assumptions A–F, measured: A holds — 812/812, 151/151, 60/60, 72/72; paid exactly as above, no ceiling touched. B holds — grep -n -i "tier|contract-review|model|契约复审|达档|档位" skills/objectstack-pm-dispatch/SKILL.md hits only the heading 「State model」 at :132; check:skill-frame-sync green (「binding sentence present in all 2; 4 count mention(s) agree; 76 markdown files scanned」). C holds — MANDATORY_TIER_GLOBS already goes through hintCovers, which collapses a final-segment ** glob the same way SUSPECT_TIER_GLOBS's packages/spec/src/** is matched; no second matcher, no helper change; skills/** measured not to reach .claude/skills/** (CLI and pure cases). D — dispatch-gates: STAGE-THEN-RUN reaches a program by an edge neither follow traverses — check:objectui-changeset inherits nothing from scripts/bump-objectui.sh #14290 (pm:on-hold, devx, Restart-touch: scripts/pm/dispatch-gates.mjs, STAGE-THEN-RUN resolution) is the declared intersection: this diff is a constant entry, a docblock, the tier rendering and self-test cases; literal/base resolution is untouched, and dispatch-gates: STAGE-THEN-RUN reaches a program by an edge neither follow traverses — check:objectui-changeset inherits nothing from scripts/bump-objectui.sh #14290 is not addressed here. E measured true — node scripts/pm/dispatch-gates.mjs --self-test outlived the 600 s foreground cap and finished detached: verdict line 「✓ dispatch-gates self-test: 1639 cases pass.」 (exit 0, tree ec15afa1); pnpm check:pm-dispatch-gates was then run detached per its own header, verdict quoted below. F — every count re-derived: 置信门 五 → 四 at SKILL.md :397 and core-rules :98 (the only two places that count them; grep -rn 置信门五条 is now empty); 四职 unchanged; 一类自裁门 三判据 unchanged; the clause-① file set is stated by enumeration, not by count.
  • Deviations from the dispatch, declared: (1) lines touched beyond the card's declared regions, each forced by the twin rule at SKILL.md :44 or by the ruling table: SKILL.md :639 and :642 (twins of core-rules :123 and contract-review :29/:34 — 「达档 PM 自审,或派契约复审档复核子任务」 was false for six of eight seats after the ruling), contract-review :19–:20 (a merge paying for the fuse-population row) and :42, director.md :47 and :72 (both named the director inside the 代裁/fuse population). (2) In dispatch-gates.mjs, tierLines is edited beyond the exits line: the two clause-② sentences, for the reason given above. (3) The dispatch's gate spellings check:skill-line-ratchet, check:doc-links, check:control-bytes and check:doc-fence-languages do not exist in package.json; the ratchet is check:pm-skill-ratchet, the control-byte gate is check:nul-bytes, and the doc gates in the derived list are check:doc-authoring and the @objectstack/lint check:doc-formula-expressions. The derived 39-command list was run instead. (4) node scripts/pm/check-governed-queue-guard.mjs --test does not exist — that script reads GITHUB_EVENT_PATH and exits 1 「could not read」 without it; the seat-side predicate is the sibling check-governed-merges.mjs --test, verdict quoted below.
  • --tier acceptance (stdout, exit 0 each): skills/objectstack-data/SKILL.md and skills/objectstack-ai/SKILL.md → 「Model tier — MANDATORY: … - PATH ⇢ 'skills/' — clause ① (2026-09-10 ruling …」 with the exits line 「the one-line-class mechanical-edit downgrade is ⛔ NOT available for this surface — 'skills/' carries no one-line exemption …」; .claude/skills/pm-dispatch/references/core-rules.md → 「Model tier — no path-derived mandate: the surface hits none of the 4 declared glob(s)」; skills/objectstack-pm-dispatch/SKILL.md → two hits (its own entry and skills/**) at one tier, no ambiguity refusal; .claude/skills/pm-dispatch/SKILL.md → the exits line unchanged from before (one-line-class exit still offered).
  • Gates run locally on ec15afa1 (list derived with node scripts/pm/dispatch-gates.mjs --commands from the merge-base change set, 39 commands, identical to the pre-edit derivation over the five paths); verdict lines quoted from each gate's own output, exit codes captured before any pipe:
    • pnpm -s check:pm-skill-ratchet exit 0 — 「✓ check-skill-line-ratchet: declared cross-file moves: 1, total ceilings down 9 lines.」
    • pnpm -s check:skill-frame-sync exit 0 — 「binding sentence present in all 2; 4 count mention(s) agree; 76 markdown files scanned for undeclared copies.」
    • pnpm -s check:skill-compatibility exit 0 — 「✓ check-skill-compatibility-version: 11 SKILL.md file(s) reconciled against 80 workspace packages」
    • pnpm -s check:pm-skill-id-lint exit 0 — 「✓ check-skill-id-lint: 27 file(s) clean (pattern /#[0-9]{3,}/g).」
    • pnpm -s check:nul-bytes exit 0 — 「check-nul-bytes: OK (scanned 8132 text file(s) … no raw ASCII control bytes).」
    • pnpm -s check:pm-governed-prose exit 0 — 「✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces」
    • pnpm -s check:pm-governed-merges exit 0; pnpm -s check:doc-authoring exit 0; pnpm -s check:agent-test-spelling exit 0; pnpm -s check:bash32-floor exit 0; pnpm -s check:cli-command-ids exit 0; pnpm -s check:declared-population-live exit 0 — 「241 of 291 famil(ies) declare a path population, and every one of them reaches this tree's 8139 tracked files」; pnpm -s check:entry-guard exit 0; pnpm -s check:parse-guard exit 0; pnpm -s check:watch-hint-literal exit 0 — 「69 declaration(s) across 4 rostered name(s)」; pnpm -s check:ratchet-remedy-authority exit 0; pnpm -s check:refd-timer-probe exit 0; pnpm -s check:pnpm-filter-targets exit 0; pnpm -s check:cross-package-test-inputs exit 0; pnpm -s check:driver-memory-census exit 0.
    • Direct node families, each exit 0: check-ci-filter-parity, check-closing-keyword-parity (+ --self-test, 「24 assertions, 5 mutations … driven to red」), check-comment-mask-corpus (「6466 files, 0 disagree, 0 unparseable」), check-declaration-mirrors (+ self-test), check-scripts-symbol-anchors (+ self-test), check-self-test-wired (+ self-test, 「every one of the 199 script(s) CI runs that ship a --self-test has that self-test run by CI」), check-self-test-workflow-commands (+ self-test), check-whole-set-label-write (+ self-test), scripts/pm/check-governed-queue-guard.mjs --self-test (「144 cases pass」), report-test-timings.mjs --self-test (「61 cases across 4 batteries」), packages/lint/scripts/check-reference-carrier-shape.mjs (+ self-test, 「6466 file(s) scanned, 649 reference site(s)」).
    • node scripts/pm/dispatch-gates.mjs --self-test exit 0 — 「✓ dispatch-gates self-test: 1639 cases pass.」 (detached; includes the 15 new cases, each found as ✓ by name in the log).
    • pnpm check:pm-dispatch-gates — run detached per its own header (PID recorded, waited on with tail --pid, 03:47Z → 04:00Z); its log ends 「✓ dispatch-gates self-test: 1639 cases pass.」 and carries neither of the wrapper’s failure prints (「✗ check:pm-dispatch-gates: … was killed by …」 / 「could not run …」) — the wrapper prints nothing of its own on success and exits with the battery’s status; the detached process’s exit code itself was not captured.
    • pnpm --filter @objectstack/lint run check:doc-formula-expressions — first run exit 3 「PREREQUISITE NOT MET — the workspace package @objectstack/formula is not built」 (nothing measured); after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2 through scripts/pm/os-verify-lock.sh (「os-verify-lock: VERDICT command-exit 0 · held the lock 191s (3m11s) · waited 0s」, turbo 「Tasks: 4 successful, 4 total」): exit 0 — 「✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 440 files / 1374 TS blocks judged clean by @objectstack/formula.」, plus the spec-TSDoc line (「9 @example(s) judged clean across 1317 packages/spec/src files」) and the field-level line (「14 predicate(s) … judged clean; 6 skipped as undeterminable」), all ✓.
    • node scripts/pm/check-governed-merges.mjs --test over the five files — exit 3 — 「governed-surface predicate: 4 of 5 path(s) hit the register (5 surfaces, repo-agnostic). ⛔ GOVERNED — a human merge is the review record for this PR」; hits .claude/** ×4; scripts/pm/dispatch-gates.mjs is not on the register but the PR is governed whole on the four hits.
    • node scripts/pm/dispatch-gates.mjs --ran reconciliation — exit 0 — 「✓ dispatch-gates --ran: 39 derived famil(ies) accounted for — 39 run, 0 NOT-MEASURED.」 (the record is spelled as the derivation prints it; the runs used pnpm -s, which only silences pnpm’s banner — a first reconciliation with the -s spelling reported those 19 rows UNRUN, which is the record’s spelling, not a missing run).
  • origin/main advanced to a256f189 during this run (the skills seat’s other PR, on skills/objectstack-ai/SKILL.md — disjoint from this diff; git diff --name-only ebf9a489 origin/main over this surface names only that file). The branch stays on ebf9a489; nothing to merge.
  • Not run locally, by design: repo-wide pnpm lint / pnpm test (CI's; no package source is touched, so no build closure and no package tests are owed); the two CI-only families and the Test Core job steps the derivation lists as NOT MEASURED.
  • Not touched, as instructed: .claude/agents/os-dev.md; skills/objectstack-pm-dispatch/SKILL.md (assumption B held); references/lanes/triage.md; references/lanes/spec.md (:25 stays a pointer to SKILL.md 模型分档); the decision frame block; anything in dispatch-gates.mjs beyond the tier constants, their docblock, the tier rendering and the self-test.
  • Noted, not filed (no defect class; 承接者: the skills seat's next charter pass): references/lanes/skills.md:20 (「pm-dispatch 根恒契约复审档」) and references/lanes/cli.md:18 stay true but do not mention the skills/** widening — both defer to --tier, which now carries it.
  • Ruling 5 (telling seats with existing contract-review-tier requirements that the default tier suffices) was executed by the PM seat as card comments (card comment 5612098082) and is not part of this PR, per the card's out-of-scope section.

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

Generated by Claude Code


Generated by Claude Code

os-justin and others added 2 commits September 10, 2026 03:31
…or skills seat, spec clause-② review; director tier is the maintainer's choice

INCOMPLETE AND UNREVIEWED: skill-file half only; dispatch-gates.mjs half follows.

Claude-Session: https://claude.ai/code/session_01MoTv7pn338AZ71owsp19gQ
Co-authored-by: Claude <noreply@anthropic.com>
…-line exit; docblock and self-test follow the 2026-09-10 rulings

INCOMPLETE AND UNREVIEWED: self-test not yet run on this tree.

Claude-Session: https://claude.ai/code/session_01MoTv7pn338AZ71owsp19gQ
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation labels Sep 10, 2026
@os-justin os-justin added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 10, 2026 — with Claude

Copy link
Copy Markdown
Collaborator Author

维护者速读

改了什么 —— 把「谁用契约复审档」从「所有车道都派、没有就等复审」收窄到两处:skills 席(三个协议文件加对外发布的 skills/**,施工与复核都用)和 spec 席的条款②复核。分诊席(含紧急分诊子代理)与 engine / services / cli / devx / ui / hotcrm 执行席全部默认判断档,不再起契约复审档子代理。裁决(决策箱、代裁、一类自裁)只出自你召唤的总监席,档位由你逐场按项目定,不设档位硬门。五个文件:主文件 SKILL.md、核心条款、契约复核细则、总监章程各改几行,dispatch-gates.mjs 的强制档位表加一条 skills/**(并关掉该根的「一行级机械改可降档」出口),配 15 条自测。

为什么改 —— 你今天的六条指示(PR 正文顶部逐字引用)。旧文本把 fable 当默认施工档和默认裁决档,各车道等复核等到饥饿(cli 席量到 8 张卡在等档位);实际风险集中在两个对外契约面(packages/spec 与已发布的 skills 树)和协议自身。改后每个席位的档位有唯一答案,可从 --tier 输出机读。

风险与代价(含回滚) —— 代价:spec 席以外的条款②卡不再有契约复审档复核,靠该席默认档自审加 check-clause2-carriers / check-widening-tells 门禁兜底。风险两点:① 总监席低档召唤时,裁决质量由你人工判断承担(第六条指示的明示选择);② 紧急分诊子代理改默认档是本席对「分诊席现在也是 opus」的整体读法,若非你本意只回滚 :332 一行。回滚:五个文件的文本加一条常量,git revert 一次即回旧口径,无发布物、无迁移。

席位意见 —— 本席按契约复审档自审通过:diff 与卡上六条裁决逐行对得上;四个技能文件全在棘轮天花板上净零(812 / 151 / 60 / 72),决策框架块 md5 未动;--tierskills/objectstack-data/SKILL.mdskills/objectstack-ai/SKILL.md 印出强制档并拒绝一行级出口,对内部 references/core-rules.md 不印强制;棘轮、frame-sync、compat、id-lint、governed-merges --test(exit 3 = 受管)本席在复核 worktree 重跑全绿。dev 超出申报区域改的六行(:639、:642、contract-review :19–:20、:42、director :47、:72)都是「主文件与核心条款同 PR 同改」规则逼出来的孪生行,本席逐行核过。未落进本 PR 的两件:发布版 skills/objectstack-pm-dispatch 是否删除(等你一个字)、hotcrm 卡片归属那三行(#17288,本 PR 合后串行)。

你要做的 —— 人工合并本 draft PR(受管面 .claude/** + scripts/pm/**,席位不翻 ready、不入队、不批准)。若对 :332 紧急分诊子代理改默认档有异议,在 PR 上说一句,本席回滚该行后再合。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 10, 2026 04:41
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 10, 2026
Merged via the queue into main with commit c47edbb Sep 10, 2026
39 of 40 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-17285-tier-policy branch September 10, 2026 05:05
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 size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants