@dommaker/harness 1.1.1 → 1.2.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 (348) hide show
  1. package/CHANGELOG.md +10 -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 +7 -32
  7. package/dist/cli/commands/check.js.map +1 -1
  8. package/dist/cli/commands/definitions.d.ts +2 -0
  9. package/dist/cli/commands/definitions.d.ts.map +1 -1
  10. package/dist/cli/commands/definitions.js.map +1 -1
  11. package/dist/cli/commands/init.d.ts.map +1 -1
  12. package/dist/cli/commands/init.js +6 -37
  13. package/dist/cli/commands/init.js.map +1 -1
  14. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  15. package/dist/cli/commands/knowledge.js +1 -12
  16. package/dist/cli/commands/knowledge.js.map +1 -1
  17. package/dist/cli/commands/report.d.ts.map +1 -1
  18. package/dist/cli/commands/report.js +0 -2
  19. package/dist/cli/commands/report.js.map +1 -1
  20. package/dist/cli/commands/status.js +2 -2
  21. package/dist/cli/commands/status.js.map +1 -1
  22. package/dist/context/index.d.ts +9 -6
  23. package/dist/context/index.d.ts.map +1 -1
  24. package/dist/context/index.js +18 -20
  25. package/dist/context/index.js.map +1 -1
  26. package/dist/core/constraints/capabilities-parser.d.ts +3 -2
  27. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  28. package/dist/core/constraints/capabilities-parser.js +25 -47
  29. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  30. package/dist/core/constraints/checker.d.ts +29 -32
  31. package/dist/core/constraints/checker.d.ts.map +1 -1
  32. package/dist/core/constraints/checker.js +34 -126
  33. package/dist/core/constraints/checker.js.map +1 -1
  34. package/dist/core/constraints/checkers/index.d.ts +2 -1
  35. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  36. package/dist/core/constraints/checkers/index.js +3 -0
  37. package/dist/core/constraints/checkers/index.js.map +1 -1
  38. package/dist/core/constraints/checkers/types.d.ts +25 -0
  39. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  40. package/dist/core/constraints/checkers/types.js +24 -0
  41. package/dist/core/constraints/checkers/types.js.map +1 -1
  42. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  43. package/dist/core/constraints/definitions/guidelines.js +0 -2
  44. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  45. package/dist/core/constraints/definitions/prompts.d.ts.map +1 -1
  46. package/dist/core/constraints/definitions/prompts.js +0 -5
  47. package/dist/core/constraints/definitions/prompts.js.map +1 -1
  48. package/dist/core/constraints/index.d.ts +1 -2
  49. package/dist/core/constraints/index.d.ts.map +1 -1
  50. package/dist/core/constraints/index.js +1 -7
  51. package/dist/core/constraints/index.js.map +1 -1
  52. package/dist/core/constraints/usage-report.d.ts +1 -2
  53. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  54. package/dist/core/constraints/usage-report.js +2 -5
  55. package/dist/core/constraints/usage-report.js.map +1 -1
  56. package/dist/core/effective-constraints.d.ts +24 -4
  57. package/dist/core/effective-constraints.d.ts.map +1 -1
  58. package/dist/core/effective-constraints.js +28 -7
  59. package/dist/core/effective-constraints.js.map +1 -1
  60. package/dist/core/effective-set.d.ts +30 -0
  61. package/dist/core/effective-set.d.ts.map +1 -0
  62. package/dist/core/effective-set.js +35 -0
  63. package/dist/core/effective-set.js.map +1 -0
  64. package/dist/core/index.d.ts +13 -6
  65. package/dist/core/index.d.ts.map +1 -1
  66. package/dist/core/index.js +44 -21
  67. package/dist/core/index.js.map +1 -1
  68. package/dist/core/project-config-loader.d.ts +3 -6
  69. package/dist/core/project-config-loader.d.ts.map +1 -1
  70. package/dist/core/project-config-loader.js +47 -61
  71. package/dist/core/project-config-loader.js.map +1 -1
  72. package/dist/failure/constraint-handler.d.ts +1 -1
  73. package/dist/failure/constraint-handler.js +1 -1
  74. package/dist/gates/checker-gate.d.ts +1 -4
  75. package/dist/gates/checker-gate.d.ts.map +1 -1
  76. package/dist/gates/checker-gate.js +3 -11
  77. package/dist/gates/checker-gate.js.map +1 -1
  78. package/dist/gates/definitions.d.ts +9 -38
  79. package/dist/gates/definitions.d.ts.map +1 -1
  80. package/dist/gates/definitions.js +24 -13
  81. package/dist/gates/definitions.js.map +1 -1
  82. package/dist/gates/effective-gates.d.ts.map +1 -1
  83. package/dist/gates/effective-gates.js +14 -18
  84. package/dist/gates/effective-gates.js.map +1 -1
  85. package/dist/gates/index.d.ts +1 -1
  86. package/dist/gates/index.d.ts.map +1 -1
  87. package/dist/gates/index.js.map +1 -1
  88. package/dist/hooks/bootstrap.d.ts.map +1 -1
  89. package/dist/hooks/bootstrap.js +0 -3
  90. package/dist/hooks/bootstrap.js.map +1 -1
  91. package/dist/index.d.ts +43 -60
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +180 -143
  94. package/dist/index.js.map +1 -1
  95. package/dist/knowledge/query.d.ts +15 -0
  96. package/dist/knowledge/query.d.ts.map +1 -1
  97. package/dist/knowledge/query.js +23 -0
  98. package/dist/knowledge/query.js.map +1 -1
  99. package/dist/monitoring/analyzer-base.d.ts +0 -4
  100. package/dist/monitoring/analyzer-base.d.ts.map +1 -1
  101. package/dist/monitoring/analyzer-base.js +0 -21
  102. package/dist/monitoring/analyzer-base.js.map +1 -1
  103. package/dist/monitoring/index.d.ts +6 -12
  104. package/dist/monitoring/index.d.ts.map +1 -1
  105. package/dist/monitoring/index.js +13 -29
  106. package/dist/monitoring/index.js.map +1 -1
  107. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  108. package/dist/monitoring/trace-analyzer.js +2 -68
  109. package/dist/monitoring/trace-analyzer.js.map +1 -1
  110. package/dist/monitoring/traces.d.ts +0 -4
  111. package/dist/monitoring/traces.d.ts.map +1 -1
  112. package/dist/monitoring/traces.js +0 -14
  113. package/dist/monitoring/traces.js.map +1 -1
  114. package/dist/presets/index.d.ts +2 -2
  115. package/dist/presets/index.d.ts.map +1 -1
  116. package/dist/presets/index.js +3 -4
  117. package/dist/presets/index.js.map +1 -1
  118. package/dist/presets/standard.d.ts +10 -22
  119. package/dist/presets/standard.d.ts.map +1 -1
  120. package/dist/presets/standard.js +15 -75
  121. package/dist/presets/standard.js.map +1 -1
  122. package/dist/types/constraint.d.ts +1 -29
  123. package/dist/types/constraint.d.ts.map +1 -1
  124. package/dist/types/constraint.js +1 -1
  125. package/dist/types/constraint.js.map +1 -1
  126. package/dist/types/index.d.ts +0 -3
  127. package/dist/types/index.d.ts.map +1 -1
  128. package/dist/types/index.js +0 -4
  129. package/dist/types/index.js.map +1 -1
  130. package/dist/types/project-config.d.ts +4 -8
  131. package/dist/types/project-config.d.ts.map +1 -1
  132. package/dist/types/trace.d.ts +5 -18
  133. package/dist/types/trace.d.ts.map +1 -1
  134. package/package.json +2 -2
  135. package/src/CONTEXT.md +4 -5
  136. package/src/__tests__/checker-extra.test.ts +33 -139
  137. package/src/__tests__/checker.test.ts +0 -376
  138. package/src/__tests__/project-config-loader-extra.test.ts +42 -29
  139. package/src/__tests__/public-exports.test.ts +138 -0
  140. package/src/__tests__/trace-analyzer-extra.test.ts +6 -86
  141. package/src/__tests__/trace-analyzer.test.ts +4 -5
  142. package/src/__tests__/trace-collector.test.ts +0 -11
  143. package/src/__tests__/traces.test.ts +3 -22
  144. package/src/cli/commands/CONTEXT.md +2 -2
  145. package/src/cli/commands/__tests__/check-skip-output.test.ts +10 -7
  146. package/src/cli/commands/__tests__/check.test.ts +29 -69
  147. package/src/cli/commands/__tests__/constraints-report.test.ts +1 -1
  148. package/src/cli/commands/__tests__/knowledge.test.ts +90 -1
  149. package/src/cli/commands/__tests__/registry.test.ts +8 -6
  150. package/src/cli/commands/__tests__/status-extra.test.ts +6 -6
  151. package/src/cli/commands/__tests__/status.test.ts +6 -6
  152. package/src/cli/commands/check.ts +8 -34
  153. package/src/cli/commands/definitions.ts +2 -0
  154. package/src/cli/commands/init.ts +6 -37
  155. package/src/cli/commands/knowledge.ts +1 -16
  156. package/src/cli/commands/report.ts +0 -2
  157. package/src/cli/commands/status.ts +2 -2
  158. package/src/context/index.ts +29 -6
  159. package/src/core/CONTEXT.md +4 -3
  160. package/src/core/__tests__/effective-set.test.ts +80 -0
  161. package/src/core/constraints/capabilities-parser.ts +43 -49
  162. package/src/core/constraints/checker.ts +51 -145
  163. package/src/core/constraints/checkers/index.ts +2 -1
  164. package/src/core/constraints/checkers/types.ts +42 -0
  165. package/src/core/constraints/definitions/guidelines.ts +0 -2
  166. package/src/core/constraints/definitions/prompts.ts +0 -5
  167. package/src/core/constraints/index.ts +2 -17
  168. package/src/core/constraints/usage-report.ts +5 -8
  169. package/src/core/effective-constraints.ts +35 -7
  170. package/src/core/effective-set.ts +56 -0
  171. package/src/core/index.ts +80 -6
  172. package/src/core/project-config-loader.ts +53 -68
  173. package/src/failure/CONTEXT.md +1 -1
  174. package/src/failure/constraint-handler.ts +1 -1
  175. package/src/gates/CONTEXT.md +3 -3
  176. package/src/gates/checker-gate.ts +4 -12
  177. package/src/gates/definitions.ts +27 -50
  178. package/src/gates/effective-gates.ts +14 -21
  179. package/src/gates/index.ts +1 -1
  180. package/src/hooks/bootstrap.ts +0 -3
  181. package/src/index.ts +384 -148
  182. package/src/knowledge/CONTEXT.md +2 -2
  183. package/src/knowledge/__tests__/query.test.ts +64 -0
  184. package/src/knowledge/query.ts +28 -0
  185. package/src/monitoring/CONTEXT.md +7 -13
  186. package/src/monitoring/__tests__/traces.test.ts +0 -10
  187. package/src/monitoring/analyzer-base.ts +0 -22
  188. package/src/monitoring/index.ts +6 -12
  189. package/src/monitoring/trace-analyzer.ts +2 -73
  190. package/src/monitoring/traces.ts +0 -20
  191. package/src/presets/__tests__/standard.test.ts +48 -69
  192. package/src/presets/index.ts +3 -5
  193. package/src/presets/standard.ts +14 -79
  194. package/src/spec/CONTEXT.md +5 -13
  195. package/src/types/constraint.ts +1 -51
  196. package/src/types/index.ts +0 -12
  197. package/src/types/project-config.ts +4 -10
  198. package/src/types/trace.ts +5 -30
  199. package/dist/core/constraints/interceptor.d.ts +0 -39
  200. package/dist/core/constraints/interceptor.d.ts.map +0 -1
  201. package/dist/core/constraints/interceptor.js +0 -166
  202. package/dist/core/constraints/interceptor.js.map +0 -1
  203. package/dist/dashboard/data.d.ts +0 -31
  204. package/dist/dashboard/data.d.ts.map +0 -1
  205. package/dist/dashboard/data.js +0 -81
  206. package/dist/dashboard/data.js.map +0 -1
  207. package/dist/dashboard/index.d.ts +0 -4
  208. package/dist/dashboard/index.d.ts.map +0 -1
  209. package/dist/dashboard/index.js +0 -20
  210. package/dist/dashboard/index.js.map +0 -1
  211. package/dist/dashboard/stats.d.ts +0 -20
  212. package/dist/dashboard/stats.d.ts.map +0 -1
  213. package/dist/dashboard/stats.js +0 -115
  214. package/dist/dashboard/stats.js.map +0 -1
  215. package/dist/dashboard/types.d.ts +0 -110
  216. package/dist/dashboard/types.d.ts.map +0 -1
  217. package/dist/dashboard/types.js +0 -8
  218. package/dist/dashboard/types.js.map +0 -1
  219. package/dist/monitoring/constraint-doctor.d.ts +0 -76
  220. package/dist/monitoring/constraint-doctor.d.ts.map +0 -1
  221. package/dist/monitoring/constraint-doctor.js +0 -189
  222. package/dist/monitoring/constraint-doctor.js.map +0 -1
  223. package/dist/monitoring/diagnosis-rules.d.ts +0 -18
  224. package/dist/monitoring/diagnosis-rules.d.ts.map +0 -1
  225. package/dist/monitoring/diagnosis-rules.js +0 -119
  226. package/dist/monitoring/diagnosis-rules.js.map +0 -1
  227. package/dist/monitoring/knowledge-doctor.d.ts +0 -78
  228. package/dist/monitoring/knowledge-doctor.d.ts.map +0 -1
  229. package/dist/monitoring/knowledge-doctor.js +0 -266
  230. package/dist/monitoring/knowledge-doctor.js.map +0 -1
  231. package/dist/monitoring/knowledge-evolver.d.ts +0 -72
  232. package/dist/monitoring/knowledge-evolver.d.ts.map +0 -1
  233. package/dist/monitoring/knowledge-evolver.js +0 -205
  234. package/dist/monitoring/knowledge-evolver.js.map +0 -1
  235. package/dist/monitoring/performance-analyzer.d.ts +0 -92
  236. package/dist/monitoring/performance-analyzer.d.ts.map +0 -1
  237. package/dist/monitoring/performance-analyzer.js +0 -343
  238. package/dist/monitoring/performance-analyzer.js.map +0 -1
  239. package/dist/monitoring/performance-collector.d.ts +0 -103
  240. package/dist/monitoring/performance-collector.d.ts.map +0 -1
  241. package/dist/monitoring/performance-collector.js +0 -298
  242. package/dist/monitoring/performance-collector.js.map +0 -1
  243. package/dist/safety/index.d.ts +0 -6
  244. package/dist/safety/index.d.ts.map +0 -1
  245. package/dist/safety/index.js +0 -22
  246. package/dist/safety/index.js.map +0 -1
  247. package/dist/safety/input-guardrail.d.ts +0 -36
  248. package/dist/safety/input-guardrail.d.ts.map +0 -1
  249. package/dist/safety/input-guardrail.js +0 -118
  250. package/dist/safety/input-guardrail.js.map +0 -1
  251. package/dist/safety/output-guardrail.d.ts +0 -39
  252. package/dist/safety/output-guardrail.d.ts.map +0 -1
  253. package/dist/safety/output-guardrail.js +0 -147
  254. package/dist/safety/output-guardrail.js.map +0 -1
  255. package/dist/safety/sandbox.d.ts +0 -45
  256. package/dist/safety/sandbox.d.ts.map +0 -1
  257. package/dist/safety/sandbox.js +0 -134
  258. package/dist/safety/sandbox.js.map +0 -1
  259. package/dist/safety/tool-guardrail.d.ts +0 -51
  260. package/dist/safety/tool-guardrail.d.ts.map +0 -1
  261. package/dist/safety/tool-guardrail.js +0 -147
  262. package/dist/safety/tool-guardrail.js.map +0 -1
  263. package/dist/safety/types.d.ts +0 -104
  264. package/dist/safety/types.d.ts.map +0 -1
  265. package/dist/safety/types.js +0 -6
  266. package/dist/safety/types.js.map +0 -1
  267. package/dist/spec/annotation-checker.d.ts +0 -47
  268. package/dist/spec/annotation-checker.d.ts.map +0 -1
  269. package/dist/spec/annotation-checker.js +0 -279
  270. package/dist/spec/annotation-checker.js.map +0 -1
  271. package/dist/types/enforcement.d.ts +0 -42
  272. package/dist/types/enforcement.d.ts.map +0 -1
  273. package/dist/types/enforcement.js +0 -6
  274. package/dist/types/enforcement.js.map +0 -1
  275. package/dist/types/monitoring-types.d.ts +0 -53
  276. package/dist/types/monitoring-types.d.ts.map +0 -1
  277. package/dist/types/monitoring-types.js +0 -10
  278. package/dist/types/monitoring-types.js.map +0 -1
  279. package/dist/types/performance.d.ts +0 -204
  280. package/dist/types/performance.d.ts.map +0 -1
  281. package/dist/types/performance.js +0 -12
  282. package/dist/types/performance.js.map +0 -1
  283. package/dist/verification/index.d.ts +0 -4
  284. package/dist/verification/index.d.ts.map +0 -1
  285. package/dist/verification/index.js +0 -20
  286. package/dist/verification/index.js.map +0 -1
  287. package/dist/verification/loop.d.ts +0 -30
  288. package/dist/verification/loop.d.ts.map +0 -1
  289. package/dist/verification/loop.js +0 -114
  290. package/dist/verification/loop.js.map +0 -1
  291. package/dist/verification/rules-based.d.ts +0 -40
  292. package/dist/verification/rules-based.d.ts.map +0 -1
  293. package/dist/verification/rules-based.js +0 -130
  294. package/dist/verification/rules-based.js.map +0 -1
  295. package/dist/verification/types.d.ts +0 -69
  296. package/dist/verification/types.d.ts.map +0 -1
  297. package/dist/verification/types.js +0 -6
  298. package/dist/verification/types.js.map +0 -1
  299. package/src/__tests__/annotation-checker.test.ts +0 -183
  300. package/src/__tests__/constraint-doctor.test.ts +0 -271
  301. package/src/__tests__/doctor-extra.test.ts +0 -155
  302. package/src/__tests__/extend-exceptions.test.ts +0 -149
  303. package/src/__tests__/interceptor.test.ts +0 -89
  304. package/src/__tests__/performance-analyzer.test.ts +0 -499
  305. package/src/__tests__/performance-collector.test.ts +0 -276
  306. package/src/__tests__/presets.test.ts +0 -65
  307. package/src/core/constraints/__tests__/interceptor.test.ts +0 -267
  308. package/src/core/constraints/interceptor.ts +0 -217
  309. package/src/dashboard/CONTEXT.md +0 -21
  310. package/src/dashboard/__tests__/data.test.ts +0 -111
  311. package/src/dashboard/__tests__/stats.test.ts +0 -159
  312. package/src/dashboard/data.ts +0 -103
  313. package/src/dashboard/index.ts +0 -3
  314. package/src/dashboard/stats.ts +0 -127
  315. package/src/dashboard/types.ts +0 -130
  316. package/src/monitoring/__tests__/knowledge-doctor.test.ts +0 -278
  317. package/src/monitoring/__tests__/knowledge-evolver.test.ts +0 -368
  318. package/src/monitoring/__tests__/performance-analyzer.test.ts +0 -137
  319. package/src/monitoring/__tests__/performance-collector.test.ts +0 -331
  320. package/src/monitoring/constraint-doctor.ts +0 -228
  321. package/src/monitoring/diagnosis-rules.ts +0 -132
  322. package/src/monitoring/knowledge-doctor.ts +0 -322
  323. package/src/monitoring/knowledge-evolver.ts +0 -289
  324. package/src/monitoring/performance-analyzer.ts +0 -400
  325. package/src/monitoring/performance-collector.ts +0 -326
  326. package/src/safety/CONTEXT.md +0 -23
  327. package/src/safety/__tests__/input-guardrail.test.ts +0 -105
  328. package/src/safety/__tests__/output-guardrail.test.ts +0 -108
  329. package/src/safety/__tests__/sandbox.test.ts +0 -158
  330. package/src/safety/__tests__/tool-guardrail.test.ts +0 -127
  331. package/src/safety/index.ts +0 -5
  332. package/src/safety/input-guardrail.ts +0 -133
  333. package/src/safety/output-guardrail.ts +0 -170
  334. package/src/safety/sandbox.ts +0 -148
  335. package/src/safety/tool-guardrail.ts +0 -176
  336. package/src/safety/types.ts +0 -124
  337. package/src/spec/__tests__/annotation-checker.test.ts +0 -294
  338. package/src/spec/annotation-checker.ts +0 -320
  339. package/src/types/enforcement.ts +0 -48
  340. package/src/types/monitoring-types.ts +0 -68
  341. package/src/types/performance.ts +0 -295
  342. package/src/verification/CONTEXT.md +0 -23
  343. package/src/verification/__tests__/loop.test.ts +0 -303
  344. package/src/verification/__tests__/rules-based.test.ts +0 -240
  345. package/src/verification/index.ts +0 -3
  346. package/src/verification/loop.ts +0 -137
  347. package/src/verification/rules-based.ts +0 -152
  348. package/src/verification/types.ts +0 -81
@@ -1,368 +0,0 @@
1
- import { KnowledgeEvolver } from '../knowledge-evolver';
2
- import type { KnowledgeDiagnosis } from '../knowledge-doctor';
3
- import type { KnowledgeEntry } from '../../knowledge/types';
4
-
5
- function makeEntry(overrides: Partial<KnowledgeEntry> = {}): KnowledgeEntry {
6
- return {
7
- id: 'entry-1',
8
- type: 'guideline',
9
- title: 'Test Entry',
10
- content: 'content',
11
- maturity: 'draft',
12
- layer: 'team',
13
- created: '2025-01-01T00:00:00Z',
14
- lastReferenced: new Date().toISOString(),
15
- contributors: ['user-1'],
16
- projects: ['proj-1'],
17
- tags: ['test'],
18
- applicablePhases: ['implementation'],
19
- sourceReferences: [],
20
- referencedBy: ['ref-1'],
21
- executionResults: [],
22
- consumptionMode: 'reference',
23
- origin: 'agent',
24
- ...overrides,
25
- };
26
- }
27
-
28
- describe('KnowledgeEvolver', () => {
29
- describe('升级提案', () => {
30
- it('draft 有引用时提议升级为 verified', () => {
31
- const evolver = new KnowledgeEvolver();
32
- const entry = makeEntry({ maturity: 'draft', referencedBy: ['r1'] });
33
- const proposals = evolver.generateProposals([entry]);
34
- const promote = proposals.filter(p => p.action === 'promote');
35
- expect(promote).toHaveLength(1);
36
- expect(promote[0].targetMaturity).toBe('verified');
37
- expect(promote[0].risk).toBe('low');
38
- expect(promote[0].autoApprovable).toBe(true);
39
- });
40
-
41
- it('draft 无引用时不提议升级', () => {
42
- const evolver = new KnowledgeEvolver();
43
- const entry = makeEntry({ maturity: 'draft', referencedBy: [] });
44
- const proposals = evolver.generateProposals([entry]);
45
- expect(proposals.filter(p => p.action === 'promote')).toHaveLength(0);
46
- });
47
-
48
- it('verified 有足够项目验证时提议升级为 proven', () => {
49
- const evolver = new KnowledgeEvolver({ promoteThreshold: 2 });
50
- const entry = makeEntry({ maturity: 'verified', projects: ['p1', 'p2'] });
51
- const proposals = evolver.generateProposals([entry]);
52
- const promote = proposals.filter(p => p.action === 'promote');
53
- expect(promote).toHaveLength(1);
54
- expect(promote[0].targetMaturity).toBe('proven');
55
- });
56
-
57
- it('verified 项目数不足时不提议升级', () => {
58
- const evolver = new KnowledgeEvolver({ promoteThreshold: 5 });
59
- const entry = makeEntry({ maturity: 'verified', projects: ['p1'] });
60
- const proposals = evolver.generateProposals([entry]);
61
- expect(proposals.filter(p => p.action === 'promote')).toHaveLength(0);
62
- });
63
-
64
- it('proven 不会提议升级(已到顶)', () => {
65
- const evolver = new KnowledgeEvolver();
66
- const entry = makeEntry({ maturity: 'proven', referencedBy: ['r1', 'r2'], projects: ['p1', 'p2'] });
67
- const proposals = evolver.generateProposals([entry]);
68
- expect(proposals.filter(p => p.action === 'promote')).toHaveLength(0);
69
- });
70
- });
71
-
72
- describe('降级提案', () => {
73
- it('长期未引用的 verified 提议降级', () => {
74
- const evolver = new KnowledgeEvolver({ demoteDays: 30 });
75
- const entry = makeEntry({
76
- maturity: 'verified',
77
- lastReferenced: '2020-01-01T00:00:00Z',
78
- });
79
- const proposals = evolver.generateProposals([entry]);
80
- const demote = proposals.filter(p => p.action === 'demote');
81
- expect(demote).toHaveLength(1);
82
- expect(demote[0].targetMaturity).toBe('draft');
83
- });
84
-
85
- it('长期未引用的 proven 提议降级为 verified', () => {
86
- const evolver = new KnowledgeEvolver({ demoteDays: 30 });
87
- const entry = makeEntry({
88
- maturity: 'proven',
89
- lastReferenced: '2020-01-01T00:00:00Z',
90
- });
91
- const proposals = evolver.generateProposals([entry]);
92
- const demote = proposals.filter(p => p.action === 'demote');
93
- expect(demote).toHaveLength(1);
94
- expect(demote[0].targetMaturity).toBe('verified');
95
- });
96
-
97
- it('draft 不会提议降级(已到底)', () => {
98
- const evolver = new KnowledgeEvolver({ demoteDays: 1 });
99
- const entry = makeEntry({
100
- maturity: 'draft',
101
- lastReferenced: '2020-01-01T00:00:00Z',
102
- });
103
- const proposals = evolver.generateProposals([entry]);
104
- expect(proposals.filter(p => p.action === 'demote')).toHaveLength(0);
105
- });
106
-
107
- it('近期有引用的不提议降级', () => {
108
- const evolver = new KnowledgeEvolver({ demoteDays: 180 });
109
- const entry = makeEntry({ maturity: 'verified' });
110
- const proposals = evolver.generateProposals([entry]);
111
- expect(proposals.filter(p => p.action === 'demote')).toHaveLength(0);
112
- });
113
- });
114
-
115
- describe('archived 条目', () => {
116
- it('跳过 archived 条目', () => {
117
- const evolver = new KnowledgeEvolver();
118
- const entry = makeEntry({ maturity: 'archived' });
119
- const proposals = evolver.generateProposals([entry]);
120
- expect(proposals).toHaveLength(0);
121
- });
122
- });
123
-
124
- describe('矛盾诊断 → freeze 提案', () => {
125
- it('从矛盾诊断生成 freeze 提案', () => {
126
- const evolver = new KnowledgeEvolver();
127
- const entry = makeEntry({ id: 'e1', maturity: 'verified' });
128
- const diagnosis: KnowledgeDiagnosis = {
129
- id: 'd1',
130
- type: 'contradiction',
131
- severity: 'high',
132
- entryId: 'e1',
133
- title: 'Contradiction',
134
- description: 'Conflicting entries',
135
- rootCause: 'Same tag different maturity',
136
- impact: 'Confusion',
137
- recommendations: ['Freeze'],
138
- timestamp: new Date().toISOString(),
139
- };
140
- const proposals = evolver.generateProposals([entry], [diagnosis]);
141
- const freeze = proposals.filter(p => p.action === 'freeze');
142
- expect(freeze).toHaveLength(1);
143
- expect(freeze[0].risk).toBe('medium');
144
- expect(freeze[0].autoApprovable).toBe(false);
145
- });
146
-
147
- it('无 entryId 的矛盾诊断不生成提案', () => {
148
- const evolver = new KnowledgeEvolver();
149
- const diagnosis: KnowledgeDiagnosis = {
150
- id: 'd1',
151
- type: 'contradiction',
152
- severity: 'high',
153
- title: 'Contradiction',
154
- description: 'Conflicting entries',
155
- rootCause: 'Unknown',
156
- impact: 'Unknown',
157
- recommendations: [],
158
- timestamp: new Date().toISOString(),
159
- };
160
- const proposals = evolver.generateProposals([], [diagnosis]);
161
- expect(proposals).toHaveLength(0);
162
- });
163
- });
164
-
165
- describe('审核', () => {
166
- it('低风险自动通过提案自动批准', () => {
167
- const evolver = new KnowledgeEvolver();
168
- const entry = makeEntry({ maturity: 'draft', referencedBy: ['r1'] });
169
- const proposals = evolver.generateProposals([entry]);
170
- const result = evolver.review(proposals[0]);
171
- expect(result.approved).toBe(true);
172
- });
173
-
174
- it('proven 直接归档被拒绝', () => {
175
- const evolver = new KnowledgeEvolver();
176
- const proposal = {
177
- id: 'p1',
178
- entryId: 'e1',
179
- action: 'archive' as const,
180
- currentMaturity: 'proven' as const,
181
- targetMaturity: 'archived' as const,
182
- reason: 'test',
183
- evidence: [],
184
- risk: 'low' as const,
185
- autoApprovable: true,
186
- status: 'pending' as const,
187
- createdAt: new Date().toISOString(),
188
- };
189
- const result = evolver.review(proposal);
190
- expect(result.approved).toBe(false);
191
- expect(result.reason).toContain('proven');
192
- });
193
-
194
- it('高风险升级被拒绝', () => {
195
- const evolver = new KnowledgeEvolver();
196
- const proposal = {
197
- id: 'p1',
198
- entryId: 'e1',
199
- action: 'promote' as const,
200
- currentMaturity: 'draft' as const,
201
- targetMaturity: 'verified' as const,
202
- reason: 'test',
203
- evidence: [],
204
- risk: 'high' as const,
205
- autoApprovable: false,
206
- status: 'pending' as const,
207
- createdAt: new Date().toISOString(),
208
- };
209
- const result = evolver.review(proposal);
210
- expect(result.approved).toBe(false);
211
- expect(result.reason).toContain('高风险');
212
- });
213
-
214
- it('中等风险提案通过审核', () => {
215
- const evolver = new KnowledgeEvolver();
216
- const proposal = {
217
- id: 'p1',
218
- entryId: 'e1',
219
- action: 'freeze' as const,
220
- currentMaturity: 'verified' as const,
221
- targetMaturity: 'verified' as const,
222
- reason: 'test',
223
- evidence: [],
224
- risk: 'medium' as const,
225
- autoApprovable: false,
226
- status: 'pending' as const,
227
- createdAt: new Date().toISOString(),
228
- };
229
- const result = evolver.review(proposal);
230
- expect(result.approved).toBe(true);
231
- expect(result.reason).toBe('提案通过审核');
232
- });
233
- });
234
-
235
- describe('执行提案', () => {
236
- it('无 store 时返回 false', () => {
237
- const evolver = new KnowledgeEvolver();
238
- const proposal = {
239
- id: 'p1',
240
- entryId: 'e1',
241
- action: 'promote' as const,
242
- currentMaturity: 'draft' as const,
243
- targetMaturity: 'verified' as const,
244
- reason: 'test',
245
- evidence: [],
246
- risk: 'low' as const,
247
- autoApprovable: true,
248
- status: 'approved' as const,
249
- createdAt: new Date().toISOString(),
250
- };
251
- expect(evolver.implement(proposal)).toBe(false);
252
- });
253
-
254
- it('非 approved 状态返回 false', () => {
255
- const evolver = new KnowledgeEvolver();
256
- const proposal = {
257
- id: 'p1',
258
- entryId: 'e1',
259
- action: 'promote' as const,
260
- currentMaturity: 'draft' as const,
261
- targetMaturity: 'verified' as const,
262
- reason: 'test',
263
- evidence: [],
264
- risk: 'low' as const,
265
- autoApprovable: true,
266
- status: 'pending' as const,
267
- createdAt: new Date().toISOString(),
268
- };
269
- expect(evolver.implement(proposal)).toBe(false);
270
- });
271
-
272
- it('store 中不存在条目时返回 false', () => {
273
- const mockStore = { get: () => undefined, update: jest.fn() };
274
- const evolver = new KnowledgeEvolver({}, mockStore as any);
275
- const proposal = {
276
- id: 'p1', entryId: 'e1', action: 'promote' as const,
277
- currentMaturity: 'draft' as const, targetMaturity: 'verified' as const,
278
- reason: 'test', evidence: [], risk: 'low' as const,
279
- autoApprovable: true, status: 'approved' as const,
280
- createdAt: new Date().toISOString(),
281
- };
282
- expect(evolver.implement(proposal)).toBe(false);
283
- });
284
-
285
- it('archive 操作执行成功', () => {
286
- const mockStore = { get: () => makeEntry(), update: jest.fn() };
287
- const evolver = new KnowledgeEvolver({}, mockStore as any);
288
- const proposal = {
289
- id: 'p1', entryId: 'entry-1', action: 'archive' as const,
290
- currentMaturity: 'draft' as const, targetMaturity: 'archived' as const,
291
- reason: 'test', evidence: [], risk: 'low' as const,
292
- autoApprovable: true, status: 'approved' as const,
293
- createdAt: new Date().toISOString(),
294
- };
295
- expect(evolver.implement(proposal)).toBe(true);
296
- expect(mockStore.update).toHaveBeenCalledWith('entry-1', { maturity: 'archived' });
297
- expect(proposal.status).toBe('implemented');
298
- });
299
-
300
- it('freeze 操作不调用 update', () => {
301
- const mockStore = { get: () => makeEntry(), update: jest.fn() };
302
- const evolver = new KnowledgeEvolver({}, mockStore as any);
303
- const proposal = {
304
- id: 'p1', entryId: 'entry-1', action: 'freeze' as const,
305
- currentMaturity: 'verified' as const, targetMaturity: 'verified' as const,
306
- reason: 'test', evidence: [], risk: 'medium' as const,
307
- autoApprovable: false, status: 'approved' as const,
308
- createdAt: new Date().toISOString(),
309
- };
310
- expect(evolver.implement(proposal)).toBe(true);
311
- expect(mockStore.update).not.toHaveBeenCalled();
312
- expect(proposal.status).toBe('implemented');
313
- });
314
-
315
- it('未知 action 返回 false', () => {
316
- const mockStore = { get: () => makeEntry(), update: jest.fn() };
317
- const evolver = new KnowledgeEvolver({}, mockStore as any);
318
- const proposal = {
319
- id: 'p1', entryId: 'entry-1', action: 'merge' as const,
320
- currentMaturity: 'draft' as const, targetMaturity: 'verified' as const,
321
- reason: 'test', evidence: [], risk: 'low' as const,
322
- autoApprovable: true, status: 'approved' as const,
323
- createdAt: new Date().toISOString(),
324
- };
325
- expect(evolver.implement(proposal)).toBe(false);
326
- });
327
- });
328
-
329
- describe('批量处理', () => {
330
- it('processProposals 审核并生成报告', () => {
331
- const evolver = new KnowledgeEvolver();
332
- const entry = makeEntry({ maturity: 'draft', referencedBy: ['r1'] });
333
- const proposals = evolver.generateProposals([entry]);
334
- const report = evolver.processProposals(proposals);
335
- expect(report.proposals.length).toBeGreaterThan(0);
336
- expect(report.proposals[0].status).toBe('approved');
337
- expect(report.summary).toBeDefined();
338
- });
339
-
340
- it('processProposals 拒绝高风险提案', () => {
341
- const evolver = new KnowledgeEvolver();
342
- const proposal = {
343
- id: 'p1', entryId: 'e1', action: 'promote' as const,
344
- currentMaturity: 'draft' as const, targetMaturity: 'verified' as const,
345
- reason: 'test', evidence: [], risk: 'high' as const,
346
- autoApprovable: false, status: 'pending' as const,
347
- createdAt: new Date().toISOString(),
348
- };
349
- const report = evolver.processProposals([proposal]);
350
- expect(report.proposals[0].status).toBe('rejected');
351
- });
352
-
353
- it('autoImplement 模式自动执行低风险提案', () => {
354
- const mockStore = {
355
- get: (id: string) => makeEntry({ id, maturity: 'draft' }),
356
- update: jest.fn(),
357
- };
358
- const evolver = new KnowledgeEvolver({ autoImplement: true }, mockStore as any);
359
- const entry = makeEntry({ maturity: 'draft', referencedBy: ['r1'] });
360
- const proposals = evolver.generateProposals([entry]);
361
- const report = evolver.processProposals(proposals);
362
- const promote = report.proposals.find(p => p.action === 'promote');
363
- if (promote?.autoApprovable) {
364
- expect(promote.status).toBe('implemented');
365
- }
366
- });
367
- });
368
- });
@@ -1,137 +0,0 @@
1
- /**
2
- * PerformanceAnalyzer 测试
3
- */
4
-
5
- import { PerformanceAnalyzer } from '../performance-analyzer';
6
- import { PerformanceCollector } from '../performance-collector';
7
- import type { PerformanceTrace } from '../../types/performance';
8
-
9
- // Mock PerformanceCollector
10
- jest.mock('../performance-collector');
11
-
12
- // Mock fs
13
- jest.mock('fs', () => ({
14
- existsSync: jest.fn(),
15
- mkdirSync: jest.fn(),
16
- readFileSync: jest.fn(),
17
- writeFileSync: jest.fn(),
18
- }));
19
-
20
- const MockPerformanceCollector = PerformanceCollector as jest.MockedClass<typeof PerformanceCollector>;
21
-
22
- describe('PerformanceAnalyzer', () => {
23
- let analyzer: PerformanceAnalyzer;
24
- let mockCollector: PerformanceCollector;
25
-
26
- const mockTraces: PerformanceTrace[] = [
27
- { operation: 'test', timestamp: Date.now(), duration: 100, result: 'ok' },
28
- { operation: 'test', timestamp: Date.now() + 1000, duration: 200, result: 'ok' },
29
- { operation: 'test', timestamp: Date.now() + 2000, duration: 35000, result: 'exceeded', threshold: 30000 },
30
- { operation: 'test2', timestamp: Date.now(), duration: 500, result: 'ok' },
31
- ];
32
-
33
- beforeEach(() => {
34
- jest.clearAllMocks();
35
- mockCollector = new MockPerformanceCollector();
36
- analyzer = new PerformanceAnalyzer(mockCollector);
37
- });
38
-
39
- describe('constructor', () => {
40
- it('should create with default config', () => {
41
- expect(analyzer).toBeDefined();
42
- });
43
-
44
- it('should accept custom config', () => {
45
- const customAnalyzer = new PerformanceAnalyzer(mockCollector, {
46
- periodMs: 7200 * 1000,
47
- });
48
- expect(customAnalyzer).toBeDefined();
49
- });
50
- });
51
-
52
- describe('summarize()', () => {
53
- it('should group by operation', () => {
54
- const summaries = analyzer.summarize(mockTraces);
55
- expect(summaries.length).toBeGreaterThan(0);
56
- });
57
-
58
- it('should calculate total calls', () => {
59
- const summaries = analyzer.summarize(mockTraces);
60
- const testSummary = summaries.find(s => s.operation === 'test');
61
- expect(testSummary).toBeDefined();
62
- expect(testSummary!.totalCalls).toBe(3);
63
- });
64
-
65
- it('should calculate ok rate', () => {
66
- const summaries = analyzer.summarize(mockTraces);
67
- const testSummary = summaries.find(s => s.operation === 'test');
68
- expect(testSummary).toBeDefined();
69
- });
70
-
71
- it('should handle empty traces', () => {
72
- const summaries = analyzer.summarize([]);
73
- expect(summaries).toEqual([]);
74
- });
75
-
76
- it('should handle single trace', () => {
77
- const summaries = analyzer.summarize([
78
- { operation: 'single', timestamp: Date.now(), duration: 100, result: 'ok' },
79
- ]);
80
- expect(summaries.length).toBe(1);
81
- });
82
- });
83
-
84
- describe('detectAnomalies()', () => {
85
- it('should detect high exceeded rate', () => {
86
- const highExceededTraces: PerformanceTrace[] = [
87
- { operation: 'test', timestamp: Date.now(), duration: 35000, result: 'exceeded', threshold: 30000 },
88
- { operation: 'test', timestamp: Date.now() + 1000, duration: 40000, result: 'exceeded', threshold: 30000 },
89
- { operation: 'test', timestamp: Date.now() + 2000, duration: 100, result: 'ok' },
90
- ];
91
-
92
- const summaries = analyzer.summarize(highExceededTraces);
93
- const anomalies = analyzer.detectAnomalies(summaries);
94
- expect(anomalies.length).toBeGreaterThanOrEqual(0);
95
- });
96
-
97
- it('should return empty array for normal traces', () => {
98
- const normalTraces: PerformanceTrace[] = [
99
- { operation: 'test', timestamp: Date.now(), duration: 100, result: 'ok' },
100
- { operation: 'test', timestamp: Date.now() + 1000, duration: 150, result: 'ok' },
101
- ];
102
-
103
- const summaries = analyzer.summarize(normalTraces);
104
- const anomalies = analyzer.detectAnomalies(summaries);
105
- expect(Array.isArray(anomalies)).toBe(true);
106
- });
107
- });
108
-
109
- describe('compareWithPrevious()', () => {
110
- it('should compare two summaries', () => {
111
- const current = analyzer.summarize(mockTraces);
112
- const previous = [...current];
113
-
114
- const compared = analyzer.compareWithPrevious(current, previous);
115
- expect(Array.isArray(compared)).toBe(true);
116
- });
117
-
118
- it('should handle empty comparison', () => {
119
- const compared = analyzer.compareWithPrevious([], []);
120
- expect(compared).toEqual([]);
121
- });
122
- });
123
-
124
- describe('runHourlySummary()', () => {
125
- it('should run hourly summary', () => {
126
- // Verify method exists - actual execution depends on collector state
127
- expect(typeof analyzer.runHourlySummary).toBe('function');
128
- });
129
- });
130
-
131
- describe('runDailyAnomalyCheck()', () => {
132
- it('should have method', () => {
133
- // Verify method exists
134
- expect(typeof analyzer.runDailyAnomalyCheck).toBe('function');
135
- });
136
- });
137
- });