agentic-flow-kit 1.4.0 → 1.5.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.
- package/modules/hosts/claude/agents/implementer.md +5 -6
- package/modules/hosts/claude/agents/independent-reviewer.md +6 -6
- package/modules/hosts/claude/agents/ui-verifier.md +5 -5
- package/modules/hosts/claude/commands/wf-build.md +21 -21
- package/modules/hosts/claude/commands/wf-deploy.md +2 -2
- package/modules/hosts/claude/commands/wf-design.md +8 -8
- package/modules/hosts/claude/commands/wf-gate-checklist.md +8 -8
- package/modules/hosts/claude/commands/wf-maintain.md +12 -12
- package/modules/hosts/claude/commands/wf-new-task.md +9 -9
- package/modules/hosts/claude/commands/wf-pipeline-run.md +3 -3
- package/modules/hosts/claude/commands/wf-plan.md +10 -11
- package/modules/hosts/claude/commands/wf-review.md +4 -4
- package/modules/hosts/claude/commands/wf-source-sync-check.md +10 -10
- package/modules/hosts/claude/commands/wf-sync-hosts.md +9 -9
- package/modules/hosts/claude/commands/wf-test.md +5 -6
- package/modules/hosts/codex/agents/implementer.md +5 -6
- package/modules/hosts/codex/agents/independent-reviewer.md +6 -6
- package/modules/hosts/codex/agents/ui-verifier.md +5 -5
- package/modules/hosts/codex/commands/wf-build.md +21 -21
- package/modules/hosts/codex/commands/wf-deploy.md +2 -2
- package/modules/hosts/codex/commands/wf-design.md +8 -8
- package/modules/hosts/codex/commands/wf-gate-checklist.md +8 -8
- package/modules/hosts/codex/commands/wf-maintain.md +12 -12
- package/modules/hosts/codex/commands/wf-new-task.md +9 -9
- package/modules/hosts/codex/commands/wf-pipeline-run.md +3 -3
- package/modules/hosts/codex/commands/wf-plan.md +10 -11
- package/modules/hosts/codex/commands/wf-review.md +4 -4
- package/modules/hosts/codex/commands/wf-source-sync-check.md +10 -10
- package/modules/hosts/codex/commands/wf-sync-hosts.md +9 -9
- package/modules/hosts/codex/commands/wf-test.md +5 -6
- package/modules/hosts/cursor/agents/implementer.md +5 -6
- package/modules/hosts/cursor/agents/independent-reviewer.md +6 -6
- package/modules/hosts/cursor/agents/ui-verifier.md +5 -5
- package/modules/hosts/cursor/commands/wf-build.md +21 -21
- package/modules/hosts/cursor/commands/wf-deploy.md +2 -2
- package/modules/hosts/cursor/commands/wf-design.md +8 -8
- package/modules/hosts/cursor/commands/wf-gate-checklist.md +8 -8
- package/modules/hosts/cursor/commands/wf-maintain.md +12 -12
- package/modules/hosts/cursor/commands/wf-new-task.md +9 -9
- package/modules/hosts/cursor/commands/wf-pipeline-run.md +3 -3
- package/modules/hosts/cursor/commands/wf-plan.md +10 -11
- package/modules/hosts/cursor/commands/wf-review.md +4 -4
- package/modules/hosts/cursor/commands/wf-source-sync-check.md +10 -10
- package/modules/hosts/cursor/commands/wf-sync-hosts.md +9 -9
- package/modules/hosts/cursor/commands/wf-test.md +5 -6
- package/modules/hosts/omp/agents/implementer.md +5 -6
- package/modules/hosts/omp/agents/independent-reviewer.md +6 -6
- package/modules/hosts/omp/agents/ui-verifier.md +5 -5
- package/modules/hosts/opencode/agents/implementer.md +5 -6
- package/modules/hosts/opencode/agents/independent-reviewer.md +6 -6
- package/modules/hosts/opencode/agents/ui-verifier.md +5 -5
- package/modules/hosts/opencode/commands/wf-build.md +21 -21
- package/modules/hosts/opencode/commands/wf-deploy.md +2 -2
- package/modules/hosts/opencode/commands/wf-design.md +8 -8
- package/modules/hosts/opencode/commands/wf-gate-checklist.md +8 -8
- package/modules/hosts/opencode/commands/wf-maintain.md +12 -12
- package/modules/hosts/opencode/commands/wf-new-task.md +9 -9
- package/modules/hosts/opencode/commands/wf-pipeline-run.md +3 -3
- package/modules/hosts/opencode/commands/wf-plan.md +10 -11
- package/modules/hosts/opencode/commands/wf-review.md +4 -4
- package/modules/hosts/opencode/commands/wf-source-sync-check.md +10 -10
- package/modules/hosts/opencode/commands/wf-sync-hosts.md +9 -9
- package/modules/hosts/opencode/commands/wf-test.md +5 -6
- package/modules/hosts/trae/agents/implementer.md +5 -6
- package/modules/hosts/trae/agents/independent-reviewer.md +6 -6
- package/modules/hosts/trae/agents/ui-verifier.md +5 -5
- package/modules/hosts/trae/commands/wf-build.md +21 -21
- package/modules/hosts/trae/commands/wf-deploy.md +2 -2
- package/modules/hosts/trae/commands/wf-design.md +8 -8
- package/modules/hosts/trae/commands/wf-gate-checklist.md +8 -8
- package/modules/hosts/trae/commands/wf-maintain.md +12 -12
- package/modules/hosts/trae/commands/wf-new-task.md +9 -9
- package/modules/hosts/trae/commands/wf-pipeline-run.md +3 -3
- package/modules/hosts/trae/commands/wf-plan.md +10 -11
- package/modules/hosts/trae/commands/wf-review.md +4 -4
- package/modules/hosts/trae/commands/wf-source-sync-check.md +10 -10
- package/modules/hosts/trae/commands/wf-sync-hosts.md +9 -9
- package/modules/hosts/trae/commands/wf-test.md +5 -6
- package/modules/hosts/zcode/agents/implementer.md +5 -6
- package/modules/hosts/zcode/agents/independent-reviewer.md +6 -6
- package/modules/hosts/zcode/agents/ui-verifier.md +5 -5
- package/package.json +7 -2
- package/src/doctor.mjs +1 -1
- package/src/init.test.mjs +1 -1
- package/src/run-tests.mjs +15 -1
- package/src/sync-hosts.test.mjs +4 -4
- package/src/sync.test.mjs +1 -1
- package/templates/_agents/commands/build.md +21 -21
- package/templates/_agents/commands/deploy.md +2 -2
- package/templates/_agents/commands/design.md +8 -8
- package/templates/_agents/commands/gate-checklist.md +8 -8
- package/templates/_agents/commands/maintain.md +12 -12
- package/templates/_agents/commands/new-task.md +9 -9
- package/templates/_agents/commands/pipeline-run.md +3 -3
- package/templates/_agents/commands/plan.md +10 -11
- package/templates/_agents/commands/review.md +4 -4
- package/templates/_agents/commands/source-sync-check.md +10 -10
- package/templates/_agents/commands/sync-hosts.md +9 -9
- package/templates/_agents/commands/test.md +5 -6
- package/templates/_agents/roles/implementer.md +5 -6
- package/templates/_agents/roles/independent-reviewer.md +6 -6
- package/templates/_agents/roles/ui-verifier.md +5 -5
- package/templates/_agents/scripts/agg-delegations.cjs +0 -1
- package/templates/_agents/scripts/agg-delegations.test.mjs +2 -2
- package/templates/_agents/scripts/check-hygiene.mjs +2 -2
- package/templates/_agents/scripts/check-ledger-invariant.mjs +0 -1
- package/templates/_agents/scripts/check-loop.mjs +33 -10
- package/templates/_agents/scripts/check-loop.test.mjs +1 -1
- package/templates/_agents/scripts/commit-check-trigger.test.mjs +0 -1
- package/templates/_agents/scripts/confirm-doc.mjs +0 -1
- package/templates/_agents/scripts/ensure-board.mjs +2 -2
- package/templates/_agents/scripts/fill-intent.mjs +2 -2
- package/templates/_agents/scripts/fill-plan.mjs +1 -2
- package/templates/_agents/scripts/gen-wiki-board.mjs +1 -1
- package/templates/_agents/scripts/gen-workflow-dashboard.test.mjs +0 -2
- package/templates/_agents/scripts/gen-workflow-index.test.mjs +1 -1
- package/templates/_agents/scripts/gen-workflow-metrics.mjs +1 -1
- package/templates/_agents/scripts/kb-search.mjs +1 -2
- package/templates/_agents/scripts/kb-search.test.mjs +1 -1
- package/templates/_agents/scripts/pipeline-run-docs.mjs +76 -0
- package/templates/_agents/scripts/pipeline-run-run.mjs +63 -0
- package/templates/_agents/scripts/pipeline-run.mjs +8 -128
- package/templates/_agents/scripts/policy.mjs +7 -1
- package/templates/_agents/scripts/source-sync-check.mjs +2 -2
- package/templates/_agents/scripts/source-sync-check.test.mjs +1 -1
- package/templates/_agents/scripts/verify-wiki-consistency.mjs +0 -1
- package/templates/_agents/scripts/verify.test.mjs +2 -2
- package/templates/_agents/scripts/workflow-board-server.test.mjs +0 -1
- package/templates/_agents/scripts/workflow-enums.test.mjs +0 -1
- package/templates/_agents/scripts-test-exempt.txt +4 -1
|
@@ -25,16 +25,16 @@ next: .agents/commands/build.md(漂移属 build 改权威源未同步导致的
|
|
|
25
25
|
> 比 `templates/_agents` ↔ `modules/hosts/<宿主键>/`;含 `.agents` → 装户:比 `.agents` ↔ 项目根下 `<宿主点目录>/`),
|
|
26
26
|
> 目标根取 `--dir <目录>` > 当前目录。
|
|
27
27
|
|
|
28
|
-
## 何时跑
|
|
28
|
+
## 1. 何时跑
|
|
29
29
|
|
|
30
30
|
- 改 `templates/_agents/commands/*.md` 正文后(11 个 commands 文件)
|
|
31
31
|
- 改 `templates/_agents/roles/*.md` 正文后(3 个 roles 文件)
|
|
32
32
|
- 装户跑 `flow-kit doctor` 报"跨宿主薄适配正文漂移 N 对" WARN 时
|
|
33
33
|
- 不跑:仅改 frontmatter;改 trae 钩子/规则;改包源其他文件
|
|
34
34
|
|
|
35
|
-
## 怎么跑
|
|
35
|
+
## 2. 怎么跑
|
|
36
36
|
|
|
37
|
-
### 默认 `--diff`(仅报告)
|
|
37
|
+
### 2.1 默认 `--diff`(仅报告)
|
|
38
38
|
|
|
39
39
|
```
|
|
40
40
|
node bin/flow-kit.mjs sync-hosts --diff # 包源仓(在包源根跑)
|
|
@@ -48,7 +48,7 @@ flow-kit sync-hosts --diff # 装户仓(在装户根跑;或
|
|
|
48
48
|
- **⚠️ 权威源声明但薄适配缺失** — `add-host <h>` 接管后跑 `--apply` 才会装(apply 不自动创建)
|
|
49
49
|
- **⚠️ 孤儿薄适配(权威源无对应文件)** — 历史残留或宿主特化,apply 不删
|
|
50
50
|
|
|
51
|
-
### `--apply` 单向同步
|
|
51
|
+
### 2.2 `--apply` 单向同步
|
|
52
52
|
|
|
53
53
|
```
|
|
54
54
|
node bin/flow-kit.mjs sync-hosts --apply
|
|
@@ -56,7 +56,7 @@ node bin/flow-kit.mjs sync-hosts --apply
|
|
|
56
56
|
|
|
57
57
|
按权威源正文覆盖薄适配正文段;薄适配原 frontmatter 保留(trae name: wf-X、opencode 描述、zcode/omp 中文风格各自不动)。apply 不反向同步——薄适配手改了正文也会被覆盖(这是设计选择,避免漂移方向歧义)。
|
|
58
58
|
|
|
59
|
-
### 自验
|
|
59
|
+
### 2.3 自验
|
|
60
60
|
|
|
61
61
|
```
|
|
62
62
|
npm test # 含 sync-hosts.test.mjs 8 场景
|
|
@@ -64,7 +64,7 @@ node bin/flow-kit.mjs doctor # 装户跑 §7.x PASS;包源
|
|
|
64
64
|
sh .agents/scripts/check-loop.sh # Windows 无 sh 时 doctor 已探测分流
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
## 边界(不要做)
|
|
67
|
+
## 3. 边界(不要做)
|
|
68
68
|
|
|
69
69
|
- 不要 `--apply` 反向同步(写权威源):权威源是真相,薄适配手改会被覆盖——这是设计,apply 前先看 `--diff`
|
|
70
70
|
- 不要删除孤儿薄适配:可能是宿主特化或历史残留,apply 不动
|
|
@@ -72,14 +72,14 @@ sh .agents/scripts/check-loop.sh # Windows 无 sh 时 doctor 已
|
|
|
72
72
|
- 不要把「避免与权威版本漂移」明文加回去——这是旧契约的指针风格,已被 B-b 正文副本取代
|
|
73
73
|
- 装了新宿主后跑 `--apply`:新宿主目录空白,apply 不会自动创建薄适配(薄适配须经 `add-host <h>` 接管)
|
|
74
74
|
|
|
75
|
-
## 不在本次同步范围
|
|
75
|
+
## 4. 不在本次同步范围
|
|
76
76
|
|
|
77
77
|
- trae 钩子(`modules/hosts/trae/hooks/*.cjs`)— 独立演进的工程件
|
|
78
78
|
- trae 规则(`modules/hosts/trae/rules/*.md`)— 同上
|
|
79
79
|
- 包源 .agents/scripts/*.cjs(pre-commit 等钩子)— 同步由 `flow-kit sync` 走 managed 台账负责
|
|
80
80
|
|
|
81
|
-
## 相关留痕
|
|
81
|
+
## 5. 相关留痕
|
|
82
82
|
|
|
83
83
|
- intent:`workflow/intents/2026-09-25-cross-host-sync.md`
|
|
84
84
|
- plan:`workflow/plans/2026-09-25-cross-host-sync.md`(含 B-b 方案拍板)
|
|
85
|
-
- incident:`workflow/incidents/2026-09-25-wf-runtime.md`(双源纪律教训,规范 §7.x 包源环境跳过)
|
|
85
|
+
- incident:`workflow/incidents/2026-09-25-wf-runtime.md`(双源纪律教训,规范 §7.x 包源环境跳过)
|
|
@@ -65,20 +65,19 @@ node bin/flow-kit.mjs doctor # §6.5 delegations + §6.6 o
|
|
|
65
65
|
- 复核者读入口文档(intent / incident) + spec + plan + diff,判断变更意图与风险
|
|
66
66
|
- 复核意见交用户定性(采纳 / 驳回);采纳项回 `build.md` 修改
|
|
67
67
|
|
|
68
|
-
## 子代理调用约定
|
|
68
|
+
## 5. 子代理调用约定
|
|
69
69
|
|
|
70
70
|
- 静态门不委派;UI 实测委派 `ui-verifier`(静态门通过后)、独立复核委派 `independent-reviewer`,均要求读取对应 `.agents/roles/*.md`;宿主不支持时按 frontmatter `fallback`(reviewer 必须另开新会话,不得主智能体自查冒充)。
|
|
71
71
|
- 子智能体只返回证据与结论——失败项修复仍回 `build.md`,不得在 Test 阶段顺手改代码;修复后重跑本阶段,全过后用户确认再关单。
|
|
72
72
|
|
|
73
|
-
##
|
|
73
|
+
## 6. 确认后(关单)
|
|
74
74
|
|
|
75
|
-
- 输出测试报告(通过项 / 失败项)
|
|
76
|
-
- 失败项已修复并复测通过
|
|
75
|
+
- 输出测试报告(通过项 / 失败项);失败项已修复并复测通过。
|
|
77
76
|
- **关单**(日常闭环点,不依赖是否上 prod):
|
|
78
77
|
- 关单前一键过门:`node .agents/scripts/verify.mjs --doc workflow/intents/<本单>.md`(npm test + check-loop 固定编排,任一失败非零退出,非绿不关单);**`--doc` 把测试绿凭证绑到本单**——不带它落下的绿行不给任何单背书,confirm-doc 前置与检查 8 对账只认带本单 `--doc` 的绿行(仅 v6+ 生效);**装户仓**(根目录无 `package.json`,工程在子目录)默认 `npm test` 不可跑 → 脚本**显式跳过步骤 1 且不落测试绿凭证**(防假绿)并提示;此时按项目口径手工跑测试,或带 `--test-cmd "<项目测试命令>"` 指定(2026-10-07 papercut)
|
|
79
|
-
- 新需求:逐条勾验入口 intent「验收标准」,每条补「证据:」(例如:粘贴 CI 运行结果、UI 截图路径、或具体的 commit SHA),intent
|
|
78
|
+
- 新需求:逐条勾验入口 intent「验收标准」,每条补「证据:」(例如:粘贴 CI 运行结果、UI 截图路径、或具体的 commit SHA),intent → done;同名 spec/Quick-Plan(若有)仍 approved → done。**注意:勾选但缺证据会被 check-loop 拦截(hard-block)**
|
|
80
79
|
- **approved 留痕提交**(2026-09-30 起):done 确认前确认**本次关单文档**的 approved 态已进 git 历史(越早越好——approved 后即应提交;若尚未,先补提交再 done;门为逐份校验,三件套均关单时逐份各自满足)——confirm-doc 的 done 前置门硬校验(历史未出现「状态: approved」→ 拒绝落账);done 后再提交 done 态与其余改动
|
|
81
|
-
|
|
80
|
+
- **确认落态**:唯一入口 `node .agents/scripts/confirm-doc.mjs <path>`(两形态 / 逐件+逐件原话 / done 内容绑定(关单编辑先于 done 确认、confirm-doc 是最后一次写入)/ 台账对质全口径见根 `AGENTS.md` §1.3 确认门)。
|
|
82
81
|
- 修复:防复发验证已落地,incident → closed(经确认门 confirm-doc:open→fixed / fixed→closed 两跳、无单跳;2026-09-28 起 check-loop 15 对账——关单编辑先于 closed 确认,口径同 done 内容绑定)
|
|
83
82
|
- **同族收尾**:入口置终态时,同名 plan 一并置 `done`(spec 见上条),不留 `approved` 孤儿(口径同看板「入口已 done,本 plan 未终态」告警)
|
|
84
83
|
- 主智能体自做的 L1+ 新需求在 `workflow/delegations.md`「自做任务结果表」记一行(修复类不重复记)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 公共角色契约(本文件):`.agents/roles/implementer.md`。宿主薄适配(各宿主目录下 `agents/implementer.md`)正文段同源本文件,frontmatter 各自保留宿主特化字段(check-loop 检查项 6 按本引用校验适配层不断线)。
|
|
4
4
|
|
|
5
|
-
## 职责
|
|
5
|
+
## 1. 职责
|
|
6
6
|
|
|
7
7
|
执行已经由主智能体和用户确认、范围明确的实现任务。适用范围仅限:
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
- 编写或调整任务直接要求的测试
|
|
12
12
|
- 修复与任务直接相关的编译错误
|
|
13
13
|
|
|
14
|
-
## 必需输入
|
|
14
|
+
## 2. 必需输入
|
|
15
15
|
|
|
16
16
|
开始前必须获得:
|
|
17
17
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
任一输入缺失或相互冲突时,停止并向主智能体报告,不自行扩大范围。
|
|
24
24
|
|
|
25
|
-
## 行为边界
|
|
25
|
+
## 3. 行为边界
|
|
26
26
|
|
|
27
27
|
- 只修改明确授权的文件;若必须触及其他文件,先停止并说明原因。
|
|
28
28
|
- 仓库可能有其他智能体或用户同时工作;保留现有改动,不回退、不覆盖无关修改。
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
- 不执行提交、推送、发布、数据迁移或破坏性操作。
|
|
32
32
|
- 不顺手重构、格式化或清理与任务无关的代码。
|
|
33
33
|
|
|
34
|
-
## 验证
|
|
34
|
+
## 4. 验证
|
|
35
35
|
|
|
36
36
|
- 运行任务指定的最小相关检查。
|
|
37
37
|
- 检查失败时只修复由本次改动引起且仍在授权范围内的问题。
|
|
38
38
|
- 同一验证连续失败三次,或继续需要猜测需求时,停止并报告阻塞。
|
|
39
39
|
|
|
40
|
-
## 输出
|
|
40
|
+
## 5. 输出
|
|
41
41
|
|
|
42
42
|
返回给主智能体:
|
|
43
43
|
|
|
@@ -45,4 +45,3 @@
|
|
|
45
45
|
2. 每个文件的改动摘要
|
|
46
46
|
3. 已运行的验证及结果
|
|
47
47
|
4. 未解决的阻塞或剩余风险
|
|
48
|
-
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> 公共角色契约(本文件):`.agents/roles/independent-reviewer.md`。宿主薄适配(各宿主目录下 `agents/independent-reviewer.md`)正文段同源本文件,frontmatter 各自保留宿主特化字段(check-loop 检查项 6 按本引用校验适配层不断线)。
|
|
4
4
|
|
|
5
|
-
## 职责
|
|
5
|
+
## 1. 职责
|
|
6
6
|
|
|
7
7
|
在独立上下文中对 spec、plan 或代码 diff 做只读复核,发现原作者可能遗漏的正确性、契约、架构、数据安全和回归风险。
|
|
8
8
|
|
|
9
|
-
## 必需输入
|
|
9
|
+
## 2. 必需输入
|
|
10
10
|
|
|
11
11
|
开始前必须获得:
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
输入不足以确定范围时,停止并向主智能体报告。
|
|
19
19
|
|
|
20
|
-
## 行为边界
|
|
20
|
+
## 3. 行为边界
|
|
21
21
|
|
|
22
22
|
- 只读,不修改任何仓库文件。
|
|
23
23
|
- 不替用户决定问题定性、方案取舍、合入或上线。
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
- 不把样式偏好、假设性风险或既有无关问题包装成缺陷。
|
|
27
27
|
- 无法验证的事项明确标为未验证,不声称已经通过。
|
|
28
28
|
|
|
29
|
-
## 复核重点
|
|
29
|
+
## 4. 复核重点
|
|
30
30
|
|
|
31
31
|
1. 实现是否满足入口文档和验收标准
|
|
32
32
|
2. 是否违反根 `AGENTS.md` 与改动域目录级 `AGENTS.md` 的架构、数据和所在域红线
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
4. 是否缺少能防止回归的验证
|
|
35
35
|
5. 是否存在数据丢失、安全、权限或发布风险
|
|
36
36
|
|
|
37
|
-
## 输出
|
|
37
|
+
## 5. 输出
|
|
38
38
|
|
|
39
39
|
按严重度输出问题清单:
|
|
40
40
|
|
|
@@ -42,4 +42,4 @@
|
|
|
42
42
|
- `P1`:功能错误、明确回归或违反项目硬约束
|
|
43
43
|
- `P2`:非阻断但有证据的维护性问题
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
每项必须包含:位置、问题、证据、建议。没有发现时明确输出"未发现阻断问题",并列出未验证范围。
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> 公共角色契约(本文件):`.agents/roles/ui-verifier.md`。宿主薄适配(各宿主目录下 `agents/ui-verifier.md`)正文段同源本文件,frontmatter 各自保留宿主特化字段(check-loop 检查项 6 按本引用校验适配层不断线)。
|
|
4
4
|
|
|
5
|
-
## 职责
|
|
5
|
+
## 1. 职责
|
|
6
6
|
|
|
7
7
|
对已经实现的 UI 改动执行浏览器实测并收集可复核证据。只验证,不修复。
|
|
8
8
|
|
|
9
|
-
## 必需输入
|
|
9
|
+
## 2. 必需输入
|
|
10
10
|
|
|
11
11
|
开始前必须获得:
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
缺少可观察的预期结果时,停止并向主智能体报告。
|
|
19
19
|
|
|
20
|
-
## 执行
|
|
20
|
+
## 3. 执行
|
|
21
21
|
|
|
22
22
|
1. 读取项目根目录 `AGENTS.md`,以及改动域目录级 `AGENTS.md`(如有,前端改动域)。
|
|
23
23
|
2. 读取并遵循项目 UI 实测技能 `.agents/skills/verify-ui/SKILL.md`(如有)。
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
5. 收集控制台、网络请求、DOM 数据或截图等证据。
|
|
27
27
|
6. 结束时关闭本次启动的后台进程。
|
|
28
28
|
|
|
29
|
-
## 行为边界
|
|
29
|
+
## 4. 行为边界
|
|
30
30
|
|
|
31
31
|
- 不修改代码、配置、测试数据或工作流文档。
|
|
32
32
|
- 不自行修复发现的问题;将失败证据交还主智能体。
|
|
33
33
|
- 不使用生产环境或真实业务数据。
|
|
34
34
|
- 无法启动环境或完成关键路径时,报告阻塞,不把部分验证标记为通过。
|
|
35
35
|
|
|
36
|
-
## 输出
|
|
36
|
+
## 5. 输出
|
|
37
37
|
|
|
38
38
|
返回:
|
|
39
39
|
|
|
@@ -14,7 +14,6 @@ const fs = require('fs');
|
|
|
14
14
|
const path = require('path');
|
|
15
15
|
|
|
16
16
|
const ROOT = path.resolve(__dirname, '..', '..');
|
|
17
|
-
const LEDGER = path.join(ROOT, 'workflow', 'delegations.md');
|
|
18
17
|
const INCIDENTS = path.join(ROOT, 'workflow', 'incidents');
|
|
19
18
|
|
|
20
19
|
const argMonth = (process.argv.find((a) => a.startsWith('--month=')) || '').split('=')[1] || null;
|
|
@@ -96,8 +96,8 @@ const { metrics, gateMonth, expansionVerdict, parseResult } = requireCjs(path.jo
|
|
|
96
96
|
// 场景 4:审查反例——30 任务、2 主兜底、平均返工 0.25(旧口径四门全过,声明口径下必须 ❌)
|
|
97
97
|
{
|
|
98
98
|
const rows = [
|
|
99
|
-
...Array.from({ length: 22 }, (
|
|
100
|
-
...Array.from({ length: 6 }, (
|
|
99
|
+
...Array.from({ length: 22 }, () => ({ scope: '委派', result: '一次通过' })),
|
|
100
|
+
...Array.from({ length: 6 }, () => ({ scope: '委派', result: '返工×1' })),
|
|
101
101
|
{ scope: '委派', result: '主兜底' }, { scope: '委派', result: '主兜底' },
|
|
102
102
|
];
|
|
103
103
|
const m = metrics(rows);
|
|
@@ -85,7 +85,7 @@ export function runCheckHygiene(ctx) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
// --- 9. 文件名英文 kebab-case [warning]
|
|
88
|
+
// --- 9. 文件名英文 kebab-case [warning](2026-09-11 规则)---
|
|
89
89
|
markGate('9', '文件名 kebab-case');
|
|
90
90
|
for (const sub of DOC_DIRS) {
|
|
91
91
|
const dir = path.join(ROOT, WF, sub);
|
|
@@ -99,7 +99,7 @@ export function runCheckHygiene(ctx) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
// --- 11. 生成物漂移 [warning](调生成器 --check
|
|
102
|
+
// --- 11. 生成物漂移 [warning](调生成器 --check,口径单一不复刻渲染;INDEX 2026-09-21 检索层 / DASHBOARD 2026-10-08 扩覆盖面)---
|
|
103
103
|
markGate('11', '生成物漂移(INDEX+DASHBOARD)');
|
|
104
104
|
// ⚠️ 位置:本段须排在 12/13 之前——check-loop 输出按 warnings 插入序,行序是稳定输出契约
|
|
105
105
|
// (pre-push / pre-commit 消费者 + doctor 按 WARN 行计数);原序为 2 → 9 → 11 → 12 → 13,勿调换。
|
|
@@ -41,7 +41,6 @@ const gitText = (args) => execFileSync('git', args, { cwd: ROOT, encoding: 'utf8
|
|
|
41
41
|
const blobOf = (ref) => git(['show', ref]); // ref 必须为完整对象引用(<sha>:<path> / HEAD:<path> / :<path>)
|
|
42
42
|
|
|
43
43
|
const problems = [];
|
|
44
|
-
const fail = (msg) => { console.error(msg); process.exit(1); };
|
|
45
44
|
|
|
46
45
|
// ---- --staged:暂存 blob ⊇ HEAD blob ----
|
|
47
46
|
if (staged) {
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
// L0/L1 勾触达红线 → 「红线判低」hard——协作道不受理 STOP 级改动,就高不就低,
|
|
18
18
|
// 2026-09-30 hybrid-governance-risk-lanes) [hard-block]
|
|
19
19
|
// 2. 模板字段占位符残留(YYYY-MM-DD / <主题> 等未替换;<主题> 与 .md 同行 = 命名约定描述,豁免) [warning]
|
|
20
|
-
// (2026-10-08 selfmeasure-and-modularize:实现已迁 check-hygiene.mjs,判据与文案未变)
|
|
21
20
|
// 3. incidents 复盘三件套完整性 + 状态严格枚举 + 新 intent 回路(回路断档=hard,其他=warning)
|
|
22
21
|
// 4. 引用有效性(文档/指令中引用的 .agents/ 路径必须存在;支持 fill-{a,b,c}.mjs 花括号展开与 fill-*.mjs 通配;
|
|
23
22
|
// workflow 文档仅扫活跃态——终态件的引用是历史叙述,不扫,2026-09-27 audit-gate-hardening) [warning]
|
|
@@ -30,15 +29,11 @@
|
|
|
30
29
|
// 非 git / 查不到加入记录 → 不可判定 → 走存量口径(不误报 hard)
|
|
31
30
|
// 证据可写在 [x] 行的续行(仓库通写法「(证据:…)」另起一行;全/半角冒号皆认)
|
|
32
31
|
// 9. 文件名英文 kebab-case(非 ASCII 文件名=warning,2026-09-11 规则)
|
|
33
|
-
// (2026-10-08 selfmeasure-and-modularize:实现已迁 check-hygiene.mjs,判据与文案未变)
|
|
34
32
|
// 10. 级别 vs 迁移文件一致性(L1/L2 入口文档加入提交触及迁移 SQL/Migrations=疑似判低,warning)
|
|
35
33
|
// 11. 生成物漂移:workflow/INDEX.md(2026-09-21 检索层) + workflow/DASHBOARD.md(2026-10-08 扩覆盖面)=warning;
|
|
36
|
-
// 各自调对应生成器 --check,口径单一不复刻渲染;实现已迁 check-hygiene.mjs
|
|
37
34
|
// 12. frontmatter「模块:」合法性(枚举非法 / 2026-09-22 起新建缺字段=warning;词表单源 .agents/workflow-modules.txt)
|
|
38
|
-
// (2026-10-08 selfmeasure-and-modularize:实现已迁 check-hygiene.mjs,判据与文案未变)
|
|
39
35
|
// 13. 常驻面体积预算(超限=warning;判定单源 rule-budget.sh——经 sh 调用,
|
|
40
36
|
// 无 sh 环境静默跳过:advisory 级且 pre-commit 侧在 git 钩子 sh 环境照常硬拦)
|
|
41
|
-
// (2026-10-08 selfmeasure-and-modularize:实现已迁 check-hygiene.mjs,判据与文案未变)
|
|
42
37
|
// 14. 新 done 的 spec/plan 须在 git 历史里出现过 `状态: approved`(确认环节留痕,2026-09-22;恒 advisory 永不升级 hard)
|
|
43
38
|
// 15. 确认指纹对账(2026-09-27 起:approved/done 须 confirm-doc.mjs 确认指纹+台账配对,缺=hard-block;
|
|
44
39
|
// 两形态——TTY 亲手 / --delegated 对话委托代录,台账 source 如实区分,配对判据与 source 无关)
|
|
@@ -114,8 +109,6 @@ import os from 'node:os';
|
|
|
114
109
|
import path from 'node:path';
|
|
115
110
|
import { spawnSync } from 'node:child_process';
|
|
116
111
|
import { createHash } from 'node:crypto';
|
|
117
|
-
import { createRequire } from 'node:module';
|
|
118
|
-
import { fileURLToPath } from 'node:url';
|
|
119
112
|
import { loadEnums } from './workflow-enums.mjs';
|
|
120
113
|
import { runCheck16 } from './check-metric-claims.mjs';
|
|
121
114
|
import { auditEnabled, loadKitPolicy, hasFreshVerifyLine } from './policy.mjs';
|
|
@@ -129,7 +122,6 @@ import { MARK_RE, approvedTraceHit } from './stage-gates.mjs';
|
|
|
129
122
|
import { runCheckHygiene } from './check-hygiene.mjs';
|
|
130
123
|
import { gateSeg, finishSegs, makeCollector } from './gate-seg.mjs';
|
|
131
124
|
|
|
132
|
-
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
133
125
|
// CHECK_LOOP_GIT:测试注入钩子(指向不存在/不可执行路径可稳定触发 spawn 异常);未设置时与原行为逐字节一致(2026-10-05-gitout-fail-open)
|
|
134
126
|
const GIT = process.env.CHECK_LOOP_GIT || (process.platform === 'win32' ? 'git.exe' : 'git');
|
|
135
127
|
|
|
@@ -723,7 +715,7 @@ export function runCheckLoop(opts = {}) {
|
|
|
723
715
|
if (/^##\s+(改动面|任务拆解|改动方案)/.test(line)) { inDeclaredSec = true; continue; }
|
|
724
716
|
if (inDeclaredSec && /^##\s+/.test(line)) { inDeclaredSec = false; continue; }
|
|
725
717
|
if (inDeclaredSec) {
|
|
726
|
-
const fileMatch = line.match(/([a-zA-Z0-9._
|
|
718
|
+
const fileMatch = line.match(/([a-zA-Z0-9._/-]+\.[a-zA-Z0-9]+)/);
|
|
727
719
|
if (fileMatch) declaredFiles.push(fileMatch[1]);
|
|
728
720
|
}
|
|
729
721
|
}
|
|
@@ -773,8 +765,39 @@ export function runCheckLoop(opts = {}) {
|
|
|
773
765
|
const verifyFreshGlobal = verifyLines ? hasFreshVerifyLine(verifyLines) : false;
|
|
774
766
|
// 2026-10-08 verify-doc-binding:v6+(verifyDocSince)按本 doc 精确匹配;缺键维持全局布尔。
|
|
775
767
|
const verifyDocBound = typeof kitPolicy.verifyDocSince === 'string';
|
|
768
|
+
// 2026-10-09 verifydoc-anchor:v6 精确匹配的**追溯边界**——只对「确认门 done ts ≥ verifyDocSince」的单生效。
|
|
769
|
+
// 背景(用户 2026-10-09 拍板 D):4 单(verify-evidence / workflow-dashboard / selfmeasure / gate-roi-metrics)
|
|
770
|
+
// 的 done ts 均 < v6 上线日(2026-10-08 17:37),它们关单时既无 --doc 机制、也无从补证——被精确匹配追责
|
|
771
|
+
// 会产 9 条不可消退 advisory(补跑=自证,回溯不了关单当时全绿,与门禁本意相悖)。退回全局布尔 = v5 语义
|
|
772
|
+
// (不误报、不伪造),与检查 15/18 生效日锚同构。done ts 台账读一次循环外缓存,零新增子进程。
|
|
773
|
+
const verifyDocSinceTs = verifyDocBound ? kitPolicy.verifyDocSince : null;
|
|
774
|
+
const doneTsOf = (() => {
|
|
775
|
+
const map = new Map();
|
|
776
|
+
try {
|
|
777
|
+
const lp = path.join(ROOT, '.agents', 'confirmations.jsonl');
|
|
778
|
+
if (fs.existsSync(lp)) {
|
|
779
|
+
for (const line of fs.readFileSync(lp, 'utf8').split(/\r?\n/)) {
|
|
780
|
+
if (!line.trim()) continue;
|
|
781
|
+
try {
|
|
782
|
+
const e = JSON.parse(line);
|
|
783
|
+
// append-only 取末次 done 跳转(同一 doc 多次 done 取最后一条 ts)
|
|
784
|
+
if (e && e.doc && ['done', 'closed'].includes(e.stage)) map.set(e.doc, e.ts || '');
|
|
785
|
+
} catch { /* 坏行跳过(同检查 15 口径) */ }
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
} catch { /* 台账不可读 → 无锚 → 全走全局布尔(fail-open,不误报 hard) */ }
|
|
789
|
+
return map;
|
|
790
|
+
})();
|
|
791
|
+
// 该 doc 的确认门 done 是否落在 v6 追溯窗口内;无台账行 / 台账不可读 → false(存量豁免,退回全局布尔)
|
|
792
|
+
// 2026-10-09 verifydoc-anchor:按 ISO 时刻比较(不再是日期粒度)——机制上线当日的更早时刻 done 的单
|
|
793
|
+
// 仍在窗口外(日期粒度会把同日的早时刻误纳入,见 policy.mjs verifyDocSince 注释)。
|
|
794
|
+
const verifyDocInWindow = (rel) => {
|
|
795
|
+
if (!verifyDocSinceTs) return false;
|
|
796
|
+
const ts = doneTsOf.get(rel);
|
|
797
|
+
return !!ts && ts >= verifyDocSinceTs;
|
|
798
|
+
};
|
|
776
799
|
const verifyFreshFor = (rel) => (verifyLines
|
|
777
|
-
? hasFreshVerifyLine(verifyLines, Date.now(),
|
|
800
|
+
? hasFreshVerifyLine(verifyLines, Date.now(), verifyDocInWindow(rel) ? rel : null)
|
|
778
801
|
: false);
|
|
779
802
|
for (const intent of docFiles('intents')) {
|
|
780
803
|
if (fmGet(intent, '状态') !== 'done') continue;
|
|
@@ -12,7 +12,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
12
12
|
import { fileURLToPath } from 'node:url';
|
|
13
13
|
import { computeFingerprint } from './confirm-doc.mjs';
|
|
14
14
|
import { POLICIES, loadKitPolicy } from './policy.mjs';
|
|
15
|
-
import { entryConfirmed,
|
|
15
|
+
import { entryConfirmed, laneOfEntry, laneOfDoc } from './stage-gates.mjs';
|
|
16
16
|
|
|
17
17
|
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
18
18
|
const CHECK_LOOP = path.join(SCRIPT_DIR, 'check-loop.mjs');
|
|
@@ -9,7 +9,6 @@ import { fileURLToPath } from 'node:url';
|
|
|
9
9
|
|
|
10
10
|
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
11
11
|
const HOOK = path.join(SCRIPT_DIR, '..', 'hooks', 'commit-check.cjs');
|
|
12
|
-
const MARK = 'TRIGGER_TEST_BUILD_RAN';
|
|
13
12
|
|
|
14
13
|
let pass = 0, fail = 0;
|
|
15
14
|
const check = (desc, cond, detail = '') => {
|
|
@@ -38,7 +38,6 @@ import fs from 'node:fs';
|
|
|
38
38
|
import path from 'node:path';
|
|
39
39
|
import readline from 'node:readline';
|
|
40
40
|
import { createHash, randomBytes } from 'node:crypto';
|
|
41
|
-
import { fileURLToPath } from 'node:url';
|
|
42
41
|
import { confirmGateFor, doneGateFor, laneOfEntry, laneOfDoc } from './stage-gates.mjs';
|
|
43
42
|
import { loadKitPolicy, hasFreshVerifyLine } from './policy.mjs';
|
|
44
43
|
|
|
@@ -105,7 +105,7 @@ function openBrowser(url) {
|
|
|
105
105
|
try {
|
|
106
106
|
if (process.platform === 'win32') spawn('cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore', windowsHide: true }).unref();
|
|
107
107
|
else spawn(process.platform === 'darwin' ? 'open' : 'xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
108
|
-
} catch { }
|
|
108
|
+
} catch { /* 浏览器拉起失败不阻断看板流程 */ }
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// ---- 主流程(返回退出码,自然排水退出——不用 process.exit:强退在 Windows 上会触发 libuv 断言)----
|
|
@@ -123,7 +123,7 @@ async function main() {
|
|
|
123
123
|
board = b;
|
|
124
124
|
const stale = staleCode(b.startedAt);
|
|
125
125
|
if (stale === true) {
|
|
126
|
-
try { process.kill(b.pid); } catch {
|
|
126
|
+
try { process.kill(b.pid); } catch { /* 进程可能已自行退出 */ }
|
|
127
127
|
await sleep(500);
|
|
128
128
|
action = 'restarted (stale code detected)';
|
|
129
129
|
} else if (stale === null) {
|
|
@@ -31,8 +31,8 @@ const SECTIONS = [
|
|
|
31
31
|
{ title: '目标', hint: '- <可验证的目标>' },
|
|
32
32
|
{ title: '非目标(L1 微改动无实质内容可删本节,不硬填)', hint: '- <明确不做的,防止范围蔓延>' },
|
|
33
33
|
{ title: '约束(L1 微改动无实质内容可删本节,不硬填)', hint: '- <复用什么、不许动什么>' },
|
|
34
|
-
{ title: '影响面', hint: '- 模块:<词表之一,见 .agents/workflow-modules.txt>\n- 数据库:无 / <表名>(涉及 schema 变更
|
|
35
|
-
{ title: '触达红线(对照 AGENTS.md,勾选仅标记触及范围;具体如何满足在同名 spec 或 Quick-Plan 中说明)', hint: '- [ ] <按本项目 AGENTS.md 红线逐行补;无则删本行>\n- [ ] 规则 / 契约变更(编码权威 / 共享契约 / 接口签名 / 既有参数语义 /
|
|
34
|
+
{ title: '影响面', hint: '- 模块:<词表之一,见 .agents/workflow-modules.txt>\n- 数据库:无 / <表名>(涉及 schema 变更 → L3;无 schema 的运行时 / 管线结构面亦为 L3,判据见 .agents/commands/new-task.md §级别判断)\n- 前端页面:<路由或组件,无则删本行>' },
|
|
35
|
+
{ title: '触达红线(对照 AGENTS.md,勾选仅标记触及范围;具体如何满足在同名 spec 或 Quick-Plan 中说明)', hint: '- [ ] <按本项目 AGENTS.md 红线逐行补;无则删本行>\n- [ ] 规则 / 契约变更(编码权威 / 共享契约 / 接口签名 / 既有参数语义 / 全局口径)→ 级别至少 L2\n- [ ] schema / 迁移 SQL / DI 链 / 认证与中间件管线 → 级别 L3\n\n> 触及任一红线即为 L2 / L3,必须立 ../specs/YYYY-MM-DD-<主题>.md 写明如何满足,方可起草 plan。' },
|
|
36
36
|
{ title: '验收标准(可测试)', hint: '- [ ] <逐条可测试;写不出可测试判据 = 还没想清楚>\n\n> **闭环对账**:关单在 test 阶段(不依赖 deploy)。intent 置 done 前逐条勾验,每条补证据——`- [x] <判据>(证据:<commit SHA / 测试用例名 / 冒烟脚本输出>)`。\n> done 状态仍有未勾项会被 check-loop 拦截(2026-09-12 起新建 intent 为 hard-block,存量 intent 仅 warning 提示);勾选但缺「证据:」为 hard-block。' },
|
|
37
37
|
];
|
|
38
38
|
|
|
@@ -9,7 +9,6 @@ import path from 'node:path';
|
|
|
9
9
|
import { ENUMS } from './workflow-enums.mjs';
|
|
10
10
|
import { draftGateFor, resolveWorkspace } from './stage-gates.mjs';
|
|
11
11
|
|
|
12
|
-
const TODAY = new Date().toISOString().slice(0, 10);
|
|
13
12
|
const LEVELS = ENUMS['level.all']; // 级别词表单源(.agents/workflow-enums.txt)
|
|
14
13
|
|
|
15
14
|
function parseArgs(argv) {
|
|
@@ -40,7 +39,7 @@ const FULL_SECTIONS = [
|
|
|
40
39
|
L1_SECTIONS[2],
|
|
41
40
|
];
|
|
42
41
|
|
|
43
|
-
export function renderPlan({ topic, level = 'L1'
|
|
42
|
+
export function renderPlan({ topic, level = 'L1' }) {
|
|
44
43
|
if (!LEVELS.includes(level)) throw new Error('level 不在枚举 ' + LEVELS.join('|') + ':' + level);
|
|
45
44
|
const sections = level === 'L1' ? L1_SECTIONS : FULL_SECTIONS;
|
|
46
45
|
const fm = '---\n状态: draft\n级别: ' + level + '\n模块: pipeline\n---\n';
|
|
@@ -141,7 +141,7 @@ let out = indexText;
|
|
|
141
141
|
{
|
|
142
142
|
const lines = out.split(/\r?\n/);
|
|
143
143
|
const headIdx = lines.findIndex((l) => /^\| 主题 \|/.test(l));
|
|
144
|
-
if (headIdx < 0 || !/^[
|
|
144
|
+
if (headIdx < 0 || !/^[|:\-\s]+$/.test(lines[headIdx + 1] || '')) {
|
|
145
145
|
console.error('❌ INDEX 速览表表头未找到,未写盘');
|
|
146
146
|
process.exit(1);
|
|
147
147
|
}
|
|
@@ -12,8 +12,6 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
12
12
|
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
13
13
|
const { closeDurations, pickPct, durationVerdict, qualityRows, DURATION_BAND, normalizeForCheck, gateRoiLines } =
|
|
14
14
|
await import(pathToFileURL(path.join(SCRIPT_DIR, 'gen-workflow-dashboard.mjs')).href);
|
|
15
|
-
const agg = (await import(pathToFileURL(path.join(SCRIPT_DIR, 'agg-delegations.cjs')).href)).default
|
|
16
|
-
?? null; // .cjs 经 import 具名空间取——见下方 createRequire 兜底
|
|
17
15
|
import { createRequire } from 'node:module';
|
|
18
16
|
const require2 = createRequire(import.meta.url);
|
|
19
17
|
const aggCjs = require2(path.join(SCRIPT_DIR, 'agg-delegations.cjs'));
|
|
@@ -124,7 +124,7 @@ const run = (root, args = []) => spawnSync(process.execPath, [GEN, ...args], { c
|
|
|
124
124
|
'状态: draft\n级别: L1\n日期: 2026-09-22\n模块: pipeline',
|
|
125
125
|
'workflow-doc-retrieval',
|
|
126
126
|
), 'utf8');
|
|
127
|
-
|
|
127
|
+
run(root);
|
|
128
128
|
const idx = fs.readFileSync(path.join(root, 'workflow', 'INDEX.md'), 'utf8');
|
|
129
129
|
check('场景 5:kebab-case H1 完整保留(未被截成末段)', idx.includes('| workflow-doc-retrieval |') && !idx.includes('| retrieval |'), idx.split('\n').filter((l) => l.includes('retrieval')).join('\n'));
|
|
130
130
|
check('场景 5:em-dash 前缀仍正常剥离', idx.includes('| 在跑的需求甲 |'), '');
|
|
@@ -48,7 +48,7 @@ const DOC_TYPES = ['intents', 'specs', 'plans', 'incidents'];
|
|
|
48
48
|
// **不能用固定上溯级数**(2026-09-28 修正):本脚本在两处运行、深度不同——
|
|
49
49
|
// 包源 `templates/_agents/scripts/` → 上溯 3 级到仓库根
|
|
50
50
|
// 装户 `.agents/scripts/` → 上溯 2 级到安装根
|
|
51
|
-
// 首版硬编码 3 级,故**在每个装户安装里都解析不到枚举文件**(报错路径 `<install
|
|
51
|
+
// 首版硬编码 3 级,故**在每个装户安装里都解析不到枚举文件**(报错路径 `<install>/../.agents/…`)。
|
|
52
52
|
// 实测暴露路径:CI 新增「shipped 套件」步骤后,`.agents/scripts/gen-workflow-metrics.test.mjs`
|
|
53
53
|
// 场景 1 即 exit 1(workflow-enums 单源文件不可读),而包源侧同字节跑出全绿。
|
|
54
54
|
// 改为**逐级上溯探测**:找到含 `.agents/workflow-enums.txt` 的那一级即用,找不到则回退标准位置让
|
|
@@ -39,7 +39,6 @@ const USAGE = `用法: node .agents/scripts/kb-search.mjs [选项] <词1> [词2
|
|
|
39
39
|
|
|
40
40
|
const args = process.argv.slice(2);
|
|
41
41
|
let scope = '';
|
|
42
|
-
let scopeExplicit = false;
|
|
43
42
|
let typeFilter = null;
|
|
44
43
|
let moduleFilter = '';
|
|
45
44
|
let statusFilter = 'all';
|
|
@@ -53,7 +52,7 @@ let rebuild = false;
|
|
|
53
52
|
const words = [];
|
|
54
53
|
for (let i = 0; i < args.length; i++) {
|
|
55
54
|
const a = args[i];
|
|
56
|
-
if (a === '--scope') { scope = args[++i] || '';
|
|
55
|
+
if (a === '--scope') { scope = args[++i] || ''; }
|
|
57
56
|
else if (a === '--type') typeFilter = (args[++i] || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
58
57
|
else if (a === '--module') moduleFilter = args[++i] || '';
|
|
59
58
|
else if (a === '--status') statusFilter = args[++i] || '';
|
|
@@ -109,7 +109,7 @@ const files = (out) => (out.match(/^📄 (workflow\/\S+)/gm) || []).map((l) => l
|
|
|
109
109
|
// ---- 场景 5:增量失效——warm 后改 1 个源文件,仅该文件重解析且输出与纯扫一致 ----
|
|
110
110
|
{
|
|
111
111
|
const root = mkfix();
|
|
112
|
-
|
|
112
|
+
run(root, ['编码模板']);
|
|
113
113
|
const planP = path.join(root, 'workflow', 'plans', '2026-09-20-ccc.md');
|
|
114
114
|
fs.appendFileSync(planP, '\n## 影响面\n- 新标记NEWWORD:编码模板修订\n', 'utf8');
|
|
115
115
|
const after = run(root, ['编码模板', 'NEWWORD']);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// pipeline-run-docs.mjs — 文档纯函数层(2026-10-08 engine-quality-batch,L2 自 pipeline-run.mjs 拆出)
|
|
2
|
+
// fmGet / placeholdersIn / sectionBody / validateDraftContent / closeoutComplete / summarizeDoc——
|
|
3
|
+
// 零 IO、零 process 依赖、单向被 pipeline-run.mjs(CLI 编排层)消费;判据注释随函数原样迁入。
|
|
4
|
+
// export 面 = 原主文件具名导出(placeholdersIn/validateDraftContent/closeoutComplete)+ 层内消费三函数;
|
|
5
|
+
// 主文件经 re-export 保持对外导出面不变(workflow-board-server 等消费方零改动)。
|
|
6
|
+
export function fmGet(text, key) {
|
|
7
|
+
const m = text.split(/\r?\n/).find((l) => l.startsWith(`${key}:`));
|
|
8
|
+
return m ? m.slice(key.length + 1).trim() : null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 占位符判定(复核 P1-3 收窄,2026-10-02):先剔除 code span(`…`)与引号串("…")——
|
|
12
|
+
// 正文合法的命令语法占位(如 `next --delegated "<原话>"`)几乎总在 code span 内,
|
|
13
|
+
// 模板实占位符(如 <为什么做;写明需求来源…>)从不包 code span;再匹配剩余裸尖括号。
|
|
14
|
+
export function placeholdersIn(text) {
|
|
15
|
+
const stripped = String(text)
|
|
16
|
+
.replace(/^```[\s\S]*?^```$/gm, '') // 复核 P2-B:跨行 code fence 整块剔除(围栏内命令示例占位不属模板占位符)
|
|
17
|
+
.replace(/`[^`\n]*`/g, '')
|
|
18
|
+
.replace(/"[^"\n]*"/g, '');
|
|
19
|
+
const hits = [];
|
|
20
|
+
for (const re of [/<[^>\n]{1,60}>/g, /YYYY-MM-DD 用户/g]) {
|
|
21
|
+
let m; while ((m = re.exec(stripped))) hits.push(m[0]);
|
|
22
|
+
}
|
|
23
|
+
return [...new Set(hits)].slice(0, 5);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function sectionBody(text, title) {
|
|
27
|
+
const lines = text.split(/\r?\n/);
|
|
28
|
+
const i = lines.findIndex((l) => l.trim() === `## ${title}` || l.trim() === `## ${title}(L1 微改动无实质内容可删本节,不硬填)` || l.trim().startsWith(`## ${title}`));
|
|
29
|
+
if (i < 0) return null;
|
|
30
|
+
const body = [];
|
|
31
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
32
|
+
if (/^##\s/.test(lines[j])) break;
|
|
33
|
+
body.push(lines[j]);
|
|
34
|
+
}
|
|
35
|
+
return body.join('\n').trim();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function validateDraftContent(text, kind, level) {
|
|
39
|
+
const problems = [];
|
|
40
|
+
if (!text) return ['文件不存在或为空'];
|
|
41
|
+
const state = fmGet(text, '状态');
|
|
42
|
+
if (!state) problems.push('frontmatter 缺「状态:」行');
|
|
43
|
+
if (kind !== 'incident' && !fmGet(text, '级别')) problems.push('frontmatter 缺「级别:」行');
|
|
44
|
+
const ph = placeholdersIn(text);
|
|
45
|
+
if (ph.length) problems.push(`模板占位符残留:${ph.join('、')}`);
|
|
46
|
+
const required = {
|
|
47
|
+
intent: level === 'L1' ? ['背景与问题', '目标', '验收标准'] : ['背景与问题', '历史教训/防复发', '目标', '非目标', '约束', '验收标准'],
|
|
48
|
+
spec: ['功能行为', '数据流', '系统改动', '约束遵守映射'],
|
|
49
|
+
plan: level === 'L1' ? ['改动方案', '约束与风险', '验证计划'] : ['改动方案', '任务拆解', '执行顺序', '验证计划'],
|
|
50
|
+
incident: ['时间线', '根因', '复盘三件套'],
|
|
51
|
+
}[kind] || [];
|
|
52
|
+
for (const sec of required) {
|
|
53
|
+
const b = sectionBody(text, sec);
|
|
54
|
+
if (b === null) { if (!(level === 'L1' && ['非目标', '约束', '任务拆解', '执行顺序'].includes(sec))) problems.push(`缺节:## ${sec}`); }
|
|
55
|
+
else if (!b) problems.push(`节为空:## ${sec}`);
|
|
56
|
+
}
|
|
57
|
+
return problems;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function closeoutComplete(text) {
|
|
61
|
+
const body = sectionBody(text, '验收标准');
|
|
62
|
+
if (body === null) return { ok: false, problems: ['缺「## 验收标准」节'] };
|
|
63
|
+
const lines = body.split(/\r?\n/);
|
|
64
|
+
const open = lines.filter((l) => /^\s*-\s\[\s\]\s/.test(l));
|
|
65
|
+
// 复核 P2-6:证据冒号后须直接跟内容(非空白、非收括号)——「(证据:)」空值不算过
|
|
66
|
+
const checkedNoEv = lines.filter((l) => /^\s*-\s\[x\]\s/.test(l) && !/证据[::][^)\s]/.test(l));
|
|
67
|
+
const problems = [];
|
|
68
|
+
if (open.length) problems.push(`未勾验收 ${open.length} 条`);
|
|
69
|
+
if (checkedNoEv.length) problems.push(`已勾缺证据 ${checkedNoEv.length} 条`);
|
|
70
|
+
return { ok: problems.length === 0, problems };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function summarizeDoc(text) {
|
|
74
|
+
const body = text.split(/\r?\n/).filter((l) => l.trim() && !l.startsWith('---') && !/^状态:|^级别:|^日期:|^模块:|^备注:|^risk_level:/.test(l));
|
|
75
|
+
return body.slice(0, 3).join(' / ').slice(0, 200);
|
|
76
|
+
}
|