agentic-flow-kit 0.9.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +93 -93
  2. package/modules/hosts/claude/commands/wf-build.md +3 -3
  3. package/modules/hosts/claude/commands/wf-design.md +3 -3
  4. package/modules/hosts/claude/commands/wf-new-task.md +14 -2
  5. package/modules/hosts/claude/commands/wf-pipeline-run.md +35 -0
  6. package/modules/hosts/claude/commands/wf-plan.md +3 -3
  7. package/modules/hosts/claude/commands/wf-sync-hosts.md +1 -1
  8. package/modules/hosts/claude/commands/wf-test.md +1 -1
  9. package/modules/hosts/codex/commands/wf-build.md +3 -3
  10. package/modules/hosts/codex/commands/wf-design.md +3 -3
  11. package/modules/hosts/codex/commands/wf-new-task.md +14 -2
  12. package/modules/hosts/codex/commands/wf-pipeline-run.md +35 -0
  13. package/modules/hosts/codex/commands/wf-plan.md +3 -3
  14. package/modules/hosts/codex/commands/wf-sync-hosts.md +1 -1
  15. package/modules/hosts/codex/commands/wf-test.md +1 -1
  16. package/modules/hosts/cursor/commands/wf-build.md +3 -3
  17. package/modules/hosts/cursor/commands/wf-design.md +3 -3
  18. package/modules/hosts/cursor/commands/wf-new-task.md +14 -2
  19. package/modules/hosts/cursor/commands/wf-pipeline-run.md +35 -0
  20. package/modules/hosts/cursor/commands/wf-plan.md +3 -3
  21. package/modules/hosts/cursor/commands/wf-sync-hosts.md +1 -1
  22. package/modules/hosts/cursor/commands/wf-test.md +1 -1
  23. package/modules/hosts/opencode/commands/wf-build.md +3 -3
  24. package/modules/hosts/opencode/commands/wf-design.md +3 -3
  25. package/modules/hosts/opencode/commands/wf-new-task.md +14 -2
  26. package/modules/hosts/opencode/commands/wf-pipeline-run.md +35 -0
  27. package/modules/hosts/opencode/commands/wf-plan.md +3 -3
  28. package/modules/hosts/opencode/commands/wf-sync-hosts.md +1 -1
  29. package/modules/hosts/opencode/commands/wf-test.md +1 -1
  30. package/modules/hosts/trae/commands/wf-build.md +3 -3
  31. package/modules/hosts/trae/commands/wf-design.md +3 -3
  32. package/modules/hosts/trae/commands/wf-new-task.md +14 -2
  33. package/modules/hosts/trae/commands/wf-pipeline-run.md +36 -0
  34. package/modules/hosts/trae/commands/wf-plan.md +3 -3
  35. package/modules/hosts/trae/commands/wf-sync-hosts.md +1 -1
  36. package/modules/hosts/trae/commands/wf-test.md +1 -1
  37. package/modules/hosts/trae/rules/project-workflow.md +1 -1
  38. package/package.json +45 -45
  39. package/templates/_agents/commands/build.md +2 -2
  40. package/templates/_agents/commands/design.md +1 -1
  41. package/templates/_agents/commands/new-task.md +1 -0
  42. package/templates/_agents/commands/pipeline-run.md +43 -0
  43. package/templates/_agents/commands/plan.md +3 -3
  44. package/templates/_agents/commands/sync-hosts.md +1 -1
  45. package/templates/_agents/scripts/check-lane-surface.mjs +20 -7
  46. package/templates/_agents/scripts/check-lane-surface.test.mjs +24 -2
  47. package/templates/_agents/scripts/check-ledger-invariant.mjs +135 -0
  48. package/templates/_agents/scripts/check-ledger-invariant.test.mjs +161 -0
  49. package/templates/_agents/scripts/check-loop.mjs +70 -18
  50. package/templates/_agents/scripts/check-loop.test.mjs +155 -8
  51. package/templates/_agents/scripts/confirm-doc.mjs +19 -7
  52. package/templates/_agents/scripts/confirm-doc.test.mjs +31 -0
  53. package/templates/_agents/scripts/fill-intent.mjs +1 -1
  54. package/templates/_agents/scripts/fill-plan.test.mjs +4 -3
  55. package/templates/_agents/scripts/gate-checklist.mjs +1 -0
  56. package/templates/_agents/scripts/gen-workflow-metrics.mjs +75 -5
  57. package/templates/_agents/scripts/gen-workflow-metrics.test.mjs +104 -2
  58. package/templates/_agents/scripts/pipeline-run.mjs +999 -0
  59. package/templates/_agents/scripts/pipeline-run.test.mjs +537 -0
  60. package/templates/_agents/scripts/policy.mjs +1 -0
  61. package/templates/_agents/scripts/pre-push.test.mjs +8 -1
  62. package/templates/_agents/scripts/solidify-task.test.mjs +5 -2
  63. package/templates/_agents/scripts/stage-gates.mjs +29 -6
  64. package/templates/_agents/scripts/trust-mode.test.mjs +110 -0
  65. package/templates/_agents/scripts-test-exempt.txt +10 -0
  66. package/templates/_githooks/pre-commit +12 -0
  67. package/templates/workflow/README.md +3 -2
  68. package/templates/workflow/plans/_TEMPLATE.md +1 -1
@@ -119,7 +119,7 @@ export function entryConfirmed(root, base) {
119
119
  const intentAbs = path.join(root, intentRel);
120
120
  if (fs.existsSync(intentAbs)) {
121
121
  const r = judgeDoc(root, intentAbs, intentRel, ENTRY_STATUSES);
122
- return { ...r, kind: 'intent', rel: intentRel, level: readFm(intentAbs, '级别'), risk: readFm(intentAbs, 'risk_level'), storageLegacy: entryStorageLegacy(root, intentAbs) };
122
+ return { ...r, kind: 'intent', rel: intentRel, level: readFm(intentAbs, '级别'), risk: readFm(intentAbs, 'risk_level'), date: readFm(intentAbs, '日期'), storageLegacy: entryStorageLegacy(root, intentAbs) };
123
123
  }
124
124
  const incRel = `workflow/incidents/${base}.md`;
125
125
  const incAbs = path.join(root, incRel);
@@ -143,15 +143,38 @@ export function specConfirmed(root, base) {
143
143
  return judgeDoc(root, abs, rel, ENTRY_STATUSES);
144
144
  }
145
145
 
146
+ // laneOfEntry / laneOfDoc:泳道单源取法(2026-10-02 caliber-convergence 方案 C「分歧双严」)
147
+ // risk_level 为 intent 专属协议字段(fill-intent 双写),生效锚 policy.riskLevelSince:
148
+ // 级别非法/缺失 → suspect(fail-closed 就严);
149
+ // 日期 ≥ 锚(双字段协议期):risk 合法且与级别一致 → 按值判 low/high,否则(缺失/非法/分歧)→ suspect;
150
+ // 日期 < 锚(协议前存量):两值俱在且分歧 → suspect,否则按级别单字段判(risk 缺席不惩罚——字段协议尚不存在)。
151
+ // suspect 消费规则(双严):红线类检查按 low 执行(拦红线);豁免类门(起草豁免/--batch/--auto/加固门
152
+ // lane/泳道豁免/逐阶段深度)按 high 执行(不豁免)。取代原三处并存语义(任一低即低 / 级别优先回落 / 仅级别)。
153
+ export function laneOfEntry(level, risk, riskLevelSince, date) {
154
+ const L = /^L[0-3]$/.test(level || '') ? level : '';
155
+ if (!L) return 'suspect';
156
+ const R = /^L[0-3]$/.test(risk || '') ? risk : '';
157
+ const dualProtocol = !!riskLevelSince && /^\d{4}-\d{2}-\d{2}$/.test(date || '') && date >= riskLevelSince;
158
+ if (dualProtocol) return (R && R === L) ? ((L === 'L0' || L === 'L1') ? 'low' : 'high') : 'suspect';
159
+ if (R && R !== L) return 'suspect';
160
+ return (L === 'L0' || L === 'L1') ? 'low' : 'high';
161
+ }
162
+
163
+ // laneOfDoc:非 intent 件(spec/plan/incident——级别单字段协议):合法按值判,非法 → suspect。
164
+ export function laneOfDoc(level) {
165
+ if (!/^L[0-3]$/.test(level || '')) return 'suspect';
166
+ return (level === 'L0' || level === 'L1') ? 'low' : 'high';
167
+ }
168
+
146
169
  // draftGateFor:起草门总判(kind = 'spec' | 'plan',fill 工具与 confirm-doc 逐阶段门共用)
147
170
  export function draftGateFor(kind, root, base) {
148
171
  const entry = entryConfirmed(root, base);
149
172
  if (!entry.ok) {
150
- // 探索泳道豁免(2026-09-30 hybrid-governance-explore-hardening,口径见头部注释):L0/L1 draft intent
151
- // 放行起草——「先动手后确认」;泳道取级别优先、缺失/非法回落 risk_level(与 fill-intent 双写兼容,
152
- // 级别合法但为 L2/L3 时不回落——fail-closed 就严)。
153
- const lane = /^L[0-3]$/.test(entry.level || '') ? entry.level : entry.risk;
154
- if (entry.kind === 'intent' && entry.status === 'draft' && (lane === 'L0' || lane === 'L1')) {
173
+ // 探索泳道豁免(2026-09-30 hybrid-governance-explore-hardening):L0/L1 draft intent 放行起草
174
+ // ——「先动手后确认」;泳道取法自 2026-10-02 caliber-convergence 起单源 laneOfEntry(方案 C 分歧
175
+ // 双严:suspect 不豁免——级别/risk_level 缺失、非法或分歧均按防御道走入口确认)。
176
+ const lane = laneOfEntry(entry.level, entry.risk, loadKitPolicy(root).riskLevelSince, entry.date);
177
+ if (entry.kind === 'intent' && entry.status === 'draft' && lane === 'low') {
155
178
  return { ok: true, entry, laneBypass: true };
156
179
  }
157
180
  return {
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+ // trust-mode.test.mjs — AI 自治信任等级 fixture 套件(2026-10-01 gate-script-test-coverage)
3
+ // 覆盖:三级语义(Strict/Standard/Trusted 名称↔数值双轨)、缺文件 fail-closed 回落 Strict、
4
+ // --enable/--disable/--status CLI 行为、非法 --level 拒绝、与 confirm-doc --auto 的端到端
5
+ // (Strict 缺文件拒绝不落账 / Trusted 放行 source=ai-auto-trust-L2)。
6
+ import fs from 'node:fs';
7
+ import os from 'node:os';
8
+ import path from 'node:path';
9
+ import { spawnSync } from 'node:child_process';
10
+ import { fileURLToPath } from 'node:url';
11
+
12
+ const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
13
+ const TRUST = path.join(SCRIPT_DIR, 'trust-mode.mjs');
14
+ const CONFIRM = path.join(SCRIPT_DIR, 'confirm-doc.mjs');
15
+
16
+ let pass = 0;
17
+ let fail = 0;
18
+ const check = (desc, cond, detail = '') => {
19
+ if (cond) { pass++; console.log(`PASS ${desc}`); }
20
+ else { fail++; console.log(`FAIL ${desc}${detail ? '\n ' + detail : ''}`); }
21
+ };
22
+
23
+ const mkfix = () => {
24
+ const d = fs.mkdtempSync(path.join(os.tmpdir(), 'trust-test-'));
25
+ for (const s of ['intents', 'plans', 'specs', 'incidents']) {
26
+ fs.mkdirSync(path.join(d, 'workflow', s), { recursive: true });
27
+ }
28
+ fs.mkdirSync(path.join(d, '.agents'), { recursive: true });
29
+ fs.mkdirSync(path.join(d, '.zcode'), { recursive: true });
30
+ fs.writeFileSync(path.join(d, '.agents', 'workflow-enums.txt'),
31
+ ['doc.status.all=draft approved done superseded cancelled', 'doc.status.confirmed=approved done superseded cancelled',
32
+ 'doc.status.active=draft approved', 'doc.status.terminal=done superseded cancelled', 'doc.status.abandoned=superseded cancelled',
33
+ 'incident.status.all=open fixed closed', 'incident.status.active=open', 'level.all=L0 L1 L2 L3'].join('\n') + '\n');
34
+ fs.writeFileSync(path.join(d, '.agents', 'workflow-modules.txt'), '# modules\npipeline\nui\n');
35
+ return d;
36
+ };
37
+ const runTrust = (root, args) => {
38
+ const r = spawnSync(process.execPath, [TRUST, ...args], { cwd: root, encoding: 'utf8' });
39
+ return { code: r.status, out: `${r.stdout || ''}${r.stderr || ''}` };
40
+ };
41
+ const cfg = (root) => {
42
+ const p = path.join(root, '.agents', 'trust-mode.json');
43
+ return fs.existsSync(p) ? JSON.parse(fs.readFileSync(p, 'utf8')) : null;
44
+ };
45
+ const ledgerLines = (root) => {
46
+ const p = path.join(root, '.agents', 'confirmations.jsonl');
47
+ return fs.existsSync(p) ? fs.readFileSync(p, 'utf8').split(/\n/).filter(Boolean) : [];
48
+ };
49
+ const DRAFT = (level = 'L1') => `---\n状态: draft\n级别: ${level}\nrisk_level: ${level}\n日期: 2026-10-01\n模块: pipeline\n---\n# INTENT — demo\n`;
50
+
51
+ // T1:缺文件 → fail-closed Strict 默认
52
+ {
53
+ const d = mkfix();
54
+ const r = runTrust(d, ['--status']);
55
+ check('T1 缺文件 --status 输出 Strict/level0/enabled false', r.code === 0 && r.out.includes('"name": "Strict"') && r.out.includes('"level": 0') && r.out.includes('"enabled": false'), r.out);
56
+ }
57
+ // T2:三级语义映射正确
58
+ {
59
+ check('T2 名称↔数值双轨(NAME_BY_LEVEL 内容)',
60
+ fs.readFileSync(TRUST, 'utf8').includes("NAME_BY_LEVEL = { 0: 'Strict', 1: 'Standard', 2: 'Trusted' }"), '');
61
+ }
62
+ // T3:--enable --level Trusted → 落盘 enabled true/level 2/name Trusted
63
+ {
64
+ const d = mkfix();
65
+ const r = runTrust(d, ['--enable', '--level', 'Trusted']);
66
+ const c = cfg(d);
67
+ check('T3 --level Trusted 落盘正确', r.code === 0 && c && c.enabled === true && c.level === 2 && c.name === 'Trusted', JSON.stringify(c));
68
+ }
69
+ // T4:--enable --level 0(Strict 数字)→ 关闭
70
+ {
71
+ const d = mkfix();
72
+ const r = runTrust(d, ['--enable', '--level', '0']);
73
+ const c = cfg(d);
74
+ check('T4 --level 0 → 关闭 Strict', r.code === 0 && c && c.enabled === false && c.level === 0 && c.name === 'Strict', JSON.stringify(c));
75
+ }
76
+ // T5:非法 --level → 拒绝 exit 1
77
+ {
78
+ const d = mkfix();
79
+ const r = runTrust(d, ['--enable', '--level', 'Bogus']);
80
+ check('T5 非法 --level 拒绝 exit 1', r.code === 1 && r.out.includes('必须为'), r.out);
81
+ }
82
+ // T6:--disable → 关闭 Strict
83
+ {
84
+ const d = mkfix();
85
+ runTrust(d, ['--enable', '--level', 'Trusted']);
86
+ const r = runTrust(d, ['--disable']);
87
+ const c = cfg(d);
88
+ check('T6 --disable 复位 Strict', r.code === 0 && c && c.enabled === false && c.level === 0 && c.name === 'Strict', JSON.stringify(c));
89
+ }
90
+ // T7 e2e:Strict(缺文件)下 confirm-doc --auto 拒绝不落账
91
+ {
92
+ const d = mkfix();
93
+ fs.writeFileSync(path.join(d, 'workflow', 'intents', '2026-10-01-demo.md'), DRAFT('L1'));
94
+ const r = spawnSync(process.execPath, [CONFIRM, 'workflow/intents/2026-10-01-demo.md', '--root', d, '--auto'], { cwd: d, encoding: 'utf8' });
95
+ check('T7 Strict 下 --auto 拒绝且零台账', r.status !== 0 && ledgerLines(d).length === 0, `${r.stdout}${r.stderr}\n${ledgerLines(d).join('|')}`);
96
+ }
97
+ // T8 e2e:Trusted 下 confirm-doc --auto 放行 L1,台账 source=ai-auto-trust-L2
98
+ {
99
+ const d = mkfix();
100
+ fs.writeFileSync(path.join(d, 'workflow', 'intents', '2026-10-01-demo.md'), DRAFT('L1'));
101
+ runTrust(d, ['--enable', '--level', 'Trusted']);
102
+ const r = spawnSync(process.execPath, [CONFIRM, 'workflow/intents/2026-10-01-demo.md', '--root', d, '--auto'], { cwd: d, encoding: 'utf8' });
103
+ const lines = ledgerLines(d);
104
+ check('T8 Trusted 下 --auto 放行并记 ai-auto-trust-L2',
105
+ r.status === 0 && lines.length === 1 && lines[0].includes('ai-auto-trust-L2') && lines[0].includes('"stage":"approved"'),
106
+ `${r.stdout}${r.stderr}\n${lines.join('|')}`);
107
+ }
108
+
109
+ console.log(`\n${fail ? `❌ ${fail} failed` : '✅ all passed'}(${pass} passed)`);
110
+ process.exit(fail ? 1 : 0);
@@ -0,0 +1,10 @@
1
+ # 引擎脚本测试覆盖豁免登记(单源:本文件——check-loop 检查 20 共读,经 sync 下发装副本)
2
+ # 格式:<脚本名> | <豁免理由> | <覆盖证据(套件名;无自动化覆盖如实写「无」)>
3
+ # 语义:登记 ≠ 免责——须写明理由与覆盖证据;无覆盖的登记是「工具/启动器豁免」,后续批次评估补测。
4
+ # 新增引擎脚本默认必须带同名 .test.mjs(README 规范条目);确属库件/工具才登记本文件。
5
+ check-metric-claims.mjs | 经 check-loop.mjs 消费 | 由 check-loop.test.mjs 间接覆盖其调用路径
6
+ ensure-board.mjs | 看板启动器(需真实端口/进程环境) | 无(工具豁免,后续批次评估补测)
7
+ policy.mjs | 库件 | 被 check-loop.test.mjs 直接 import 覆盖
8
+ stage-gates.mjs | 库件 | 被 check-loop.test.mjs 直接 import 覆盖(fill-*/confirm-doc.test 消费其行为)
9
+ verify-wiki-consistency.mjs | wiki 一致性校验工具 | 无(工具豁免,后续批次评估补测)
10
+ wiki-search.mjs | 检索库件 | 无(工具豁免,后续批次评估补测)
@@ -93,6 +93,18 @@ if [ -d templates/_agents ] && [ -f .agents/scripts/check-ledger.mjs ]; then
93
93
  fi
94
94
  fi
95
95
 
96
+ # 确认台账不变量前置(--staged,2026-10-02 ledger-ci-invariant):暂存的 confirmations.jsonl 必须
97
+ # 是 HEAD 的逐字节前缀扩展(append-only)——本地提交时刻即拦「顺手重写台账」,CI 历史全扫兜底。
98
+ # guard 旧装副本自然跳过;暂存未触台账静默。
99
+ if [ -f .agents/scripts/check-ledger-invariant.mjs ] && command -v node >/dev/null 2>&1; then
100
+ if git -c core.quotepath=off diff --cached --name-only | grep -q '^\.agents/confirmations\.jsonl$'; then
101
+ if ! node .agents/scripts/check-ledger-invariant.mjs --staged; then
102
+ echo "pre-commit: 确认台账不变量未通过,提交已阻止——历史行禁删改(append-only),修正走追加补偿行" >&2
103
+ exit 1
104
+ fi
105
+ fi
106
+ fi
107
+
96
108
  # 项目门禁挂载点:.agents/hooks/local-pre-commit(项目自建门禁/门禁模块接线处,存在即执行)
97
109
  if [ -f .agents/hooks/local-pre-commit ]; then
98
110
  run_gate "项目门禁(local-pre-commit)" .agents/hooks/local-pre-commit
@@ -53,8 +53,9 @@
53
53
  3. **确认留痕**:approved / done / fixed / closed 须经 `confirm-doc.mjs`,指纹与台账一致。`--delegated` 原话仅限用户对话内明确确认的当次措辞——官方脚本/门禁不得自动代录或编造 quote(2026-10-01 v09-review-defects:solidify-task 曾自动伪造原话,已修复并纳入回归)。
54
54
  4. **敏感信息**:pre-commit 的 commit-check 扫描密钥。
55
55
  5. **双源与台账**:doctor 核对 managed / owned 的 sha;引擎改动改包源 `templates/` 再 `sync`。
56
+ 6. **台账不可变**(2026-10-02 ledger-ci-invariant):`confirmations.jsonl` 历史行禁删改(append-only 前缀不变量,机器门 = CI 历史全扫 + pre-commit `--staged` 前置);误写/修正只能**追加补偿行**,篡改历史属审计事件(`git revert` 整个提交后重新追加)。
56
57
 
57
- 其余检查(占位符、引用、模块字段、常驻面预算、量化签名、阶段索引、适配器断线)只在 `audit` 不是 `false` 时出警告。
58
+ 其余检查(占位符、引用、模块字段、常驻面预算、量化签名、阶段索引、适配器断线、引擎脚本测试覆盖(检查 20,包源环境——新增引擎脚本默认必须带 `.test.mjs`,库件/工具须登记 `.agents/scripts-test-exempt.txt`,2026-10-01 gate-script-test-coverage))只在 `audit` 不是 `false` 时出警告。
58
59
 
59
60
  **发版草稿**:最近一次改动 `package.json` 的 `version` 的那次提交里,当时已经是 draft 或 approved 的 intent、spec、plan,若被扫描的树上仍是 draft 或 approved,则阻断。当时已是 draft 的不看版本锚。当时已是 approved 的,只在发版版本大于 `policy.mjs` 的 `check17UnclosedAfter` 时阻断;版本 1 没有该键。不带 `--rev` 时现在的状态读工作区,带 `--rev` 时读被推送的那棵树。那次提交之后新建的文件不在范围内。状态为 open 的 incident 不在此列。
60
61
 
@@ -63,7 +64,7 @@
63
64
  ## 闭环规则
64
65
 
65
66
  1. L1 以上新需求始于已确认的 intent;L1 以上修复始于已确认的 incident 草稿(作为 intent 等价入口)
66
- 2. L2 / L3 变更必须先有与入口文档同名的 spec 确认通过(L3 加新会话独立复核),方可起草 plan;L1 用极简 plan——改动面 + 验证方式两节起步,多文件多步骤再加任务拆解/执行顺序。**逐阶段前置已机器强制**(2026-09-30 stage-gate-machine):fill-spec / fill-plan / confirm-doc 校验入口与 spec 前置未过即拒;顺序审计 = check-loop 检查 19
67
+ 2. L2 / L3 变更必须先有与入口文档同名的 spec 确认通过(L3 加新会话独立复核),方可起草 plan;L1 用 Quick-Plan 极简三节——改动方案 / 约束与风险 / 验证计划起步(fill-plan.mjs 单源),多文件多步骤再加任务拆解/执行顺序。**逐阶段前置已机器强制**(2026-09-30 stage-gate-machine):fill-spec / fill-plan / confirm-doc 校验入口与 spec 前置未过即拒;顺序审计 = check-loop 检查 19
67
68
  3. 实现产物必须通过静态门(构建 + 测试 + 项目门禁)
68
69
  4. 线上 / 实测缺陷回落到 `incidents/`,复盘三件套(新 intent、防复发验证、规范条目)缺一不可;**根因属「门禁缺位 / 规范未落地 / 系统性问题」时,即使结构性修复已完成也必须立新 intent** 追踪系统性改进,禁止以「修复已完成」为由绕过 intent 回路
69
70
  5. 关单在 test:逐条勾验入口文档「验收标准」并补证据后 intent → done(不依赖是否上 prod)。done 仍有未勾项会被 check-loop 拦(新建 intent hard-block)。上 prod 另走 deploy(tag / 回滚 / 观察)
@@ -6,7 +6,7 @@
6
6
  # PLAN — <与入口文档同名主题>
7
7
  <!-- 与 intents/ 或 incidents/ 下同名入口文档配对;L2/L3 必须先有 ../specs/ 同名 spec 确认通过;AI 起草、用户对话内确认后开工 -->
8
8
  <!-- frontmatter 受限子集(2026-09-13):状态∈draft/approved/done/superseded/cancelled(严格枚举,附注写备注键);级别∈L0/L1/L2/L3;正文不再写状态/级别行 -->
9
- <!-- L1 极简形态(2026-09-13 瘦身,L1 默认):单/少文件微改动只填「改动面」+「验证方式」两节——改动面逐条列改哪个文件做什么(判据细节直接写进条目),验证一行静态门 + 按需 UI 实测;任务拆解/执行顺序仅 L1 多文件多步骤时保留 -->
9
+ <!-- L1 极简形态(Quick-Plan,与 fill-plan.mjs 单源一致):单/少文件微改动只填「改动方案」+「约束与风险」+「验证计划」三节——改动方案逐条列改哪个文件做什么(判据细节直接写进条目),验证计划一行静态门 + 按需 UI 实测;任务拆解/执行顺序仅 L1 多文件多步骤时保留 -->
10
10
 
11
11
  对应入口:../intents/YYYY-MM-DD-<主题>.md 或 ../incidents/YYYY-MM-DD-<主题>.md(保留实际一项)
12
12
  对应 spec:../specs/YYYY-MM-DD-<主题>.md(L1 可省略)