Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/skills/pm-dispatch/references/execution-duties.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@
- 下限档给机械卡(正确性由门禁农场机械判定)。
- 默认判断档给 M/L、裁决实施与任何带设计判断的卡;拿不准就升一档。
- 上限 = 契约复审档(`CONTRACT_REVIEW_TIER`),给最重协议/流程/编排卡,按卡取用非新默认。
- 强制条款①:凡改协议语义面的卡一律契约复审档。
- 强制条款①:凡改协议语义面或 `docs/adr/**` 的卡一律契约复审档;后者 effort 下限 `xhigh`。
- 协议语义面 = 本 `SKILL.md`、决策框架拷贝所在文件、`.claude/agents/os-dev.md` 与 `skills/**`。
- 仅 `references/**` 面、或治理面上一行级机械文本改动的卡,降为默认判断档施工。
- 发布的 `skills/**` 整根随 `npx skills add` 发运,⛔ 无一行级豁免,逐行判机械不作数。
- `skills/**`(随 `npx skills add` 发运)与 `docs/adr/**` ⛔ 无一行级豁免,逐行判机械不作数。
- 纯机械一行 PM 酌定可至下限档;降档施工的补偿控制 = 复核席跑契约复审档。
- 降档施工只经契约复审档复核到达维护者,⛔ 不新增标签不新增链。
- 强制条款②:放宽接受集或扩大公开面的卡默认判断档施工;命中即 spec 车道的活。
Expand Down
19 changes: 15 additions & 4 deletions scripts/pm/dispatch-gates.data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,8 +1098,9 @@ export const CHANGE_KIND_ROWS = [
* encoded: the one-line-class downgrade does not exist for a surface under
* `skills/**` — the 2026-09-10 ruling's 必须, because a closed enumeration
* beats a per-line "is this mechanical" call on a catalog third parties
* install — so that entry carries `oneLineExit: false` and `tierLines`
* refuses to offer the exit for any card whose surface hits it.
* install — nor under `docs/adr/**`, whose 2026-10-25 order says 都需要 —
* so those entries carry `oneLineExit: false` and `tierLines` refuses to
* offer the exit for any card whose surface hits one of them.
*
* ## Why the globs are matched with `hintCovers`, asymmetry included
*
Expand Down Expand Up @@ -1160,8 +1161,9 @@ export const CHANGE_KIND_ROWS = [
*
* The authority for the policy is the maintainer ruling quoted in the PM
* dispatch skill (2026-08-10 three-tier ruling, clause ① of its 强制条款, as
* narrowed to protocol semantics by the 2026-08-20 ruling quoted there, and
* widened to the published `skills/**` catalog by the 2026-09-10 ruling).
* narrowed to protocol semantics by the 2026-08-20 ruling quoted there,
* widened to the published `skills/**` catalog by the 2026-09-10 ruling, and
* to ADR text, `docs/adr/**`, by the 2026-10-25 order quoted in its row).
* This table is a machine-readable copy of ONE predicate from it, not a second
* statement of the policy: when they disagree, the skill wins and this table is
* the thing to fix. The frame-copy half of the predicate is DEFINED by another
Expand Down Expand Up @@ -1189,6 +1191,15 @@ export const MANDATORY_TIER_GLOB_ROWS = [
// beats a per-line call on an installed catalog), so it is data, not prose.
oneLineExit: false,
},
{
glob: 'docs/adr/**',
tier: 'CONTRACT_REVIEW_TIER',
why: 'the 2026-10-25 order (marchtian, verbatim 「adr 这种任务都需要 fable extra,重新处理并立skills 卡片」): an ADR binds every later card cut from it until a superseding ADR says otherwise, and lands only by the maintainer\'s hand, so a drafting error is paid by the maintainer and again by each implementation card — 都需要 leaves no one-line exemption, and the same order fixes the effort floor at xhigh (the PM skill states it beside clause ①)',
// 都需要 closes the one-line-class exit by PATH, the same shape as the
// skills/** row; the effort floor is skill text, since this table carries a
// tier and the dispatch-gates freeze admits no new printed line.
oneLineExit: false,
},
];

/**
Expand Down
10 changes: 6 additions & 4 deletions scripts/pm/dispatch-gates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12115,17 +12115,19 @@ export function tierLines(result) {
];
}
// The one-line-class exit is a card-CONTENT judgment for every mandated
// surface but one: a glob declared with `oneLineExit: false` (the published
// catalog, 2026-09-10 ruling) closes it by PATH, and one such hit closes it
// for the WHOLE card — the exit is taken per card, not per file.
// surface except those whose glob is declared with `oneLineExit: false` (the
// published catalog, 2026-09-10 ruling; ADR text, 2026-10-25 order): that
// closes it by PATH, and one such hit closes it for the WHOLE card — the exit
// is taken per card, not per file. The reason printed is the row's own `why`,
// already on the hit lines above, so this line names no ruling of its own.
const oneLineBarred = [...new Set(hits.filter((h) => h.oneLineExit === false).map((h) => h.glob))];
const oneLineExit =
oneLineBarred.length === 0
? 'a one-line-class mechanical governed edit drops to opus execution (sonnet floor for pure one-liners at PM' +
` discretion, compensated by the skill-face review at ${CONTRACT_REVIEW_TIER}) — judged from the card CONTENT,` +
' never from paths'
: `the one-line-class mechanical-edit downgrade is ⛔ NOT available for this surface — ${oneLineBarred.map((g) => `'${g}'`).join(', ')}` +
' carries no one-line exemption (the published catalog, 2026-09-10 ruling), and one such path closes the exit for the whole card';
' carries no one-line exemption (its row declares `oneLineExit: false`; the reason is on its hit line above), and one such path closes the exit for the whole card';
return [
`Model tier — MANDATORY: ${tier} (derived from the file surface, not recalled).`,
...hits.map((h) => ` - ${h.path} ⇢ '${h.glob}' — ${h.why}`),
Expand Down
11 changes: 10 additions & 1 deletion scripts/pm/dispatch-gates.self-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9999,7 +9999,16 @@ export function selfTest({ tier = 'full' } = {}) {
t('no per-file entry for the deleted published PM skill survives it, and its old path carries the root mandate only', !MANDATORY_TIER_GLOBS.some((g) => g.glob.includes('objectstack-pm-dispatch')) && fableOf(['skills/objectstack-pm-dispatch/SKILL.md']).hits.every((h) => h.glob === 'skills/**'));
t('skills/** does NOT reach the internal .claude/skills tree — a pm-dispatch references file still carries no mandate', fableOf(['.claude/skills/pm-dispatch/references/state-machine.md']).mandatory === false);
t('the skills/** entry is declared with its one-line exit switched off, as data', MANDATORY_TIER_GLOBS.some((g) => g.glob === 'skills/**' && g.oneLineExit === false && g.tier === CONTRACT_REVIEW_TIER));
t('every other mandatory entry keeps the one-line exit open (the flag is an opt-out, absent by default)', MANDATORY_TIER_GLOBS.filter((g) => g.glob !== 'skills/**').every((g) => g.oneLineExit === undefined) && catalogHit.hits.every((h) => h.glob !== 'skills/**' || h.oneLineExit === false));
// The ADR order (2026-10-25, 「都需要」): ADR text is the second surface whose
// one-line exit is closed by path; the rest keep the opt-out absent.
const ONE_LINE_BARRED = ['skills/**', 'docs/adr/**'];
t('the docs/adr/** entry is declared at the contract-review tier with its one-line exit switched off, as data', MANDATORY_TIER_GLOBS.some((g) => g.glob === 'docs/adr/**' && g.oneLineExit === false && g.tier === CONTRACT_REVIEW_TIER));
t('every other mandatory entry keeps the one-line exit open (the flag is an opt-out, absent by default)', MANDATORY_TIER_GLOBS.filter((g) => !ONE_LINE_BARRED.includes(g.glob)).every((g) => g.oneLineExit === undefined) && catalogHit.hits.every((h) => h.glob !== 'skills/**' || h.oneLineExit === false));
const adrHit = fableOf(['docs/adr/0028-metadata-naming-and-namespace-isolation.md']);
t('an ADR file is mandated, by the docs/adr/** entry alone', adrHit.tier === CONTRACT_REVIEW_TIER && adrHit.hits.length === 1 && adrHit.hits[0].glob === 'docs/adr/**');
t('docs/adr/** does NOT reach the rest of docs/ — a sibling docs file carries no mandate', fableOf(['docs/NORTH-STAR.md']).mandatory === false && fableOf(['docs/adr-notes.md']).mandatory === false);
const adrLines = tierLines(adrHit).join('\n');
t("the ADR rendering refuses the one-line-class exit, naming the glob, and does not borrow the catalog's reason", adrLines.includes("NOT available for this surface — 'docs/adr/**'") && !adrLines.includes('drops to opus execution') && !adrLines.includes('(the published catalog'));
const catalogLines = tierLines(catalogHit).join('\n');
t('the published-catalog rendering refuses the one-line-class exit, in those words', catalogLines.includes('one-line-class') && catalogLines.includes('NOT available') && catalogLines.includes('no one-line exemption'));
t('and does not offer the opus-execution drop the other mandated surfaces get', !catalogLines.includes('drops to opus execution'));
Expand Down
Loading