agentic-flow-kit 1.7.16 → 1.8.1
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/README.md +11 -7
- package/modules/hosts/claude/commands/wf-build.md +1 -1
- package/modules/hosts/claude/commands/wf-maintain.md +1 -1
- package/modules/hosts/claude/commands/wf-new-task.md +9 -8
- package/modules/hosts/claude/commands/wf-plan.md +1 -1
- package/modules/hosts/claude/commands/wf-review.md +2 -2
- package/modules/hosts/claude/commands/wf-test.md +1 -1
- package/modules/hosts/codex/commands/wf-build.md +1 -1
- package/modules/hosts/codex/commands/wf-maintain.md +1 -1
- package/modules/hosts/codex/commands/wf-new-task.md +9 -8
- package/modules/hosts/codex/commands/wf-plan.md +1 -1
- package/modules/hosts/codex/commands/wf-review.md +2 -2
- package/modules/hosts/codex/commands/wf-test.md +1 -1
- package/modules/hosts/cursor/commands/wf-build.md +1 -1
- package/modules/hosts/cursor/commands/wf-maintain.md +1 -1
- package/modules/hosts/cursor/commands/wf-new-task.md +9 -8
- package/modules/hosts/cursor/commands/wf-plan.md +1 -1
- package/modules/hosts/cursor/commands/wf-review.md +2 -2
- package/modules/hosts/cursor/commands/wf-test.md +1 -1
- package/modules/hosts/opencode/commands/wf-build.md +1 -1
- package/modules/hosts/opencode/commands/wf-maintain.md +1 -1
- package/modules/hosts/opencode/commands/wf-new-task.md +9 -8
- package/modules/hosts/opencode/commands/wf-plan.md +1 -1
- package/modules/hosts/opencode/commands/wf-review.md +2 -2
- package/modules/hosts/opencode/commands/wf-test.md +1 -1
- package/modules/hosts/trae/commands/wf-build.md +1 -1
- package/modules/hosts/trae/commands/wf-maintain.md +1 -1
- package/modules/hosts/trae/commands/wf-new-task.md +9 -8
- package/modules/hosts/trae/commands/wf-plan.md +1 -1
- package/modules/hosts/trae/commands/wf-review.md +2 -2
- package/modules/hosts/trae/commands/wf-test.md +1 -1
- package/package.json +1 -1
- package/src/cli.mjs +6 -2
- package/src/doctor.mjs +11 -2
- package/src/executor.mjs +25 -8
- package/src/executor.test.mjs +4 -1
- package/src/fresh-init.test.mjs +1 -1
- package/src/init.mjs +20 -3
- package/src/profiles.mjs +7 -3
- package/src/rule-budget.test.mjs +2 -2
- package/src/stack-profile.test.mjs +6 -0
- package/src/validate.mjs +6 -1
- package/src/validate.test.mjs +1 -1
- package/templates/.gitattributes +4 -1
- package/templates/AGENTS.md +2 -2
- package/templates/_agents/commands/build.md +1 -1
- package/templates/_agents/commands/maintain.md +1 -1
- package/templates/_agents/commands/new-task.md +9 -8
- package/templates/_agents/commands/plan.md +1 -1
- package/templates/_agents/commands/review.md +2 -2
- package/templates/_agents/commands/test.md +1 -1
- package/templates/_agents/engine-lock.json +130 -42
- package/templates/_agents/hooks/check-index-incremental.mjs +48 -0
- package/templates/_agents/hooks/check-pairing-incremental.mjs +66 -0
- package/templates/_agents/hooks/check-wiki-ledger.mjs +30 -0
- package/templates/_agents/lane-surfaces.txt +4 -1
- package/templates/_agents/level-hints.txt +1 -1
- package/templates/_agents/loop/papercut-debt/DESIGN.md +112 -0
- package/templates/_agents/mechanism-registry.md +27 -0
- package/templates/_agents/rule-budgets.txt +2 -2
- package/templates/_agents/scripts/agg-delegations.cjs +21 -3
- package/templates/_agents/scripts/agg-gate-stats.mjs +3 -3
- package/templates/_agents/scripts/agg-judgments.mjs +80 -0
- package/templates/_agents/scripts/agg-judgments.test.mjs +45 -0
- package/templates/_agents/scripts/archive-sweep.mjs +233 -0
- package/templates/_agents/scripts/archive-sweep.test.mjs +129 -0
- package/templates/_agents/scripts/check-attribution.mjs +37 -0
- package/templates/_agents/scripts/check-convergence.mjs +119 -0
- package/templates/_agents/scripts/check-engine-integrity.mjs +4 -1
- package/templates/_agents/scripts/check-funnel.mjs +56 -0
- package/templates/_agents/scripts/check-hygiene.mjs +5 -5
- package/templates/_agents/scripts/check-index-incremental.test.mjs +73 -0
- package/templates/_agents/scripts/check-lane-surface.mjs +2 -2
- package/templates/_agents/scripts/check-lane-surface.test.mjs +5 -5
- package/templates/_agents/scripts/check-ledger-invariant.mjs +403 -152
- package/templates/_agents/scripts/check-ledger-invariant.test.mjs +433 -3
- package/templates/_agents/scripts/check-loop-rev.test.mjs +8 -5
- package/templates/_agents/scripts/check-loop-unit.test.mjs +8 -0
- package/templates/_agents/scripts/check-loop.mjs +215 -34
- package/templates/_agents/scripts/check-loop.test.mjs +582 -49
- package/templates/_agents/scripts/check-prejudgment.mjs +64 -0
- package/templates/_agents/scripts/check-registry.mjs +45 -0
- package/templates/_agents/scripts/check-scope.mjs +96 -0
- package/templates/_agents/scripts/check-scope.test.mjs +96 -0
- package/templates/_agents/scripts/check-scripts-syntax.mjs +61 -0
- package/templates/_agents/scripts/check-scripts-syntax.test.mjs +72 -0
- package/templates/_agents/scripts/check-spec-verif.mjs +47 -0
- package/templates/_agents/scripts/compact-ledgers.mjs +3 -3
- package/templates/_agents/scripts/confirm-doc.mjs +114 -38
- package/templates/_agents/scripts/confirm-doc.test.mjs +180 -4
- package/templates/_agents/scripts/edit-face-check.mjs +5 -3
- package/templates/_agents/scripts/fill-intent.mjs +5 -3
- package/templates/_agents/scripts/fill-intent.test.mjs +19 -1
- package/templates/_agents/scripts/fill-plan.mjs +10 -6
- package/templates/_agents/scripts/fill-plan.test.mjs +19 -3
- package/templates/_agents/scripts/fill-spec.mjs +6 -3
- package/templates/_agents/scripts/fill-spec.test.mjs +12 -4
- package/templates/_agents/scripts/fixture-scripts.mjs +2 -2
- package/templates/_agents/scripts/fixture-scripts.test.mjs +6 -1
- package/templates/_agents/scripts/gate-checklist.mjs +6 -0
- package/templates/_agents/scripts/gate-seg.mjs +1 -1
- package/templates/_agents/scripts/gen-effective-policy.mjs +107 -0
- package/templates/_agents/scripts/gen-effective-policy.test.mjs +100 -0
- package/templates/_agents/scripts/gen-verify-evidence.mjs +107 -0
- package/templates/_agents/scripts/gen-verify-evidence.test.mjs +84 -0
- package/templates/_agents/scripts/gen-workflow-dashboard.mjs +8 -3
- package/templates/_agents/scripts/gen-workflow-dashboard.test.mjs +2 -1
- package/templates/_agents/scripts/gen-workflow-metrics.mjs +3 -3
- package/templates/_agents/scripts/git-core.mjs +45 -0
- package/templates/_agents/scripts/judgment-ledger.mjs +65 -0
- package/templates/_agents/scripts/judgment-ledger.test.mjs +129 -0
- package/templates/_agents/scripts/kb-search.mjs +19 -4
- package/templates/_agents/scripts/kb-search.test.mjs +33 -0
- package/templates/_agents/scripts/lane-surface-audit.mjs +143 -0
- package/templates/_agents/scripts/lane-surface-audit.test.mjs +93 -0
- package/templates/_agents/scripts/ledger-shards.mjs +307 -0
- package/templates/_agents/scripts/ledger-shards.test.mjs +339 -0
- package/templates/_agents/scripts/level-criteria.mjs +9 -10
- package/templates/_agents/scripts/level-criteria.test.mjs +7 -5
- package/templates/_agents/scripts/papercut-debt-controller.mjs +141 -0
- package/templates/_agents/scripts/papercut-debt-controller.test.mjs +127 -0
- package/templates/_agents/scripts/papercut-debt-sensor.mjs +170 -0
- package/templates/_agents/scripts/papercut-debt-sensor.test.mjs +146 -0
- package/templates/_agents/scripts/pipeline-run.mjs +6 -22
- package/templates/_agents/scripts/pipeline-run.test.mjs +22 -42
- package/templates/_agents/scripts/policy.mjs +28 -0
- package/templates/_agents/scripts/resolve-merge-conflicts.mjs +110 -0
- package/templates/_agents/scripts/resolve-merge-conflicts.test.mjs +87 -0
- package/templates/_agents/scripts/rewrite-file.mjs +133 -0
- package/templates/_agents/scripts/rewrite-file.test.mjs +148 -0
- package/templates/_agents/scripts/rule-budget.mjs +83 -0
- package/templates/_agents/scripts/run-tests.mjs +99 -0
- package/templates/_agents/scripts/run-tests.test.mjs +105 -0
- package/templates/_agents/scripts/solidify-task.test.mjs +1 -1
- package/templates/_agents/scripts/stage-gates.mjs +34 -12
- package/templates/_agents/scripts/trust-mode.mjs +4 -4
- package/templates/_agents/scripts/trust-mode.test.mjs +1 -1
- package/templates/_agents/scripts/verify.mjs +135 -58
- package/templates/_agents/scripts/verify.test.mjs +156 -47
- package/templates/_agents/scripts/wf-journal.mjs +8 -4
- package/templates/_agents/scripts/workflow-board-server.test.mjs +2 -2
- package/templates/_agents/scripts/workflow-enums.test.mjs +14 -5
- package/templates/_agents/scripts-test-exempt.txt +1 -0
- package/templates/_agents/skills/papercut-fix/SKILL.md +60 -0
- package/templates/_agents/skills/papercut-fix/references/response-template.md +81 -0
- package/templates/_agents/skills/review-method/SKILL.md +55 -0
- package/templates/_agents/workflow-enums.txt +8 -1
- package/templates/_githooks/pre-commit +110 -90
- package/templates/_githooks/pre-merge-commit +27 -23
- package/templates/_githooks/pre-push +4 -3
- package/templates/_github/workflows/kit-ci.yml +4 -3
- package/templates/workflow/README.md +14 -7
- package/templates/workflow/incidents/_TEMPLATE.md +4 -1
- package/templates/workflow/intents/_TEMPLATE.md +4 -2
- package/templates/workflow/papercuts.md +2 -0
- package/templates/workflow/plans/_TEMPLATE.md +10 -5
- package/templates/workflow/regression-checklist.md +1 -0
- package/templates/workflow/specs/_TEMPLATE.md +17 -1
- package/templates/_agents/hooks/check-pairing-incremental.sh +0 -43
- package/templates/_agents/hooks/check-wiki-ledger.sh +0 -18
- package/templates/_agents/scripts/rule-budget.sh +0 -74
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// workflow-enums.test.mjs — 枚举单源读取器测试(2026-09-25 enum-single-source)
|
|
2
2
|
// 判据:① 真实单源文件解析 + 不变量通过 ② 坏数据(坏行/重复键/重复值/缺键/子集破/重叠)fail-loud
|
|
3
|
-
// ③ 缺文件 fail-loud ④ sh 消费方同口径(sed
|
|
3
|
+
// ③ 缺文件 fail-loud ④ sh 消费方同口径(sed 可取到全部键)
|
|
4
4
|
// 用法:node templates/_agents/scripts/workflow-enums.test.mjs(npm test 随跑)
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { execSync } from 'node:child_process';
|
|
@@ -20,14 +20,22 @@ const throwsWith = (fn, kw) => {
|
|
|
20
20
|
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
21
21
|
const ENUMS_TXT = path.join(SCRIPT_DIR, '..', 'workflow-enums.txt');
|
|
22
22
|
|
|
23
|
-
// ---- S1 模块级 ENUMS 即加载即校验(真实文件),
|
|
23
|
+
// ---- S1 模块级 ENUMS 即加载即校验(真实文件),10 键齐(2026-10-13 自 Shipyard 回灌归因两键)----
|
|
24
24
|
{
|
|
25
25
|
const keys = Object.keys(ENUMS).sort();
|
|
26
|
-
check('S1 真实单源文件加载成功且
|
|
27
|
-
keys.length ===
|
|
26
|
+
check('S1 真实单源文件加载成功且 10 键齐',
|
|
27
|
+
keys.length === 10 && keys.join(',') === 'doc.status.abandoned,doc.status.active,doc.status.all,doc.status.confirmed,doc.status.terminal,incident.env.all,incident.source.all,incident.status.active,incident.status.all,level.all',
|
|
28
28
|
JSON.stringify(keys));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
// ---- S1b 归因两键值域逐字对齐 Shipyard(incident.source.all / incident.env.all)----
|
|
32
|
+
{
|
|
33
|
+
check('S1b 归因两键值域:source=self user test monitor、env=dev staging prod none',
|
|
34
|
+
ENUMS['incident.source.all'].join('+') === 'self+user+test+monitor'
|
|
35
|
+
&& ENUMS['incident.env.all'].join('+') === 'dev+staging+prod+none',
|
|
36
|
+
JSON.stringify(ENUMS));
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
// ---- S2 真实文件关键值口径(check-loop/看板/检索的行为锚点,值变更须连本测试一起改)----
|
|
32
40
|
{
|
|
33
41
|
check('S2 关键集值口径:confirmed 不含 draft、active=draft+approved、terminal 含 done、abandoned ⊆ terminal',
|
|
@@ -35,7 +43,8 @@ const ENUMS_TXT = path.join(SCRIPT_DIR, '..', 'workflow-enums.txt');
|
|
|
35
43
|
&& ENUMS['doc.status.active'].join('+') === 'draft+approved'
|
|
36
44
|
&& ENUMS['doc.status.terminal'].includes('done')
|
|
37
45
|
&& ENUMS['doc.status.abandoned'].every((v) => ENUMS['doc.status.terminal'].includes(v))
|
|
38
|
-
|
|
46
|
+
// level.all=L1 L2 L3——L0 已退役(2026-10-13 自源仓收敛系列 1 回灌)
|
|
47
|
+
&& ENUMS['level.all'].join('+') === 'L1+L2+L3',
|
|
39
48
|
JSON.stringify(ENUMS));
|
|
40
49
|
}
|
|
41
50
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# 新增引擎脚本默认必须带同名 .test.mjs(README 规范条目);确属库件/工具才登记本文件。
|
|
5
5
|
# 2026-10-09 A2 评估:verify-wiki-consistency 已移出(补测 3 场景);wiki-search 已移出(转发壳,判定单源 kb-search.test 覆盖)。
|
|
6
6
|
check-metric-claims.mjs | 经 check-loop.mjs 消费 | 由 check-loop.test.mjs 间接覆盖其调用路径
|
|
7
|
+
rule-budget.mjs | 判定器(2026-10-13 自 .sh 移植 node;经 check-hygiene 检查 13 与 pre-commit 消费,Shipyard 侧同无直测) | check-loop.test.mjs 场景 28-30(含 --staged 硬拦两态)+ check-loop-rev.test.mjs 间接覆盖;src/rule-budget.test.mjs 平行实现作口径对照
|
|
7
8
|
ensure-board.mjs | 看板启动器 | 永久工具豁免(需真实端口/进程环境,自动化覆盖无性价比——2026-10-09 engine-quality-round2 A2 评估定性)
|
|
8
9
|
policy.mjs | 库件 | 被 check-loop.test.mjs 直接 import 覆盖
|
|
9
10
|
# 2026-10-12 needs-clarification:stage-gates.mjs 已建同名直测(stage-gates.test.mjs 15 断言),
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: papercut-fix
|
|
3
|
+
description: 修 workflow/papercuts.md 里指定的未升级 papercut 条目(把存量债降到 0 的回路执行器)。按控制器给的行号定位症状、照「拟修」列改权威文件、回写台账并跑验证门。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# papercut-fix — 单条 papercut 升级执行器
|
|
7
|
+
|
|
8
|
+
## 目标
|
|
9
|
+
将 `workflow/papercuts.md` 中指定的一条 papercut 条目状态更新为「已消债」。
|
|
10
|
+
|
|
11
|
+
## 触发条件
|
|
12
|
+
- 用户指令:`跑一轮 papercut 回路` / `清 papercut 存量` / `修第 N 条 papercut`。
|
|
13
|
+
|
|
14
|
+
## 约束与红线
|
|
15
|
+
- **单一目标**:每轮执行仅处理一条目标,禁止顺手修复相邻条目或夹带其他改动。
|
|
16
|
+
- **范围限制**:改动仅限文档面(`.agents/commands/`, `.agents/roles/`, `.agents/skills/`, `.githooks/`, `.agents/scripts/`, `workflow/`)。
|
|
17
|
+
- **绝对禁区**:禁止修改 `backend/`, `frontend/`, `tests/`, `wiki/`,禁止连接数据库——与控制器 scope gate(`OUT_OF_SCOPE` 正则)同一清单,命中即停。超出范围时必须停止并报告用户。
|
|
18
|
+
- **验证优先**:禁止凭台账描述臆测现状。必须先读权威文件验证症状是否成立。
|
|
19
|
+
- **编辑规范**:修改 `workflow/` 文档必须使用 Edit 工具。禁止使用 `node -e` 或脚本批量替换(CRLF 环境下会静默失败)。
|
|
20
|
+
- **消债判定**:分支 A(修复)与分支 B(暂缓/失效)**均**满足 `debt -1` 不变量。
|
|
21
|
+
|
|
22
|
+
## 工作流
|
|
23
|
+
|
|
24
|
+
### 1. 定位与预检
|
|
25
|
+
- 从控制器输出提取:`行号` (Lxx), `位置` (路径), `症状`, `拟修`。
|
|
26
|
+
- 使用 Read 工具读取该行及其上下文。
|
|
27
|
+
|
|
28
|
+
### 2. 现状验证
|
|
29
|
+
- 读取「位置」列指定的权威文件。
|
|
30
|
+
- **判定结论**:
|
|
31
|
+
- **缺陷仍在** $\rightarrow$ 进入分支 A。
|
|
32
|
+
- **已失效** (已被其他改动修复/文件已删除) $\rightarrow$ 进入分支 B。
|
|
33
|
+
- **方向相反/描述有误** $\rightarrow$ 重新定性后再执行。
|
|
34
|
+
|
|
35
|
+
### 3. 执行修复
|
|
36
|
+
- **分支 A (缺陷仍在)**:
|
|
37
|
+
1. 对权威文件执行最小化修复。
|
|
38
|
+
2. 在 `workflow/papercuts.md`(或承载该条目的 `workflow/papercuts.d/` 分片)该行末尾追加:`✅ 已升级修复(YYYY-MM-DD): <改动描述> <commit>`。
|
|
39
|
+
3. 若原「拟修」描述已不适用,在追加记录中写明实际修法。
|
|
40
|
+
- **分支 B (已失效)**:
|
|
41
|
+
1. 在 `workflow/papercuts.md`(或承载该条目的分片)该行末尾追加:`⏸ 暂缓(YYYY-MM-DD): <失效理由>`。理由必须明确。
|
|
42
|
+
2. **核实纪律**:
|
|
43
|
+
- 检查用户级技能目录(`~/.claude/skills/`、`~/.trae/skills/` 等宿主适配目录)确认文件是否仅是迁移而非删除。
|
|
44
|
+
- 区分「环境约束」与「代码缺陷」。
|
|
45
|
+
- 针对「跨环境」症状,使用 `git worktree` 构建真实检出态实验证伪。
|
|
46
|
+
- 针对「已落地」症状,使用 `git log -S` 追溯引入提交日期。
|
|
47
|
+
- **分支 C (越界)**:停止执行,报告理由并请求授权。
|
|
48
|
+
|
|
49
|
+
### 4. 验证与收尾
|
|
50
|
+
- **备份**:修改台账(主台账或分片)前强制 `cp <台账文件> tmp/papercuts.wip-backup.md`。
|
|
51
|
+
- **运行检查**:
|
|
52
|
+
- `node .agents/scripts/papercut-debt-sensor.mjs` $\rightarrow$ `debt` 必须恰好减少 1。
|
|
53
|
+
- `node .agents/scripts/papercut-debt-controller.mjs` $\rightarrow$ 确认目标推进。
|
|
54
|
+
- 检查台账(主台账 ∪ 分片)的总行数(`total` 不得减少——`debt` 符合预期 ≠ 文件没被压行)、列数分布及是否存在超长行(压行信号)。
|
|
55
|
+
- **体积检查**:若修改了 `.agents/commands/`,跑 `node .agents/scripts/rule-budget.mjs --staged` 对比 `.agents/rule-budgets.txt` 上限(一进一出;禁用工作区 `wc -c` 核对——CRLF 膨胀会误报)。
|
|
56
|
+
|
|
57
|
+
## 回报要求
|
|
58
|
+
- 参照 `references/response-template.md` 输出。
|
|
59
|
+
- 包含:行号、位置、分支结论(A/B/C)、改动文件、验证结果(debt 前后值)、待决策事项。
|
|
60
|
+
- **禁令**:禁止自动 commit 或 push。
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# papercut-fix 回应模板
|
|
2
|
+
|
|
3
|
+
单轮回路执行器的最终输出格式。给用户看,决定他是否放行这次改动。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 模板
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
papercut 回路 · 第 N 轮
|
|
11
|
+
|
|
12
|
+
**目标**:L{line} `{location}`({date},第 {hits} 次命中)
|
|
13
|
+
**结论**:{A 缺陷仍在 / B 已失效 / B2 账未销(拟修已由别的改动落地)/ B3 台账方向记反(检出态实验证伪)/ C 越界待授权}
|
|
14
|
+
|
|
15
|
+
### 改动
|
|
16
|
+
|
|
17
|
+
| 文件 | 改了什么 |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `{权威文件路径}` | {一句话} |
|
|
20
|
+
| `workflow/papercuts.md` | 回写行标记:{`✅ 已升级修复(日期)` / `⏸ 暂缓(日期):理由`} |
|
|
21
|
+
|
|
22
|
+
### 验证
|
|
23
|
+
|
|
24
|
+
- `papercut-debt-sensor.mjs`:debt {before} → {after}(预期 -1)
|
|
25
|
+
- {其他检查,如体积预算核对:通过 / 不适用}
|
|
26
|
+
|
|
27
|
+
### 台账依据
|
|
28
|
+
|
|
29
|
+
{若实际修法与「拟修」列描述不一致,在此说明「拟修」列写的什么、实际怎么做的、为什么。
|
|
30
|
+
B2 结论必须写出落地提交:`由 <sha>(<日期>,<标题>)落地`。}
|
|
31
|
+
|
|
32
|
+
### 需你决定
|
|
33
|
+
|
|
34
|
+
{列出需要用户拍板的事项;没有则写「无」。典型场景:
|
|
35
|
+
- 结论为 C(越界)——是否单独授权改源码/连库
|
|
36
|
+
- 「拟修」列描述已过期——是否更新该列文本
|
|
37
|
+
- 控制器列出的「待人工定性」条目——是否本轮顺带定性
|
|
38
|
+
- 改动触及常驻面体积预算——是否接受,或改为下沉/删除被取代条目}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 格式要求
|
|
44
|
+
|
|
45
|
+
1. **先给结论,再给细节**。用户扫第一行就要知道"修了哪条、结论是什么"。
|
|
46
|
+
2. **「需你决定」不许空着**。即使本轮无事,也显式写「无」——让"没有待决事项"和"忘了写"可区分。
|
|
47
|
+
3. **验证值给具体数字**,不要只说"验证通过"。debt 的前后值是设定点误差,必须可核。
|
|
48
|
+
4. **不粉饰失败**。验证门红了就写红,附命令与原始报错摘要。回路的价值在于给出可信的账,不是好看的账。
|
|
49
|
+
5. **不写"建议接下来…"式的空话**。要写就写具体动作 + 具体条目编号。
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 示例(结论 A,示意——占位符形态,非真实条目)
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
papercut 回路 · 第 3 轮
|
|
57
|
+
|
|
58
|
+
**目标**:L34 `.agents/commands/test.md`(静态门清单 §2 缺一条豁免说明)(<日期>)
|
|
59
|
+
**结论**:A 缺陷仍在
|
|
60
|
+
|
|
61
|
+
### 改动
|
|
62
|
+
|
|
63
|
+
| 文件 | 改了什么 |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `.agents/commands/test.md` | §2 补一条:跳过条件的判据以 <权威判据> 为准,不以 <表象> 为准;§常见误判 补对应条目 |
|
|
66
|
+
| `workflow/papercuts.md` | 回写 L34 标记:`✅ 已升级修复(YYYY-MM-DD)` |
|
|
67
|
+
|
|
68
|
+
### 验证
|
|
69
|
+
|
|
70
|
+
- `papercut-debt-sensor.mjs`:debt 16 → 15(预期 -1)
|
|
71
|
+
- 体积预算:`node .agents/scripts/rule-budget.mjs --staged` 通过(未触 `.agents/commands/` 上限)
|
|
72
|
+
|
|
73
|
+
### 台账依据
|
|
74
|
+
|
|
75
|
+
「拟修」列写的是「补一条 <表象> 的判定说明」。实际执行时发现症状描述的是 <相邻机制>,而 §2 真正缺的是**判据本身**(<相邻机制> 只在特定前提后需要,判据该按 <权威判据>)。两者相邻但不同,已按判据写,相邻条目并入同节。
|
|
76
|
+
|
|
77
|
+
### 需你决定
|
|
78
|
+
|
|
79
|
+
- 「拟修」列文本与实际修法有偏差(见上),是否更新该列描述以免下次复发时对不上?
|
|
80
|
+
- 控制器列出的「待人工定性」3 条(位置列路径已不存在)——其中 1 条指向的脚本性能问题已随某次重构解决,本轮修完后建议一并定性。要不要现在处理?
|
|
81
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-method
|
|
3
|
+
description: 代码复核走查方法(Standards×Spec 双轴 + 坏味道清单 + 合入标尺)。供 independent-reviewer 或主智能体复核 diff 时使用;是 .agents/commands/review.md 执行流程的方法层单源,不依赖宿主全局技能。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# review-method — 复核走查方法
|
|
7
|
+
|
|
8
|
+
## 定位与分工
|
|
9
|
+
复核三层各自单源,本文件只管「怎么走查」:
|
|
10
|
+
|
|
11
|
+
| 层 | 单源 |
|
|
12
|
+
|---|---|
|
|
13
|
+
| 拦什么(不变量) | `.agents/commands/review.md` P0/P1 表 |
|
|
14
|
+
| 以什么身份查(证据纪律) | `.agents/roles/independent-reviewer.md` Constraints |
|
|
15
|
+
| 怎么走查(本文件) | 双轴框架 + 坏味道清单 + 合入标尺 |
|
|
16
|
+
|
|
17
|
+
宿主有全局 `code-review` / `review-verification-protocol` 技能时可叠加;无则本文件兜底。
|
|
18
|
+
|
|
19
|
+
## 双轴框架(分轴报告,禁合并排序)
|
|
20
|
+
| 轴 | 问的问题 | 依据 |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| **Standards** | 是否符合本仓成文标准 | 根/目录级 `AGENTS.md` + review.md P0/P1 表 |
|
|
23
|
+
| **Spec** | 是否忠实实现入口文档承诺 | intent/plan「验收标准」+ spec §测试用例 |
|
|
24
|
+
|
|
25
|
+
两轴独立成立:合规范但做错事(Standards 过、Spec 挂)与做对事但破规范(Spec 过、Standards 挂)都存在——分开报告防一轴掩盖另一轴。Spec 轴报三类发现:承诺缺失/部分落地、超范围(scope creep)、实现走样。
|
|
26
|
+
|
|
27
|
+
## 坏味道走查清单(Standards 轴补充)
|
|
28
|
+
P0/P1 表之外的判断项。约束:仓库成文标准优先(成文认可即压制本清单);始终是判断项非硬违规;门禁/tooling 已拦的跳过。每条 = 是什么 $\rightarrow$ 怎么修:
|
|
29
|
+
|
|
30
|
+
| 坏味道 | 是什么 $\rightarrow$ 怎么修 |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Mysterious Name 神秘命名 | 名字不揭示用途 $\rightarrow$ 重命名;起不出诚实名字 = 设计混浊 |
|
|
33
|
+
| Duplicated Code 重复代码 | 同形逻辑在多处出现 $\rightarrow$ 提取共享实现,两处调用 |
|
|
34
|
+
| Feature Envy 依恋情结 | 方法够别家数据多过自己 $\rightarrow$ 把方法移到所依恋的数据上 |
|
|
35
|
+
| Data Clumps 数据泥团 | 几个字段/参数总是结伴出行 $\rightarrow$ 捆成一个类型传递 |
|
|
36
|
+
| Primitive Obsession 基本类型偏执 | 原始值顶替领域概念 $\rightarrow$ 为概念建专属小类型 |
|
|
37
|
+
| Repeated Switches 重复开关 | 对同一类型的 switch/级联 if 反复出现 $\rightarrow$ 多态或共享映射 |
|
|
38
|
+
| Shotgun Surgery 霰弹式修改 | 一个逻辑变更迫使多文件分散编辑 $\rightarrow$ 聚拢到同一模块 |
|
|
39
|
+
| Divergent Change 发散式变化 | 一个模块因多个不相关原因被改 $\rightarrow$ 按单一变化理由拆分 |
|
|
40
|
+
| Speculative Generality 投机泛化 | 为 spec 没有的需求加抽象/参数/钩子 $\rightarrow$ 删掉内联,等真实需求出现 |
|
|
41
|
+
| Message Chains 消息链 | 长 `a.b().c().d()` 导航 $\rightarrow$ 在首对象上藏一个方法 |
|
|
42
|
+
| Middle Man 中间人 | 类/函数几乎只做转发 $\rightarrow$ 删掉,直调真目标 |
|
|
43
|
+
| Refused Bequest 拒绝继承 | 子类忽略/覆盖大部分继承物 $\rightarrow$ 弃继承改组合 |
|
|
44
|
+
|
|
45
|
+
性能三项(P1 分页条款之外):N+1 查询、无界取数/循环、热路径大对象。
|
|
46
|
+
|
|
47
|
+
## 结构化修复动作
|
|
48
|
+
报结构问题时给命名动作,禁只说「这里复杂」让作者猜:消条件链建类型/分发器、折叠重复分支、编排与业务分离、特性逻辑移回所属层、复用权威 helper 禁近亲复制、显式类型边界消下游分支、删无澄清价值的透传包装、抽 helper 或拆大文件。
|
|
49
|
+
|
|
50
|
+
## 合入标尺(防 P2 纠缠)
|
|
51
|
+
确定改善整体代码健康即建议合入,不因「不是我会这么写」而拦——完美不存在,持续改进是目标。样式偏好与假设性风险禁报(证据纪律见角色契约 Constraints)。
|
|
52
|
+
|
|
53
|
+
## 出处
|
|
54
|
+
- 双轴框架与坏味道清单:提炼自宿主全局 `code-review` 技能(Fowler《Refactoring》ch.3 基线)。
|
|
55
|
+
- 结构化修复动作与合入标尺:借自 [addyosmani/agent-skills](https://github.com/addyosmani/agent-skills)(MIT)。
|
|
@@ -16,4 +16,11 @@ doc.status.terminal=done superseded cancelled
|
|
|
16
16
|
doc.status.abandoned=superseded cancelled
|
|
17
17
|
incident.status.all=open fixed closed
|
|
18
18
|
incident.status.active=open
|
|
19
|
-
|
|
19
|
+
# 归因枚举(2026-10-13 自 Shipyard 回灌 incident-attribution):归因检查(B6b 落地后编号以 check-loop.mjs 头部清单为准)校验 incident frontmatter 的「来源:」/「影响环境:」。
|
|
20
|
+
# source = 谁发现(self=AI 自查 / user=用户报出 / test=测试或实测暴露 / monitor=监控告警)
|
|
21
|
+
# env = 缺陷触达的环境(none=未触达任何运行环境,如仅静态检查发现)
|
|
22
|
+
# 锚前存量不回填;新 open 件必填(生效锚随 B6b 归因检查落地)。
|
|
23
|
+
incident.source.all=self user test monitor
|
|
24
|
+
incident.env.all=dev staging prod none
|
|
25
|
+
# 级别三档(2026-10-13 L0 退役自源仓收敛系列 1 回灌):L1 = 一份 plan 即入口(协作道);L2/L3 = 防御道。
|
|
26
|
+
level.all=L1 L2 L3
|
|
@@ -1,101 +1,121 @@
|
|
|
1
|
-
#!/bin/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Git 原生 pre-commit hook(经 core.hooksPath 挂载)— agentic-flow-kit 通用编排
|
|
3
|
+
// 2026-10-13 门禁去 sh 化(B2,自 Shipyard.Material 参考实现回灌):钩子体不再含 sh 逻辑——git 仍以自带
|
|
4
|
+
// sh 启动本文件(钩子机制要求),但 shebang 即 node,PATH 无 sh 不再影响任何逻辑;语言单化后 CI 代理/
|
|
5
|
+
// 本地行为一致。写法为 CommonJS——无扩展名文件 node 缺省按 CJS 解析,不依赖 ≥22.7 的 ESM 语法探测。
|
|
6
|
+
// 通用门禁序:闭环配对(增量) → 泳道完整性(增量) → wiki 台账(增量) → 索引漂移(增量) → 常驻面体积预算(增量) → 确认台账不变量(暂存触台账) → 项目门禁(local-pre-commit) → 敏感信息扫描+条件构建(commit-check.cjs)
|
|
7
|
+
// 项目专属门禁(架构红线/业务守卫等)放 .agents/hooks/local-pre-commit——sh 挂载点(add-gate 生态按行接线),
|
|
8
|
+
// 存在即在本钩子内以 sh(缺则 bash)执行,返回非零即阻断提交
|
|
9
|
+
// 合并提交场景由 .githooks/pre-merge-commit 原样转发到本脚本(合并时 git 调的是 pre-merge-commit,
|
|
10
|
+
// 不是 pre-commit)——门禁清单只此一份,避免两处分叉
|
|
11
|
+
// fail-closed(沿 Shipyard 2026-10-09 口径;node 化后天然成立——本进程即 node):门脚本缺失 = 拒提交;
|
|
12
|
+
// 仅 local-pre-commit 保留「存在即执行」挂载点语义(缺失打 advisory)。
|
|
13
|
+
const { spawnSync } = require('node:child_process');
|
|
14
|
+
const fs = require('node:fs');
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
gate_label="$1"; shift
|
|
13
|
-
if command -v sh >/dev/null 2>&1; then sh "$@"; else bash "$@"; fi
|
|
14
|
-
rc=$?
|
|
15
|
-
if [ $rc -ne 0 ]; then
|
|
16
|
-
echo "pre-commit: $gate_label 未通过,提交已阻止" >&2
|
|
17
|
-
exit $rc
|
|
18
|
-
fi
|
|
16
|
+
const top = spawnSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8' });
|
|
17
|
+
if (top.status !== 0 || !top.stdout.trim()) {
|
|
18
|
+
console.error('pre-commit: 无法定位仓库根(git rev-parse --show-toplevel 失败)——提交已阻止');
|
|
19
|
+
process.exit(1);
|
|
19
20
|
}
|
|
21
|
+
process.chdir(top.stdout.trim());
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
else
|
|
37
|
-
run_gate "闭环配对(增量)" .agents/hooks/check-pairing-incremental.sh
|
|
38
|
-
fi
|
|
23
|
+
// gate(label, script, args):node 直跑门脚本,非零即阻断(含 fail-closed 缺失检查)
|
|
24
|
+
const requireScript = (rel) => {
|
|
25
|
+
if (!fs.existsSync(rel)) {
|
|
26
|
+
console.error(`pre-commit: 门脚本缺失 ${rel}——提交已阻止(脚本随包下发;flow-kit sync 恢复后重试)`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const gate = (label, script, args = []) => {
|
|
31
|
+
requireScript(script);
|
|
32
|
+
const r = spawnSync(process.execPath, [script, ...args], { stdio: 'inherit' });
|
|
33
|
+
if (r.status !== 0) {
|
|
34
|
+
console.error(`pre-commit: ${label} 未通过,提交已阻止`);
|
|
35
|
+
process.exit(r.status === null ? 1 : r.status);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
// 闭环配对门禁(增量版,check-pairing-incremental.mjs:本次暂存的 intents/incidents 入口须已有同名 plan;
|
|
40
|
+
// L2/L3 另须同名 spec)。experiment/* 泳道分支(2026-09-30 hybrid-governance-explore-hardening):
|
|
41
|
+
// 降级为 advisory——快速 PoC 迭代不因闭环文档断档被拦(断档报告照出),转正合入 main 由 pre-push
|
|
42
|
+
// 加固门(check-loop --hardening)兜底。仅降级闭环文档面:常驻面 / 台账 / 敏感信息扫描等门禁不豁免。
|
|
43
|
+
// 分支不可判(detached HEAD 等)走严格模式。
|
|
44
|
+
const branch = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { encoding: 'utf8' });
|
|
45
|
+
const branchName = branch.status === 0 ? branch.stdout.trim() : '';
|
|
46
|
+
if (branchName.startsWith('experiment/')) {
|
|
47
|
+
console.error('pre-commit: experiment/* 泳道分支——闭环配对门禁降级为 advisory(报告不阻断;转正入 main 须过加固门)');
|
|
48
|
+
const adv = spawnSync(process.execPath, ['.agents/hooks/check-pairing-incremental.mjs'], { stdio: 'inherit' });
|
|
49
|
+
if (adv.status !== 0) console.error('pre-commit: (advisory)闭环配对断档已在上方列出——experiment 泳道不阻断提交');
|
|
50
|
+
} else {
|
|
51
|
+
gate('闭环配对(增量)', '.agents/hooks/check-pairing-incremental.mjs');
|
|
52
|
+
}
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
// 泳道完整性(增量,check-lane-surface.mjs——2026-10-01 drift-hardening):
|
|
55
|
+
// 检查 A「触达面判低」——暂存命中项目 L2 触达面(.agents/lane-surfaces.txt,ERE 逐行;缺失/空=跳过,
|
|
56
|
+
// 装户无感)且活跃入口(draft/approved / open/fixed)全为 L0/L1 → 拦;有活跃 L2/L3 → 放行;无活跃入口 →
|
|
57
|
+
// 仅 advisory(docs/bootstrap 豁免类)。experiment/* 分支降级 advisory(转正由 pre-push 加固门兜底)。
|
|
58
|
+
// 检查 B「探索标记缺失」——experiment/* 分支暂存 intent 缺「阶段: exploring」→ 拦(标记零成本,
|
|
59
|
+
// advisory 免纪律不免标记——标记是加固门覆盖率的前提)。
|
|
60
|
+
// 脚本缺失 fail-closed 阻断(见 gate())。
|
|
61
|
+
gate('泳道完整性(增量)', '.agents/scripts/check-lane-surface.mjs');
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
run_gate "常驻面体积预算" .agents/scripts/rule-budget.sh --staged
|
|
63
|
-
fi
|
|
63
|
+
// wiki 台账门禁(增量,check-wiki-ledger.mjs:暂存区触及 wiki/ 时跑 verify-wiki-consistency 三方一致性;
|
|
64
|
+
// 无 wiki/ 变更即跳过。脚本缺失 fail-closed)
|
|
65
|
+
gate('wiki 台账(增量)', '.agents/hooks/check-wiki-ledger.mjs');
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if git -c core.quotepath=off diff --cached --name-only | grep -q '^\.agents/confirmations\.jsonl$'; then
|
|
70
|
-
if ! node .agents/scripts/check-ledger-invariant.mjs --staged; then
|
|
71
|
-
echo "pre-commit: 确认台账不变量未通过,提交已阻止——历史行禁删改(append-only),修正走追加补偿行" >&2
|
|
72
|
-
exit 1
|
|
73
|
-
fi
|
|
74
|
-
fi
|
|
75
|
-
fi
|
|
67
|
+
// 索引漂移(增量硬拦,check-index-incremental.mjs):暂存触及 workflow 四目录 / 归档 / INDEX.md 时,
|
|
68
|
+
// gen-workflow-index.mjs --check 不一致即拒。卫生段检查 11 仍是 WARN,挡不住关单提交。
|
|
69
|
+
// 未触及这些路径则脚本内跳过。脚本缺失 fail-closed。
|
|
70
|
+
gate('索引漂移(增量)', '.agents/hooks/check-index-incremental.mjs');
|
|
76
71
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
// 常驻面体积预算(增量硬拦,rule-budget.mjs --staged:只查本次暂存触及的条目与触及目录的合计;
|
|
73
|
+
// 超限即阻断——常驻面只增不减,须先删除或下沉一条被取代条目再增。预算登记表缺失同样 fail-closed)
|
|
74
|
+
requireScript('.agents/rule-budgets.txt');
|
|
75
|
+
gate('常驻面体积预算', '.agents/scripts/rule-budget.mjs', ['--staged']);
|
|
81
76
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
77
|
+
// 确认台账不变量前置(--staged,2026-10-02 ledger-ci-invariant):暂存的 confirmations.jsonl 与分片
|
|
78
|
+
// confirmations.d/*.jsonl(2026-10-13 ledger-shard-default 起分片为默认写入口径,触发面同步扩大)必须
|
|
79
|
+
// 是 HEAD 的逐字节前缀扩展(append-only)——本地提交时刻即拦「顺手重写台账」,CI 历史全扫兜底。
|
|
80
|
+
// 暂存未触台账静默;触台账而脚本缺失 fail-closed 阻断。
|
|
81
|
+
const staged = spawnSync('git', ['-c', 'core.quotepath=off', 'diff', '--cached', '--name-only'], { encoding: 'utf8' });
|
|
82
|
+
const stagedFiles = String(staged.stdout || '').split(/\r?\n/).filter(Boolean).map((f) => f.replace(/\\/g, '/'));
|
|
83
|
+
const touchesLedger = stagedFiles.some((f) => /^\.agents\/confirmations\.jsonl$|^\.agents\/confirmations\.d\/[^/]+\.jsonl$/.test(f));
|
|
84
|
+
if (touchesLedger) {
|
|
85
|
+
requireScript('.agents/scripts/check-ledger-invariant.mjs');
|
|
86
|
+
const li = spawnSync(process.execPath, ['.agents/scripts/check-ledger-invariant.mjs', '--staged'], { stdio: 'inherit' });
|
|
87
|
+
if (li.status !== 0) {
|
|
88
|
+
console.error('pre-commit: 确认台账不变量未通过,提交已阻止——历史行禁删改(append-only),修正走追加补偿行');
|
|
89
|
+
process.exit(li.status === null ? 1 : li.status);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
// 项目门禁挂载点:.agents/hooks/local-pre-commit(项目自建门禁/门禁模块接线处,add-gate 生态往里写行)。
|
|
94
|
+
// 保持 sh 形态:以 sh(缺则 bash)执行;存在即执行、缺失打 advisory 不阻断(挂载点可选语义),
|
|
95
|
+
// 但缺失不再无声——该文件随包下发,advisory 即误删信号。
|
|
96
|
+
if (fs.existsSync('.agents/hooks/local-pre-commit')) {
|
|
97
|
+
const shBin = spawnSync('sh', ['-c', 'true']).status === 0 ? 'sh' : 'bash';
|
|
98
|
+
const lp = spawnSync(shBin, ['.agents/hooks/local-pre-commit'], { stdio: 'inherit' });
|
|
99
|
+
if (lp.status !== 0) {
|
|
100
|
+
console.error('pre-commit: 项目门禁(local-pre-commit)未通过,提交已阻止');
|
|
101
|
+
process.exit(lp.status === null ? 1 : lp.status);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
console.error('pre-commit: (advisory)项目门禁挂载点 .agents/hooks/local-pre-commit 不在场——add-gate 接线处随包下发,若为误删请 flow-kit sync 恢复');
|
|
105
|
+
}
|
|
94
106
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
107
|
+
// 合并提交 → 构建验证覆盖【完整合并树】,不做按扩展名的条件裁剪。
|
|
108
|
+
// 两条路径:`git merge` 自动提交由 .githooks/pre-merge-commit 显式传 `--full` 转发到本脚本;
|
|
109
|
+
// 冲突解决后手动 `git commit` 由 git 直接调本脚本,此处按 MERGE_HEAD 探测补上(此时合并仍在进行)。
|
|
110
|
+
let fullArgs = process.argv.slice(2);
|
|
111
|
+
if (fullArgs.length === 0) {
|
|
112
|
+
const mergeHead = spawnSync('git', ['rev-parse', '-q', '--verify', 'MERGE_HEAD'], { encoding: 'utf8' });
|
|
113
|
+
if (mergeHead.status === 0) fullArgs = ['--full'];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const cc = spawnSync(process.execPath, ['.agents/hooks/commit-check.cjs', ...fullArgs], { stdio: 'inherit' });
|
|
117
|
+
if (cc.status !== 0) {
|
|
118
|
+
console.error('pre-commit: 验证未通过,提交已阻止');
|
|
119
|
+
process.exit(cc.status === null ? 1 : cc.status);
|
|
120
|
+
}
|
|
121
|
+
process.exit(0);
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
#!/bin/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Git 原生 pre-merge-commit hook(经 core.hooksPath 挂载;2026-10-13 随 pre-commit node 化(B2)改为 node 转发
|
|
3
|
+
// ——转发不再经 sh。CommonJS——无扩展名文件 node 缺省按 CJS 解析,不依赖 ESM 语法探测)
|
|
4
|
+
//
|
|
5
|
+
// 背景:git 对 `git merge` 调的是**本钩子**,不是 pre-commit。此前仓库只挂了
|
|
6
|
+
// pre-commit / pre-push / commit-msg,故合并提交绕过全部门禁、未经任何校验直接落库
|
|
7
|
+
// (2026-09-19 实测,见 workflow/papercuts.md 同日行——那次合并带入后端 .cs 改动,
|
|
8
|
+
// 靠人工补跑静态门 + 全量测试才覆盖到)。
|
|
9
|
+
//
|
|
10
|
+
// 做法:转发到 .githooks/pre-commit(门禁清单只此一份,避免两份拷贝日后分叉),
|
|
11
|
+
// 并显式传 `--full`——本钩子「只对 merge 触发」这一身份就是最强信号,无需再去探测
|
|
12
|
+
// MERGE_HEAD(2026-09-19 实测:本时点 MERGE_HEAD 已不可靠)。`--full` 令编译验证
|
|
13
|
+
// 覆盖【完整合并树】、不按扩展名的条件裁剪:合并结果是没人验证过的新状态,且其 diff
|
|
14
|
+
// 相对第一父,裁剪会漏掉需要重跑的一侧。
|
|
15
|
+
//
|
|
16
|
+
// 冲突解决后手动 `git commit` 走的是 pre-commit 自身,那条路径由 pre-commit 内部的
|
|
17
|
+
// MERGE_HEAD 探测覆盖(此时合并仍在进行,MERGE_HEAD 确定存在)。
|
|
18
|
+
const { spawnSync } = require('node:child_process');
|
|
19
|
+
const path = require('node:path');
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const top = spawnSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8' });
|
|
22
|
+
if (top.status !== 0 || !top.stdout.trim()) {
|
|
23
|
+
console.error('pre-merge-commit: 无法定位仓库根——合并提交已阻止');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const hook = path.join(top.stdout.trim(), '.githooks', 'pre-commit');
|
|
27
|
+
const r = spawnSync(process.execPath, [hook, '--full'], { stdio: 'inherit' });
|
|
28
|
+
process.exit(r.status === null ? 1 : r.status);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
# Git 原生 pre-push hook(经 core.hooksPath 挂载,git push 时触发)
|
|
3
|
-
# 跑 .agents/scripts/check-loop.sh:扫 workflow/
|
|
4
|
-
# - 硬阻断(exit 1)= 配对断裂 / 回路断档 → push 立即阻断
|
|
5
|
-
# -
|
|
3
|
+
# 跑 .agents/scripts/check-loop.sh:扫 workflow/ 闭环骨架断档(2026-10-13 分道——默认只扫硬门,源仓同款)
|
|
4
|
+
# - 硬阻断(exit 1)= 配对断裂 / 回路断档 等硬门违例 → push 立即阻断
|
|
5
|
+
# - 卫生项(索引/宿主/词表/体积预算等 WARN 面)不进 push 门——要看时手跑 check-loop.mjs --hygiene
|
|
6
|
+
# (--all 两面都跑 = 分道前的裸跑全量)
|
|
6
7
|
# stdin 有行时,每个非删除的本地 sha 用 --rev 扫那棵树。没有行时(手跑钩子)仍无参数扫工作区。
|
|
7
8
|
#
|
|
8
9
|
# experiment/* 泳道(2026-09-30 hybrid-governance-explore-hardening):**目标分支**为 experiment/* 时,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# kit-ci —— agentic-flow-kit 装户远端门(GitHub Actions 薄模板,2026-10-07 adopter-ci-github)
|
|
2
2
|
# 语义:本地 git hooks 可被 --no-verify / 未配 hooksPath 的克隆绕过——本工作流在 GitHub runner 上复跑
|
|
3
|
-
# 统一入口 node .agents/scripts/verify.mjs
|
|
4
|
-
#
|
|
3
|
+
# 统一入口 node .agents/scripts/verify.mjs(七门 GATES 编排:语法自检 / 测试【有根 package.json 才跑】/
|
|
4
|
+
# 编排脚本检查 / 常驻面预算 / 生效规则视图漂移 / check-loop 闭环硬门 / 台账不变量历史全扫——门清单见
|
|
5
|
+
# verify.mjs --list),任一门红即红;不在 YAML 里复制门禁逻辑(本地/远端单源,防口径漂移)。
|
|
5
6
|
# 本文件归装户自持(owned):触发分支 / node 版本 / 测试命令可自改,flow-kit sync 永不覆盖。
|
|
6
7
|
# 装户仓工程在子目录(根无 package.json)时 verify 会跳过测试——改用
|
|
7
8
|
# node .agents/scripts/verify.mjs --test-cmd "<项目测试命令>"
|
|
@@ -24,7 +25,7 @@ jobs:
|
|
|
24
25
|
- name: 安装依赖(有根 package.json 才跑;私有源在此加 registry 配置)
|
|
25
26
|
if: hashFiles('package.json') != ''
|
|
26
27
|
run: npm ci || npm install || npm install --registry=https://registry.npmjs.org # 末级官方源兜底(2026-10-09 engine-quality-round3 W3:镜像故障不阻塞 CI)
|
|
27
|
-
- name:
|
|
28
|
+
- name: 远端门(verify 七门编排)
|
|
28
29
|
run: node .agents/scripts/verify.mjs
|
|
29
30
|
- name: CI 红回溯点名(2026-10-09 engine-quality-round2 B3:红时列出最近关单,复核优先)
|
|
30
31
|
if: failure()
|