@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
@@ -1,276 +0,0 @@
1
- /**
2
- * PerformanceCollector 测试
3
- */
4
-
5
- import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
6
- import { PerformanceCollector } from '../monitoring/performance-collector';
7
- import * as fs from 'fs';
8
- import * as path from 'path';
9
-
10
- describe('PerformanceCollector', () => {
11
- const tempDir = path.join(process.cwd(), 'temp-test-perf');
12
- const logFile = path.join(tempDir, 'performance.log');
13
- let collector: PerformanceCollector;
14
-
15
- beforeAll(() => {
16
- fs.mkdirSync(tempDir, { recursive: true });
17
- });
18
-
19
- afterAll(() => {
20
- try {
21
- fs.rmSync(tempDir, { recursive: true, force: true });
22
- } catch {
23
- // ignore
24
- }
25
- });
26
-
27
- beforeEach(() => {
28
- fs.writeFileSync(logFile, '');
29
- collector = new PerformanceCollector({ logFile, enabled: true });
30
- });
31
-
32
- describe('record', () => {
33
- it('应该记录性能数据', () => {
34
- collector.record({
35
- operation: 'test_op',
36
- timestamp: Date.now(),
37
- duration: 100,
38
- result: 'ok',
39
- });
40
-
41
- const content = fs.readFileSync(logFile, 'utf-8');
42
- expect(content).toContain('test_op');
43
- expect(content).toContain('ok');
44
- });
45
-
46
- it('禁用时应该不记录', () => {
47
- const disabledCollector = new PerformanceCollector({
48
- logFile,
49
- enabled: false,
50
- });
51
-
52
- disabledCollector.record({
53
- operation: 'test',
54
- timestamp: Date.now(),
55
- duration: 100,
56
- result: 'ok',
57
- });
58
-
59
- const content = fs.readFileSync(logFile, 'utf-8');
60
- expect(content).toBe('');
61
- });
62
- });
63
-
64
- describe('recordOk', () => {
65
- it('应该记录正常执行', () => {
66
- collector.recordOk('extract', 150);
67
-
68
- const content = fs.readFileSync(logFile, 'utf-8');
69
- expect(content).toContain('extract');
70
- expect(content).toContain('150');
71
- expect(content).toContain('ok');
72
- });
73
-
74
- it('应该支持元数据', () => {
75
- collector.recordOk('extract', 150, { files: 10 });
76
-
77
- const content = fs.readFileSync(logFile, 'utf-8');
78
- expect(content).toContain('files');
79
- });
80
- });
81
-
82
- describe('recordExceeded', () => {
83
- it('应该记录超阈值执行', () => {
84
- collector.recordExceeded('invokeAgent', 35000, 30000);
85
-
86
- const content = fs.readFileSync(logFile, 'utf-8');
87
- expect(content).toContain('invokeAgent');
88
- expect(content).toContain('exceeded');
89
- expect(content).toContain('35000');
90
- });
91
- });
92
-
93
- describe('read', () => {
94
- it('应该读取性能数据', () => {
95
- collector.recordOk('op1', 100);
96
- collector.recordOk('op2', 200);
97
-
98
- const traces = collector.read();
99
- expect(traces.length).toBe(2);
100
- });
101
-
102
- it('空文件应该返回空数组', () => {
103
- fs.writeFileSync(logFile, '');
104
- const traces = collector.read();
105
- expect(traces).toEqual([]);
106
- });
107
- });
108
-
109
- describe('getStats', () => {
110
- it('应该返回统计信息', () => {
111
- collector.recordOk('op1', 100);
112
- collector.recordOk('op2', 200);
113
- collector.recordExceeded('op3', 500, 400);
114
-
115
- const stats = collector.getStats();
116
-
117
- expect(stats.totalRecords).toBe(3);
118
- });
119
-
120
- it('应该正确读取数据', () => {
121
- collector.recordOk('op1', 100);
122
- collector.recordOk('op2', 200);
123
-
124
- const traces = collector.read();
125
-
126
- expect(traces.length).toBe(2);
127
- });
128
-
129
- it('文件不存在时应该返回空统计', () => {
130
- fs.unlinkSync(logFile);
131
- const tmpFile = path.join(require('os').tmpdir(), 'harness-test-nonexistent', 'perf.log');
132
- const newCollector = new PerformanceCollector({ logFile: tmpFile });
133
-
134
- const stats = newCollector.getStats();
135
-
136
- expect(stats.fileExists).toBe(false);
137
- expect(stats.totalRecords).toBe(0);
138
- });
139
- });
140
-
141
- describe('recordError', () => {
142
- it('应该记录错误', () => {
143
- collector.recordError('failing-op', 100, 'Something went wrong');
144
-
145
- const content = fs.readFileSync(logFile, 'utf-8');
146
- expect(content).toContain('error');
147
- expect(content).toContain('Something went wrong');
148
- });
149
-
150
- it('应该支持 Error 对象', () => {
151
- collector.recordError('failing-op', 100, new Error('Test error'));
152
-
153
- const content = fs.readFileSync(logFile, 'utf-8');
154
- expect(content).toContain('Test error');
155
- });
156
-
157
- it('应该支持元数据', () => {
158
- collector.recordError('failing-op', 100, 'Error', { retryCount: 3 });
159
-
160
- const content = fs.readFileSync(logFile, 'utf-8');
161
- expect(content).toContain('retryCount');
162
- });
163
- });
164
-
165
- describe('readRecent', () => {
166
- it('应该读取最近 N 小时的数据', () => {
167
- collector.recordOk('recent-op', 100);
168
-
169
- const traces = collector.readRecent(1);
170
- expect(traces.length).toBe(1);
171
- });
172
- });
173
-
174
- describe('readByOperation', () => {
175
- it('应该过滤特定操作', () => {
176
- collector.recordOk('op1', 100);
177
- collector.recordOk('op2', 200);
178
- collector.recordOk('op1', 150);
179
-
180
- const traces = collector.readByOperation('op1');
181
- expect(traces.length).toBe(2);
182
- });
183
- });
184
-
185
- describe('过滤条件', () => {
186
- it('应该按时间范围过滤', () => {
187
- const now = Date.now();
188
- collector.record({ operation: 'old', timestamp: now - 100000, duration: 100, result: 'ok' });
189
- collector.record({ operation: 'new', timestamp: now, duration: 100, result: 'ok' });
190
-
191
- const traces = collector.read({
192
- timeRange: { start: now - 50000, end: now + 1000 },
193
- });
194
-
195
- expect(traces.length).toBe(1);
196
- expect(traces[0]?.operation).toBe('new');
197
- });
198
-
199
- it('应该按结果类型过滤', () => {
200
- collector.recordOk('ok-op', 100);
201
- collector.recordError('err-op', 200, 'error');
202
-
203
- const traces = collector.read({ result: 'error' });
204
- expect(traces.length).toBe(1);
205
- expect(traces[0]?.operation).toBe('err-op');
206
- });
207
-
208
- it('应该按项目路径过滤', () => {
209
- collector.record({ operation: 'op1', timestamp: Date.now(), duration: 100, result: 'ok', projectPath: '/project1' });
210
- collector.record({ operation: 'op2', timestamp: Date.now(), duration: 100, result: 'ok', projectPath: '/project2' });
211
-
212
- const traces = collector.read({ projectPath: '/project1' });
213
- expect(traces.length).toBe(1);
214
- });
215
-
216
- it('应该按会话 ID 过滤', () => {
217
- collector.record({ operation: 'op1', timestamp: Date.now(), duration: 100, result: 'ok', sessionId: 'session-1' });
218
- collector.record({ operation: 'op2', timestamp: Date.now(), duration: 100, result: 'ok', sessionId: 'session-2' });
219
-
220
- const traces = collector.read({ sessionId: 'session-1' });
221
- expect(traces.length).toBe(1);
222
- });
223
-
224
- it('应该按任务 ID 过滤', () => {
225
- collector.record({ operation: 'op1', timestamp: Date.now(), duration: 100, result: 'ok', taskId: 'task-1' });
226
- collector.record({ operation: 'op2', timestamp: Date.now(), duration: 100, result: 'ok', taskId: 'task-2' });
227
-
228
- const traces = collector.read({ taskId: 'task-1' });
229
- expect(traces.length).toBe(1);
230
- });
231
-
232
- it('应该按角色 ID 过滤', () => {
233
- collector.record({ operation: 'op1', timestamp: Date.now(), duration: 100, result: 'ok', roleId: 'role-1' });
234
- collector.record({ operation: 'op2', timestamp: Date.now(), duration: 100, result: 'ok', roleId: 'role-2' });
235
-
236
- const traces = collector.read({ roleId: 'role-1' });
237
- expect(traces.length).toBe(1);
238
- });
239
- });
240
-
241
- describe('cleanupOldFiles', () => {
242
- it('应该清理旧备份文件', () => {
243
- // 创建一些备份文件(模拟滚动)
244
- const backupFile = logFile.replace('.log', '-2026-01-01.log');
245
- fs.writeFileSync(backupFile, 'old data');
246
-
247
- // 由于文件是新建的,需要修改 mtime
248
- // 简单验证函数运行不崩溃
249
- const deleted = collector.cleanupOldFiles(0);
250
- expect(deleted).toBeGreaterThanOrEqual(0);
251
-
252
- // 清理备份文件
253
- try { fs.unlinkSync(backupFile); } catch {}
254
- });
255
-
256
- it('不存在目录时应该返回 0', () => {
257
- // 创建新的 collector,使用临时目录
258
- const nonexistentDir = path.join(process.cwd(), 'temp-nonexistent-perf');
259
- const nonexistentLogFile = path.join(nonexistentDir, 'perf.log');
260
- const newCollector = new PerformanceCollector({ logFile: nonexistentLogFile });
261
-
262
- const deleted = newCollector.cleanupOldFiles(30);
263
- expect(deleted).toBe(0);
264
- });
265
- });
266
-
267
- describe('文件滚动', () => {
268
- it('应该检查文件大小', () => {
269
- // 创建大文件触发滚动检查
270
- collector.recordOk('test', 100);
271
-
272
- // 文件应该存在
273
- expect(fs.existsSync(logFile)).toBe(true);
274
- });
275
- });
276
- });
@@ -1,65 +0,0 @@
1
- /**
2
- * presets 测试
3
- */
4
-
5
- import { describe, it, expect } from '@jest/globals';
6
- import { STRICT_PRESET, STANDARD_PRESET, RELAXED_PRESET, getPreset } from '../presets/standard';
7
-
8
- describe('Presets', () => {
9
- describe('STRICT_PRESET', () => {
10
- it('应该启用所有约束', () => {
11
- expect(STRICT_PRESET.name).toBe('strict');
12
- expect(STRICT_PRESET.ironLaws).toBeNull();
13
- expect(STRICT_PRESET.guidelines).toBeNull();
14
- expect(STRICT_PRESET.prompts).toBeNull();
15
- });
16
- });
17
-
18
- describe('STANDARD_PRESET', () => {
19
- it('应该启用所有约束', () => {
20
- expect(STANDARD_PRESET.name).toBe('standard');
21
- expect(STANDARD_PRESET.ironLaws).toBeNull();
22
- expect(STANDARD_PRESET.guidelines).toBeNull();
23
- expect(STANDARD_PRESET.prompts).toBeNull();
24
- });
25
- });
26
-
27
- describe('RELAXED_PRESET', () => {
28
- it('应该只启用核心约束', () => {
29
- expect(RELAXED_PRESET.name).toBe('relaxed');
30
- expect(RELAXED_PRESET.ironLaws).not.toBeNull();
31
- expect(RELAXED_PRESET.guidelines).not.toBeNull();
32
- expect(RELAXED_PRESET.prompts).toEqual([]);
33
- });
34
-
35
- it('应该包含 no_completion_without_verification', () => {
36
- expect(RELAXED_PRESET.ironLaws).toContain('no_completion_without_verification');
37
- });
38
-
39
- it('应该包含 no_bypass_checkpoint', () => {
40
- expect(RELAXED_PRESET.guidelines).toContain('no_bypass_checkpoint');
41
- });
42
- });
43
-
44
- describe('getPreset', () => {
45
- it('应该返回 strict 预设', () => {
46
- const preset = getPreset('strict');
47
- expect(preset.name).toBe('strict');
48
- });
49
-
50
- it('应该返回 standard 预设', () => {
51
- const preset = getPreset('standard');
52
- expect(preset.name).toBe('standard');
53
- });
54
-
55
- it('应该返回 relaxed 预设', () => {
56
- const preset = getPreset('relaxed');
57
- expect(preset.name).toBe('relaxed');
58
- });
59
-
60
- it('未知预设应该返回 standard', () => {
61
- const preset = getPreset('unknown');
62
- expect(preset.name).toBe('standard');
63
- });
64
- });
65
- });
@@ -1,267 +0,0 @@
1
- /**
2
- * ConstraintInterceptor 测试
3
- */
4
-
5
- import { ConstraintInterceptor } from '../interceptor';
6
- import { constraintChecker } from '../checker';
7
- import type { ConstraintContext } from '../../../types/constraint';
8
- import type { EnforcementExecutor } from '../../../types/enforcement';
9
-
10
- // Mock constraintChecker
11
- jest.mock('../checker', () => ({
12
- constraintChecker: {
13
- getConstraints: jest.fn(),
14
- check: jest.fn().mockResolvedValue({ satisfied: true }),
15
- },
16
- }));
17
-
18
- const mockChecker = constraintChecker as jest.Mocked<typeof constraintChecker>;
19
-
20
- describe('ConstraintInterceptor', () => {
21
- let interceptor: ConstraintInterceptor;
22
-
23
- const mockCheck = jest.fn().mockResolvedValue({ satisfied: true });
24
-
25
- const mockIronLaw = {
26
- id: 'test_iron_law',
27
- kind: 'check' as const,
28
- rule: 'Test Iron Law',
29
- message: 'Test iron law message',
30
- level: 'iron_law' as const,
31
- trigger: 'code_implementation',
32
- enforcement: 'test-enforcement',
33
- check: mockCheck,
34
- };
35
-
36
- const mockGuideline = {
37
- id: 'test_guideline',
38
- kind: 'check' as const,
39
- rule: 'Test Guideline',
40
- message: 'Test guideline message',
41
- level: 'guideline' as const,
42
- trigger: 'code_implementation',
43
- enforcement: 'guideline-enforcement',
44
- check: mockCheck,
45
- };
46
-
47
- const mockContext: ConstraintContext = {
48
- operation: 'code_implementation',
49
- projectPath: '/test',
50
- };
51
-
52
- const mockExecutor: EnforcementExecutor = {
53
- execute: jest.fn(),
54
- };
55
-
56
- beforeEach(() => {
57
- jest.clearAllMocks();
58
- // Use the singleton instance
59
- interceptor = ConstraintInterceptor.getInstance();
60
- // Clear any previous state
61
- interceptor.clearSkips();
62
- interceptor.setEnabled(true);
63
-
64
- mockChecker.getConstraints.mockReturnValue({
65
- ironLaws: { test_iron_law: mockIronLaw },
66
- guidelines: { test_guideline: mockGuideline },
67
- prompts: {},
68
- });
69
- });
70
-
71
- describe('getInstance', () => {
72
- it('should return singleton instance', () => {
73
- const instance1 = ConstraintInterceptor.getInstance();
74
- const instance2 = ConstraintInterceptor.getInstance();
75
- expect(instance1).toBe(instance2);
76
- });
77
- });
78
-
79
- describe('register', () => {
80
- it('should register executor', () => {
81
- interceptor.register('test-enforcement', mockExecutor);
82
- expect(interceptor.hasExecutor('test-enforcement')).toBe(true);
83
- });
84
- });
85
-
86
- describe('registerBatch', () => {
87
- it('should register multiple executors', () => {
88
- interceptor.registerBatch([
89
- { enforcementId: 'exec1', executor: mockExecutor },
90
- { enforcementId: 'exec2', executor: mockExecutor },
91
- ]);
92
- expect(interceptor.hasExecutor('exec1')).toBe(true);
93
- expect(interceptor.hasExecutor('exec2')).toBe(true);
94
- });
95
- });
96
-
97
- describe('unregister', () => {
98
- it('should unregister executor', () => {
99
- interceptor.register('test-enforcement', mockExecutor);
100
- const result = interceptor.unregister('test-enforcement');
101
- expect(result).toBe(true);
102
- expect(interceptor.hasExecutor('test-enforcement')).toBe(false);
103
- });
104
-
105
- it('should return false if not exists', () => {
106
- const result = interceptor.unregister('nonexistent');
107
- expect(result).toBe(false);
108
- });
109
- });
110
-
111
- describe('getExecutor', () => {
112
- it('should return registered executor', () => {
113
- interceptor.register('test-enforcement', mockExecutor);
114
- const executor = interceptor.getExecutor('test-enforcement');
115
- expect(executor).toBe(mockExecutor);
116
- });
117
-
118
- it('should return undefined if not registered', () => {
119
- const executor = interceptor.getExecutor('nonexistent');
120
- expect(executor).toBeUndefined();
121
- });
122
- });
123
-
124
- describe('getRegistrations', () => {
125
- it('should return all registrations', () => {
126
- interceptor.unregister('test-enforcement'); // Clear any existing
127
- interceptor.register('test-enforcement', mockExecutor);
128
- const registrations = interceptor.getRegistrations();
129
- const found = registrations.find(r => r.id === 'test-enforcement');
130
- expect(found).toBeDefined();
131
- });
132
- });
133
-
134
- describe('setEnabled', () => {
135
- it('should disable interceptor', () => {
136
- interceptor.setEnabled(false);
137
- interceptor.register('test-enforcement', mockExecutor);
138
-
139
- const result = interceptor.intercept('code_implementation', mockContext);
140
- // When disabled, should pass without checking
141
- expect(result).resolves.toHaveProperty('passed', true);
142
- });
143
- });
144
-
145
- describe('skip', () => {
146
- it('should skip specified enforcements', async () => {
147
- interceptor.register('test-enforcement', mockExecutor);
148
- interceptor.skip(['test-enforcement']);
149
-
150
- const result = await interceptor.intercept('code_implementation', mockContext);
151
- expect(result.constraints.some(c => c.skipped)).toBe(true);
152
- });
153
- });
154
-
155
- describe('clearSkips', () => {
156
- it('should clear all skips', async () => {
157
- interceptor.register('test-enforcement', mockExecutor);
158
- interceptor.skip(['test-enforcement']);
159
- interceptor.clearSkips();
160
-
161
- (mockExecutor.execute as jest.Mock).mockResolvedValue({ passed: true });
162
- await interceptor.intercept('code_implementation', mockContext);
163
- expect(mockExecutor.execute).toHaveBeenCalled();
164
- });
165
- });
166
-
167
- describe('intercept', () => {
168
- it('should pass when all constraints satisfied', async () => {
169
- interceptor.register('test-enforcement', mockExecutor);
170
- interceptor.register('guideline-enforcement', mockExecutor);
171
-
172
- (mockExecutor.execute as jest.Mock).mockResolvedValue({ passed: true });
173
-
174
- const result = await interceptor.intercept('code_implementation', mockContext);
175
- expect(result.passed).toBe(true);
176
- expect(result.violations.length).toBe(0);
177
- });
178
-
179
- it('should fail on iron law violation', async () => {
180
- interceptor.register('test-enforcement', mockExecutor);
181
- (mockExecutor.execute as jest.Mock).mockResolvedValue({ passed: false });
182
-
183
- await expect(interceptor.intercept('code_implementation', mockContext)).rejects.toThrow();
184
- });
185
-
186
- it('should record guideline violation without throwing', async () => {
187
- interceptor.register('test-enforcement', mockExecutor);
188
- interceptor.register('guideline-enforcement', mockExecutor);
189
-
190
- (mockExecutor.execute as jest.Mock)
191
- .mockResolvedValueOnce({ passed: true }) // iron law passes
192
- .mockResolvedValueOnce({ passed: false }); // guideline fails
193
-
194
- const result = await interceptor.intercept('code_implementation', mockContext);
195
- expect(result.passed).toBe(true); // guidelines don't block
196
- expect(result.violations.length).toBe(1);
197
- });
198
-
199
- it('should handle missing executor', async () => {
200
- // No constraints at all
201
- mockChecker.getConstraints.mockReturnValue({
202
- ironLaws: {},
203
- guidelines: {},
204
- prompts: {},
205
- });
206
-
207
- const result = await interceptor.intercept('code_implementation', mockContext);
208
- expect(result.passed).toBe(true);
209
- expect(result.constraints.length).toBe(0);
210
- });
211
-
212
- it('should handle executor error for iron law', async () => {
213
- interceptor.register('test-enforcement', mockExecutor);
214
- (mockExecutor.execute as jest.Mock).mockRejectedValue(new Error('Executor error'));
215
-
216
- await expect(interceptor.intercept('code_implementation', mockContext)).rejects.toThrow();
217
- });
218
-
219
- it('should forward customConfig to checker.getConstraints', async () => {
220
- interceptor.register('test-enforcement', mockExecutor);
221
- (mockExecutor.execute as jest.Mock).mockResolvedValue({ passed: true });
222
-
223
- const customConfig = {
224
- ironLaws: { test_iron_law: mockIronLaw },
225
- guidelines: {},
226
- prompts: {},
227
- } as any;
228
-
229
- await interceptor.intercept('code_implementation', mockContext, customConfig);
230
- expect(mockChecker.getConstraints).toHaveBeenCalledWith(customConfig);
231
- });
232
- });
233
-
234
- describe('claim', () => {
235
- it('should pass when constraints satisfied', async () => {
236
- interceptor.register('test-enforcement', mockExecutor);
237
- (mockExecutor.execute as jest.Mock).mockResolvedValue({ passed: true });
238
-
239
- await expect(interceptor.claim('code_implementation', mockContext)).resolves.not.toThrow();
240
- });
241
-
242
- it('should throw on violation', async () => {
243
- interceptor.register('test-enforcement', mockExecutor);
244
- (mockExecutor.execute as jest.Mock).mockResolvedValue({ passed: false });
245
-
246
- await expect(interceptor.claim('code_implementation', mockContext)).rejects.toThrow();
247
- });
248
- });
249
-
250
- describe('canProceed', () => {
251
- it('should return true when passed', async () => {
252
- interceptor.register('test-enforcement', mockExecutor);
253
- (mockExecutor.execute as jest.Mock).mockResolvedValue({ passed: true });
254
-
255
- const result = await interceptor.canProceed('code_implementation', mockContext);
256
- expect(result).toBe(true);
257
- });
258
-
259
- it('should return false on error', async () => {
260
- interceptor.register('test-enforcement', mockExecutor);
261
- (mockExecutor.execute as jest.Mock).mockRejectedValue(new Error('Error'));
262
-
263
- const result = await interceptor.canProceed('code_implementation', mockContext);
264
- expect(result).toBe(false);
265
- });
266
- });
267
- });