agentic-flow-kit 1.8.2 → 1.8.7

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 (47) hide show
  1. package/README.md +1 -1
  2. package/modules/hosts/claude/commands/wf-build.md +1 -1
  3. package/modules/hosts/claude/commands/wf-design.md +1 -1
  4. package/modules/hosts/claude/commands/wf-review.md +1 -1
  5. package/modules/hosts/codex/commands/wf-build.md +1 -1
  6. package/modules/hosts/codex/commands/wf-design.md +1 -1
  7. package/modules/hosts/codex/commands/wf-review.md +1 -1
  8. package/modules/hosts/cursor/commands/wf-build.md +1 -1
  9. package/modules/hosts/cursor/commands/wf-design.md +1 -1
  10. package/modules/hosts/cursor/commands/wf-review.md +1 -1
  11. package/modules/hosts/opencode/commands/wf-build.md +1 -1
  12. package/modules/hosts/opencode/commands/wf-design.md +1 -1
  13. package/modules/hosts/opencode/commands/wf-review.md +1 -1
  14. package/modules/hosts/trae/commands/wf-build.md +1 -1
  15. package/modules/hosts/trae/commands/wf-design.md +1 -1
  16. package/modules/hosts/trae/commands/wf-review.md +1 -1
  17. package/package.json +1 -1
  18. package/src/jscpd-drift.test.mjs +3 -2
  19. package/templates/AGENTS.md +1 -0
  20. package/templates/_agents/commands/build.md +1 -1
  21. package/templates/_agents/commands/design.md +1 -1
  22. package/templates/_agents/commands/review.md +1 -1
  23. package/templates/_agents/engine-lock.json +12 -12
  24. package/templates/_agents/mechanism-registry.md +8 -0
  25. package/templates/_agents/rule-budgets.txt +4 -2
  26. package/templates/_agents/scripts/check-lane-surface.test.mjs +1 -1
  27. package/templates/_agents/scripts/check-ledger-invariant.mjs +80 -21
  28. package/templates/_agents/scripts/check-ledger-invariant.test.mjs +1 -1
  29. package/templates/_agents/scripts/check-loop.mjs +32 -3
  30. package/templates/_agents/scripts/check-loop.test.mjs +37 -0
  31. package/templates/_agents/scripts/check-scope.test.mjs +4 -1
  32. package/templates/_agents/scripts/check-scripts-syntax.mjs +33 -10
  33. package/templates/_agents/scripts/confirm-doc.mjs +13 -6
  34. package/templates/_agents/scripts/confirm-doc.test.mjs +25 -9
  35. package/templates/_agents/scripts/gen-workflow-metrics.mjs +141 -9
  36. package/templates/_agents/scripts/gen-workflow-metrics.test.mjs +119 -0
  37. package/templates/_agents/scripts/lane-surface-audit.test.mjs +1 -1
  38. package/templates/_agents/scripts/pre-push.test.mjs +1 -1
  39. package/templates/_agents/scripts/solidify-task.mjs +3 -1
  40. package/templates/_agents/scripts/solidify-task.test.mjs +10 -10
  41. package/templates/_agents/scripts/trust-mode.test.mjs +1 -1
  42. package/templates/_agents/scripts/verify.mjs +209 -74
  43. package/templates/_agents/scripts/verify.test.mjs +15 -0
  44. package/templates/_agents/skills/review-method/SKILL.md +3 -0
  45. package/templates/workflow/README.md +2 -1
  46. package/templates/workflow/intents/_TEMPLATE.md +5 -0
  47. package/templates/workflow/specs/_TEMPLATE.md +1 -1
package/README.md CHANGED
@@ -35,7 +35,7 @@ node .agents/scripts/confirm-doc.mjs workflow/intents/<文件>.md # 终端里
35
35
 
36
36
  **门禁信任档**(`.agents/kit.json` 的 `gateTrust`):默认 `project` —— gate 安装锚失配只 WARN(装户对门有最终所有权,锚只提供可见性)。多仓或组织场景改成 `org`,失配即 `doctor` FAIL(exit 1),对齐托管策略的组织级强制。缺键或非法值一律回退 `project`,不会因写错而变严。
37
37
 
38
- **待澄清标记**:起草 spec / plan 时不确定的地方照实写一行 `- 待澄清:<你卡在哪>`,不要猜——「我不知道」是负责,猜是失职(与检查 2 的模板占位符语义相反:占位符是忘了填)。起草门不拦(零阻塞),但 `draft→approved` 确认时仍挂着未澄清项会被 `confirm-doc` 拒绝落账。解决后把行首改成 `- 已澄清:`(保留行,留痕曾不清楚过)或删行。
38
+ **待澄清标记**:起草 intent / spec / plan 时不确定的地方照实写一行 `- 待澄清:<你卡在哪>`,不要猜——「我不知道」是负责,猜是失职(与检查 2 的模板占位符语义相反:占位符是忘了填)。起草门不拦(零阻塞),但 `draft→approved` 确认时仍挂着未澄清项会被 `confirm-doc` 拒绝落账(2026-10-18 立项跳对称化起 intents 同口径挂门——intent 是后链全部文档的种子;存量无标记零回溯)。解决后把行首改成 `- 已澄清:`(保留行,留痕曾不清楚过)或删行。
39
39
 
40
40
  **关于「确认门」的诚实边界**:确认门是**留痕机制,不是防伪机制**。`confirm-doc.mjs` 把确认事件写进 `.agents/confirmations.jsonl`(append-only,入 git),check-loop 据此对账——但台账是本地可写文件,**刻意手改台账仍可伪造**。门禁的实际作用是把「顺手绕过」抬到「主动伪造」(两者性质不同、可事后对质),而非关闭通道。引擎注释对此有完整声明(见包源 `templates/_agents/scripts/stage-gates.mjs` 头部信任边界段;装户径同份在 `.agents/scripts/stage-gates.mjs`)。委托代录(`--delegated`)的台账行如实记 `source` 与用户原话供事后对质,永不伪装 TTY 确认。
41
41
 
@@ -64,6 +64,6 @@ description: Build 阶段:起 plan + 实现代码 + 自验(确认后才动代码
64
64
 
65
65
  ## 5. 确认后
66
66
 
67
- - plan 状态 → done(实现完成;intent / spec 关单在 test)
67
+ - plan 状态保持 `approved`,**不在此置 `done`**——实现完成 ≠ 关单;`done` 在 `test.md` §6 验收勾验后经 confirm-doc 置(intent / spec / 修复的同名 plan 亦在 test 一并收口;build 直跳 `done` 会绕过确认门、触发检查 15 指纹对账)
68
68
  - commit:L1+ 入口文档 / spec / plan 随代码同一提交(Conventional Commits 中文 feat/fix/refactor/perf);docs 豁免与 bootstrap 可单独 `docs(*)`
69
69
  - 进 `next: .agents/commands/test.md`
@@ -24,7 +24,7 @@ description: Design 阶段:起 spec(L2/L3 强制,L1 可省略)
24
24
  - **填空工具先跑**:`node .agents/scripts/fill-spec.mjs --level <L1|L2|L3> --topic <主题> --output workflow/specs/<date>-<主题>.md`——输出含 frontmatter 5 字段 + 5 节正文(功能行为/数据流/系统改动/约束遵守映射/风险评估)的草稿;AI 据此填实
25
25
  - 复制 `workflow/specs/_TEMPLATE.md` → `workflow/specs/YYYY-MM-DD-<主题>.md`(与入口文档同名)
26
26
  - 按 5 节填写:功能行为 / 数据流 / 系统改动 / 约束遵守映射 / 风险评估
27
- - 约束映射必须对照根 `AGENTS.md` 红线/约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
27
+ - 约束映射必须对照根 `AGENTS.md` 红线与「工程原则」节及约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
28
28
  - 存在多个可行方案时,在 spec 中列出各方案取舍与 AI 建议项,由用户选定后方可确认
29
29
  - **页面/交互入口形态必须用户确认**:spec 须写明入口是「表单(字段清单)」还是「选择器/弹窗」,禁止自行推定交互形态
30
30
  4. 起草后停下,输出草稿全文给用户过目。
@@ -44,6 +44,6 @@ description: 代码评审标准(按风险分级:机器兜底 + AI 自查出
44
44
  ## 4. 审查分工(用户决策 + AI 协作)
45
45
 
46
46
  - **机器兜底**(pre-commit / pre-push / test 自动拦,无需人守):门禁清单与判据以 `.githooks/`、`.agents/hooks/`、`check-loop.sh` 头部注释为准;`项目测试命令` 跑自动化用例。
47
- - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。
47
+ - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。**落账**:复核收口时在 `workflow/reviews.d/<当月>.md` 追加一行事件记录——八列 `| 日期 | 对象 | 复核员(宿主) | 意见数 | 采纳 | 拒绝 | 误报 | 备注 |`,自洽约束 采纳+拒绝+误报=意见数(gen-workflow-metrics 按此校验,破坏即拦);月度聚合进 metrics「复核效果」表
48
48
  - **独立性**:L2 / L3 必须用独立子智能体,宿主不支持时另开新会话,不得由原作者自查冒充;L1 且宿主不支持子智能体时可由主智能体按同一复核契约执行。
49
49
  - **用户决策**:问题定性(误报驳回 / P0 成立必修 / P1、P2 处置裁量)+ 合入时机;git 历史即评审记录,追溯靠 commit 与 tag。
@@ -64,6 +64,6 @@ description: Build 阶段:起 plan + 实现代码 + 自验(确认后才动代码
64
64
 
65
65
  ## 5. 确认后
66
66
 
67
- - plan 状态 → done(实现完成;intent / spec 关单在 test)
67
+ - plan 状态保持 `approved`,**不在此置 `done`**——实现完成 ≠ 关单;`done` 在 `test.md` §6 验收勾验后经 confirm-doc 置(intent / spec / 修复的同名 plan 亦在 test 一并收口;build 直跳 `done` 会绕过确认门、触发检查 15 指纹对账)
68
68
  - commit:L1+ 入口文档 / spec / plan 随代码同一提交(Conventional Commits 中文 feat/fix/refactor/perf);docs 豁免与 bootstrap 可单独 `docs(*)`
69
69
  - 进 `next: .agents/commands/test.md`
@@ -24,7 +24,7 @@ description: Design 阶段:起 spec(L2/L3 强制,L1 可省略)
24
24
  - **填空工具先跑**:`node .agents/scripts/fill-spec.mjs --level <L1|L2|L3> --topic <主题> --output workflow/specs/<date>-<主题>.md`——输出含 frontmatter 5 字段 + 5 节正文(功能行为/数据流/系统改动/约束遵守映射/风险评估)的草稿;AI 据此填实
25
25
  - 复制 `workflow/specs/_TEMPLATE.md` → `workflow/specs/YYYY-MM-DD-<主题>.md`(与入口文档同名)
26
26
  - 按 5 节填写:功能行为 / 数据流 / 系统改动 / 约束遵守映射 / 风险评估
27
- - 约束映射必须对照根 `AGENTS.md` 红线/约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
27
+ - 约束映射必须对照根 `AGENTS.md` 红线与「工程原则」节及约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
28
28
  - 存在多个可行方案时,在 spec 中列出各方案取舍与 AI 建议项,由用户选定后方可确认
29
29
  - **页面/交互入口形态必须用户确认**:spec 须写明入口是「表单(字段清单)」还是「选择器/弹窗」,禁止自行推定交互形态
30
30
  4. 起草后停下,输出草稿全文给用户过目。
@@ -44,6 +44,6 @@ description: 代码评审标准(按风险分级:机器兜底 + AI 自查出
44
44
  ## 4. 审查分工(用户决策 + AI 协作)
45
45
 
46
46
  - **机器兜底**(pre-commit / pre-push / test 自动拦,无需人守):门禁清单与判据以 `.githooks/`、`.agents/hooks/`、`check-loop.sh` 头部注释为准;`项目测试命令` 跑自动化用例。
47
- - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。
47
+ - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。**落账**:复核收口时在 `workflow/reviews.d/<当月>.md` 追加一行事件记录——八列 `| 日期 | 对象 | 复核员(宿主) | 意见数 | 采纳 | 拒绝 | 误报 | 备注 |`,自洽约束 采纳+拒绝+误报=意见数(gen-workflow-metrics 按此校验,破坏即拦);月度聚合进 metrics「复核效果」表
48
48
  - **独立性**:L2 / L3 必须用独立子智能体,宿主不支持时另开新会话,不得由原作者自查冒充;L1 且宿主不支持子智能体时可由主智能体按同一复核契约执行。
49
49
  - **用户决策**:问题定性(误报驳回 / P0 成立必修 / P1、P2 处置裁量)+ 合入时机;git 历史即评审记录,追溯靠 commit 与 tag。
@@ -64,6 +64,6 @@ description: Build 阶段:起 plan + 实现代码 + 自验(确认后才动代码
64
64
 
65
65
  ## 5. 确认后
66
66
 
67
- - plan 状态 → done(实现完成;intent / spec 关单在 test)
67
+ - plan 状态保持 `approved`,**不在此置 `done`**——实现完成 ≠ 关单;`done` 在 `test.md` §6 验收勾验后经 confirm-doc 置(intent / spec / 修复的同名 plan 亦在 test 一并收口;build 直跳 `done` 会绕过确认门、触发检查 15 指纹对账)
68
68
  - commit:L1+ 入口文档 / spec / plan 随代码同一提交(Conventional Commits 中文 feat/fix/refactor/perf);docs 豁免与 bootstrap 可单独 `docs(*)`
69
69
  - 进 `next: .agents/commands/test.md`
@@ -24,7 +24,7 @@ description: Design 阶段:起 spec(L2/L3 强制,L1 可省略)
24
24
  - **填空工具先跑**:`node .agents/scripts/fill-spec.mjs --level <L1|L2|L3> --topic <主题> --output workflow/specs/<date>-<主题>.md`——输出含 frontmatter 5 字段 + 5 节正文(功能行为/数据流/系统改动/约束遵守映射/风险评估)的草稿;AI 据此填实
25
25
  - 复制 `workflow/specs/_TEMPLATE.md` → `workflow/specs/YYYY-MM-DD-<主题>.md`(与入口文档同名)
26
26
  - 按 5 节填写:功能行为 / 数据流 / 系统改动 / 约束遵守映射 / 风险评估
27
- - 约束映射必须对照根 `AGENTS.md` 红线/约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
27
+ - 约束映射必须对照根 `AGENTS.md` 红线与「工程原则」节及约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
28
28
  - 存在多个可行方案时,在 spec 中列出各方案取舍与 AI 建议项,由用户选定后方可确认
29
29
  - **页面/交互入口形态必须用户确认**:spec 须写明入口是「表单(字段清单)」还是「选择器/弹窗」,禁止自行推定交互形态
30
30
  4. 起草后停下,输出草稿全文给用户过目。
@@ -44,6 +44,6 @@ description: 代码评审标准(按风险分级:机器兜底 + AI 自查出
44
44
  ## 4. 审查分工(用户决策 + AI 协作)
45
45
 
46
46
  - **机器兜底**(pre-commit / pre-push / test 自动拦,无需人守):门禁清单与判据以 `.githooks/`、`.agents/hooks/`、`check-loop.sh` 头部注释为准;`项目测试命令` 跑自动化用例。
47
- - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。
47
+ - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。**落账**:复核收口时在 `workflow/reviews.d/<当月>.md` 追加一行事件记录——八列 `| 日期 | 对象 | 复核员(宿主) | 意见数 | 采纳 | 拒绝 | 误报 | 备注 |`,自洽约束 采纳+拒绝+误报=意见数(gen-workflow-metrics 按此校验,破坏即拦);月度聚合进 metrics「复核效果」表
48
48
  - **独立性**:L2 / L3 必须用独立子智能体,宿主不支持时另开新会话,不得由原作者自查冒充;L1 且宿主不支持子智能体时可由主智能体按同一复核契约执行。
49
49
  - **用户决策**:问题定性(误报驳回 / P0 成立必修 / P1、P2 处置裁量)+ 合入时机;git 历史即评审记录,追溯靠 commit 与 tag。
@@ -64,6 +64,6 @@ description: Build 阶段 · 起 plan + 实现代码 + 自验(两道确认门
64
64
 
65
65
  ## 5. 确认后
66
66
 
67
- - plan 状态 → done(实现完成;intent / spec 关单在 test)
67
+ - plan 状态保持 `approved`,**不在此置 `done`**——实现完成 ≠ 关单;`done` 在 `test.md` §6 验收勾验后经 confirm-doc 置(intent / spec / 修复的同名 plan 亦在 test 一并收口;build 直跳 `done` 会绕过确认门、触发检查 15 指纹对账)
68
68
  - commit:L1+ 入口文档 / spec / plan 随代码同一提交(Conventional Commits 中文 feat/fix/refactor/perf);docs 豁免与 bootstrap 可单独 `docs(*)`
69
69
  - 进 `next: .agents/commands/test.md`
@@ -24,7 +24,7 @@ description: Design 阶段 · 起 spec(L2/L3 强制,L1 可省略直接进 bu
24
24
  - **填空工具先跑**:`node .agents/scripts/fill-spec.mjs --level <L1|L2|L3> --topic <主题> --output workflow/specs/<date>-<主题>.md`——输出含 frontmatter 5 字段 + 5 节正文(功能行为/数据流/系统改动/约束遵守映射/风险评估)的草稿;AI 据此填实
25
25
  - 复制 `workflow/specs/_TEMPLATE.md` → `workflow/specs/YYYY-MM-DD-<主题>.md`(与入口文档同名)
26
26
  - 按 5 节填写:功能行为 / 数据流 / 系统改动 / 约束遵守映射 / 风险评估
27
- - 约束映射必须对照根 `AGENTS.md` 红线/约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
27
+ - 约束映射必须对照根 `AGENTS.md` 红线与「工程原则」节及约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
28
28
  - 存在多个可行方案时,在 spec 中列出各方案取舍与 AI 建议项,由用户选定后方可确认
29
29
  - **页面/交互入口形态必须用户确认**:spec 须写明入口是「表单(字段清单)」还是「选择器/弹窗」,禁止自行推定交互形态
30
30
  4. 起草后停下,输出草稿全文给用户过目。
@@ -44,6 +44,6 @@ description: Review · 代码评审(横切,合入前使用;P0/P1/P2 分级
44
44
  ## 4. 审查分工(用户决策 + AI 协作)
45
45
 
46
46
  - **机器兜底**(pre-commit / pre-push / test 自动拦,无需人守):门禁清单与判据以 `.githooks/`、`.agents/hooks/`、`check-loop.sh` 头部注释为准;`项目测试命令` 跑自动化用例。
47
- - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。
47
+ - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。**落账**:复核收口时在 `workflow/reviews.d/<当月>.md` 追加一行事件记录——八列 `| 日期 | 对象 | 复核员(宿主) | 意见数 | 采纳 | 拒绝 | 误报 | 备注 |`,自洽约束 采纳+拒绝+误报=意见数(gen-workflow-metrics 按此校验,破坏即拦);月度聚合进 metrics「复核效果」表
48
48
  - **独立性**:L2 / L3 必须用独立子智能体,宿主不支持时另开新会话,不得由原作者自查冒充;L1 且宿主不支持子智能体时可由主智能体按同一复核契约执行。
49
49
  - **用户决策**:问题定性(误报驳回 / P0 成立必修 / P1、P2 处置裁量)+ 合入时机;git 历史即评审记录,追溯靠 commit 与 tag。
@@ -65,6 +65,6 @@ description: Build 阶段 · 起 plan + 实现代码 + 自验(两道确认门
65
65
 
66
66
  ## 5. 确认后
67
67
 
68
- - plan 状态 → done(实现完成;intent / spec 关单在 test)
68
+ - plan 状态保持 `approved`,**不在此置 `done`**——实现完成 ≠ 关单;`done` 在 `test.md` §6 验收勾验后经 confirm-doc 置(intent / spec / 修复的同名 plan 亦在 test 一并收口;build 直跳 `done` 会绕过确认门、触发检查 15 指纹对账)
69
69
  - commit:L1+ 入口文档 / spec / plan 随代码同一提交(Conventional Commits 中文 feat/fix/refactor/perf);docs 豁免与 bootstrap 可单独 `docs(*)`
70
70
  - 进 `next: .agents/commands/test.md`
@@ -25,7 +25,7 @@ description: Design 阶段 · 起 spec(L2/L3 强制,L1 可省略直接进 wf
25
25
  - **填空工具先跑**:`node .agents/scripts/fill-spec.mjs --level <L1|L2|L3> --topic <主题> --output workflow/specs/<date>-<主题>.md`——输出含 frontmatter 5 字段 + 5 节正文(功能行为/数据流/系统改动/约束遵守映射/风险评估)的草稿;AI 据此填实
26
26
  - 复制 `workflow/specs/_TEMPLATE.md` → `workflow/specs/YYYY-MM-DD-<主题>.md`(与入口文档同名)
27
27
  - 按 5 节填写:功能行为 / 数据流 / 系统改动 / 约束遵守映射 / 风险评估
28
- - 约束映射必须对照根 `AGENTS.md` 红线/约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
28
+ - 约束映射必须对照根 `AGENTS.md` 红线与「工程原则」节及约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
29
29
  - 存在多个可行方案时,在 spec 中列出各方案取舍与 AI 建议项,由用户选定后方可确认
30
30
  - **页面/交互入口形态必须用户确认**:spec 须写明入口是「表单(字段清单)」还是「选择器/弹窗」,禁止自行推定交互形态
31
31
  4. 起草后停下,输出草稿全文给用户过目。
@@ -45,6 +45,6 @@ description: Review · 代码评审(横切,合入前使用;P0/P1/P2 分级
45
45
  ## 4. 审查分工(用户决策 + AI 协作)
46
46
 
47
47
  - **机器兜底**(pre-commit / pre-push / test 自动拦,无需人守):门禁清单与判据以 `.githooks/`、`.agents/hooks/`、`check-loop.sh` 头部注释为准;`项目测试命令` 跑自动化用例。
48
- - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。
48
+ - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。**落账**:复核收口时在 `workflow/reviews.d/<当月>.md` 追加一行事件记录——八列 `| 日期 | 对象 | 复核员(宿主) | 意见数 | 采纳 | 拒绝 | 误报 | 备注 |`,自洽约束 采纳+拒绝+误报=意见数(gen-workflow-metrics 按此校验,破坏即拦);月度聚合进 metrics「复核效果」表
49
49
  - **独立性**:L2 / L3 必须用独立子智能体,宿主不支持时另开新会话,不得由原作者自查冒充;L1 且宿主不支持子智能体时可由主智能体按同一复核契约执行。
50
50
  - **用户决策**:问题定性(误报驳回 / P0 成立必修 / P1、P2 处置裁量)+ 合入时机;git 历史即评审记录,追溯靠 commit 与 tag。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-flow-kit",
3
- "version": "1.8.2",
3
+ "version": "1.8.7",
4
4
  "description": "AI-Native 闭环工作流 + wiki 知识层脚手架——flow-kit init 一条命令为新项目装好 .agents 工作流引擎(阶段命令/角色契约/门禁钩子/kb 检索/看板/规则面预算)+ workflow 文档闭环 + wiki 知识库,装完本地可跑、零运行时依赖",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -7,9 +7,10 @@ import fs from 'node:fs';
7
7
  import os from 'node:os';
8
8
  import path from 'node:path';
9
9
  import { spawnSync } from 'node:child_process';
10
- import { pathToFileURL } from 'node:url';
10
+ import { fileURLToPath, pathToFileURL } from 'node:url';
11
11
 
12
- const ROOT = path.resolve(path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, '$1')), '..');
12
+ // fileURLToPath 而非手搓 pathname 解码(源仓 fdded128 同根因):非 ASCII 路径经 URL 百分号编码后解析错路径。
13
+ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
13
14
  const SCRIPT = path.join(ROOT, 'scripts', 'jscpd-drift.mjs');
14
15
 
15
16
  let pass = 0;
@@ -54,4 +54,5 @@
54
54
  - **构建 / 测试 / 类型检查命令**(静态门,各阶段命令引用此处口径):构建 = {{BUILD_CMD}};测试 = {{TEST_CMD}};类型检查 = {{TYPECHECK_CMD}}
55
55
  - **运行时环境**(端口 / 进程 / 终端差异):`.agents/notes/runtime-env.md`
56
56
  - **目录级规则**:如 `backend/AGENTS.md`、`frontend/AGENTS.md`(如有)——目录级约定不回填本文件
57
+ - **工程原则**(起草 / 复核对照用,不入机器判据——2026-10-18 立项质量批):项目品味条款逐行列此——示例:简洁优先、直接用平台能力不另包一层|新增依赖须证不可替代|禁 speculative 功能(「非目标」节能省则省)|spec 写 WHAT/WHY,HOW 落 plan。消费:起草 intent / spec 对照自查(「约束遵守映射」逐行对账)与独立复核 Standards 轴;违反本节是复核意见(人工判),违反红线才判低升档(机器)。条款装户自填自持
57
58
  - **权限与提交验证配置**:`.agents/settings.json`(allow / deny / ask)、`.agents/hooks/commit-check.config.json`(条件构建 / 质量检测命令与密钥白名单——质量检测只放秒级确定性检查(lint / 类型检查 / vet),测试不放提交门,关单在 test 阶段门)
@@ -79,6 +79,6 @@ next: .agents/commands/test.md
79
79
 
80
80
  ## 5. 确认后
81
81
 
82
- - plan 状态 → done(实现完成;intent / spec 关单在 test)
82
+ - plan 状态保持 `approved`,**不在此置 `done`**——实现完成 ≠ 关单;`done` 在 `test.md` §6 验收勾验后经 confirm-doc 置(intent / spec / 修复的同名 plan 亦在 test 一并收口;build 直跳 `done` 会绕过确认门、触发检查 15 指纹对账)
83
83
  - commit:L1+ 入口文档 / spec / plan 随代码同一提交(Conventional Commits 中文 feat/fix/refactor/perf);docs 豁免与 bootstrap 可单独 `docs(*)`
84
84
  - 进 `next: .agents/commands/test.md`
@@ -38,7 +38,7 @@ next: .agents/commands/build.md
38
38
  - **填空工具先跑**:`node .agents/scripts/fill-spec.mjs --level <L1|L2|L3> --topic <主题> --output workflow/specs/<date>-<主题>.md`——输出含 frontmatter 5 字段 + 5 节正文(功能行为/数据流/系统改动/约束遵守映射/风险评估)的草稿;AI 据此填实
39
39
  - 复制 `workflow/specs/_TEMPLATE.md` → `workflow/specs/YYYY-MM-DD-<主题>.md`(与入口文档同名)
40
40
  - 按 5 节填写:功能行为 / 数据流 / 系统改动 / 约束遵守映射 / 风险评估
41
- - 约束映射必须对照根 `AGENTS.md` 红线/约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
41
+ - 约束映射必须对照根 `AGENTS.md` 红线与「工程原则」节及约束相关节(如「项目适配区」「门禁与提交」)与改动域目录级 `AGENTS.md`(如有)逐条说明如何满足
42
42
  - 存在多个可行方案时,在 spec 中列出各方案取舍与 AI 建议项,由用户选定后方可确认
43
43
  - **页面/交互入口形态必须用户确认**:spec 须写明入口是「表单(字段清单)」还是「选择器/弹窗」,禁止自行推定交互形态
44
44
  4. 起草后停下,输出草稿全文给用户过目。
@@ -57,6 +57,6 @@ next: .agents/commands/build.md(仅 P0 / P1 未清时;清零后经用户确
57
57
  ## 4. 审查分工(用户决策 + AI 协作)
58
58
 
59
59
  - **机器兜底**(pre-commit / pre-push / test 自动拦,无需人守):门禁清单与判据以 `.githooks/`、`.agents/hooks/`、`check-loop.sh` 头部注释为准;`项目测试命令` 跑自动化用例。
60
- - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。
60
+ - **AI 复核**:机器门禁完成后优先委派 `independent-reviewer`,聚焦 P0 hook 未覆盖项 + 全部 P1(P2 视精力)——产出分级问题清单 + 修复建议。复核方法走 `.agents/skills/review-method/SKILL.md`(Standards×Spec 双轴 + 坏味道走查 + 合入标尺;有全局 `code-review` 技能时可叠加);每条 finding 报告前过 `review-verification-protocol` 防误报门(锚定 file:line、给出证据、校准严重级,不确定就降级为提问)。**落账**:复核收口时在 `workflow/reviews.d/<当月>.md` 追加一行事件记录——八列 `| 日期 | 对象 | 复核员(宿主) | 意见数 | 采纳 | 拒绝 | 误报 | 备注 |`,自洽约束 采纳+拒绝+误报=意见数(gen-workflow-metrics 按此校验,破坏即拦);月度聚合进 metrics「复核效果」表
61
61
  - **独立性**:L2 / L3 必须用独立子智能体,宿主不支持时另开新会话,不得由原作者自查冒充;L1 且宿主不支持子智能体时可由主智能体按同一复核契约执行。
62
62
  - **用户决策**:问题定性(误报驳回 / P0 成立必修 / P1、P2 处置裁量)+ 合入时机;git 历史即评审记录,追溯靠 commit 与 tag。
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": 1,
3
- "generatedAt": "2026-10-16T08:29:49.685Z",
3
+ "generatedAt": "2026-10-18T07:42:40.254Z",
4
4
  "files": {
5
5
  ".github/workflows/ci.yml": {
6
6
  "sha256": "e9cffb90dec8f0a49bfe231a13fb8df375a2494cc75c38d991b5eb7c7be104b5",
@@ -11,8 +11,8 @@
11
11
  "hard": 0
12
12
  },
13
13
  "templates/AGENTS.md": {
14
- "sha256": "521b8549ce077278f31074db10f1934bc7f63788d43a6bb68f1c1510ad31cf82",
15
- "hard": 27
14
+ "sha256": "6462975ff6242f6b99435dab26833e9c930e44ae274bbe3f3225652c51263380",
15
+ "hard": 28
16
16
  },
17
17
  "templates/_agents/control-surfaces.txt": {
18
18
  "sha256": "ae6072b58fde4cf2ad65ce27d0216133dabbd189b0542a0dbf11bbd9e0608407",
@@ -31,7 +31,7 @@
31
31
  "hard": 8
32
32
  },
33
33
  "templates/_agents/rule-budgets.txt": {
34
- "sha256": "48f31a386019b7c427ed3244939d7c455fb33ec79d634d47141695e2308bcb6b",
34
+ "sha256": "32f5115af858802bad4dca711a7308abc594c23477eaeef51fd976b48d84f9b1",
35
35
  "hard": 3
36
36
  },
37
37
  "templates/_agents/scripts-test-exempt.txt": {
@@ -75,11 +75,11 @@
75
75
  "hard": 2
76
76
  },
77
77
  "templates/_agents/scripts/check-ledger-invariant.mjs": {
78
- "sha256": "0f62db2d88d4da7f720c5c148d7d461dcc286a5e7c27c41cda591994c1201925",
78
+ "sha256": "2eca0ca122e09d5c1dda7675d787d08bfcce6a50a93f62019eeebfb28af8b01e",
79
79
  "hard": 2
80
80
  },
81
81
  "templates/_agents/scripts/check-loop.mjs": {
82
- "sha256": "e4e8843248d0a14e349f29dc9b4c1f0bbdbe1e5bd3c0745c723721c117e58f5a",
82
+ "sha256": "12aea495fd78e8c5c2927c9400ce5c34c90cfaefa1e0c106571a1cf13aa8b2d4",
83
83
  "hard": 32
84
84
  },
85
85
  "templates/_agents/scripts/check-metric-claims.mjs": {
@@ -99,7 +99,7 @@
99
99
  "hard": 1
100
100
  },
101
101
  "templates/_agents/scripts/check-scripts-syntax.mjs": {
102
- "sha256": "0a6db271a1e02dae8e10ef197ff51376d256da844e9d83df4806d3cf50ac0454",
102
+ "sha256": "8d2950ee18327e67471db0993f331ff9688c17390c3fcc7b6adbe6eb0892d1d1",
103
103
  "hard": 3
104
104
  },
105
105
  "templates/_agents/scripts/check-spec-verif.mjs": {
@@ -119,7 +119,7 @@
119
119
  "hard": 1
120
120
  },
121
121
  "templates/_agents/scripts/confirm-doc.mjs": {
122
- "sha256": "7829a2af4476bf5cddfbc123f3d1a9a95b2e1fa0337c4e0382875cb3e3ddb74a",
122
+ "sha256": "d30b918d8a20ec87cdaf7eca4deaa2b8d724788e5fc9c338cce61fe4612f661f",
123
123
  "hard": 13
124
124
  },
125
125
  "templates/_agents/scripts/draft-sediment.mjs": {
@@ -179,7 +179,7 @@
179
179
  "hard": 3
180
180
  },
181
181
  "templates/_agents/scripts/gen-workflow-metrics.mjs": {
182
- "sha256": "577401cc384f814a5cfc4ec7204b52bab3d11c93697c3ead697594f5a0d5a6b1",
182
+ "sha256": "c0b6f9e7a67fa60d4ed9e7c90d8693fa1b9e6e8bc90df41b677d8c94ccf620f6",
183
183
  "hard": 2
184
184
  },
185
185
  "templates/_agents/scripts/git-core.mjs": {
@@ -267,7 +267,7 @@
267
267
  "hard": 3
268
268
  },
269
269
  "templates/_agents/scripts/solidify-task.mjs": {
270
- "sha256": "5e5983b9ab6ae4eaaeced150018592b2501c4d6885b4913d03c6f29138630825",
270
+ "sha256": "35c7e307c9b7a10d446c2c75eb77ff316be1939c57bec937e0940b42e6fe1499",
271
271
  "hard": 3
272
272
  },
273
273
  "templates/_agents/scripts/stage-gates.mjs": {
@@ -283,8 +283,8 @@
283
283
  "hard": 4
284
284
  },
285
285
  "templates/_agents/scripts/verify.mjs": {
286
- "sha256": "e0e3b4fa415d046375947026b8a37367f8da988bf6c669972e1193c941bc600e",
287
- "hard": 3
286
+ "sha256": "fad5ed87c5539c6a6be3811f489efa7d39157ddab2ace99ccaefb7d072fe388c",
287
+ "hard": 4
288
288
  },
289
289
  "templates/_agents/scripts/wf-journal.mjs": {
290
290
  "sha256": "302e9f6deb96d4b40b8a220f7ae773e44b59abd3313c8dd62a27eb239f11f4c1",
@@ -14,6 +14,7 @@
14
14
  |---|---|---|---|---|---|---|
15
15
  | 确认指纹对账(示例行) | check-loop 检查 15 | hard「指纹不配对/确认内容漂移」计数(月,经 agg-judgments 查判定流水) | 不退役(防伪造确认主干) | 示例:建门留档见包源仓 git 历史与 CHANGELOG | 现役 | — |
16
16
  | 触达面判低门(示例行) | check-lane-surface(pre-commit/CI 泳道完整性) | hard「触达面判低/产品契约面」计数(月) | 不退役(级别闭环主干) | 示例:在用 | 现役 | — |
17
+ | 复核效果台账(示例行) | workflow/reviews.d/ 意见级处置(采纳/拒绝/误报)→ gen-workflow-metrics.mjs 月度聚合 | metrics.md「复核效果」表(采纳率/误报率;区分「门禁制造返工 vs 拦下问题」的意见级信号源) | 连续 6 个有数据月零记录且 delegations 复核采纳行恒 0 → 评估退役(数据面非门禁) | 示例:随 1.8.3 分发,建账口径见 review.md 落账子项 | 现役 | — |
17
18
 
18
19
  > 以上两行为**示例行**,只示范登记口径,不参与装户对账;装户按自有机制增删行,
19
20
  > 首次对账时可将示例行替换为真实运营数据。
@@ -24,4 +25,11 @@
24
25
  - **月度对账**:每月初按「触发统计口径」列刷新计数(半自动:`node .agents/scripts/agg-judgments.mjs`
25
26
  查判定流水 `.agents/judgments.jsonl`——check-loop 每次真实运行自动落账,替代人工 grep 输出;
26
27
  git log 统计口径不变);达到阈值的行改「待退役」并填处置期限。
28
+ - **数据面机制的「现役」≠「有数据」**:复核效果台账 / 评审黄金集校准类数据面机制登记后,月度对账须区分两件事:① 资产是否存在(建账即存在);② 本月是否产生数据并写进留痕面——未产生 → 该月记「无跑数」,连续 6 个**有数据月**零记录才走退役阈值,缺月不算零命中(**年轻遥测不得制造假候选**,口径同 `agg-judgments --retire-candidates`)。
27
29
  - **退役动作**:状态改「已退役」当日删除机制代码 + 其测试 + 本表更新,同一提交完成(不留死代码)。
30
+ - **模型代际触发**:每个机制都是对当前模型能力边界的假设(外部实证:harness 组件随模型代际逐件移动),既有退役阈值只有使用维度、缺代际维度——主力模型**代际变更**(主版本号或模型家族更换,如 GLM-4.x → 5.x;小版本/推理档变更不算)后的**下一次月度对账**须按下面分组逐件重评去留,结论写各机制「最近触发」列;重评本身不改状态列(退役仍走既有阈值)。首次对账时把本表现有机制按下组归类(此后新增机制在登记时即注明组别;本节用列表不用表格——防管道行被误当机制行解析):
31
+ - **A · 纪律假设**(假设:无机器检查时模型会跳步/声称未做之事,如配对完整性、留痕、占位符残留类检查)——重评动作:观察新代际下 WARN/hard 是否加速归零(是 → 按既有退役阈值自然走);**不因代际主动拆门**——判据已机器化、边际成本 ≈ 0,拆门收益低于一次漏拦。
32
+ - **B · 能力边界假设**(假设:机制强度绑在当前模型能力短板上,代际升级后假设可能失效,**须主动重评**,如常驻面体积预算、复核上下文独立性、判低逃逸类检查)——只重定阈值不轻拆门;其中信任边界/安全主干(凭据扫描、确认防伪类)**代际不撤门**,只重评执行成本。
33
+ - **C · 机器判据**(纯确定性检查,与模型能力无关——格式/枚举/漂移/同步类)——代际免评。
34
+ - **D · 宿主生态**(跟宿主软件版本走,不跟模型代际;宿主升级时随 Adapter 检查顺带过)。
35
+ - **E · 测量自举**(数据面,代际只影响测量结论的解释、不改机制本身;跨代际比较月度指标先读委派/复核台账的模型代际基线注)——如门禁耗时、复核效果台账、退役催办。
@@ -12,7 +12,9 @@
12
12
  # 2026-10-07 adopter-ci-github:AGENTS.md 门禁节补 CI 远端门一行(299B,实测 7969B 超 7680 被拦)——
13
13
  # 新门入册属合法增长,同 512B 步进上调 7680→8192。
14
14
  # 2026-10-16 减重系列回灌:new-task.md 增「预判留痕」指针行(§25 使用者入口 + engine-internals 维护者
15
- # 面分离,自源仓减重手段⑤终态回灌)实测 8914B 超 8704 被拦——合法增长,同 512B 步进上调 8704→9216。
16
- AGENTS.md 8192
15
+ # 面分离,自源仓减重手段⑤终态回灌)实测 8914B 超 8704 被拦——合法增长,同 512B 步进上调 8704→9216。
16
+ # 2026-10-18 立项质量批:AGENTS.md 项目适配区新登「工程原则」节(起草 / 复核对照面,不入机器判据)——
17
+ # 实测 8546B 超 8192 被拦(先压缩措辞再入账),合法结构新增,同 512B 步进上调 8192→8704。
18
+ AGENTS.md 8704
17
19
  .agents/commands/*.md 9216
18
20
  .agents/commands/ 65536
@@ -298,5 +298,5 @@ const FM_LOW_NEW = '状态: draft\n级别: L1\n日期: 2026-10-01\n模块: ui';
298
298
  `${r.stdout || ''}${r.stderr || ''}`);
299
299
  }
300
300
 
301
- console.log(`\n${fail ? `❌ ${fail} failed` : '✅ all passed'}(${pass} passed)`);
301
+ console.log(`\n合计: PASS ${pass} / FAIL ${fail}`);
302
302
  process.exit(fail ? 1 : 0);
@@ -5,6 +5,9 @@
5
5
  // 判据自多 worktree 合并丢行事故后的实战实现逐字回灌(出处留包源仓 git 历史与 CHANGELOG))
6
6
  // 目的:把「台账本地可写」的伪造面从事后对质级升为机器可检出级(能力评审审计维度扣分项)。
7
7
  // 台账不可变原则:confirmations 历史行禁删改——修正只能走追加补偿行(README 硬规则 6)。
8
+ // 性能(2026-10-16 自源仓 ledger-git-batch 回灌):历史全扫原为逐提交 `git show <sha>:<path>` +
9
+ // `git log -1 %P`,即 O(提交数) 次进程创建(Windows 单次 ~68ms,随历史线性膨胀);改为一次
10
+ // `git log` 取 sha+父、一次 `cat-file --batch` 取该路径全部 blob(O(路径数)),判据与输出不变。
8
11
  //
9
12
  // 分片形态(2026-10-10 中期方案;2026-10-12 起为 confirm-doc 默认写入口径):
10
13
  // .agents/confirmations.d/<doc 基名>.jsonl —— 按 doc 分片,跨机/跨 worktree 确认不同 doc 时
@@ -103,14 +106,50 @@ const VALID_STAGES = new Set(['approved', 'done', 'fixed', 'closed', 'superseded
103
106
  // 历史基线(机制 2026-10-13 ledger-history-baseline,详见头注):kit 缺省空 = 全量扫描
104
107
  const HISTORY_BASELINE = process.env.LEDGER_HISTORY_BASELINE || '';
105
108
 
106
- const git = (args, opts = {}) => execFileSync('git', args, { cwd: ROOT, encoding: 'buffer', maxBuffer: 64 * 1024 * 1024, ...opts });
107
109
  const gitText = (args) => execFileSync('git', args, { cwd: ROOT, encoding: 'utf8' });
108
- const blobOf = (ref) => git(['show', ref]); // ref 必须为完整对象引用(<sha>:<path> / HEAD:<path> / :<path>)
109
- // tryBlob:安全读 blob,失败返回 null 且**不向 stderr 外泄 git fatal 噪声**(删片场景读当前提交必失败,
110
- // 那是预期路径不是错误——历史扫描的高频探针路径必须静默)。
110
+
111
+ // ---- git 对象批量读取(2026-10-16 自源仓 ledger-git-batch 回灌)----
112
+ // 动机:逐提交 `git show <sha>:<path>` 在 Windows 上 ~68ms/次(进程创建主导),主台账提交数 × 2 次
113
+ // (blob + 父列表)随历史线性膨胀;改为「一次 git log 取 sha+父」+「一次 cat-file --batch 取该路径
114
+ // 全部 blob」——spawn 数自 O(提交数) 降到 O(路径数),判据与输出不变。
115
+ const blobCache = new Map(); // ref -> Buffer | null(null = 对象不可读,与旧 tryBlob 同语义)
116
+ const prefetchBlobs = (refs) => {
117
+ const want = [...new Set(refs)].filter((r) => !blobCache.has(r));
118
+ if (!want.length) return;
119
+ const r = spawnSync('git', ['cat-file', '--batch'], {
120
+ cwd: ROOT, input: `${want.join('\n')}\n`, maxBuffer: 512 * 1024 * 1024,
121
+ });
122
+ // 非零 = 真错误(仓库不可读 / spawn 失败 / 输出超 maxBuffer),不是「对象不存在」——后者由
123
+ // `<ref> missing` 头表达且 status 仍为 0。此处必须响亮抛出:静默置 null 会让每个 blobOf 都判
124
+ // 「对象不可读」,把一次环境抖动伪装成满屏「台账删除」的假硬拦(判据失真比崩溃更坏)。
125
+ if (r.status !== 0) {
126
+ throw new Error(`git cat-file --batch 失败(exit ${r.status ?? r.error?.code}):${String(r.stderr || r.error?.message || '').trim().slice(0, 200)}`);
127
+ }
128
+ const buf = r.stdout;
129
+ let off = 0;
130
+ for (const ref of want) {
131
+ const nl = buf.indexOf(0x0a, off);
132
+ if (nl < 0) { blobCache.set(ref, null); continue; }
133
+ const header = buf.toString('utf8', off, nl);
134
+ off = nl + 1;
135
+ const m = /^[0-9a-f]+ \w+ (\d+)$/.exec(header); // 不匹配 = `<ref> missing` / ambiguous
136
+ if (!m) { blobCache.set(ref, null); continue; }
137
+ const size = Number(m[1]);
138
+ blobCache.set(ref, buf.subarray(off, off + size));
139
+ off += size + 1; // 内容后随一个 LF
140
+ }
141
+ };
142
+ // blobOf:ref 必须为完整对象引用(<sha>:<path> / HEAD:<path> / :<path>);不可读即抛(调用方据此判删除)
143
+ const blobOf = (ref) => {
144
+ if (!blobCache.has(ref)) prefetchBlobs([ref]);
145
+ const b = blobCache.get(ref);
146
+ if (b === null) throw new Error(`git cat-file: ${ref} 不可读`);
147
+ return b;
148
+ };
149
+ // tryBlob:安全读 blob,失败返回 null(缓存 miss 时单点回源;删片场景读当前提交必失败,是预期路径)。
111
150
  const tryBlob = (ref) => {
112
- const r = spawnSync('git', ['show', ref], { cwd: ROOT, encoding: 'buffer', maxBuffer: 64 * 1024 * 1024 });
113
- return r.status === 0 ? r.stdout : null;
151
+ if (!blobCache.has(ref)) prefetchBlobs([ref]);
152
+ return blobCache.get(ref);
114
153
  };
115
154
  const linesOf = (buf) => buf.toString('utf8').split('\n').filter((l, i, a) => !(l === '' && i === a.length - 1) && l !== '');
116
155
  const isShard = (rel) => rel.startsWith(`${SHARD_DIR}/`) && rel.endsWith('.jsonl');
@@ -187,13 +226,26 @@ const shardDeleteReason = (sha, rel) => {
187
226
  // allowShardDelete:分片允许「已归并后删片(或缺行已终树补登)」这一种合法消失形态;主台账永不因归并被删。
188
227
  // 返回该路径的提交史(空 = 从未入库:装户/新仓/尚在暂存区)——零史路径整体跳过,与原实现
189
228
  // 「零提交历史即静默」的契约一致(行级校验也只覆盖有史的路径,否则新仓首版会被 doc 不存在误杀)。
190
- function historyShas(rel) {
229
+ // 2026-10-16 ledger-git-batch:一次 git log 同取 %H 与 %P(父列表原先逐提交另起一次 spawn),
230
+ // 结果按 rel 缓存并回填 parentMap 供 parentShas 免 spawn 查询。
231
+ const historyCache = new Map(); // rel -> [{sha, parents}]
232
+ const parentMap = new Map(); // sha -> parents
233
+ function historyEntries(rel) {
234
+ if (historyCache.has(rel)) return historyCache.get(rel);
235
+ let entries = [];
191
236
  try {
192
237
  // --full-history:不做历史简化——TREESAME 合并也入列,防「ours 合并丢一侧行」被简化隐藏(审计门立场)
193
- return gitText(['log', '--full-history', '--format=%H', '--reverse', '--', rel]).split(/\s+/).filter(Boolean);
238
+ const out = gitText(['log', '--full-history', '--format=%H %P', '--reverse', '--', rel]);
239
+ entries = out.split(/\r?\n/).filter((l) => l.trim()).map((l) => {
240
+ const [sha, ...parents] = l.trim().split(/\s+/);
241
+ return { sha, parents };
242
+ });
194
243
  } catch {
195
- return [];
244
+ entries = [];
196
245
  }
246
+ for (const e of entries) parentMap.set(e.sha, e.parents);
247
+ historyCache.set(rel, entries);
248
+ return entries;
197
249
  }
198
250
 
199
251
  // 基线后提交集(含基线可达性探测;无基线声明或基线不在本仓 → null = 基线不生效,全史扫描)
@@ -210,8 +262,9 @@ const postBaselineSet = () => {
210
262
  return _postBaseline;
211
263
  };
212
264
 
213
- // 多父提交的父列表(%P 全父)
265
+ // 多父提交的父列表(%P 全父)——优先查 historyEntries 回填的 parentMap(免 spawn),未命中才回退 git
214
266
  const parentShas = (sha) => {
267
+ if (parentMap.has(sha)) return parentMap.get(sha);
215
268
  try {
216
269
  return gitText(['log', '-1', '--format=%P', sha]).split(/\s+/).filter(Boolean);
217
270
  } catch {
@@ -274,19 +327,26 @@ const mergePruneProblem = (parents, rel, curBuf, manifest) => {
274
327
  };
275
328
 
276
329
  function scanHistory(rel, { allowShardDelete }) {
277
- const allShas = historyShas(rel);
278
- if (!allShas.length) return allShas;
279
- let shas = allShas;
330
+ const allEntries = historyEntries(rel);
331
+ if (!allEntries.length) return [];
332
+ let entries = allEntries;
280
333
  // 历史基线:只走基线后提交(详见头注)——DAG 感知比对下各提交自对己父,无需线性化起点
281
334
  const post = postBaselineSet();
282
335
  if (post) {
283
- const kept = shas.filter((sha) => post.has(sha));
284
- if (kept.length !== shas.length) {
285
- console.error(`[info] ${rel}:${shas.length - kept.length} 个前基线提交按 HISTORY_BASELINE 声明豁免(owner 授权,见脚本头注)`);
336
+ const kept = entries.filter((e) => post.has(e.sha));
337
+ if (kept.length !== entries.length) {
338
+ console.error(`[info] ${rel}:${entries.length - kept.length} 个前基线提交按 HISTORY_BASELINE 声明豁免(owner 授权,见脚本头注)`);
286
339
  }
287
- shas = kept;
340
+ entries = kept;
341
+ }
342
+ // 批量预取本路径全部 blob(各提交版本 + 各父版本)——一次 cat-file --batch 取代逐提交 git show
343
+ const refs = [];
344
+ for (const e of entries) {
345
+ refs.push(`${e.sha}:${rel}`);
346
+ for (const p of e.parents) refs.push(`${p}:${rel}`);
288
347
  }
289
- for (const sha of shas) {
348
+ prefetchBlobs(refs);
349
+ for (const { sha, parents } of entries) {
290
350
  let cur;
291
351
  try { cur = blobOf(`${sha}:${rel}`); } catch {
292
352
  // 删除提交不是静默边界(复核 P2 收口):主台账在 append-only 世界里永不应删除——任一历史提交删除
@@ -305,13 +365,12 @@ function scanHistory(rel, { allowShardDelete }) {
305
365
  }
306
366
  // DAG 感知基准:本提交第一父的 blob(dag-aware-base)——线性化「前一承」在分支汇合处会拿
307
367
  // 另一侧提交当基准产生伪前缀破坏;根提交(无父)视为新文件起步。
308
- const parents = parentShas(sha);
309
368
  const base = parents.length ? tryBlob(`${parents[0]}:${rel}`) : null;
310
369
  if (base === null) continue; // 首现(父无此路径):无基线可比,行级校验兜底
311
370
  if (parents.length >= 2) {
312
371
  // 多父提交无条件走并集对账(前缀通过不得短路——ours-resolution 合并树与第一父逐字节同 blob,
313
372
  // 嵌套判法对静默丢行全盲)
314
- const unionFail = mergeUnionProblem(parentShas(sha), rel, cur);
373
+ const unionFail = mergeUnionProblem(parents, rel, cur);
315
374
  if (!unionFail) {
316
375
  console.error(`[info] ${sha.slice(0, 10)}:合并并集无丢失——union 合并语义认可,续扫`);
317
376
  continue;
@@ -338,7 +397,7 @@ function scanHistory(rel, { allowShardDelete }) {
338
397
  }
339
398
  }
340
399
  }
341
- return allShas; // 交回该路径的全量提交史,供调用方判定「有史才进行级校验」
400
+ return allEntries.map((e) => e.sha); // 交回该路径的全量提交史,供调用方判定「有史才进行级校验」
342
401
  }
343
402
 
344
403
  // ---- 台账路径全集:主台账 + 历史上出现过的全部分片 ----
@@ -635,5 +635,5 @@ const mkMergePruneRepo = () => {
635
635
  fs.rmSync(d, { recursive: true, force: true });
636
636
  }
637
637
 
638
- console.log(`\n${fail ? `❌ ${fail} failed` : '✅ all passed'}(${pass} passed)`);
638
+ console.log(`\n合计: PASS ${pass} / FAIL ${fail}`);
639
639
  process.exit(fail ? 1 : 0);