@dommaker/harness 1.1.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -4
  3. package/bin/harness.js +12 -37
  4. package/dist/cli/commands/check.d.ts +2 -2
  5. package/dist/cli/commands/check.d.ts.map +1 -1
  6. package/dist/cli/commands/check.js +8 -33
  7. package/dist/cli/commands/check.js.map +1 -1
  8. package/dist/cli/commands/constraints-report.js +1 -1
  9. package/dist/cli/commands/constraints-report.js.map +1 -1
  10. package/dist/cli/commands/constraints-retire.d.ts +6 -3
  11. package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
  12. package/dist/cli/commands/constraints-retire.js +34 -25
  13. package/dist/cli/commands/constraints-retire.js.map +1 -1
  14. package/dist/cli/commands/definitions.d.ts +2 -0
  15. package/dist/cli/commands/definitions.d.ts.map +1 -1
  16. package/dist/cli/commands/definitions.js.map +1 -1
  17. package/dist/cli/commands/init.d.ts +21 -1
  18. package/dist/cli/commands/init.d.ts.map +1 -1
  19. package/dist/cli/commands/init.js +118 -40
  20. package/dist/cli/commands/init.js.map +1 -1
  21. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  22. package/dist/cli/commands/knowledge.js +1 -12
  23. package/dist/cli/commands/knowledge.js.map +1 -1
  24. package/dist/cli/commands/report.d.ts.map +1 -1
  25. package/dist/cli/commands/report.js +0 -2
  26. package/dist/cli/commands/report.js.map +1 -1
  27. package/dist/cli/commands/status.js +2 -2
  28. package/dist/cli/commands/status.js.map +1 -1
  29. package/dist/context/index.d.ts +9 -6
  30. package/dist/context/index.d.ts.map +1 -1
  31. package/dist/context/index.js +18 -20
  32. package/dist/context/index.js.map +1 -1
  33. package/dist/core/constraints/capabilities-parser.d.ts +3 -2
  34. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  35. package/dist/core/constraints/capabilities-parser.js +25 -47
  36. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  37. package/dist/core/constraints/checker.d.ts +29 -32
  38. package/dist/core/constraints/checker.d.ts.map +1 -1
  39. package/dist/core/constraints/checker.js +34 -126
  40. package/dist/core/constraints/checker.js.map +1 -1
  41. package/dist/core/constraints/checkers/governance-presence.d.ts +20 -0
  42. package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -0
  43. package/dist/core/constraints/checkers/governance-presence.js +76 -0
  44. package/dist/core/constraints/checkers/governance-presence.js.map +1 -0
  45. package/dist/core/constraints/checkers/index.d.ts +2 -1
  46. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  47. package/dist/core/constraints/checkers/index.js +5 -0
  48. package/dist/core/constraints/checkers/index.js.map +1 -1
  49. package/dist/core/constraints/checkers/types.d.ts +25 -0
  50. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  51. package/dist/core/constraints/checkers/types.js +24 -0
  52. package/dist/core/constraints/checkers/types.js.map +1 -1
  53. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  54. package/dist/core/constraints/definitions/guidelines.js +21 -2
  55. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  56. package/dist/core/constraints/definitions/prompts.d.ts.map +1 -1
  57. package/dist/core/constraints/definitions/prompts.js +0 -5
  58. package/dist/core/constraints/definitions/prompts.js.map +1 -1
  59. package/dist/core/constraints/index.d.ts +1 -2
  60. package/dist/core/constraints/index.d.ts.map +1 -1
  61. package/dist/core/constraints/index.js +1 -7
  62. package/dist/core/constraints/index.js.map +1 -1
  63. package/dist/core/constraints/injection-drift.d.ts +29 -4
  64. package/dist/core/constraints/injection-drift.d.ts.map +1 -1
  65. package/dist/core/constraints/injection-drift.js +52 -20
  66. package/dist/core/constraints/injection-drift.js.map +1 -1
  67. package/dist/core/constraints/usage-report.d.ts +1 -2
  68. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  69. package/dist/core/constraints/usage-report.js +2 -5
  70. package/dist/core/constraints/usage-report.js.map +1 -1
  71. package/dist/core/effective-constraints.d.ts +24 -4
  72. package/dist/core/effective-constraints.d.ts.map +1 -1
  73. package/dist/core/effective-constraints.js +28 -7
  74. package/dist/core/effective-constraints.js.map +1 -1
  75. package/dist/core/effective-set.d.ts +30 -0
  76. package/dist/core/effective-set.d.ts.map +1 -0
  77. package/dist/core/effective-set.js +35 -0
  78. package/dist/core/effective-set.js.map +1 -0
  79. package/dist/core/index.d.ts +13 -6
  80. package/dist/core/index.d.ts.map +1 -1
  81. package/dist/core/index.js +44 -21
  82. package/dist/core/index.js.map +1 -1
  83. package/dist/core/project-config-loader.d.ts +3 -6
  84. package/dist/core/project-config-loader.d.ts.map +1 -1
  85. package/dist/core/project-config-loader.js +47 -61
  86. package/dist/core/project-config-loader.js.map +1 -1
  87. package/dist/failure/constraint-handler.d.ts +1 -1
  88. package/dist/failure/constraint-handler.js +1 -1
  89. package/dist/gates/checker-gate.d.ts +1 -4
  90. package/dist/gates/checker-gate.d.ts.map +1 -1
  91. package/dist/gates/checker-gate.js +3 -11
  92. package/dist/gates/checker-gate.js.map +1 -1
  93. package/dist/gates/definitions.d.ts +9 -38
  94. package/dist/gates/definitions.d.ts.map +1 -1
  95. package/dist/gates/definitions.js +24 -13
  96. package/dist/gates/definitions.js.map +1 -1
  97. package/dist/gates/effective-gates.d.ts.map +1 -1
  98. package/dist/gates/effective-gates.js +14 -18
  99. package/dist/gates/effective-gates.js.map +1 -1
  100. package/dist/gates/index.d.ts +1 -1
  101. package/dist/gates/index.d.ts.map +1 -1
  102. package/dist/gates/index.js.map +1 -1
  103. package/dist/hooks/bootstrap.d.ts.map +1 -1
  104. package/dist/hooks/bootstrap.js +0 -3
  105. package/dist/hooks/bootstrap.js.map +1 -1
  106. package/dist/index.d.ts +43 -60
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +180 -143
  109. package/dist/index.js.map +1 -1
  110. package/dist/knowledge/query.d.ts +15 -0
  111. package/dist/knowledge/query.d.ts.map +1 -1
  112. package/dist/knowledge/query.js +23 -0
  113. package/dist/knowledge/query.js.map +1 -1
  114. package/dist/monitoring/analyzer-base.d.ts +0 -4
  115. package/dist/monitoring/analyzer-base.d.ts.map +1 -1
  116. package/dist/monitoring/analyzer-base.js +0 -21
  117. package/dist/monitoring/analyzer-base.js.map +1 -1
  118. package/dist/monitoring/index.d.ts +6 -12
  119. package/dist/monitoring/index.d.ts.map +1 -1
  120. package/dist/monitoring/index.js +13 -29
  121. package/dist/monitoring/index.js.map +1 -1
  122. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  123. package/dist/monitoring/trace-analyzer.js +2 -68
  124. package/dist/monitoring/trace-analyzer.js.map +1 -1
  125. package/dist/monitoring/traces.d.ts +0 -4
  126. package/dist/monitoring/traces.d.ts.map +1 -1
  127. package/dist/monitoring/traces.js +0 -14
  128. package/dist/monitoring/traces.js.map +1 -1
  129. package/dist/presets/index.d.ts +2 -2
  130. package/dist/presets/index.d.ts.map +1 -1
  131. package/dist/presets/index.js +3 -4
  132. package/dist/presets/index.js.map +1 -1
  133. package/dist/presets/standard.d.ts +10 -22
  134. package/dist/presets/standard.d.ts.map +1 -1
  135. package/dist/presets/standard.js +15 -75
  136. package/dist/presets/standard.js.map +1 -1
  137. package/dist/types/constraint.d.ts +1 -29
  138. package/dist/types/constraint.d.ts.map +1 -1
  139. package/dist/types/constraint.js +1 -1
  140. package/dist/types/constraint.js.map +1 -1
  141. package/dist/types/index.d.ts +0 -3
  142. package/dist/types/index.d.ts.map +1 -1
  143. package/dist/types/index.js +0 -4
  144. package/dist/types/index.js.map +1 -1
  145. package/dist/types/project-config.d.ts +4 -8
  146. package/dist/types/project-config.d.ts.map +1 -1
  147. package/dist/types/trace.d.ts +5 -18
  148. package/dist/types/trace.d.ts.map +1 -1
  149. package/package.json +2 -2
  150. package/src/CONTEXT.md +4 -5
  151. package/src/__tests__/checker-extra.test.ts +33 -139
  152. package/src/__tests__/checker.test.ts +0 -376
  153. package/src/__tests__/governance-presence.test.ts +129 -0
  154. package/src/__tests__/iron-laws.test.ts +7 -7
  155. package/src/__tests__/project-config-loader-extra.test.ts +42 -29
  156. package/src/__tests__/public-exports.test.ts +138 -0
  157. package/src/__tests__/trace-analyzer-extra.test.ts +6 -86
  158. package/src/__tests__/trace-analyzer.test.ts +4 -5
  159. package/src/__tests__/trace-collector.test.ts +0 -11
  160. package/src/__tests__/traces.test.ts +3 -22
  161. package/src/cli/commands/CONTEXT.md +6 -3
  162. package/src/cli/commands/__tests__/check-skip-output.test.ts +10 -7
  163. package/src/cli/commands/__tests__/check.test.ts +29 -69
  164. package/src/cli/commands/__tests__/constraints-report.test.ts +3 -3
  165. package/src/cli/commands/__tests__/constraints-retire.test.ts +45 -4
  166. package/src/cli/commands/__tests__/init-injection.test.ts +202 -0
  167. package/src/cli/commands/__tests__/knowledge.test.ts +90 -1
  168. package/src/cli/commands/__tests__/registry.test.ts +8 -6
  169. package/src/cli/commands/__tests__/status-extra.test.ts +6 -6
  170. package/src/cli/commands/__tests__/status.test.ts +6 -6
  171. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +28 -0
  172. package/src/cli/commands/check.ts +9 -35
  173. package/src/cli/commands/constraints-report.ts +1 -1
  174. package/src/cli/commands/constraints-retire.ts +38 -27
  175. package/src/cli/commands/definitions.ts +2 -0
  176. package/src/cli/commands/init.ts +129 -40
  177. package/src/cli/commands/knowledge.ts +1 -16
  178. package/src/cli/commands/report.ts +0 -2
  179. package/src/cli/commands/status.ts +2 -2
  180. package/src/context/index.ts +29 -6
  181. package/src/core/CONTEXT.md +4 -3
  182. package/src/core/__tests__/effective-set.test.ts +80 -0
  183. package/src/core/constraints/__tests__/injection-drift.test.ts +90 -0
  184. package/src/core/constraints/capabilities-parser.ts +43 -49
  185. package/src/core/constraints/checker.ts +51 -145
  186. package/src/core/constraints/checkers/governance-presence.ts +74 -0
  187. package/src/core/constraints/checkers/index.ts +4 -1
  188. package/src/core/constraints/checkers/types.ts +42 -0
  189. package/src/core/constraints/definitions/guidelines.ts +22 -2
  190. package/src/core/constraints/definitions/prompts.ts +0 -5
  191. package/src/core/constraints/index.ts +2 -17
  192. package/src/core/constraints/injection-drift.ts +60 -21
  193. package/src/core/constraints/usage-report.ts +5 -8
  194. package/src/core/effective-constraints.ts +35 -7
  195. package/src/core/effective-set.ts +56 -0
  196. package/src/core/index.ts +80 -6
  197. package/src/core/project-config-loader.ts +53 -68
  198. package/src/failure/CONTEXT.md +1 -1
  199. package/src/failure/constraint-handler.ts +1 -1
  200. package/src/gates/CONTEXT.md +3 -3
  201. package/src/gates/checker-gate.ts +4 -12
  202. package/src/gates/definitions.ts +27 -50
  203. package/src/gates/effective-gates.ts +14 -21
  204. package/src/gates/index.ts +1 -1
  205. package/src/hooks/bootstrap.ts +0 -3
  206. package/src/index.ts +384 -148
  207. package/src/knowledge/CONTEXT.md +2 -2
  208. package/src/knowledge/__tests__/query.test.ts +64 -0
  209. package/src/knowledge/query.ts +28 -0
  210. package/src/monitoring/CONTEXT.md +7 -13
  211. package/src/monitoring/__tests__/traces.test.ts +0 -10
  212. package/src/monitoring/analyzer-base.ts +0 -22
  213. package/src/monitoring/index.ts +6 -12
  214. package/src/monitoring/trace-analyzer.ts +2 -73
  215. package/src/monitoring/traces.ts +0 -20
  216. package/src/presets/__tests__/standard.test.ts +48 -69
  217. package/src/presets/index.ts +3 -5
  218. package/src/presets/standard.ts +14 -79
  219. package/src/spec/CONTEXT.md +5 -13
  220. package/src/types/constraint.ts +1 -51
  221. package/src/types/index.ts +0 -12
  222. package/src/types/project-config.ts +4 -10
  223. package/src/types/trace.ts +5 -30
  224. package/dist/core/constraints/interceptor.d.ts +0 -39
  225. package/dist/core/constraints/interceptor.d.ts.map +0 -1
  226. package/dist/core/constraints/interceptor.js +0 -166
  227. package/dist/core/constraints/interceptor.js.map +0 -1
  228. package/dist/dashboard/data.d.ts +0 -31
  229. package/dist/dashboard/data.d.ts.map +0 -1
  230. package/dist/dashboard/data.js +0 -81
  231. package/dist/dashboard/data.js.map +0 -1
  232. package/dist/dashboard/index.d.ts +0 -4
  233. package/dist/dashboard/index.d.ts.map +0 -1
  234. package/dist/dashboard/index.js +0 -20
  235. package/dist/dashboard/index.js.map +0 -1
  236. package/dist/dashboard/stats.d.ts +0 -20
  237. package/dist/dashboard/stats.d.ts.map +0 -1
  238. package/dist/dashboard/stats.js +0 -115
  239. package/dist/dashboard/stats.js.map +0 -1
  240. package/dist/dashboard/types.d.ts +0 -110
  241. package/dist/dashboard/types.d.ts.map +0 -1
  242. package/dist/dashboard/types.js +0 -8
  243. package/dist/dashboard/types.js.map +0 -1
  244. package/dist/monitoring/constraint-doctor.d.ts +0 -76
  245. package/dist/monitoring/constraint-doctor.d.ts.map +0 -1
  246. package/dist/monitoring/constraint-doctor.js +0 -189
  247. package/dist/monitoring/constraint-doctor.js.map +0 -1
  248. package/dist/monitoring/diagnosis-rules.d.ts +0 -18
  249. package/dist/monitoring/diagnosis-rules.d.ts.map +0 -1
  250. package/dist/monitoring/diagnosis-rules.js +0 -119
  251. package/dist/monitoring/diagnosis-rules.js.map +0 -1
  252. package/dist/monitoring/knowledge-doctor.d.ts +0 -78
  253. package/dist/monitoring/knowledge-doctor.d.ts.map +0 -1
  254. package/dist/monitoring/knowledge-doctor.js +0 -266
  255. package/dist/monitoring/knowledge-doctor.js.map +0 -1
  256. package/dist/monitoring/knowledge-evolver.d.ts +0 -72
  257. package/dist/monitoring/knowledge-evolver.d.ts.map +0 -1
  258. package/dist/monitoring/knowledge-evolver.js +0 -205
  259. package/dist/monitoring/knowledge-evolver.js.map +0 -1
  260. package/dist/monitoring/performance-analyzer.d.ts +0 -92
  261. package/dist/monitoring/performance-analyzer.d.ts.map +0 -1
  262. package/dist/monitoring/performance-analyzer.js +0 -343
  263. package/dist/monitoring/performance-analyzer.js.map +0 -1
  264. package/dist/monitoring/performance-collector.d.ts +0 -103
  265. package/dist/monitoring/performance-collector.d.ts.map +0 -1
  266. package/dist/monitoring/performance-collector.js +0 -298
  267. package/dist/monitoring/performance-collector.js.map +0 -1
  268. package/dist/safety/index.d.ts +0 -6
  269. package/dist/safety/index.d.ts.map +0 -1
  270. package/dist/safety/index.js +0 -22
  271. package/dist/safety/index.js.map +0 -1
  272. package/dist/safety/input-guardrail.d.ts +0 -36
  273. package/dist/safety/input-guardrail.d.ts.map +0 -1
  274. package/dist/safety/input-guardrail.js +0 -118
  275. package/dist/safety/input-guardrail.js.map +0 -1
  276. package/dist/safety/output-guardrail.d.ts +0 -39
  277. package/dist/safety/output-guardrail.d.ts.map +0 -1
  278. package/dist/safety/output-guardrail.js +0 -147
  279. package/dist/safety/output-guardrail.js.map +0 -1
  280. package/dist/safety/sandbox.d.ts +0 -45
  281. package/dist/safety/sandbox.d.ts.map +0 -1
  282. package/dist/safety/sandbox.js +0 -134
  283. package/dist/safety/sandbox.js.map +0 -1
  284. package/dist/safety/tool-guardrail.d.ts +0 -51
  285. package/dist/safety/tool-guardrail.d.ts.map +0 -1
  286. package/dist/safety/tool-guardrail.js +0 -147
  287. package/dist/safety/tool-guardrail.js.map +0 -1
  288. package/dist/safety/types.d.ts +0 -104
  289. package/dist/safety/types.d.ts.map +0 -1
  290. package/dist/safety/types.js +0 -6
  291. package/dist/safety/types.js.map +0 -1
  292. package/dist/spec/annotation-checker.d.ts +0 -47
  293. package/dist/spec/annotation-checker.d.ts.map +0 -1
  294. package/dist/spec/annotation-checker.js +0 -279
  295. package/dist/spec/annotation-checker.js.map +0 -1
  296. package/dist/types/enforcement.d.ts +0 -42
  297. package/dist/types/enforcement.d.ts.map +0 -1
  298. package/dist/types/enforcement.js +0 -6
  299. package/dist/types/enforcement.js.map +0 -1
  300. package/dist/types/monitoring-types.d.ts +0 -53
  301. package/dist/types/monitoring-types.d.ts.map +0 -1
  302. package/dist/types/monitoring-types.js +0 -10
  303. package/dist/types/monitoring-types.js.map +0 -1
  304. package/dist/types/performance.d.ts +0 -204
  305. package/dist/types/performance.d.ts.map +0 -1
  306. package/dist/types/performance.js +0 -12
  307. package/dist/types/performance.js.map +0 -1
  308. package/dist/verification/index.d.ts +0 -4
  309. package/dist/verification/index.d.ts.map +0 -1
  310. package/dist/verification/index.js +0 -20
  311. package/dist/verification/index.js.map +0 -1
  312. package/dist/verification/loop.d.ts +0 -30
  313. package/dist/verification/loop.d.ts.map +0 -1
  314. package/dist/verification/loop.js +0 -114
  315. package/dist/verification/loop.js.map +0 -1
  316. package/dist/verification/rules-based.d.ts +0 -40
  317. package/dist/verification/rules-based.d.ts.map +0 -1
  318. package/dist/verification/rules-based.js +0 -130
  319. package/dist/verification/rules-based.js.map +0 -1
  320. package/dist/verification/types.d.ts +0 -69
  321. package/dist/verification/types.d.ts.map +0 -1
  322. package/dist/verification/types.js +0 -6
  323. package/dist/verification/types.js.map +0 -1
  324. package/src/__tests__/annotation-checker.test.ts +0 -183
  325. package/src/__tests__/constraint-doctor.test.ts +0 -271
  326. package/src/__tests__/doctor-extra.test.ts +0 -155
  327. package/src/__tests__/extend-exceptions.test.ts +0 -149
  328. package/src/__tests__/interceptor.test.ts +0 -89
  329. package/src/__tests__/performance-analyzer.test.ts +0 -499
  330. package/src/__tests__/performance-collector.test.ts +0 -276
  331. package/src/__tests__/presets.test.ts +0 -65
  332. package/src/core/constraints/__tests__/interceptor.test.ts +0 -267
  333. package/src/core/constraints/interceptor.ts +0 -217
  334. package/src/dashboard/CONTEXT.md +0 -21
  335. package/src/dashboard/__tests__/data.test.ts +0 -111
  336. package/src/dashboard/__tests__/stats.test.ts +0 -159
  337. package/src/dashboard/data.ts +0 -103
  338. package/src/dashboard/index.ts +0 -3
  339. package/src/dashboard/stats.ts +0 -127
  340. package/src/dashboard/types.ts +0 -130
  341. package/src/monitoring/__tests__/knowledge-doctor.test.ts +0 -278
  342. package/src/monitoring/__tests__/knowledge-evolver.test.ts +0 -368
  343. package/src/monitoring/__tests__/performance-analyzer.test.ts +0 -137
  344. package/src/monitoring/__tests__/performance-collector.test.ts +0 -331
  345. package/src/monitoring/constraint-doctor.ts +0 -228
  346. package/src/monitoring/diagnosis-rules.ts +0 -132
  347. package/src/monitoring/knowledge-doctor.ts +0 -322
  348. package/src/monitoring/knowledge-evolver.ts +0 -289
  349. package/src/monitoring/performance-analyzer.ts +0 -400
  350. package/src/monitoring/performance-collector.ts +0 -326
  351. package/src/safety/CONTEXT.md +0 -23
  352. package/src/safety/__tests__/input-guardrail.test.ts +0 -105
  353. package/src/safety/__tests__/output-guardrail.test.ts +0 -108
  354. package/src/safety/__tests__/sandbox.test.ts +0 -158
  355. package/src/safety/__tests__/tool-guardrail.test.ts +0 -127
  356. package/src/safety/index.ts +0 -5
  357. package/src/safety/input-guardrail.ts +0 -133
  358. package/src/safety/output-guardrail.ts +0 -170
  359. package/src/safety/sandbox.ts +0 -148
  360. package/src/safety/tool-guardrail.ts +0 -176
  361. package/src/safety/types.ts +0 -124
  362. package/src/spec/__tests__/annotation-checker.test.ts +0 -294
  363. package/src/spec/annotation-checker.ts +0 -320
  364. package/src/types/enforcement.ts +0 -48
  365. package/src/types/monitoring-types.ts +0 -68
  366. package/src/types/performance.ts +0 -295
  367. package/src/verification/CONTEXT.md +0 -23
  368. package/src/verification/__tests__/loop.test.ts +0 -303
  369. package/src/verification/__tests__/rules-based.test.ts +0 -240
  370. package/src/verification/index.ts +0 -3
  371. package/src/verification/loop.ts +0 -137
  372. package/src/verification/rules-based.ts +0 -152
  373. package/src/verification/types.ts +0 -81
@@ -0,0 +1,138 @@
1
+ /**
2
+ * 公共导出防回归(ADR-0003)
3
+ *
4
+ * 包根导出收敛为显式清单后,任何增删公共符号都必须显式评审:
5
+ * 改动 src/index.ts 导出清单时同步更新本文件的 EXPECTED_RUNTIME_EXPORTS,
6
+ * diff 即 PR 评审材料。
7
+ *
8
+ * 注意:Object.keys 只能看到运行时(值)导出;纯类型导出由
9
+ * src/index.ts 显式清单在编译期把关,不在本测试断言范围内。
10
+ */
11
+
12
+ const EXPECTED_RUNTIME_EXPORTS = [
13
+ 'AdaptiveTokenBudget',
14
+ 'AgentLifecycle',
15
+ 'CONSTRAINTS_END_MARKER',
16
+ 'CONSTRAINTS_START_MARKER',
17
+ 'CSOValidator',
18
+ 'CheckCache',
19
+ 'CheckpointValidator',
20
+ 'CleanStateManager',
21
+ 'ColdStartImporter',
22
+ 'CommandGate',
23
+ 'ConstraintViolationError',
24
+ 'ConstraintViolationHandler',
25
+ 'ContextTracker',
26
+ 'ContractGate',
27
+ 'DEFAULT_CLASSIFICATION_RULES',
28
+ 'DEFAULT_CODE_CHECKPOINTS',
29
+ 'DEFAULT_COMMAND_BLACKLIST',
30
+ 'DEFAULT_COMPACTION_CONFIG',
31
+ 'DEFAULT_DECAY_CONFIG',
32
+ 'DEFAULT_LEVEL_MAPPING',
33
+ 'DEFAULT_NONCODE_GLOBS',
34
+ 'DEFAULT_TEST_GLOBS',
35
+ 'DEFAULT_TRACE_FILE',
36
+ 'ErrorClassifier',
37
+ 'ErrorType',
38
+ 'FailureLevel',
39
+ 'FailureRecorder',
40
+ 'FileKnowledgeStore',
41
+ 'GATE_DEFINITIONS',
42
+ 'GUIDELINES',
43
+ 'HookPipeline',
44
+ 'HookRegistry',
45
+ 'IRON_LAWS',
46
+ 'KnowledgeAudit',
47
+ 'KnowledgeHealthScorer',
48
+ 'KnowledgeIngest',
49
+ 'KnowledgeInjector',
50
+ 'KnowledgeLifecycle',
51
+ 'KnowledgeLifecycleHooks',
52
+ 'KnowledgeLinter',
53
+ 'KnowledgeQuery',
54
+ 'MINIMAL_CHECKPOINTS',
55
+ 'PHASE_SUBJECT_RE',
56
+ 'PROMPTS',
57
+ 'PassesGate',
58
+ 'PerformanceGate',
59
+ 'ReferenceTracker',
60
+ 'ReviewGate',
61
+ 'SecurityGate',
62
+ 'SessionCompaction',
63
+ 'SessionManager',
64
+ 'SessionStartup',
65
+ 'SpecAcceptanceGate',
66
+ 'SpecValidator',
67
+ 'TESTED_BY_RE',
68
+ 'TESTS_NONE_RE',
69
+ 'TokenBudget',
70
+ 'TokenEstimator',
71
+ 'TraceAnalyzer',
72
+ 'TraceCollector',
73
+ 'assertGateRegistryClosed',
74
+ 'assertHookRegistryClosed',
75
+ 'bootstrapHarness',
76
+ 'bootstrapHarnessSync',
77
+ 'checkBeforeExecution',
78
+ 'checkConstraint',
79
+ 'checkConstraints',
80
+ 'classifyCommitFiles',
81
+ 'classifyError',
82
+ 'configureTraceCollector',
83
+ 'createAnalyzer',
84
+ 'createCheckerGate',
85
+ 'createCleanStateManager',
86
+ 'createCommandGate',
87
+ 'createContractGate',
88
+ 'createErrorClassifier',
89
+ 'createFailureRecorder',
90
+ 'createPassesGate',
91
+ 'createPerformanceGate',
92
+ 'createReviewGate',
93
+ 'createSecurityGate',
94
+ 'createSessionStartup',
95
+ 'createSpecAcceptanceGate',
96
+ 'decisionFromResult',
97
+ 'executeWithBlock',
98
+ 'executeWithCollect',
99
+ 'executeWithSafeBoolean',
100
+ 'extractCodeStructure',
101
+ 'findConstraintsByTrigger',
102
+ 'getAllConstraints',
103
+ 'getCommandGate',
104
+ 'getCommandRiskLevel',
105
+ 'getConstraint',
106
+ 'getEffectiveConstraints',
107
+ 'getEffectiveGates',
108
+ 'getFailureLevel',
109
+ 'getGate',
110
+ 'getRegistryPath',
111
+ 'getToolsDir',
112
+ 'getTraceCollector',
113
+ 'isCommandAllowed',
114
+ 'lintEffectiveConfig',
115
+ 'listRegisteredGates',
116
+ 'matchAnyGlob',
117
+ 'matchGlob',
118
+ 'migrateKnowledgeEntries',
119
+ 'registeredGateCount',
120
+ 'renderConstraintsByTrigger',
121
+ 'renderConstraintsSection',
122
+ 'resolveGlobs',
123
+ 'runGates',
124
+ 'sanitizeExternalContent',
125
+ 'toErrorStrategy',
126
+ 'validateAllSpecs',
127
+ 'validateSpec',
128
+ 'verifyContractPresence',
129
+ 'verifyPhaseFormat',
130
+ 'verifyTddChain',
131
+ ];
132
+
133
+ describe('公共导出清单(ADR-0003)', () => {
134
+ it('包根运行时导出键集合与显式清单一致', async () => {
135
+ const mod = await import('../index');
136
+ expect(Object.keys(mod).sort()).toEqual([...EXPECTED_RUNTIME_EXPORTS].sort());
137
+ });
138
+ });
@@ -65,22 +65,21 @@ describe('TraceAnalyzer - 补充覆盖', () => {
65
65
  describe('compareWithPrevious', () => {
66
66
  it('应该计算环比变化', () => {
67
67
  const current: any[] = [
68
- { constraintId: 'test', passRate: 0.8, failRate: 0.2, bypassRate: 0.1, level: 'iron_law' },
68
+ { constraintId: 'test', passRate: 0.8, failRate: 0.2, level: 'iron_law' },
69
69
  ];
70
70
  const previous: any[] = [
71
- { constraintId: 'test', passRate: 0.6, failRate: 0.4, bypassRate: 0.2, level: 'iron_law' },
71
+ { constraintId: 'test', passRate: 0.6, failRate: 0.4, level: 'iron_law' },
72
72
  ];
73
73
 
74
74
  const result = analyzer.compareWithPrevious(current, previous);
75
-
75
+
76
76
  expect(result[0]?.changeFromLastPeriod?.passRateDelta).toBeCloseTo(0.2);
77
77
  expect(result[0]?.changeFromLastPeriod?.failRateDelta).toBeCloseTo(-0.2);
78
- expect(result[0]?.changeFromLastPeriod?.bypassRateDelta).toBeCloseTo(-0.1);
79
78
  });
80
79
 
81
80
  it('无历史数据应该不设置变化', () => {
82
81
  const current: any[] = [
83
- { constraintId: 'new_test', passRate: 0.8, failRate: 0.2, bypassRate: 0.1, level: 'iron_law' },
82
+ { constraintId: 'new_test', passRate: 0.8, failRate: 0.2, level: 'iron_law' },
84
83
  ];
85
84
  const previous: any[] = [];
86
85
 
@@ -93,7 +92,7 @@ describe('TraceAnalyzer - 补充覆盖', () => {
93
92
  describe('saveSummary/loadSummary', () => {
94
93
  it('应该保存和加载汇总', () => {
95
94
  const summaries: any[] = [
96
- { constraintId: 'test', passRate: 0.8, failRate: 0.2, bypassRate: 0.1, level: 'iron_law', totalChecks: 10 },
95
+ { constraintId: 'test', passRate: 0.8, failRate: 0.2, level: 'iron_law', totalChecks: 10 },
97
96
  ];
98
97
 
99
98
  analyzer.saveSummary(summaries);
@@ -157,7 +156,6 @@ describe('TraceAnalyzer - 补充覆盖', () => {
157
156
  level: 'iron_law',
158
157
  passRate: 0.8,
159
158
  failRate: 0.2,
160
- bypassRate: 0.1,
161
159
  totalChecks: 100,
162
160
  recentTrend: 'stable',
163
161
  },
@@ -190,46 +188,6 @@ describe('TraceAnalyzer - 补充覆盖', () => {
190
188
  });
191
189
  });
192
190
 
193
- describe('findMostCommon', () => {
194
- it('应该找出最常见元素', () => {
195
- // 通过 bypassReasons 统计来触发
196
- const traces: ExecutionTrace[] = [
197
- { constraintId: 'common_test', level: 'iron_law', timestamp: 1000, result: 'pass' },
198
- { constraintId: 'common_test', level: 'iron_law', timestamp: 2000, result: 'pass', bypassReason: 'reason_a' },
199
- { constraintId: 'common_test', level: 'iron_law', timestamp: 3000, result: 'pass', bypassReason: 'reason_a' },
200
- { constraintId: 'common_test', level: 'iron_law', timestamp: 4000, result: 'pass', bypassReason: 'reason_b' },
201
- ];
202
-
203
- const summaries = analyzer.summarize(traces);
204
-
205
- // 验证汇总结果存在
206
- expect(summaries.length).toBeGreaterThan(0);
207
- });
208
-
209
- it('应该通过 exceptionApplied 触发 findMostCommon', () => {
210
- const traces: ExecutionTrace[] = [
211
- { constraintId: 'exc_test', level: 'guideline', timestamp: 1000, result: 'pass', exceptionApplied: 'simple_typo' },
212
- { constraintId: 'exc_test', level: 'guideline', timestamp: 2000, result: 'pass', exceptionApplied: 'simple_typo' },
213
- { constraintId: 'exc_test', level: 'guideline', timestamp: 3000, result: 'pass', exceptionApplied: 'config_error' },
214
- ];
215
-
216
- const summaries = analyzer.summarize(traces);
217
- const summary = summaries.find(s => s.constraintId === 'exc_test');
218
-
219
- expect(summary?.exceptionCount).toBe(3);
220
- expect(summary?.mostCommonException).toBe('simple_typo');
221
- });
222
-
223
- it('无 exception 时 mostCommonException 应该是 undefined', () => {
224
- const traces: ExecutionTrace[] = [
225
- { constraintId: 'no_exc', level: 'iron_law', timestamp: 1000, result: 'pass' },
226
- ];
227
-
228
- const summaries = analyzer.summarize(traces);
229
- expect(summaries[0]?.mostCommonException).toBeUndefined();
230
- });
231
- });
232
-
233
191
  describe('detectAnomalies - 更多异常类型', () => {
234
192
  it('应该检测 rising_fail_rate', () => {
235
193
  // 前半段全 fail,后半段全 pass → rising 趋势
@@ -253,44 +211,6 @@ describe('TraceAnalyzer - 补充覆盖', () => {
253
211
  const risingFail = anomalies.find(a => a.type === 'rising_fail_rate');
254
212
  expect(risingFail).toBeDefined();
255
213
  });
256
-
257
- it('应该检测 rising_bypass_rate', () => {
258
- // 前半段全 fail,后半段混合 pass+bypass → rising 趋势
259
- // bypassRate 需要 > 0.1,且 trend === 'rising'
260
- const traces: ExecutionTrace[] = [];
261
- for (let i = 0; i < 6; i++) {
262
- traces.push({ constraintId: 'rising_bypass', level: 'guideline', timestamp: 1000 + i * 100, result: 'fail' });
263
- }
264
- for (let i = 6; i < 14; i++) {
265
- // 后半段有 pass 也有 bypass,使 passRate 上升(rising),同时 bypassRate > 0.1
266
- traces.push({ constraintId: 'rising_bypass', level: 'guideline', timestamp: 1000 + i * 100, result: i % 2 === 0 ? 'pass' : 'bypassed' });
267
- }
268
-
269
- const summaries = analyzer.summarize(traces);
270
- const anomalies = analyzer.detectAnomalies(summaries);
271
-
272
- const risingBypass = anomalies.find(a => a.type === 'rising_bypass_rate');
273
- expect(risingBypass).toBeDefined();
274
- });
275
-
276
- it('应该检测 exception_overuse', () => {
277
- const traces: ExecutionTrace[] = [];
278
- for (let i = 0; i < 10; i++) {
279
- traces.push({
280
- constraintId: 'exc_overuse',
281
- level: 'guideline',
282
- timestamp: 1000 + i * 100,
283
- result: 'pass',
284
- exceptionApplied: i < 8 ? 'simple_typo' : undefined,
285
- });
286
- }
287
-
288
- const summaries = analyzer.summarize(traces);
289
- const anomalies = analyzer.detectAnomalies(summaries);
290
-
291
- const excOveruse = anomalies.find(a => a.type === 'exception_overuse');
292
- expect(excOveruse).toBeDefined();
293
- });
294
214
  });
295
215
 
296
216
  describe('createAnalyzer 工厂函数', () => {
@@ -300,7 +220,7 @@ describe('TraceAnalyzer - 补充覆盖', () => {
300
220
  });
301
221
 
302
222
  it('应该支持自定义配置', () => {
303
- const a = createAnalyzer({ thresholds: { bypassRate: 0.05 } });
223
+ const a = createAnalyzer({ thresholds: { failRate: 0.05 } });
304
224
  expect(a).toBeDefined();
305
225
  });
306
226
  });
@@ -75,11 +75,11 @@ describe('TraceAnalyzer', () => {
75
75
  });
76
76
 
77
77
  describe('detectAnomalies', () => {
78
- it('应该检测高绕过率异常', () => {
78
+ it('应该检测失败率异常', () => {
79
79
  const traces: ExecutionTrace[] = [
80
- { constraintId: 'test', level: 'guideline', timestamp: 1000, result: 'bypassed' },
81
- { constraintId: 'test', level: 'guideline', timestamp: 2000, result: 'bypassed' },
82
- { constraintId: 'test', level: 'guideline', timestamp: 3000, result: 'bypassed' },
80
+ { constraintId: 'test', level: 'guideline', timestamp: 1000, result: 'fail' },
81
+ { constraintId: 'test', level: 'guideline', timestamp: 2000, result: 'fail' },
82
+ { constraintId: 'test', level: 'guideline', timestamp: 3000, result: 'fail' },
83
83
  { constraintId: 'test', level: 'guideline', timestamp: 4000, result: 'pass' },
84
84
  ];
85
85
 
@@ -120,7 +120,6 @@ describe('TraceAnalyzer', () => {
120
120
  it('应该支持自定义阈值', () => {
121
121
  const customAnalyzer = new TraceAnalyzer(collector, {
122
122
  thresholds: {
123
- bypassRate: 0.1,
124
123
  failRate: 0.2,
125
124
  },
126
125
  });
@@ -104,17 +104,6 @@ describe('TraceCollector', () => {
104
104
  });
105
105
  });
106
106
 
107
- describe('recordBypass', () => {
108
- it('应该记录绕过 trace', () => {
109
- collector.recordBypass('no_bypass_checkpoint', 'iron_law', 'Emergency fix');
110
-
111
- const traces = collector.read();
112
- expect(traces.length).toBe(1);
113
- expect(traces[0].result).toBe('bypassed');
114
- expect(traces[0].bypassReason).toBe('Emergency fix');
115
- });
116
- });
117
-
118
107
  describe('read', () => {
119
108
  it('应该返回所有 traces', () => {
120
109
  collector.record({
@@ -57,7 +57,7 @@ describe('TraceCollector', () => {
57
57
  test('should filter traces by constraint ID', () => {
58
58
  collector.recordPass('constraint_a', 'iron_law');
59
59
  collector.recordFail('constraint_b', 'guideline');
60
- collector.recordBypass('constraint_a', 'iron_law', 'user reason');
60
+ collector.recordFail('constraint_a', 'iron_law');
61
61
 
62
62
  const traces = collector.read({ constraintId: 'constraint_a' });
63
63
  expect(traces.length).toBe(2);
@@ -226,7 +226,7 @@ describe('TraceAnalyzer', () => {
226
226
  constraintId: 'constraint_b',
227
227
  level: 'iron_law',
228
228
  timestamp: Date.now() - i * 60 * 1000,
229
- result: i < 3 ? 'pass' : 'bypassed',
229
+ result: i < 3 ? 'pass' : 'fail',
230
230
  });
231
231
  }
232
232
 
@@ -243,26 +243,7 @@ describe('TraceAnalyzer', () => {
243
243
 
244
244
  const summaryB = summaries.find(s => s.constraintId === 'constraint_b');
245
245
  expect(summaryB).toBeDefined();
246
- expect(summaryB!.bypassRate).toBeCloseTo(0.4, 1);
247
- });
248
-
249
- test('should detect high bypass rate anomaly', () => {
250
- // 记录高绕过率的 traces
251
- for (let i = 0; i < 10; i++) {
252
- collector.record({
253
- constraintId: 'problematic_constraint',
254
- level: 'guideline',
255
- timestamp: Date.now(),
256
- result: i < 3 ? 'pass' : 'bypassed', // 70% 绕过率
257
- });
258
- }
259
-
260
- const traces = collector.read();
261
- const summaries = analyzer.summarize(traces);
262
- const anomalies = analyzer.detectAnomalies(summaries);
263
-
264
- expect(anomalies.length).toBeGreaterThan(0);
265
- expect(anomalies.some(a => a.type === 'high_bypass_rate')).toBe(true);
246
+ expect(summaryB!.failRate).toBeCloseTo(0.4, 1);
266
247
  });
267
248
 
268
249
  test('should detect rising fail rate anomaly', () => {
@@ -10,9 +10,9 @@ H5(#44)起:
10
10
  ## 核心导出
11
11
  - `COMMAND_DEFINITIONS`(definitions.ts)— 全部非门禁命令定义(纯数据模块,禁止 import 命令实现)
12
12
  - 各命令文件:check / validate / passes-gate / init / report / status / spec / sync-docs / knowledge / sdd / failure / posteval-plan / release / analyze-sessions / update-user-model / constraints / doc-freshness-check / spec-baseline-check
13
- - 6 门禁命令实现在 `acceptance` / `command` / `contract` / `performance` / `review` / `security`(其 CLI 元数据在 `src/gates/definitions.ts`)
13
+ - 6 门禁命令实现在 `acceptance` / `command` / `contract` / `performance` / `review` / `security`(其 CLI 元数据在 `src/gates/definitions.ts`,形状同为 `CommandDefinition`,ADR-0007)
14
14
 
15
- `constraints` 下挂治理子命令:`constraints report`(使用统计 + 退役候选诊断 + 配置健康 + 注入漂移,`--export` 脱敏)、`constraints retire`(交互选择 + 人确认退役;带 id 直达需显式 `--yes`(#24 人确认闸门),无 `--yes` 报错 + 非零退出码且不落盘;内置落 config.yml retired 元数据,custom 落 custom-constraints.yml 条目 retired 段(#82 D6 一处真相)+ KnowledgeStore 沉淀 + CLAUDE.md 注入段同步)。
15
+ `constraints` 下挂治理子命令:`constraints report`(使用统计 + 退役候选诊断 + 配置健康 + 注入漂移,`--export` 脱敏)、`constraints retire`(交互选择 + 人确认退役;带 id 直达需显式 `--yes`(#24 人确认闸门),无 `--yes` 报错 + 非零退出码且不落盘;内置落 config.yml retired 元数据,custom 落 custom-constraints.yml 条目 retired 段(#82 D6 一处真相)+ KnowledgeStore 沉淀 + 治理注入段同步)。
16
16
 
17
17
  ## 依赖关系
18
18
  - 依赖 `src/core/constraints/` 约束引擎
@@ -30,5 +30,8 @@ H5(#44)起:
30
30
 
31
31
  ## 注意事项
32
32
  - 新增命令需同步更新 CLAUDE.md / CAPABILITIES.md / src/CONTEXT.md
33
+ - init 治理约束段写入落点(studio #302,ADR 2026-08-21 落点模型):新仓 → AGENTS.md `PRESERVE:governance` 段(sync-docs 重新生成时保留);旧模型仓(CLAUDE.md 已有 HARNESS_CONSTRAINTS 标记或 `## Governance Rules` 块)→ 续写 CLAUDE.md,幂等重跑不制造双份正本。治理段「在场守护」由 core 侧 governance_presence checker 承担(段缺失/为空时 check 报警)
34
+ - PRESERVE:governance 段内写入纪律:机器管理的只有 HARNESS_CONSTRAINTS 标记区间——有标记只换标记区间,无标记(纯手写段)在段尾追加注入段;段内其余手写内容(治理契约引言/流程/纪律等)必须原样保留(曾整段替换清空手写内容的回归,init-injection.test 有防回归用例)
35
+ - 注入段读取侧同一路由(studio #307):`resolveInjectionTarget`(core/constraints/injection-drift)按「CLAUDE.md 有标记优先,否则 AGENTS.md」定位注入段,`detectInjectionDrift` 与 `constraints retire` 的注入段同步共用;未注入 = 两处均无完整标记段
33
36
  - knowledge 命令包含 13 个子操作(list/search/import/decay/stats/upsert/sync-status/sync-rag/audit/snapshot/migrate/index/health)
34
- - 特殊路由(选项条件、子命令兜底、退出码处理)表达在定义表的 optionRoutes / subcommands / afterRun 字段,bin 是纯通用引擎、不含单命令知识
37
+ - 特殊路由(选项条件、子命令兜底、退出码处理、裸跑语义)表达在定义表的 optionRoutes / subcommands / subcommandStrict / bareRunsAction / afterRun 字段,bin 是纯通用引擎、不含单命令知识
@@ -34,13 +34,16 @@ jest.mock('../../../core/constraints/checker', () => ({
34
34
  },
35
35
  }));
36
36
 
37
- // Mock ProjectConfigLoader
38
- jest.mock('../../../core/project-config-loader', () => ({
39
- ProjectConfigLoader: jest.fn().mockImplementation(() => ({
40
- load: jest.fn(),
41
- hasCustomConfig: jest.fn().mockReturnValue(false),
42
- mergeConstraints: jest.fn().mockReturnValue({ custom: [], disabled: [] }),
43
- })),
37
+ // Mock effective-constraints(ADR-0001:check 经 getMergedConstraintsConfig 走生效集链路)
38
+ jest.mock('../../../core/effective-constraints', () => ({
39
+ getMergedConstraintsConfig: jest.fn().mockReturnValue({
40
+ ironLaws: {},
41
+ guidelines: {},
42
+ prompts: {},
43
+ custom: [],
44
+ disabled: [],
45
+ unknownIds: [],
46
+ }),
44
47
  }));
45
48
 
46
49
  // Mock chalk
@@ -5,7 +5,7 @@
5
5
  import { check, listLaws } from '../check';
6
6
  import * as fs from 'fs';
7
7
  import { constraintChecker } from '../../../core/constraints/checker';
8
- import { ProjectConfigLoader } from '../../../core/project-config-loader';
8
+ import { getMergedConstraintsConfig } from '../../../core/effective-constraints';
9
9
  import { execAsync } from '../../../utils/exec';
10
10
 
11
11
  // Mock fs
@@ -45,13 +45,16 @@ jest.mock('../../../core/constraints/checker', () => ({
45
45
  },
46
46
  }));
47
47
 
48
- // Mock ProjectConfigLoader
49
- jest.mock('../../../core/project-config-loader', () => ({
50
- ProjectConfigLoader: jest.fn().mockImplementation(() => ({
51
- load: jest.fn(),
52
- hasCustomConfig: jest.fn().mockReturnValue(false),
53
- mergeConstraints: jest.fn().mockReturnValue({ custom: [], disabled: [] }),
54
- })),
48
+ // Mock effective-constraints(ADR-0001:check 经 getMergedConstraintsConfig 走生效集链路)
49
+ jest.mock('../../../core/effective-constraints', () => ({
50
+ getMergedConstraintsConfig: jest.fn().mockReturnValue({
51
+ ironLaws: {},
52
+ guidelines: {},
53
+ prompts: {},
54
+ custom: [],
55
+ disabled: [],
56
+ unknownIds: [],
57
+ }),
55
58
  }));
56
59
 
57
60
  // Mock chalk
@@ -65,7 +68,7 @@ jest.mock('chalk', () => ({
65
68
 
66
69
  const mockFs = fs as jest.Mocked<typeof fs> & { readdirSync: jest.Mock };
67
70
  const mockChecker = constraintChecker as jest.Mocked<typeof constraintChecker>;
68
- const MockProjectConfigLoader = ProjectConfigLoader as jest.MockedClass<typeof ProjectConfigLoader>;
71
+ const mockGetMergedConfig = getMergedConstraintsConfig as jest.MockedFunction<typeof getMergedConstraintsConfig>;
69
72
  const mockExecAsync = execAsync as jest.MockedFunction<typeof execAsync>;
70
73
 
71
74
  describe('check command', () => {
@@ -73,6 +76,15 @@ describe('check command', () => {
73
76
 
74
77
  beforeEach(() => {
75
78
  jest.clearAllMocks();
79
+ // clearAllMocks 不清实现,显式恢复默认 merged config,避免用例间泄漏
80
+ mockGetMergedConfig.mockReturnValue({
81
+ ironLaws: {},
82
+ guidelines: {},
83
+ prompts: {},
84
+ custom: [],
85
+ disabled: [],
86
+ unknownIds: [],
87
+ });
76
88
  consoleSpy = jest.spyOn(console, 'log').mockImplementation();
77
89
  process.exitCode = 0;
78
90
  });
@@ -123,12 +135,14 @@ describe('check command', () => {
123
135
  });
124
136
 
125
137
  it('应该加载自定义约束', async () => {
126
- const mockLoader = {
127
- load: jest.fn(),
128
- hasCustomConfig: jest.fn().mockReturnValue(true),
129
- mergeConstraints: jest.fn().mockReturnValue({ custom: [{ id: 'custom', rule: 'test', message: 'test', level: 'iron_law', trigger: 'code_implementation', enforcement: 'checkpoint-required' }], disabled: ['disabled_constraint'] }),
130
- };
131
- (MockProjectConfigLoader as any).mockImplementation(() => mockLoader);
138
+ mockGetMergedConfig.mockReturnValue({
139
+ ironLaws: {},
140
+ guidelines: {},
141
+ prompts: {},
142
+ custom: ['custom'],
143
+ disabled: ['disabled_constraint'],
144
+ unknownIds: [],
145
+ });
132
146
 
133
147
  mockChecker.checkConstraints.mockResolvedValue({
134
148
  passed: true,
@@ -399,23 +413,6 @@ describe('check command', () => {
399
413
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('记录已足够'));
400
414
  });
401
415
 
402
- it('应该在绕过率高时提示查看详情', async () => {
403
- // 20 条记录,15 条 bypassed (75% > 30%)
404
- const traces = [
405
- ...Array(5).fill('{"result":"pass"}'),
406
- ...Array(15).fill('{"result":"bypassed"}'),
407
- ].join('\n');
408
- mockFs.existsSync.mockImplementation((p: any) => {
409
- if (p.includes('traces.log')) return true;
410
- if (p.includes('.state.json')) return false;
411
- return false;
412
- });
413
- mockFs.readFileSync.mockReturnValue(traces);
414
-
415
- await check({ preset: 'default', staged: false });
416
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('异常趋势'));
417
- });
418
-
419
416
  it('应该不重复显示已显示的提示', async () => {
420
417
  const traces = Array(50).fill('{"result":"pass"}').join('\n');
421
418
  mockFs.existsSync.mockReturnValue(true);
@@ -445,43 +442,6 @@ describe('check command', () => {
445
442
  expect(output).not.toContain('────────────────');
446
443
  });
447
444
 
448
- it('应该在绕过率低于 30% 时不提示', async () => {
449
- // 20 条记录,2 条 bypassed (10% < 30%)
450
- const traces = [
451
- ...Array(18).fill('{"result":"pass"}'),
452
- ...Array(2).fill('{"result":"bypassed"}'),
453
- ].join('\n');
454
- mockFs.existsSync.mockImplementation((p: any) => {
455
- if (p.includes('traces.log')) return true;
456
- if (p.includes('.state.json')) return false;
457
- return false;
458
- });
459
- mockFs.readFileSync.mockReturnValue(traces);
460
-
461
- await check({ preset: 'default', staged: false });
462
- const output = consoleSpy.mock.calls.map(c => c[0]).join('\n');
463
- expect(output).not.toContain('异常趋势');
464
- });
465
-
466
- it('应该处理无效 JSON trace 行', async () => {
467
- // 20 条记录,部分无效 JSON,部分 bypassed
468
- const traces = [
469
- ...Array(5).fill('invalid json'),
470
- ...Array(5).fill('{"result":"pass"}'),
471
- ...Array(10).fill('{"result":"bypassed"}'),
472
- ].join('\n');
473
- mockFs.existsSync.mockImplementation((p: any) => {
474
- if (p.includes('traces.log')) return true;
475
- if (p.includes('.state.json')) return false;
476
- return false;
477
- });
478
- mockFs.readFileSync.mockReturnValue(traces);
479
-
480
- await check({ preset: 'default', staged: false });
481
- // 15 条有效,10 条 bypassed,bypassRate = 10/20 = 0.5 > 0.3
482
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('异常趋势'));
483
- });
484
-
485
445
  it('应该保存状态文件当有提示时', async () => {
486
446
  const traces = Array(50).fill('{"result":"pass"}').join('\n');
487
447
  mockFs.existsSync.mockImplementation((p: any) => {
@@ -57,14 +57,14 @@ describe('buildConstraintsUsageReport', () => {
57
57
  const report = buildConstraintsUsageReport(root);
58
58
 
59
59
  expect(report.traceFileExists).toBe(false);
60
- expect(report.stats.length).toBe(9); // 5 iron + 4 guideline
60
+ expect(report.stats.length).toBe(10); // 5 iron + 5 guideline
61
61
  for (const s of report.stats) {
62
62
  expect(s.total).toBe(0);
63
63
  expect(s.evaluated).toBe(0);
64
64
  expect(s.failRate).toBe(0);
65
65
  expect(s.firstAt).toBeUndefined();
66
66
  }
67
- expect(report.candidates.length).toBe(9);
67
+ expect(report.candidates.length).toBe(10);
68
68
  expect(report.candidates.every(c => c.kind === 'zero_trigger')).toBe(true);
69
69
  // prompt 注入清单(standard preset、无 scenes → 14 条通用 prompt)
70
70
  expect(report.activePromptIds.length).toBe(14);
@@ -170,7 +170,7 @@ describe('buildConstraintsUsageReport', () => {
170
170
  const candidates = diagnoseRetireCandidates([
171
171
  {
172
172
  id: 'x', level: 'guideline',
173
- total: 60, pass: 0, fail: 0, skip: 60, bypassed: 0,
173
+ total: 60, pass: 0, fail: 0, skip: 60,
174
174
  evaluated: 0, failRate: 0,
175
175
  },
176
176
  ]);