@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,30 +1,22 @@
1
1
  /**
2
- * harness constraints retire —— 约束退役(ADR-0001 决策 2/5
2
+ * harness constraints retire —— 约束退役(ADR-0001 决策 2/5,ADR-0029 收窄)
3
3
  *
4
4
  * 建议层全自动(候选诊断复用 report 数据层),执行层保留一次人确认。
5
- * 落盘形态(studio#82 D6 一处真相):
5
+ * 落盘形态(一处真相):
6
6
  *
7
- * - 内置约束 → config.yml `enabled: false` + `retired` 元数据:
7
+ * - config.yml `enabled: false` + `retired` 元数据:
8
8
  *
9
9
  * constraints:
10
10
  * <id>:
11
11
  * enabled: false
12
12
  * retired: { at, reason, stats: { total, fail, failRate } }
13
13
  *
14
- * - custom 约束 → custom-constraints.yml 条目内 `retired` 元数据段
15
- * (不拆 config.yml 第二处):
14
+ * 每条同时写一条 KnowledgeStore 记录(consumptionMode: 'signal')。
16
15
  *
17
- * custom_constraints:
18
- * <id>:
19
- * rule: ...
20
- * retired: { at, reason, stats: { total, fail, failRate } }
21
- *
22
- * 每条同时写一条 KnowledgeStore 记录(consumptionMode: 'signal'),
23
- * 并同步治理注入段(CLAUDE.md 或 AGENTS.md,存在 HARNESS_CONSTRAINTS 标记时;
24
- * 落点路由与 init 一致,见 core/constraints/injection-drift resolveInjectionTarget)。
16
+ * ADR-0029:custom 纯文本约束与治理注入段同步已随文本注入层关停一并退役,
17
+ * retire 只处理内置 check 约束。
25
18
  *
26
- * retire 不是删除——恢复方法:内置删 config.yml 中 constraints.<id> 段;
27
- * custom 删 custom-constraints.yml 中 custom_constraints.<id>.retired 段。
19
+ * retire 不是删除——恢复方法:删 config.yml 中 constraints.<id> 段。
28
20
  *
29
21
  * 交互与执行分离:retireConstraint 为纯执行逻辑(同步、可测),
30
22
  * runRetireInteractive 只做 readline 交互,IO 流可注入。
@@ -37,11 +29,7 @@ import { log, logError, processIO, type CommandIO, type CommandResult } from '..
37
29
  import * as yaml from 'js-yaml';
38
30
  import chalk from 'chalk';
39
31
  import { getConstraint } from '../../core/constraints/definitions';
40
- import { renderConstraintsSection, CONSTRAINTS_START_MARKER, CONSTRAINTS_END_MARKER } from '../../core/constraints/injection-renderer';
41
- import { replaceStandaloneRange, resolveInjectionTarget } from '../../core/constraints/injection-writer';
42
- import { getEffectiveConstraints } from '../../core/effective-constraints';
43
- import { isConstraintRetired, ProjectConfigLoader } from '../../core/project-config-loader';
44
- import { getHarnessPackageVersion } from '../../utils/package-version';
32
+ import { ProjectConfigLoader } from '../../core/project-config-loader';
45
33
  import { FileKnowledgeStore } from '../../knowledge/store';
46
34
  import type { KnowledgeEntry } from '../../knowledge/types';
47
35
  import type { Constraint } from '../../types/constraint';
@@ -65,15 +53,9 @@ export type RetireStatus = 'retired' | 'already_retired' | 'unknown_id';
65
53
  export interface RetireResult {
66
54
  id: string;
67
55
  status: RetireStatus;
68
- /** 是否 check 层 iron(交互模式据此追加确认) */
69
- isIronLaw: boolean;
70
- /** 退役落点:custom 约束落 custom-constraints.yml(studio#82 D6),内置落 config.yml */
71
- landing: 'config.yml' | 'custom-constraints.yml';
56
+ /** 是否 severity='error'(交互模式据此追加确认) */
57
+ isError: boolean;
72
58
  stats: { total: number; fail: number; failRate: number };
73
- /** 治理注入段(CLAUDE.md / AGENTS.md)是否已同步 */
74
- injectionSynced: boolean;
75
- /** 实际同步的落点文件(injectionSynced 时存在) */
76
- injectionFile?: string;
77
59
  /** KnowledgeStore 条目 id(status='retired' 时存在) */
78
60
  knowledgeEntryId?: string;
79
61
  }
@@ -86,61 +68,34 @@ export interface ConstraintsRetireOptions {
86
68
  }
87
69
 
88
70
  interface RetireTargetInfo {
89
- source: 'builtin' | 'custom';
90
- isIronLaw: boolean;
91
- level: Constraint['level'];
71
+ severity: Constraint['severity'];
92
72
  description?: string;
93
73
  rule?: string;
94
74
  message?: string;
95
- promptInjection?: string;
96
75
  }
97
76
 
98
77
  /**
99
- * 查找约束定义(内置 definitions + 项目 custom-constraints
78
+ * 查找约束定义(内置 definitions)
100
79
  *
101
80
  * loader 由调用方给(一次退役一份观察面,见 retireConstraint):本函数只读它的装载结果,
102
81
  * 不再自造 ProjectConfigLoader。
103
82
  */
104
- function findRetireTarget(
105
- loader: ProjectConfigLoader,
106
- id: string
107
- ): RetireTargetInfo | undefined {
83
+ function findRetireTarget(id: string): RetireTargetInfo | undefined {
108
84
  const builtIn = getConstraint(id);
109
- if (builtIn) {
110
- return {
111
- source: 'builtin',
112
- isIronLaw: builtIn.kind === 'check' && builtIn.level === 'iron_law',
113
- level: builtIn.level,
114
- description: builtIn.description,
115
- rule: builtIn.rule,
116
- message: builtIn.message,
117
- promptInjection: builtIn.promptInjection,
118
- };
119
- }
120
-
121
- const custom = loader.getCustomConstraints()[id];
122
- if (custom) {
123
- const level = custom.level || 'guideline';
124
- return {
125
- source: 'custom',
126
- isIronLaw: false, // custom 约束统一 kind='prompt'(无 checker),不存在 check 层 iron
127
- level,
128
- description: custom.description,
129
- rule: custom.rule,
130
- message: custom.message,
131
- promptInjection: custom.promptInjection,
132
- };
133
- }
134
-
135
- return undefined;
85
+ if (!builtIn) return undefined;
86
+ return {
87
+ severity: builtIn.severity,
88
+ description: builtIn.description,
89
+ rule: builtIn.rule,
90
+ message: builtIn.message,
91
+ };
136
92
  }
137
93
 
138
94
  /**
139
95
  * YAML 条目的读-改-写单点(harness#137)
140
96
  *
141
- * 内置与 custom 两处退役落点原本是两段同型的读-改-写,只差键路径与 patch 内容。
142
97
  * js-yaml 不保留注释:原文件含注释行时重写会丢失,console 说明(`label` 是给用户看的
143
- * 文件名,与合并前两处逐字一致)。落盘字节由 `__tests__/constraints-retire.test.ts`
98
+ * 文件名)。落盘字节由 `__tests__/constraints-retire.test.ts`
144
99
  * 的逐字节冻结用例钉住——合并属内部重构,对外产物不得漂移。
145
100
  */
146
101
  function setYamlEntry(
@@ -191,7 +146,6 @@ function saveRetireKnowledge(
191
146
  target.description ? `description: ${target.description}` : undefined,
192
147
  target.rule ? `rule: ${target.rule}` : undefined,
193
148
  target.message ? `message: ${target.message}` : undefined,
194
- target.promptInjection ? `promptInjection: ${target.promptInjection}` : undefined,
195
149
  '',
196
150
  '## 退役原因',
197
151
  '',
@@ -217,7 +171,7 @@ function saveRetireKnowledge(
217
171
  lastReferenced: iso,
218
172
  contributors: [],
219
173
  projects: [],
220
- tags: ['constraint-retired', `constraint:${id}`, `level:${target.level}`],
174
+ tags: ['constraint-retired', `constraint:${id}`, `severity:${target.severity}`],
221
175
  applicablePhases: [],
222
176
  sourceReferences: [{ timestamp: iso }],
223
177
  referencedBy: [],
@@ -231,26 +185,6 @@ function saveRetireKnowledge(
231
185
  return entryId;
232
186
  }
233
187
 
234
- /**
235
- * 同步治理注入段(CLAUDE.md 或 AGENTS.md,存在 HARNESS_CONSTRAINTS 标记时)
236
- *
237
- * 落点路由复用 resolveInjectionTarget(studio #307:新模型仓注入段在
238
- * AGENTS.md PRESERVE:governance 内;旧模型仓 CLAUDE.md 优先)。
239
- * 复用 renderConstraintsSection(P3 导出纯函数)按退役后生效集重渲染。
240
- * 无标记段不动(不追加——retire 不承担 init 职责)。
241
- */
242
- function syncGovernanceInjection(projectRoot: string): { synced: boolean; file?: string } {
243
- const target = resolveInjectionTarget(projectRoot);
244
- if (!target) return { synced: false };
245
-
246
- const body = renderConstraintsSection(getEffectiveConstraints(projectRoot), getHarnessPackageVersion());
247
- const write = replaceStandaloneRange(target.content, CONSTRAINTS_START_MARKER, CONSTRAINTS_END_MARKER, body);
248
- if (write.kind === 'updated' && write.content !== target.content) {
249
- fs.writeFileSync(path.join(projectRoot, target.file), write.content, 'utf-8');
250
- }
251
- return { synced: true, file: target.file };
252
- }
253
-
254
188
  /**
255
189
  * 执行单条约束退役(纯执行逻辑,无交互)
256
190
  *
@@ -265,27 +199,20 @@ export function retireConstraint(
265
199
  const iso = now.toISOString();
266
200
  const reason = options.reason ?? '';
267
201
 
268
- // 一次退役一份观察面(ADR-0023 决策 2):定义查找、already_retired 判定与 custom 文件名
269
- // 解析共用这一份装载结果。此前同一次调用 new 了 2–3 枚加载器、各带一次 load()(harness#137)。
270
- // 只覆盖写盘**之前**的读取:写盘后 syncGovernanceInjection 必须读到新状态,另起观察面。
202
+ // 一次退役一份观察面(ADR-0023 决策 2):定义查找与 already_retired 判定共用这一份装载结果。
271
203
  const loader = new ProjectConfigLoader(projectRoot);
272
204
  loader.load();
273
205
 
274
- const target = findRetireTarget(loader, id);
206
+ const target = findRetireTarget(id);
275
207
  const emptyStats = { total: 0, fail: 0, failRate: 0 };
276
- const landing: RetireResult['landing'] =
277
- target?.source === 'custom' ? 'custom-constraints.yml' : 'config.yml';
278
208
  if (!target) {
279
- return { id, status: 'unknown_id', isIronLaw: false, landing, stats: emptyStats, injectionSynced: false };
209
+ return { id, status: 'unknown_id', isError: false, stats: emptyStats };
280
210
  }
211
+ const isError = target.severity === 'error';
281
212
 
282
- // 已退役保护:判定单点在 core/project-config-loader isConstraintRetired
283
- // (内置看 config.yml enabled:false;custom yml 条目 retired 元数据,
284
- // 历史落点 config.yml enabled:false 同样保护)
285
- const disabledInConfig = loader.getConfig().constraints?.[id]?.enabled === false;
286
- const customDef = target.source === 'custom' ? loader.getCustomConstraints()[id] : undefined;
287
- if (isConstraintRetired(customDef, disabledInConfig)) {
288
- return { id, status: 'already_retired', isIronLaw: target.isIronLaw, landing, stats: emptyStats, injectionSynced: false };
213
+ // 已退役保护:退役落点只有 config.yml constraints.<id>.enabled:false 一处
214
+ if (loader.getConfig().constraints?.[id]?.enabled === false) {
215
+ return { id, status: 'already_retired', isError, stats: emptyStats };
289
216
  }
290
217
 
291
218
  // 历史统计(来自 traces.log)
@@ -300,42 +227,24 @@ export function retireConstraint(
300
227
  failRate: evaluated > 0 ? (usage!.fail / evaluated) : 0,
301
228
  };
302
229
 
303
- // 1. 落盘退役(custom → yml 条目 retired 段;内置 → config.yml enabled:false + retired 段,
304
- // 两处原文均保留)
230
+ // 1. 落盘退役(config.yml enabled:false + retired 段,原文保留)
305
231
  const retiredMeta = { at: iso, reason, stats };
306
- if (target.source === 'custom') {
307
- const customFile = loader.getConfig().custom_constraints_file ?? 'custom-constraints.yml';
308
- setYamlEntry(
309
- path.join(projectRoot, '.harness', customFile),
310
- 'custom-constraints.yml',
311
- 'custom_constraints',
312
- id,
313
- { retired: retiredMeta }
314
- );
315
- } else {
316
- setYamlEntry(
317
- path.join(projectRoot, '.harness', 'config.yml'),
318
- 'config.yml',
319
- 'constraints',
320
- id,
321
- { enabled: false, retired: retiredMeta }
322
- );
323
- }
232
+ setYamlEntry(
233
+ path.join(projectRoot, '.harness', 'config.yml'),
234
+ 'config.yml',
235
+ 'constraints',
236
+ id,
237
+ { enabled: false, retired: retiredMeta }
238
+ );
324
239
 
325
240
  // 2. KnowledgeStore
326
241
  const knowledgeEntryId = saveRetireKnowledge(projectRoot, id, target, reason, stats, iso);
327
242
 
328
- // 3. 治理注入段同步(CLAUDE.md / AGENTS.md,路由见 syncGovernanceInjection)
329
- const injection = syncGovernanceInjection(projectRoot);
330
-
331
243
  return {
332
244
  id,
333
245
  status: 'retired',
334
- isIronLaw: target.isIronLaw,
335
- landing,
246
+ isError,
336
247
  stats,
337
- injectionSynced: injection.synced,
338
- injectionFile: injection.file,
339
248
  knowledgeEntryId,
340
249
  };
341
250
  }
@@ -346,7 +255,7 @@ export function retireConstraint(
346
255
  export function printRetireResult(result: RetireResult, io: CommandIO = processIO): CommandResult {
347
256
  switch (result.status) {
348
257
  case 'unknown_id':
349
- log(io, chalk.red(`❌ ${result.id}: 约束不存在(既非内置也非 custom-constraints),未做任何变更`));
258
+ log(io, chalk.red(`❌ ${result.id}: 约束不存在(非内置约束),未做任何变更`));
350
259
  return { kind: 'skip', reason: `${result.id}: 约束不存在,未做任何变更` };
351
260
  case 'already_retired':
352
261
  log(io, chalk.yellow(`⚠️ ${result.id}: 已处于退役状态(config.yml 中 enabled: false),跳过`));
@@ -355,14 +264,7 @@ export function printRetireResult(result: RetireResult, io: CommandIO = processI
355
264
  log(io, chalk.green(`✅ ${result.id}: 已退役`));
356
265
  log(io, ` 历史统计: total=${result.stats.total} fail=${result.stats.fail} fail率=${Math.round(result.stats.failRate * 100)}%`);
357
266
  log(io, ` 知识沉淀: ${result.knowledgeEntryId}(.harness/knowledge)`);
358
- if (result.injectionSynced) {
359
- log(io, ` 已同步 ${result.injectionFile ?? '治理文档'} 注入段`);
360
- }
361
- const recovery =
362
- result.landing === 'custom-constraints.yml'
363
- ? `删除 custom-constraints.yml 中 custom_constraints.${result.id}.retired 段`
364
- : `删除 config.yml 中 constraints.${result.id} 段`;
365
- log(io, chalk.gray(` retire 不是删除——恢复方法:${recovery}`));
267
+ log(io, chalk.gray(` retire 不是删除——恢复方法:删除 config.yml 中 constraints.${result.id} 段`));
366
268
  break;
367
269
  }
368
270
  }
@@ -439,25 +341,23 @@ export async function runRetireInteractive(
439
341
  selectedIds = [...new Set(selectedIds)];
440
342
  }
441
343
 
442
- // 逐条收集 reason + iron 二次确认(一次交互一份装载结果:候选到确认之间不写盘)
443
- const planLoader = new ProjectConfigLoader(projectRoot);
444
- planLoader.load();
445
- const plan: { id: string; reason: string; source: RetireTargetInfo['source'] }[] = [];
344
+ // 逐条收集 reason + error 级二次确认
345
+ const plan: { id: string; reason: string }[] = [];
446
346
  for (const id of selectedIds) {
447
- const target = findRetireTarget(planLoader, id);
347
+ const target = findRetireTarget(id);
448
348
  if (!target) {
449
349
  console.log(chalk.red(`❌ ${id}: 约束不存在,跳过`));
450
350
  continue;
451
351
  }
452
- if (target.isIronLaw) {
453
- const confirm = await ask(chalk.yellow(`⚠️ ${id} 是一条 Iron Law,确认退役?(y/N) `));
352
+ if (target.severity === 'error') {
353
+ const confirm = await ask(chalk.yellow(`⚠️ ${id} 是一条 error 级约束,确认退役?(y/N) `));
454
354
  if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
455
355
  console.log(` 已跳过 ${id}`);
456
356
  continue;
457
357
  }
458
358
  }
459
359
  const reason = await ask(`退役原因(${id},可留空): `);
460
- plan.push({ id, reason, source: target.source });
360
+ plan.push({ id, reason });
461
361
  }
462
362
 
463
363
  if (plan.length === 0) {
@@ -469,14 +369,9 @@ export async function runRetireInteractive(
469
369
  console.log();
470
370
  console.log(chalk.bold('将执行以下变更:'));
471
371
  for (const p of plan) {
472
- if (p.source === 'custom') {
473
- console.log(` - custom-constraints.yml: custom_constraints.${p.id}.retired 元数据(原因: ${p.reason || '(空)'})`);
474
- } else {
475
- console.log(` - config.yml: constraints.${p.id}.enabled=false + retired 元数据(原因: ${p.reason || '(空)'})`);
476
- }
372
+ console.log(` - config.yml: constraints.${p.id}.enabled=false + retired 元数据(原因: ${p.reason || '(空)'})`);
477
373
  console.log(` - KnowledgeStore: 写入 constraint-retired-${p.id}`);
478
374
  }
479
- console.log(' - CLAUDE.md / AGENTS.md: 若含 HARNESS_CONSTRAINTS 标记段则同步重渲染');
480
375
  const finalConfirm = await ask('确认执行?(y/N) ');
481
376
  if (finalConfirm.toLowerCase() !== 'y' && finalConfirm.toLowerCase() !== 'yes') {
482
377
  console.log('已取消');
@@ -527,8 +422,8 @@ export async function constraintsRetire(
527
422
  }
528
423
 
529
424
  const result = retireConstraint(projectRoot, id, { reason: options.reason });
530
- if (result.status === 'retired' && result.isIronLaw) {
531
- log(io, chalk.yellow(`⚠️ ${id} 是一条 Iron Law,已通过 --yes 直达退役(交互模式会要求二次确认)`));
425
+ if (result.status === 'retired' && result.isError) {
426
+ log(io, chalk.yellow(`⚠️ ${id} 是一条 error 级约束,已通过 --yes 直达退役(交互模式会要求二次确认)`));
532
427
  }
533
428
  return printRetireResult(result, io);
534
429
  }
@@ -2,7 +2,7 @@
2
2
  * harness constraints -- 约束集合元数据导出
3
3
  *
4
4
  * 纯数据导出,不调用 LLM,不访问文件系统(除 definitions.ts)。
5
- * 供 Studio 等消费者获取约束的 hash、计数、文本大小等元数据。
5
+ * 供 Studio 等消费者获取约束的 hash、计数等元数据。
6
6
  */
7
7
 
8
8
  import { createHash } from 'crypto';
@@ -13,41 +13,27 @@ import { log, processIO, type CommandIO, type CommandResult } from '../command-c
13
13
  export interface ConstraintsMeta {
14
14
  version: string;
15
15
  hash: string;
16
- counts: { ironLaws: number; guidelines: number; prompts: number };
17
- textSize: { total: number; perConstraint: number };
16
+ counts: { errors: number; warnings: number };
18
17
  }
19
18
 
20
19
  export function getConstraintsMeta(): ConstraintsMeta {
21
20
  const constraints = getAllConstraints();
22
21
 
23
- const ironLaws = constraints.filter(c => c.level === 'iron_law');
24
- const guidelines = constraints.filter(c => c.level === 'guideline');
25
- const prompts = constraints.filter(c => c.level === 'prompt');
22
+ const errors = constraints.filter(c => c.severity === 'error');
23
+ const warnings = constraints.filter(c => c.severity === 'warning');
26
24
 
27
- // 计算总 promptInjection 文本长度(字符数,可估算 token)
28
- const totalTextSize = constraints
29
- .map(c => (c.promptInjection || '').length)
30
- .reduce((sum, len) => sum + len, 0);
31
-
32
- // 稳定 JSON 序列化后取 hash
33
- const hashInput = JSON.stringify({
34
- ironLaws: ironLaws.map(c => ({ id: c.id, promptInjection: c.promptInjection })),
35
- guidelines: guidelines.map(c => ({ id: c.id, promptInjection: c.promptInjection })),
36
- prompts: prompts.map(c => ({ id: c.id, promptInjection: c.promptInjection })),
37
- });
25
+ // 稳定 JSON 序列化后取 hash(内容面 = id + severity + 规则文本)
26
+ const hashInput = JSON.stringify(
27
+ constraints.map(c => ({ id: c.id, severity: c.severity, rule: c.rule, message: c.message, description: c.description }))
28
+ );
38
29
  const hash = createHash('sha256').update(hashInput).digest('hex');
39
30
 
40
31
  return {
41
32
  version: getHarnessPackageVersion(),
42
33
  hash,
43
34
  counts: {
44
- ironLaws: ironLaws.length,
45
- guidelines: guidelines.length,
46
- prompts: prompts.length,
47
- },
48
- textSize: {
49
- total: totalTextSize,
50
- perConstraint: constraints.length > 0 ? Math.round(totalTextSize / constraints.length) : 0,
35
+ errors: errors.length,
36
+ warnings: warnings.length,
51
37
  },
52
38
  };
53
39
  }
@@ -62,8 +48,7 @@ export async function constraints(options: { json?: boolean }, io: CommandIO = p
62
48
  } else {
63
49
  log(io, `version: ${meta.version}`);
64
50
  log(io, `hash: ${meta.hash}`);
65
- log(io, `ironLaws: ${meta.counts.ironLaws}, guidelines: ${meta.counts.guidelines}, prompts: ${meta.counts.prompts}`);
66
- log(io, `textSize: ${meta.textSize.total} chars total, ~${meta.textSize.perConstraint} chars/constraint`);
51
+ log(io, `errors: ${meta.counts.errors}, warnings: ${meta.counts.warnings}`);
67
52
  }
68
53
  return { kind: 'ok' };
69
54
  }
@@ -101,7 +101,7 @@ export interface CommandDefinition {
101
101
  export const COMMAND_DEFINITIONS: CommandDefinition[] = [
102
102
  {
103
103
  command: 'check',
104
- description: '检查铁律是否满足',
104
+ description: '检查约束是否满足',
105
105
  options: [
106
106
  // 不给缺省值:「没传 -p」与「传了 standard」必须可区分,否则生效集侧的覆盖规则恒触发、
107
107
  // config.yml 的 preset 静默失效(漂移检测侧按 config.yml 算,两边就会稳定对不上)
@@ -109,7 +109,7 @@ export const COMMAND_DEFINITIONS: CommandDefinition[] = [
109
109
  { flags: '-s, --staged', description: '只检查暂存文件', defaultValue: false },
110
110
  { flags: '-t, --trigger <trigger>', description: '触发条件' },
111
111
  { flags: '--project-path <path>', description: '项目路径' },
112
- { flags: '--list', description: '列出所有铁律' },
112
+ { flags: '--list', description: '列出所有约束' },
113
113
  ],
114
114
  action: { module: 'check', export: 'check' },
115
115
  optionRoutes: [