@dommaker/harness 1.8.1 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +10 -13
  3. package/dist/cli/commands/check.d.ts +3 -3
  4. package/dist/cli/commands/check.d.ts.map +1 -1
  5. package/dist/cli/commands/check.js +41 -78
  6. package/dist/cli/commands/check.js.map +1 -1
  7. package/dist/cli/commands/constraints-report.d.ts +2 -10
  8. package/dist/cli/commands/constraints-report.d.ts.map +1 -1
  9. package/dist/cli/commands/constraints-report.js +4 -57
  10. package/dist/cli/commands/constraints-report.js.map +1 -1
  11. package/dist/cli/commands/constraints-retire.d.ts +9 -23
  12. package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
  13. package/dist/cli/commands/constraints-retire.js +39 -121
  14. package/dist/cli/commands/constraints-retire.js.map +1 -1
  15. package/dist/cli/commands/constraints.d.ts +3 -8
  16. package/dist/cli/commands/constraints.d.ts.map +1 -1
  17. package/dist/cli/commands/constraints.js +8 -23
  18. package/dist/cli/commands/constraints.js.map +1 -1
  19. package/dist/cli/commands/definitions.js +2 -2
  20. package/dist/cli/commands/init.d.ts +0 -32
  21. package/dist/cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/commands/init.js +7 -149
  23. package/dist/cli/commands/init.js.map +1 -1
  24. package/dist/cli/commands/report.d.ts.map +1 -1
  25. package/dist/cli/commands/report.js +14 -17
  26. package/dist/cli/commands/report.js.map +1 -1
  27. package/dist/cli/commands/scaffold-templates.d.ts +0 -2
  28. package/dist/cli/commands/scaffold-templates.d.ts.map +1 -1
  29. package/dist/cli/commands/scaffold-templates.js +2 -37
  30. package/dist/cli/commands/scaffold-templates.js.map +1 -1
  31. package/dist/cli/commands/scaffold.d.ts +0 -2
  32. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  33. package/dist/cli/commands/scaffold.js +0 -10
  34. package/dist/cli/commands/scaffold.js.map +1 -1
  35. package/dist/cli/commands/status.js +10 -10
  36. package/dist/cli/commands/status.js.map +1 -1
  37. package/dist/cli/commands/sync-docs/agents-syncer.d.ts +0 -2
  38. package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
  39. package/dist/cli/commands/sync-docs/agents-syncer.js +4 -23
  40. package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
  41. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts +22 -0
  42. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts.map +1 -1
  43. package/dist/cli/commands/sync-docs/capabilities-syncer.js +113 -8
  44. package/dist/cli/commands/sync-docs/capabilities-syncer.js.map +1 -1
  45. package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
  46. package/dist/cli/commands/sync-docs/index.js +36 -4
  47. package/dist/cli/commands/sync-docs/index.js.map +1 -1
  48. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  49. package/dist/core/constraints/capabilities-parser.js +16 -4
  50. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  51. package/dist/core/constraints/checker.d.ts +15 -24
  52. package/dist/core/constraints/checker.d.ts.map +1 -1
  53. package/dist/core/constraints/checker.js +33 -72
  54. package/dist/core/constraints/checker.js.map +1 -1
  55. package/dist/core/constraints/checkers/docs-freshness.js +1 -1
  56. package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
  57. package/dist/core/constraints/checkers/governance-presence.d.ts +2 -1
  58. package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
  59. package/dist/core/constraints/checkers/governance-presence.js +4 -3
  60. package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
  61. package/dist/core/constraints/checkers/index.d.ts +1 -1
  62. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  63. package/dist/core/constraints/checkers/index.js +4 -8
  64. package/dist/core/constraints/checkers/index.js.map +1 -1
  65. package/dist/core/constraints/checkers/iron-flags.d.ts +3 -4
  66. package/dist/core/constraints/checkers/iron-flags.d.ts.map +1 -1
  67. package/dist/core/constraints/checkers/iron-flags.js +4 -5
  68. package/dist/core/constraints/checkers/iron-flags.js.map +1 -1
  69. package/dist/core/constraints/checkers/no-test-simplification.js +1 -1
  70. package/dist/core/constraints/checkers/no-test-simplification.js.map +1 -1
  71. package/dist/core/constraints/checkers/types.d.ts +1 -1
  72. package/dist/core/constraints/checkers/types.js +1 -1
  73. package/dist/core/constraints/definitions/guidelines.d.ts +4 -4
  74. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  75. package/dist/core/constraints/definitions/guidelines.js +9 -25
  76. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  77. package/dist/core/constraints/definitions/iron-laws.d.ts +4 -4
  78. package/dist/core/constraints/definitions/iron-laws.d.ts.map +1 -1
  79. package/dist/core/constraints/definitions/iron-laws.js +10 -81
  80. package/dist/core/constraints/definitions/iron-laws.js.map +1 -1
  81. package/dist/core/constraints/definitions.d.ts +7 -9
  82. package/dist/core/constraints/definitions.d.ts.map +1 -1
  83. package/dist/core/constraints/definitions.js +13 -16
  84. package/dist/core/constraints/definitions.js.map +1 -1
  85. package/dist/core/constraints/index.d.ts +2 -5
  86. package/dist/core/constraints/index.d.ts.map +1 -1
  87. package/dist/core/constraints/index.js +3 -13
  88. package/dist/core/constraints/index.js.map +1 -1
  89. package/dist/core/constraints/injection-writer.d.ts +10 -38
  90. package/dist/core/constraints/injection-writer.d.ts.map +1 -1
  91. package/dist/core/constraints/injection-writer.js +17 -54
  92. package/dist/core/constraints/injection-writer.js.map +1 -1
  93. package/dist/core/constraints/run-env.d.ts +1 -10
  94. package/dist/core/constraints/run-env.d.ts.map +1 -1
  95. package/dist/core/constraints/run-env.js +1 -22
  96. package/dist/core/constraints/run-env.js.map +1 -1
  97. package/dist/core/constraints/usage-report.d.ts +5 -7
  98. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  99. package/dist/core/constraints/usage-report.js +5 -10
  100. package/dist/core/constraints/usage-report.js.map +1 -1
  101. package/dist/core/effective-constraints.d.ts +12 -22
  102. package/dist/core/effective-constraints.d.ts.map +1 -1
  103. package/dist/core/effective-constraints.js +13 -30
  104. package/dist/core/effective-constraints.js.map +1 -1
  105. package/dist/core/index.d.ts +2 -2
  106. package/dist/core/index.d.ts.map +1 -1
  107. package/dist/core/index.js +3 -9
  108. package/dist/core/index.js.map +1 -1
  109. package/dist/core/project-config-loader.d.ts +4 -42
  110. package/dist/core/project-config-loader.d.ts.map +1 -1
  111. package/dist/core/project-config-loader.js +16 -125
  112. package/dist/core/project-config-loader.js.map +1 -1
  113. package/dist/core/validators/passes-gate.d.ts +2 -2
  114. package/dist/core/validators/passes-gate.js +6 -6
  115. package/dist/core/validators/passes-gate.js.map +1 -1
  116. package/dist/hooks/bootstrap.d.ts +9 -12
  117. package/dist/hooks/bootstrap.d.ts.map +1 -1
  118. package/dist/hooks/bootstrap.js +9 -31
  119. package/dist/hooks/bootstrap.js.map +1 -1
  120. package/dist/hooks/index.d.ts +5 -7
  121. package/dist/hooks/index.d.ts.map +1 -1
  122. package/dist/hooks/index.js +4 -10
  123. package/dist/hooks/index.js.map +1 -1
  124. package/dist/index.d.ts +9 -12
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +10 -23
  127. package/dist/index.js.map +1 -1
  128. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  129. package/dist/monitoring/trace-analyzer.js +11 -12
  130. package/dist/monitoring/trace-analyzer.js.map +1 -1
  131. package/dist/monitoring/traces.d.ts +4 -4
  132. package/dist/monitoring/traces.d.ts.map +1 -1
  133. package/dist/monitoring/traces.js +8 -8
  134. package/dist/monitoring/traces.js.map +1 -1
  135. package/dist/presets/standard.d.ts +8 -10
  136. package/dist/presets/standard.d.ts.map +1 -1
  137. package/dist/presets/standard.js +10 -16
  138. package/dist/presets/standard.js.map +1 -1
  139. package/dist/types/constraint.d.ts +24 -35
  140. package/dist/types/constraint.d.ts.map +1 -1
  141. package/dist/types/constraint.js +8 -7
  142. package/dist/types/constraint.js.map +1 -1
  143. package/dist/types/passes-gate.d.ts +5 -5
  144. package/dist/types/passes-gate.d.ts.map +1 -1
  145. package/dist/types/project-config.d.ts +8 -66
  146. package/dist/types/project-config.d.ts.map +1 -1
  147. package/dist/types/project-config.js +3 -2
  148. package/dist/types/project-config.js.map +1 -1
  149. package/dist/types/trace.d.ts +8 -10
  150. package/dist/types/trace.d.ts.map +1 -1
  151. package/package.json +2 -2
  152. package/src/CONTEXT.md +3 -3
  153. package/src/__tests__/checker-extra.test.ts +37 -61
  154. package/src/__tests__/checker.test.ts +10 -115
  155. package/src/__tests__/effective-constraints.test.ts +18 -83
  156. package/src/__tests__/iron-laws.test.ts +71 -90
  157. package/src/__tests__/passes-gate-check.test.ts +2 -2
  158. package/src/__tests__/project-config-loader-extra.test.ts +22 -123
  159. package/src/__tests__/project-config-loader.test.ts +5 -33
  160. package/src/__tests__/public-exports.test.ts +31 -11
  161. package/src/__tests__/public-type-surface.test.ts +2 -13
  162. package/src/__tests__/public-value-surface.test.ts +1 -7
  163. package/src/__tests__/skip-semantics.test.ts +21 -37
  164. package/src/__tests__/trace-analyzer-extra.test.ts +14 -14
  165. package/src/__tests__/trace-analyzer.test.ts +21 -21
  166. package/src/__tests__/trace-collector.test.ts +22 -22
  167. package/src/__tests__/traces.test.ts +27 -28
  168. package/src/cli/commands/CONTEXT.md +12 -9
  169. package/src/cli/commands/__tests__/check-read-count.test.ts +4 -15
  170. package/src/cli/commands/__tests__/check-skip-output.test.ts +14 -14
  171. package/src/cli/commands/__tests__/check.test.ts +14 -31
  172. package/src/cli/commands/__tests__/constraints-report.test.ts +12 -80
  173. package/src/cli/commands/__tests__/constraints-retire.test.ts +42 -231
  174. package/src/cli/commands/__tests__/init-governance-io.test.ts +12 -58
  175. package/src/cli/commands/__tests__/init-ondisk.test.ts +12 -20
  176. package/src/cli/commands/__tests__/init.test.ts +0 -11
  177. package/src/cli/commands/__tests__/project-path-anchoring.test.ts +2 -2
  178. package/src/cli/commands/__tests__/registry.test.ts +39 -3
  179. package/src/cli/commands/__tests__/report-extra.test.ts +4 -4
  180. package/src/cli/commands/__tests__/report.test.ts +1 -1
  181. package/src/cli/commands/__tests__/scaffold.test.ts +4 -14
  182. package/src/cli/commands/__tests__/status-analysis-wiring.test.ts +3 -3
  183. package/src/cli/commands/__tests__/status-extra.test.ts +14 -14
  184. package/src/cli/commands/__tests__/status.test.ts +12 -12
  185. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +1 -1
  186. package/src/cli/commands/__tests__/sync-docs-table-layout.test.ts +259 -0
  187. package/src/cli/commands/check.ts +43 -82
  188. package/src/cli/commands/constraints-report.ts +4 -59
  189. package/src/cli/commands/constraints-retire.ts +49 -154
  190. package/src/cli/commands/constraints.ts +11 -26
  191. package/src/cli/commands/definitions.ts +2 -2
  192. package/src/cli/commands/init.ts +8 -179
  193. package/src/cli/commands/report.ts +19 -23
  194. package/src/cli/commands/scaffold-templates.ts +1 -37
  195. package/src/cli/commands/scaffold.ts +0 -11
  196. package/src/cli/commands/status.ts +10 -10
  197. package/src/cli/commands/sync-docs/agents-syncer.ts +4 -25
  198. package/src/cli/commands/sync-docs/capabilities-syncer.ts +139 -9
  199. package/src/cli/commands/sync-docs/index.ts +41 -4
  200. package/src/core/CONTEXT.md +9 -9
  201. package/src/core/constraints/__tests__/capability-counts.test.ts +5 -5
  202. package/src/core/constraints/__tests__/collect-constraints.test.ts +13 -8
  203. package/src/core/constraints/__tests__/git-evidence.test.ts +4 -7
  204. package/src/core/constraints/__tests__/injection-writer.test.ts +8 -61
  205. package/src/core/constraints/__tests__/run-env.test.ts +5 -34
  206. package/src/core/constraints/__tests__/trace-injection.test.ts +1 -1
  207. package/src/core/constraints/capabilities-parser.ts +17 -5
  208. package/src/core/constraints/checker.ts +39 -88
  209. package/src/core/constraints/checkers/__tests__/check-outcome.test.ts +5 -8
  210. package/src/core/constraints/checkers/__tests__/governance-presence.test.ts +1 -53
  211. package/src/core/constraints/checkers/__tests__/iron-flags.test.ts +5 -25
  212. package/src/core/constraints/checkers/docs-freshness.ts +1 -1
  213. package/src/core/constraints/checkers/governance-presence.ts +4 -3
  214. package/src/core/constraints/checkers/index.ts +4 -10
  215. package/src/core/constraints/checkers/iron-flags.ts +3 -12
  216. package/src/core/constraints/checkers/no-test-simplification.ts +1 -1
  217. package/src/core/constraints/checkers/types.ts +1 -1
  218. package/src/core/constraints/definitions/guidelines.ts +8 -25
  219. package/src/core/constraints/definitions/iron-laws.ts +9 -82
  220. package/src/core/constraints/definitions.ts +14 -15
  221. package/src/core/constraints/index.ts +4 -19
  222. package/src/core/constraints/injection-writer.ts +16 -61
  223. package/src/core/constraints/run-env.ts +1 -33
  224. package/src/core/constraints/usage-report.ts +8 -15
  225. package/src/core/effective-constraints.ts +14 -45
  226. package/src/core/index.ts +3 -10
  227. package/src/core/project-config-loader.ts +20 -145
  228. package/src/core/validators/passes-gate.ts +6 -6
  229. package/src/failure/CONTEXT.md +1 -1
  230. package/src/hooks/CONTEXT.md +12 -22
  231. package/src/hooks/__tests__/bootstrap.test.ts +24 -75
  232. package/src/hooks/bootstrap.ts +9 -48
  233. package/src/hooks/index.ts +5 -20
  234. package/src/index.ts +9 -31
  235. package/src/monitoring/__tests__/trace-file-anchoring.test.ts +1 -1
  236. package/src/monitoring/__tests__/traces.test.ts +22 -22
  237. package/src/monitoring/trace-analyzer.ts +12 -13
  238. package/src/monitoring/traces.ts +8 -8
  239. package/src/presets/__tests__/standard.test.ts +12 -16
  240. package/src/presets/standard.ts +14 -23
  241. package/src/types/__tests__/types.test.ts +3 -3
  242. package/src/types/constraint.ts +26 -40
  243. package/src/types/passes-gate.ts +5 -5
  244. package/src/types/project-config.ts +8 -77
  245. package/src/types/trace.ts +8 -11
  246. package/dist/core/constraints/agent-prompt-renderer.d.ts +0 -32
  247. package/dist/core/constraints/agent-prompt-renderer.d.ts.map +0 -1
  248. package/dist/core/constraints/agent-prompt-renderer.js +0 -55
  249. package/dist/core/constraints/agent-prompt-renderer.js.map +0 -1
  250. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts +0 -6
  251. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts.map +0 -1
  252. package/dist/core/constraints/checkers/no-bypass-checkpoint.js +0 -40
  253. package/dist/core/constraints/checkers/no-bypass-checkpoint.js.map +0 -1
  254. package/dist/core/constraints/definitions/prompts.d.ts +0 -12
  255. package/dist/core/constraints/definitions/prompts.d.ts.map +0 -1
  256. package/dist/core/constraints/definitions/prompts.js +0 -400
  257. package/dist/core/constraints/definitions/prompts.js.map +0 -1
  258. package/dist/core/constraints/injection-drift.d.ts +0 -61
  259. package/dist/core/constraints/injection-drift.d.ts.map +0 -1
  260. package/dist/core/constraints/injection-drift.js +0 -131
  261. package/dist/core/constraints/injection-drift.js.map +0 -1
  262. package/dist/core/constraints/injection-renderer.d.ts +0 -23
  263. package/dist/core/constraints/injection-renderer.d.ts.map +0 -1
  264. package/dist/core/constraints/injection-renderer.js +0 -44
  265. package/dist/core/constraints/injection-renderer.js.map +0 -1
  266. package/dist/hooks/config.d.ts +0 -30
  267. package/dist/hooks/config.d.ts.map +0 -1
  268. package/dist/hooks/config.js +0 -34
  269. package/dist/hooks/config.js.map +0 -1
  270. package/dist/hooks/pipeline.d.ts +0 -54
  271. package/dist/hooks/pipeline.d.ts.map +0 -1
  272. package/dist/hooks/pipeline.js +0 -173
  273. package/dist/hooks/pipeline.js.map +0 -1
  274. package/dist/hooks/registry.d.ts +0 -70
  275. package/dist/hooks/registry.d.ts.map +0 -1
  276. package/dist/hooks/registry.js +0 -141
  277. package/dist/hooks/registry.js.map +0 -1
  278. package/dist/hooks/types.d.ts +0 -113
  279. package/dist/hooks/types.d.ts.map +0 -1
  280. package/dist/hooks/types.js +0 -9
  281. package/dist/hooks/types.js.map +0 -1
  282. package/src/__tests__/hooks-pipeline.test.ts +0 -201
  283. package/src/cli/commands/__tests__/check-drift.test.ts +0 -158
  284. package/src/cli/commands/__tests__/init-injection.test.ts +0 -466
  285. package/src/core/constraints/__tests__/agent-prompt-renderer.test.ts +0 -129
  286. package/src/core/constraints/__tests__/injection-drift.test.ts +0 -247
  287. package/src/core/constraints/agent-prompt-renderer.ts +0 -67
  288. package/src/core/constraints/checkers/__tests__/no-bypass-checkpoint.test.ts +0 -76
  289. package/src/core/constraints/checkers/no-bypass-checkpoint.ts +0 -40
  290. package/src/core/constraints/definitions/prompts.ts +0 -414
  291. package/src/core/constraints/injection-drift.ts +0 -142
  292. package/src/core/constraints/injection-renderer.ts +0 -44
  293. package/src/hooks/__tests__/config.test.ts +0 -19
  294. package/src/hooks/__tests__/pipeline.test.ts +0 -195
  295. package/src/hooks/__tests__/registry.test.ts +0 -115
  296. package/src/hooks/config.ts +0 -33
  297. package/src/hooks/pipeline.ts +0 -202
  298. package/src/hooks/registry.ts +0 -166
  299. package/src/hooks/types.ts +0 -120
@@ -1,15 +1,15 @@
1
1
  /**
2
- * check · guideline 定义(ADR-0001:kind 二元模型)
2
+ * check 约束定义(severity='warning' 组,ADR-0029)
3
3
  *
4
- * 只保留带真实 checker 的指导原则。每条必须:
4
+ * 只保留带真实 checker 的约束。每条必须:
5
5
  * - kind: 'check'
6
- * - level: 'guideline'
6
+ * - severity: 'warning'(违规告警不阻断)
7
7
  * - 在 checkers/ 注册表中有对应实现(注册表闭环,缺失即加载期抛错)
8
8
  */
9
9
 
10
10
  import type { Constraint } from '../../../types/constraint';
11
11
 
12
- export const GUIDELINES: Record<string, Constraint> = {
12
+ export const WARNING_CONSTRAINTS: Record<string, Constraint> = {
13
13
  /**
14
14
  * 禁止硬编码凭证
15
15
  * 原因:密码/token/密钥泄露是最严重的安全漏洞,一旦提交到版本控制即不可逆
@@ -19,27 +19,10 @@ export const GUIDELINES: Record<string, Constraint> = {
19
19
  kind: 'check',
20
20
  rule: 'NO HARDCODED PASSWORDS, TOKENS, SECRETS, OR CREDENTIALS IN ANY SOURCE FILE',
21
21
  message: '禁止在代码/文档/配置文件中硬编码密码、token、密钥、API key',
22
- level: 'guideline',
22
+ severity: 'warning',
23
23
  trigger: ['code_implementation', 'doc_update', 'config_change', 'commit'],
24
24
  enforcement: 'credential-scan',
25
25
  description: `凭证(密码/token/密钥/API key)必须从环境变量或加密配置读取,严禁以明文形式出现在任何源代码文件中。包括但不限于:源码、Markdown 文档、YAML/JSON 配置、脚本文件。模板文件(.example/.sample/.template)允许占位符但不得包含真实值。建议配合 pre-commit hook 做自动扫描。`,
26
- promptInjection: '禁止在代码中硬编码密码、API 密钥、Token 等凭证。使用环境变量或安全的凭证管理方案存储敏感信息。',
27
- },
28
-
29
- /**
30
- * 禁止跳过检查点验证
31
- * 原因:安全底线,检查点是质量门控
32
- */
33
- no_bypass_checkpoint: {
34
- id: 'no_bypass_checkpoint',
35
- kind: 'check',
36
- rule: 'NO BYPASSING CHECKPOINTS',
37
- message: '禁止跳过检查点验证',
38
- level: 'guideline',
39
- trigger: 'code_implementation',
40
- enforcement: 'checkpoint-required',
41
- description: '所有检查点必须通过,不能跳过验证步骤。检查点是质量的最后一道防线。',
42
- promptInjection: '每个关键步骤后有 checkpoint 验证点,必须通过才能继续。通过标准:测试通过、类型检查无错误、lint 无新增警告。未通过时回退修复,不得跳过。',
43
26
  },
44
27
 
45
28
  /**
@@ -51,7 +34,7 @@ export const GUIDELINES: Record<string, Constraint> = {
51
34
  kind: 'check',
52
35
  rule: 'CODE CHANGES MUST UPDATE CAPABILITIES.MD',
53
36
  message: '核心模块变更必须同步功能清单(支持模块级目录条目登记)',
54
- level: 'guideline',
37
+ severity: 'warning',
55
38
  trigger: ['module_creation', 'module_modification', 'module_deletion', 'module_extension'],
56
39
  enforcement: 'update-capabilities',
57
40
  description: `在创建/修改/删除/扩展核心模块时,必须同步更新 CAPABILITIES.md:
@@ -79,7 +62,7 @@ export const GUIDELINES: Record<string, Constraint> = {
79
62
  kind: 'check',
80
63
  rule: 'KEY DIRECTORIES SHOULD HAVE CONTEXT.MD',
81
64
  message: '关键目录缺少 CONTEXT.md,运行 harness sync-docs 创建模板后填写实际内容',
82
- level: 'guideline',
65
+ severity: 'warning',
83
66
  trigger: 'module_modification',
84
67
  enforcement: 'context-check',
85
68
  description: `项目的关键目录应包含 CONTEXT.md 文件,描述目录职责和上下文。
@@ -108,7 +91,7 @@ export const GUIDELINES: Record<string, Constraint> = {
108
91
  kind: 'check',
109
92
  rule: 'GOVERNANCE CONTRACT MUST BE PRESENT (AGENTS.MD PRESERVE:GOVERNANCE BLOCK OR CLAUDE.MD GOVERNANCE RULES)',
110
93
  message: '治理契约缺失:AGENTS.md 缺少非空 PRESERVE:governance 段,且 CLAUDE.md 无 Governance Rules 块',
111
- level: 'guideline',
94
+ severity: 'warning',
112
95
  trigger: ['file_modification', 'module_creation', 'module_modification', 'doc_update', 'config_change', 'commit'],
113
96
  enforcement: 'governance-presence-check',
114
97
  description: `治理契约(约束清单正本)必须在场,两处居其一:
@@ -1,15 +1,15 @@
1
1
  /**
2
- * check · iron_law 定义(ADR-0001:kind 二元模型)
2
+ * check 约束定义(severity='error' 组,ADR-0029)
3
3
  *
4
- * 只保留带真实 checker 的铁律。每条必须:
4
+ * 只保留带真实 checker 的约束。每条必须:
5
5
  * - kind: 'check'
6
- * - level: 'iron_law'
6
+ * - severity: 'error'(违规即阻断)
7
7
  * - 在 checkers/ 注册表中有对应实现(注册表闭环,缺失即加载期抛错)
8
8
  */
9
9
 
10
10
  import type { Constraint } from '../../../types/constraint';
11
11
 
12
- export const IRON_LAWS: Record<string, Constraint> = {
12
+ export const ERROR_CONSTRAINTS: Record<string, Constraint> = {
13
13
  /**
14
14
  * 禁止无验证声明完成
15
15
  * 原因:质量底线,必须有验证命令
@@ -19,95 +19,23 @@ export const IRON_LAWS: Record<string, Constraint> = {
19
19
  kind: 'check',
20
20
  rule: 'NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE',
21
21
  message: '禁止无验证声明完成,必须运行验证命令',
22
- level: 'iron_law',
22
+ severity: 'error',
23
23
  trigger: 'code_implementation',
24
24
  enforcement: 'verify-completion',
25
25
  description: '在声明任何任务完成之前,必须运行新鲜的验证命令(项目声明的测试 + type check),以新鲜输出作为完成证据。验证命令集由项目自行声明,全量验证留给 CI 流程。',
26
- promptInjection: '在声明任务完成前,必须重新运行新鲜的验证命令(项目声明的测试 + type check),使用新鲜的输出作为完成证据,不得复用旧结果,不得凭记忆声称完成。',
27
- },
28
-
29
- /**
30
- * 禁止一次做多个任务(one-shotting)
31
- * 来源:Anthropic AI Harness - Effective Harnesses for Long-running Agents
32
- * 原因:避免中途耗尽 context,保持专注和可控
33
- */
34
- incremental_progress: {
35
- id: 'incremental_progress',
36
- kind: 'check',
37
- rule: 'ONE TASK PER SESSION',
38
- message: '禁止一次做多个任务,每次只做一件事',
39
- level: 'iron_law',
40
- trigger: 'code_implementation',
41
- enforcement: 'single-task-check',
42
- description: `一个 session 只处理一个任务,避免 one-shotting。
43
-
44
- 【禁止】
45
- - 一次做多个任务 → 中途耗尽 context
46
- - 大改动一次性完成 → 失控
47
- - 没有拆分的复杂任务 → 无法回滚
48
-
49
- 【必须】
50
- - 一个 session 一个任务 → 保持专注
51
- - 大任务拆分为小步骤 → 分步执行
52
- - 每步都有 checkpoint → 可回滚
53
-
54
- 【判断标准】
55
- - 改动涉及多个模块 → 需拆分
56
- - 改动超过 100 行 → 需拆分
57
- - 改动影响多个文件 → 需拆分
58
-
59
- 【参考】
60
- Anthropic AI: "Effective Harnesses for Long-running Agents"
61
- https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents`,
62
- promptInjection: '一次只处理一个任务。改动涉及多个模块、超过 100 行、或影响多个文件时,必须拆分为小步骤分步执行,每步有独立 checkpoint 可回滚。不要试图一次性完成所有改动。',
63
- },
64
-
65
- /**
66
- * 禁止无需求就开始实现(吸收 no_implementation_without_requirement_review)
67
- * 原因:没有需求就没有验收标准,实现方向不可控;
68
- * 实现完成后必须逐条对照 AC 验证,避免偏离需求
69
- */
70
- no_implementation_without_requirement: {
71
- id: 'no_implementation_without_requirement',
72
- kind: 'check',
73
- rule: 'NO IMPLEMENTATION WITHOUT REQUIREMENTS, AND REVIEW AGAINST AC AFTER IMPLEMENTATION',
74
- message: '禁止无需求就开始实现,实现后必须逐条对照 AC 验证',
75
- level: 'iron_law',
76
- trigger: ['code_implementation', 'design_request'],
77
- enforcement: 'requirement-exists',
78
- description: `在开始实现之前,必须有明确的需求定义;实现完成后,必须逐条对照验收标准(AC)验证。
79
-
80
- 【实现前必须执行】
81
- 1. 确认需求来源(Spec/Issue/Roadmap/用户指令)
82
- 2. 确认验收标准(AC)已定义
83
- 3. 确认边界情况已明确
84
-
85
- 【实现后必须执行】(吸收自 no_implementation_without_requirement_review)
86
- 1. 回顾需求文档(Spec/Roadmap/Issue)
87
- 2. 逐条检查实现是否符合每条 AC
88
- 3. 确认边界情况已覆盖
89
- 4. 输出验证清单(AC × 实现 × 状态)
90
-
91
- 【禁止】
92
- - 没有需求就开始写代码、凭假设开始实现
93
- - 实现后不对比需求直接提交,只测"功能能跑"不验证 AC
94
- - 跳过边界情况验证,假设"差不多就行"
95
-
96
- 【正确流程】
97
- 需求确认 → AC 定义 → 实现 → 逐条对照 AC 验证`,
98
- promptInjection: '开始编写代码前,必须确认:需求来源明确(Spec/Issue/Roadmap/用户指令)、验收标准(AC)已定义、边界情况已明确。不要凭假设或猜测开始实现。实现完成后,必须逐条对比原始需求文档中的验收标准(AC),确认每条 AC 已实现且边界情况已覆盖,输出验证清单。不得仅凭"功能能跑"就认为完成。',
99
26
  },
100
27
 
101
28
  /**
102
29
  * 禁止简化测试
103
30
  * 原因:质量底线,测试困难必须解决
31
+ * (harness#174:checker 承载执行)
104
32
  */
105
33
  no_test_simplification: {
106
34
  id: 'no_test_simplification',
107
35
  kind: 'check',
108
36
  rule: 'NO SIMPLIFYING TESTS TO AVOID DIFFICULTY',
109
37
  message: '禁止简化测试绕过困难',
110
- level: 'iron_law',
38
+ severity: 'error',
111
39
  trigger: 'test_creation',
112
40
  enforcement: 'full-test-coverage',
113
41
  description: `在编写测试时,不能因为遇到困难而简化或跳过测试。
@@ -121,19 +49,18 @@ https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agent
121
49
  - 为了绕过 mock 困难而删除测试用例
122
50
  - 为了绕过异步问题而跳过断言
123
51
  - 降低测试覆盖率要求`,
124
- promptInjection: '编写测试时遇到困难(mock、异步、环境),不得删除用例或跳过断言。正确做法:分析问题 → 查阅文档 → 尝试解决 → 仍不行则向用户说明困难请求指示。不得降低覆盖率要求。',
125
52
  },
126
53
 
127
54
  /**
128
55
  * 文档新鲜度
129
- * 原因:guideline 只警告不阻断,导致文档持续腐烂。
56
+ * 原因:只警告不阻断会导致文档持续腐烂。
130
57
  */
131
58
  docs_freshness: {
132
59
  id: 'docs_freshness',
133
60
  kind: 'check',
134
61
  rule: 'CAPABILITIES.MD MUST BE IN SYNC WITH CODE',
135
62
  message: 'CAPABILITIES.md 与源码不同步,运行 harness sync-docs 更新后重新提交',
136
- level: 'iron_law',
63
+ severity: 'error',
137
64
  trigger: ['file_modification', 'module_creation', 'module_modification'],
138
65
  enforcement: 'docs-sync-check',
139
66
  description: `CAPABILITIES.md 中列出的文件必须在 src/ 中实际存在。删除源文件时须从 CAPABILITIES.md 同步移除。运行 harness sync-docs 自动修复过期引用。
@@ -1,34 +1,33 @@
1
1
  /**
2
2
  * 约束定义(薄聚合层)
3
3
  *
4
- * kind 二元模型(ADR-0001):
5
- * - IRON_LAWS / GUIDELINES:check 层,必须带真实 checker(注册表闭环)
6
- * - PROMPTS:prompt 层,纯文本注入,不占检查位
4
+ * severity 显式模型(ADR-0029,取代 ADR-0001 三层命名):
5
+ * 全部内置约束 kind='check',severity 写死在定义上(error / warning),
6
+ * 纯文本提示层(prompts.ts)已随文本注入层关停整体删除。
7
7
  *
8
- * 工单 20:字面量定义按层拆至 ./definitions/{iron-laws,guidelines,prompts}.ts;
8
+ * 工单 20:字面量定义按 severity 分组放 ./definitions/{iron-laws,guidelines}.ts;
9
9
  * 本文件保持原路径做薄聚合(studio rule-scanner 按此路径解析,P0 #8)。
10
10
  */
11
11
 
12
12
  import type { Constraint, ConstraintTrigger } from '../../types/constraint';
13
- import { IRON_LAWS } from './definitions/iron-laws';
14
- import { GUIDELINES } from './definitions/guidelines';
15
- import { PROMPTS } from './definitions/prompts';
13
+ import { ERROR_CONSTRAINTS } from './definitions/iron-laws';
14
+ import { WARNING_CONSTRAINTS } from './definitions/guidelines';
16
15
 
17
- export { IRON_LAWS, GUIDELINES, PROMPTS };
16
+ /** 全部内置约束(check 层全量,severity 在条目上) */
17
+ export const CONSTRAINTS: Record<string, Constraint> = {
18
+ ...ERROR_CONSTRAINTS,
19
+ ...WARNING_CONSTRAINTS,
20
+ };
18
21
 
19
22
  // ========================================
20
23
  // 辅助函数
21
24
  // ========================================
22
25
 
23
26
  /**
24
- * 获取所有约束(check + prompt 全量,带 kind)
27
+ * 获取所有约束(check 全量,带 kind/severity
25
28
  */
26
29
  export function getAllConstraints(): Constraint[] {
27
- return [
28
- ...Object.values(IRON_LAWS),
29
- ...Object.values(GUIDELINES),
30
- ...Object.values(PROMPTS),
31
- ];
30
+ return Object.values(CONSTRAINTS);
32
31
  }
33
32
 
34
33
  /**
@@ -45,5 +44,5 @@ export function findConstraintsByTrigger(trigger: ConstraintTrigger): Constraint
45
44
  * 根据 ID 获取约束
46
45
  */
47
46
  export function getConstraint(id: string): Constraint | undefined {
48
- return IRON_LAWS[id] || GUIDELINES[id] || PROMPTS[id];
47
+ return CONSTRAINTS[id];
49
48
  }
@@ -2,11 +2,9 @@
2
2
  * 约束模块入口
3
3
  */
4
4
 
5
- // 约束定义(kind 二元:check + prompt 层)
5
+ // 约束定义(check 全量,severity 在条目上)
6
6
  export {
7
- IRON_LAWS,
8
- GUIDELINES,
9
- PROMPTS,
7
+ CONSTRAINTS,
10
8
  getAllConstraints,
11
9
  findConstraintsByTrigger,
12
10
  getConstraint,
@@ -22,28 +20,15 @@ export {
22
20
  } from './checker';
23
21
  export type { CheckConstraintsOptions, TraceRecorder } from './checker';
24
22
 
25
- // CLAUDE.md 约束注入段渲染(纯函数,init 注入与漂移校验共用)
26
- export {
27
- CONSTRAINTS_START_MARKER,
28
- CONSTRAINTS_END_MARKER,
29
- renderConstraintsSection,
30
- } from './injection-renderer';
31
-
32
23
  // 约束检查缓存(H6/G5:TTL 缓存 + 计数采样,公开导出)
33
24
  export { CheckCache } from './check-cache';
34
25
  export type { CheckCacheConfig, CheckSamplingConfig } from './check-cache';
35
26
 
36
- // Agent prompt 约束段渲染(H6/G6:trigger 参数化分组渲染,role 路由留 studio)
37
- export {
38
- renderConstraintsByTrigger,
39
- } from './agent-prompt-renderer';
40
- export type { RenderConstraintsByTriggerOptions } from './agent-prompt-renderer';
41
-
42
27
  // 类型导出
43
28
  export type {
44
29
  ConstraintId,
45
30
  ConstraintKind,
46
- ConstraintLevel,
31
+ ConstraintSeverity,
47
32
  ConstraintTrigger,
48
33
  Constraint,
49
34
  ConstraintResult,
@@ -52,4 +37,4 @@ export type {
52
37
  IronLawContext,
53
38
  } from '../../types/constraint';
54
39
 
55
- export { ConstraintViolationError } from '../../types/constraint';
40
+ export { ConstraintViolationError } from '../../types/constraint';
@@ -1,41 +1,26 @@
1
1
  /**
2
- * 治理注入段落点写入器(架构评审候选1,ADR-0011)
2
+ * 标记区间写入器 + 治理正本探测(架构评审候选1,ADR-0011)
3
3
  *
4
- * 「按渲染 body 替换标记区间 + 尾换行规一」的切片数学此前手抄 4 份
5
- * (init.ts 三个 writer / constraints-retire 一份),落点路由读写两侧各抄一份。
6
- * 本模块是唯一 writer:init/retire 退化为「渲染 body + 调 writer」。
4
+ * ADR-0029:约束注入段(HARNESS_CONSTRAINTS)已整体关停——本模块不再承担
5
+ * 注入段渲染/落点路由(resolveInjectionTarget / resolveGovernanceLanding 随删),
6
+ * 保留的是通用机制:
7
7
  *
8
- * 形状两种(排版约定不同,非"算哪些"的差异,故合法分叉):
8
+ * 「按渲染 body 替换标记区间 + 尾换行规一」的切片数学。形状两种
9
+ * (排版约定不同,非"算哪些"的差异,故合法分叉):
9
10
  * - replaceStandaloneRange:区间独立成节,END 标记后折叠为恰好一个空行
10
- * (CLAUDE.md 约束段 / Output Style 段 / retire 注入段同步)
11
+ * (CLAUDE.md Output Style 段)
11
12
  * - replaceEnclosedRange:区间后紧跟外层收口标记(AGENTS.md PRESERVE 段内
12
- * 的 HARNESS_CONSTRAINTS 区间)——恰好剥一个换行,手写余文原样落回
13
+ * 区间)——恰好剥一个换行,手写余文原样落回
13
14
  *
14
15
  * 半标记守护:单边缺失或顺序颠倒 → 'half',拒写(旧实现此时或追加出双份
15
16
  * 正本或产生乱序切片,属二次损坏路径,收紧为告警交人工,见 ADR-0011)。
16
17
  *
17
- * 落点路由同规则一份:
18
- * - resolveInjectionTarget:读侧(漂移检测/retire 同步)——CLAUDE.md 有完整
19
- * 标记段优先(旧模型仓豁免),否则 AGENTS.md(新模型仓住 PRESERVE 段内)
20
- * - resolveGovernanceLanding:写侧(init 落点选择)——额外承认 CLAUDE.md
21
- * 无标记的 `## Governance Rules` 旧块(续写不制造双份正本)
22
- *
23
18
  * 探测/判定同住本模块(#83,ADR-0011 补注:收口范围含探测器,不只写器)——
24
- * 「这份文档里有没有治理契约 / 有几个正本标题」此前手抄 4 份且正则已漂移,
25
- * 见文末 GOVERNANCE_HEADING / hasGovernanceContract / countGovernanceHeadings /
26
- * hasPreserveBlock。
19
+ * 「这份文档里有没有治理契约 / 有几个正本标题」,见文末 GOVERNANCE_HEADING /
20
+ * hasGovernanceContract / countGovernanceHeadings / hasPreserveBlock。
27
21
  */
28
22
 
29
23
  import * as fs from 'fs';
30
- import * as path from 'path';
31
- import {
32
- CONSTRAINTS_START_MARKER,
33
- CONSTRAINTS_END_MARKER,
34
- } from './injection-renderer';
35
-
36
- /** 注入段落点文件名(检测顺序即路由优先级:旧模型仓 CLAUDE.md 优先) */
37
- export const INJECTION_FILES = ['CLAUDE.md', 'AGENTS.md'] as const;
38
- export type InjectionFile = (typeof INJECTION_FILES)[number];
39
24
 
40
25
  /** 标记区间替换结果 */
41
26
  export type MarkerWrite =
@@ -111,40 +96,6 @@ export function replaceEnclosedRange(content: string, begin: string, end: string
111
96
  };
112
97
  }
113
98
 
114
- /**
115
- * 读侧路由:定位含完整 HARNESS_CONSTRAINTS 标记段的文件(studio #307)。
116
- * detectInjectionDrift 与 retire 注入段同步共用。
117
- */
118
- export function resolveInjectionTarget(
119
- projectRoot: string
120
- ): { file: InjectionFile; content: string; startIdx: number; endIdx: number } | null {
121
- for (const file of INJECTION_FILES) {
122
- const content = readIfExists(path.join(projectRoot, file));
123
- if (content === null) continue;
124
- const startIdx = content.indexOf(CONSTRAINTS_START_MARKER);
125
- const endIdx = content.indexOf(CONSTRAINTS_END_MARKER);
126
- if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
127
- return { file, content, startIdx, endIdx };
128
- }
129
- }
130
- return null;
131
- }
132
-
133
- /**
134
- * 写侧路由(init 落点选择,原 setupGovernanceConstraints 内联判定收于此):
135
- * CLAUDE.md 有约束标记段或有旧版 `## Governance Rules` 块 → 续写 CLAUDE.md
136
- * (旧模型仓豁免,不制造双份正本);否则 AGENTS.md PRESERVE:governance。
137
- */
138
- export function resolveGovernanceLanding(
139
- projectRoot: string
140
- ): { target: 'claude-md' | 'agents-md'; claudeContent: string | null } {
141
- const claudeContent = readIfExists(path.join(projectRoot, 'CLAUDE.md'));
142
- if (claudeContent !== null && hasGovernanceContract(claudeContent)) {
143
- return { target: 'claude-md', claudeContent };
144
- }
145
- return { target: 'agents-md', claudeContent };
146
- }
147
-
148
99
  /**
149
100
  * 治理正本标题字面量(单一来源,#83):init 的标题写点与下列两个判定谓词
150
101
  * 都由它派生,仓内不再本地拼写。字面量无正则元字符,可直接拼入 RegExp。
@@ -164,8 +115,12 @@ const GOVERNANCE_HEADING_LOOSE_RE = new RegExp(`^##\\s+${GOVERNANCE_HEADING_TEXT
164
115
  /** 严格标题正则:精确拼写 + 行尾锚定(行尾仅容忍空白) */
165
116
  const GOVERNANCE_HEADING_STRICT_RE = new RegExp(`^${GOVERNANCE_HEADING}[ \\t]*$`, 'gm');
166
117
 
167
- /** 约束标记裸文本(去注释壳),宽松谓词按「标记文本在场」判定,容忍壳残缺 */
168
- const CONSTRAINTS_START_TEXT = CONSTRAINTS_START_MARKER.replace(/^<!--\s*|\s*-->$/g, '');
118
+ /**
119
+ * 历史注入段标记裸文本(ADR-0029:注入段已关停,此处仅作历史兼容判据——
120
+ * 旧仓残留的 HARNESS_CONSTRAINTS 段仍算治理契约在场)。宽松谓词按「标记文本
121
+ * 在场」判定,容忍注释壳残缺。
122
+ */
123
+ const CONSTRAINTS_START_TEXT = 'HARNESS_CONSTRAINTS_START';
169
124
 
170
125
  /**
171
126
  * 宽松谓词:内容里是否有治理契约在场——标题宽松匹配或 HARNESS 约束标记
@@ -2,7 +2,7 @@
2
2
  * 运行级观察面(ADR-0023 决策 1)
3
3
  *
4
4
  * 一次 `harness check` 一份、跑完即弃:把「本项目有哪些源码根」「最近的 trace 记录」
5
- * 「`.harness/config.yml` 与自定义约束文件写了什么」这类上行数据的读取收在此处,
5
+ * 「`.harness/config.yml` 写了什么」这类上行数据的读取收在此处,
6
6
  * 同一次运行内每个文件至多读一次。
7
7
  *
8
8
  * 为什么不是一个对象而是两个:checker 拿到的 `CheckEnv` 里含 `context`,而 `context` 正是
@@ -20,7 +20,6 @@ import { detectSourceRoots } from '../../utils/detect-source-roots';
20
20
  import { reconcileCapabilities, type CapabilityVerdict } from './capabilities-reconcile';
21
21
  import { readJsonlWindow, type JsonlWindow, type JsonlReadResult } from '../../utils/jsonl';
22
22
  import { DEFAULT_TRACE_FILE, type ExecutionTrace } from '../../types/trace';
23
- import type { CustomConstraintDefinition } from '../../types/project-config';
24
23
 
25
24
  /** config.yml 在项目根下的相对路径(读取口径唯一落点) */
26
25
  const CONFIG_FILE_REL = path.join('.harness', 'config.yml');
@@ -49,14 +48,6 @@ export interface RunEnv {
49
48
  * 空文件 → `{}`;YAML 解析失败 → **抛出**(兜底与否属各消费方的判定,不在读面上替它决定)。
50
49
  */
51
50
  rawConfig(): Record<string, unknown> | undefined;
52
- /**
53
- * `.harness/<fileName>` 里的自定义约束定义(一次运行内同名文件至多读一次)
54
- *
55
- * 文件名由消费方(ProjectConfigLoader)从合并后的 config 解析后传入——
56
- * 「`custom_constraints_file` 怎么写才算数」属加载器口径,不在读面上判。
57
- * 文件缺失或无 `custom_constraints` 段 → `{}`(与改前的直读逐字一致)。
58
- */
59
- customConstraints(fileName: string): Record<string, CustomConstraintDefinition>;
60
51
  /**
61
52
  * `CAPABILITIES.md` 的读取 + 解析 + 与代码实况的对照判定(ADR-0023 决策 4)
62
53
  *
@@ -97,7 +88,6 @@ export function createRunEnv(projectPath: string): RunEnv {
97
88
  let sourceRoots: string[] | null = null;
98
89
  let configLoaded = false;
99
90
  let configRaw: Record<string, unknown> | undefined;
100
- const customDefs = new Map<string, Record<string, CustomConstraintDefinition>>();
101
91
  /** 能力表 memo:undefined = 未算,null = 项目无 CAPABILITIES.md */
102
92
  let caps: ProjectCapabilities | null | undefined;
103
93
 
@@ -120,14 +110,6 @@ export function createRunEnv(projectPath: string): RunEnv {
120
110
  }
121
111
  return configRaw;
122
112
  },
123
- customConstraints(fileName: string) {
124
- let defs = customDefs.get(fileName);
125
- if (!defs) {
126
- defs = readCustomConstraints(path.join(projectPath, '.harness', fileName));
127
- customDefs.set(fileName, defs);
128
- }
129
- return defs;
130
- },
131
113
  capabilities(populationFiles: string[]) {
132
114
  if (caps === undefined) {
133
115
  const content = readCapabilitiesContent();
@@ -164,20 +146,6 @@ export function createRunEnv(projectPath: string): RunEnv {
164
146
  }
165
147
  }
166
148
 
167
- /**
168
- * 读一个自定义约束文件并取出 `custom_constraints` 段
169
- *
170
- * 缺失 → `{}`。文档解析成空值(空 yaml 文件)时取段会抛——改前直读就是这个行为,
171
- * 不在此新增兜底:畸形配置文件该炸在配置上,不该被读面抹平。
172
- */
173
- function readCustomConstraints(absPath: string): Record<string, CustomConstraintDefinition> {
174
- if (!fs.existsSync(absPath)) return {};
175
- const loaded = yaml.load(fs.readFileSync(absPath, 'utf-8')) as {
176
- custom_constraints?: Record<string, CustomConstraintDefinition>;
177
- };
178
- return loaded.custom_constraints ?? {};
179
- }
180
-
181
149
  /**
182
150
  * 读并解析一个 YAML 配置文件
183
151
  *
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * `harness constraints report` 与 `harness constraints retire`(交互模式)共用的
5
5
  * 数据层:读取项目 traces.log,与生效集(getEffectiveConstraints)对齐,
6
- * 产出 check 层统计表与四类退役候选诊断。
6
+ * 产出 check 约束统计表与四类退役候选诊断。
7
7
  *
8
8
  * 只读:不创建目录、不写任何文件。
9
9
  */
@@ -23,8 +23,6 @@ import type { EffectiveConfigLint } from '../effective-constraints';
23
23
  */
24
24
  export const FLAG_EVIDENCE_CONSTRAINT_IDS: ReadonlySet<string> = new Set([
25
25
  'no_completion_without_verification',
26
- 'incremental_progress',
27
- 'no_implementation_without_requirement',
28
26
  ]);
29
27
 
30
28
  /**
@@ -32,7 +30,7 @@ export const FLAG_EVIDENCE_CONSTRAINT_IDS: ReadonlySet<string> = new Set([
32
30
  */
33
31
  export interface ConstraintUsageStats {
34
32
  id: string;
35
- level: Constraint['level'];
33
+ severity: Constraint['severity'];
36
34
 
37
35
  /** trace 总行数(含 skip) */
38
36
  total: number;
@@ -98,12 +96,10 @@ export const DEFAULT_DIAGNOSE_THRESHOLDS: DiagnoseThresholds = {
98
96
  * report 数据模型
99
97
  */
100
98
  export interface ConstraintsUsageReport {
101
- /** check 层统计表(生效集内每条 check 约束一行,零出现 total=0) */
99
+ /** check 约束统计表(生效集内每条约束一行,零出现 total=0) */
102
100
  stats: ConstraintUsageStats[];
103
101
  /** 退役候选诊断(按 zero_trigger → unevaluable → high_noise → zero_intercept 排序) */
104
102
  candidates: RetireCandidate[];
105
- /** 当前生效的 prompt 条目 id(注入清单) */
106
- activePromptIds: string[];
107
103
  /** 配置健康诊断(unknownIds 等) */
108
104
  lint: EffectiveConfigLint;
109
105
  /** trace 文件是否存在 */
@@ -145,7 +141,7 @@ export function readProjectTraces(projectRoot: string): ExecutionTrace[] {
145
141
  */
146
142
  export function collectUsageByConstraint(
147
143
  traces: ExecutionTrace[]
148
- ): Map<string, Omit<ConstraintUsageStats, 'id' | 'level' | 'evaluated' | 'failRate'>> {
144
+ ): Map<string, Omit<ConstraintUsageStats, 'id' | 'severity' | 'evaluated' | 'failRate'>> {
149
145
  const map = new Map<string, { total: number; pass: number; fail: number; skip: number; firstAt?: number; lastAt?: number }>();
150
146
  for (const t of traces) {
151
147
  let agg = map.get(t.constraintId);
@@ -163,12 +159,12 @@ export function collectUsageByConstraint(
163
159
  return map;
164
160
  }
165
161
 
166
- function toStats(id: string, level: Constraint['level'], agg: { total: number; pass: number; fail: number; skip: number; firstAt?: number; lastAt?: number } | undefined): ConstraintUsageStats {
162
+ function toStats(id: string, severity: Constraint['severity'], agg: { total: number; pass: number; fail: number; skip: number; firstAt?: number; lastAt?: number } | undefined): ConstraintUsageStats {
167
163
  const a = agg ?? { total: 0, pass: 0, fail: 0, skip: 0 };
168
164
  const evaluated = a.total - a.skip;
169
165
  return {
170
166
  id,
171
- level,
167
+ severity,
172
168
  total: a.total,
173
169
  pass: a.pass,
174
170
  fail: a.fail,
@@ -183,7 +179,7 @@ function toStats(id: string, level: Constraint['level'], agg: { total: number; p
183
179
  /**
184
180
  * 退役候选诊断(纯函数)
185
181
  *
186
- * 每条 check 约束最多归入一个类别,优先级:
182
+ * 每条约束最多归入一个类别,优先级:
187
183
  * zero_trigger → unevaluable → high_noise → zero_intercept
188
184
  */
189
185
  export function diagnoseRetireCandidates(
@@ -248,21 +244,18 @@ export function buildConstraintsUsageReport(
248
244
  thresholds: Partial<DiagnoseThresholds> = {}
249
245
  ): ConstraintsUsageReport {
250
246
  const effective = getEffectiveConstraints(projectRoot);
251
- const checkConstraints = effective.filter(c => c.kind === 'check');
252
- const activePromptIds = effective.filter(c => c.kind === 'prompt').map(c => c.id);
253
247
 
254
248
  const tracePath = path.join(projectRoot, DEFAULT_TRACE_FILE);
255
249
  const { traces, skippedLines } = readProjectTracesReport(projectRoot);
256
250
  const usage = collectUsageByConstraint(traces);
257
251
 
258
- const stats = checkConstraints.map(c => toStats(c.id, c.level, usage.get(c.id)));
252
+ const stats = effective.map(c => toStats(c.id, c.severity, usage.get(c.id)));
259
253
  const candidates = diagnoseRetireCandidates(stats, thresholds);
260
254
  const lint = lintEffectiveConfig(projectRoot);
261
255
 
262
256
  return {
263
257
  stats,
264
258
  candidates,
265
- activePromptIds,
266
259
  lint,
267
260
  traceFileExists: fs.existsSync(tracePath),
268
261
  skippedLines,