@dommaker/harness 1.1.0 → 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 (349) hide show
  1. package/CHANGELOG.md +19 -2
  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.d.ts.map +1 -1
  21. package/dist/cli/commands/status.js +2 -11
  22. package/dist/cli/commands/status.js.map +1 -1
  23. package/dist/context/index.d.ts +9 -6
  24. package/dist/context/index.d.ts.map +1 -1
  25. package/dist/context/index.js +18 -20
  26. package/dist/context/index.js.map +1 -1
  27. package/dist/core/constraints/capabilities-parser.d.ts +3 -2
  28. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  29. package/dist/core/constraints/capabilities-parser.js +25 -47
  30. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  31. package/dist/core/constraints/checker.d.ts +32 -33
  32. package/dist/core/constraints/checker.d.ts.map +1 -1
  33. package/dist/core/constraints/checker.js +38 -128
  34. package/dist/core/constraints/checker.js.map +1 -1
  35. package/dist/core/constraints/checkers/index.d.ts +2 -1
  36. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  37. package/dist/core/constraints/checkers/index.js +3 -0
  38. package/dist/core/constraints/checkers/index.js.map +1 -1
  39. package/dist/core/constraints/checkers/types.d.ts +25 -0
  40. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  41. package/dist/core/constraints/checkers/types.js +24 -0
  42. package/dist/core/constraints/checkers/types.js.map +1 -1
  43. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  44. package/dist/core/constraints/definitions/guidelines.js +0 -2
  45. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  46. package/dist/core/constraints/definitions/prompts.d.ts.map +1 -1
  47. package/dist/core/constraints/definitions/prompts.js +0 -5
  48. package/dist/core/constraints/definitions/prompts.js.map +1 -1
  49. package/dist/core/constraints/index.d.ts +1 -2
  50. package/dist/core/constraints/index.d.ts.map +1 -1
  51. package/dist/core/constraints/index.js +1 -7
  52. package/dist/core/constraints/index.js.map +1 -1
  53. package/dist/core/constraints/usage-report.d.ts +1 -2
  54. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  55. package/dist/core/constraints/usage-report.js +2 -5
  56. package/dist/core/constraints/usage-report.js.map +1 -1
  57. package/dist/core/effective-constraints.d.ts +24 -4
  58. package/dist/core/effective-constraints.d.ts.map +1 -1
  59. package/dist/core/effective-constraints.js +28 -7
  60. package/dist/core/effective-constraints.js.map +1 -1
  61. package/dist/core/effective-set.d.ts +30 -0
  62. package/dist/core/effective-set.d.ts.map +1 -0
  63. package/dist/core/effective-set.js +35 -0
  64. package/dist/core/effective-set.js.map +1 -0
  65. package/dist/core/index.d.ts +13 -6
  66. package/dist/core/index.d.ts.map +1 -1
  67. package/dist/core/index.js +44 -21
  68. package/dist/core/index.js.map +1 -1
  69. package/dist/core/project-config-loader.d.ts +3 -6
  70. package/dist/core/project-config-loader.d.ts.map +1 -1
  71. package/dist/core/project-config-loader.js +47 -61
  72. package/dist/core/project-config-loader.js.map +1 -1
  73. package/dist/failure/constraint-handler.d.ts +1 -1
  74. package/dist/failure/constraint-handler.js +1 -1
  75. package/dist/gates/checker-gate.d.ts +1 -4
  76. package/dist/gates/checker-gate.d.ts.map +1 -1
  77. package/dist/gates/checker-gate.js +3 -11
  78. package/dist/gates/checker-gate.js.map +1 -1
  79. package/dist/gates/definitions.d.ts +9 -38
  80. package/dist/gates/definitions.d.ts.map +1 -1
  81. package/dist/gates/definitions.js +24 -13
  82. package/dist/gates/definitions.js.map +1 -1
  83. package/dist/gates/effective-gates.d.ts.map +1 -1
  84. package/dist/gates/effective-gates.js +14 -18
  85. package/dist/gates/effective-gates.js.map +1 -1
  86. package/dist/gates/index.d.ts +1 -1
  87. package/dist/gates/index.d.ts.map +1 -1
  88. package/dist/gates/index.js.map +1 -1
  89. package/dist/hooks/bootstrap.d.ts.map +1 -1
  90. package/dist/hooks/bootstrap.js +0 -3
  91. package/dist/hooks/bootstrap.js.map +1 -1
  92. package/dist/index.d.ts +43 -53
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +180 -138
  95. package/dist/index.js.map +1 -1
  96. package/dist/knowledge/query.d.ts +15 -0
  97. package/dist/knowledge/query.d.ts.map +1 -1
  98. package/dist/knowledge/query.js +23 -0
  99. package/dist/knowledge/query.js.map +1 -1
  100. package/dist/monitoring/analyzer-base.d.ts +0 -4
  101. package/dist/monitoring/analyzer-base.d.ts.map +1 -1
  102. package/dist/monitoring/analyzer-base.js +0 -21
  103. package/dist/monitoring/analyzer-base.js.map +1 -1
  104. package/dist/monitoring/index.d.ts +6 -12
  105. package/dist/monitoring/index.d.ts.map +1 -1
  106. package/dist/monitoring/index.js +13 -29
  107. package/dist/monitoring/index.js.map +1 -1
  108. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  109. package/dist/monitoring/trace-analyzer.js +2 -68
  110. package/dist/monitoring/trace-analyzer.js.map +1 -1
  111. package/dist/monitoring/traces.d.ts +2 -6
  112. package/dist/monitoring/traces.d.ts.map +1 -1
  113. package/dist/monitoring/traces.js +0 -14
  114. package/dist/monitoring/traces.js.map +1 -1
  115. package/dist/presets/index.d.ts +2 -2
  116. package/dist/presets/index.d.ts.map +1 -1
  117. package/dist/presets/index.js +3 -4
  118. package/dist/presets/index.js.map +1 -1
  119. package/dist/presets/standard.d.ts +10 -22
  120. package/dist/presets/standard.d.ts.map +1 -1
  121. package/dist/presets/standard.js +15 -75
  122. package/dist/presets/standard.js.map +1 -1
  123. package/dist/types/constraint.d.ts +1 -29
  124. package/dist/types/constraint.d.ts.map +1 -1
  125. package/dist/types/constraint.js +1 -1
  126. package/dist/types/constraint.js.map +1 -1
  127. package/dist/types/index.d.ts +0 -3
  128. package/dist/types/index.d.ts.map +1 -1
  129. package/dist/types/index.js +0 -4
  130. package/dist/types/index.js.map +1 -1
  131. package/dist/types/project-config.d.ts +4 -8
  132. package/dist/types/project-config.d.ts.map +1 -1
  133. package/dist/types/trace.d.ts +9 -22
  134. package/dist/types/trace.d.ts.map +1 -1
  135. package/package.json +2 -2
  136. package/src/CONTEXT.md +5 -7
  137. package/src/__tests__/checker-extra.test.ts +80 -139
  138. package/src/__tests__/checker.test.ts +0 -376
  139. package/src/__tests__/project-config-loader-extra.test.ts +42 -29
  140. package/src/__tests__/public-exports.test.ts +138 -0
  141. package/src/__tests__/trace-analyzer-extra.test.ts +6 -86
  142. package/src/__tests__/trace-analyzer.test.ts +4 -5
  143. package/src/__tests__/trace-collector.test.ts +0 -11
  144. package/src/__tests__/traces.test.ts +3 -22
  145. package/src/cli/commands/CONTEXT.md +2 -2
  146. package/src/cli/commands/__tests__/check-skip-output.test.ts +10 -7
  147. package/src/cli/commands/__tests__/check.test.ts +29 -69
  148. package/src/cli/commands/__tests__/constraints-report.test.ts +1 -1
  149. package/src/cli/commands/__tests__/knowledge.test.ts +90 -1
  150. package/src/cli/commands/__tests__/registry.test.ts +8 -6
  151. package/src/cli/commands/__tests__/status-extra.test.ts +6 -28
  152. package/src/cli/commands/__tests__/status.test.ts +6 -21
  153. package/src/cli/commands/check.ts +8 -34
  154. package/src/cli/commands/definitions.ts +2 -0
  155. package/src/cli/commands/init.ts +6 -37
  156. package/src/cli/commands/knowledge.ts +1 -16
  157. package/src/cli/commands/report.ts +0 -2
  158. package/src/cli/commands/status.ts +2 -12
  159. package/src/context/index.ts +29 -6
  160. package/src/core/CONTEXT.md +4 -3
  161. package/src/core/__tests__/effective-set.test.ts +80 -0
  162. package/src/core/constraints/capabilities-parser.ts +43 -49
  163. package/src/core/constraints/checker.ts +56 -147
  164. package/src/core/constraints/checkers/index.ts +2 -1
  165. package/src/core/constraints/checkers/types.ts +42 -0
  166. package/src/core/constraints/definitions/guidelines.ts +0 -2
  167. package/src/core/constraints/definitions/prompts.ts +0 -5
  168. package/src/core/constraints/index.ts +2 -17
  169. package/src/core/constraints/usage-report.ts +5 -8
  170. package/src/core/effective-constraints.ts +35 -7
  171. package/src/core/effective-set.ts +56 -0
  172. package/src/core/index.ts +80 -6
  173. package/src/core/project-config-loader.ts +53 -68
  174. package/src/failure/CONTEXT.md +1 -1
  175. package/src/failure/constraint-handler.ts +1 -1
  176. package/src/gates/CONTEXT.md +3 -3
  177. package/src/gates/checker-gate.ts +4 -12
  178. package/src/gates/definitions.ts +27 -50
  179. package/src/gates/effective-gates.ts +14 -21
  180. package/src/gates/index.ts +1 -1
  181. package/src/hooks/bootstrap.ts +0 -3
  182. package/src/index.ts +384 -137
  183. package/src/knowledge/CONTEXT.md +2 -2
  184. package/src/knowledge/__tests__/query.test.ts +64 -0
  185. package/src/knowledge/query.ts +28 -0
  186. package/src/monitoring/CONTEXT.md +7 -13
  187. package/src/monitoring/__tests__/traces.test.ts +0 -10
  188. package/src/monitoring/analyzer-base.ts +0 -22
  189. package/src/monitoring/index.ts +6 -12
  190. package/src/monitoring/trace-analyzer.ts +2 -73
  191. package/src/monitoring/traces.ts +2 -22
  192. package/src/presets/__tests__/standard.test.ts +48 -69
  193. package/src/presets/index.ts +3 -5
  194. package/src/presets/standard.ts +14 -79
  195. package/src/spec/CONTEXT.md +5 -13
  196. package/src/types/constraint.ts +1 -51
  197. package/src/types/index.ts +0 -12
  198. package/src/types/project-config.ts +4 -10
  199. package/src/types/trace.ts +9 -34
  200. package/dist/core/constraints/interceptor.d.ts +0 -38
  201. package/dist/core/constraints/interceptor.d.ts.map +0 -1
  202. package/dist/core/constraints/interceptor.js +0 -166
  203. package/dist/core/constraints/interceptor.js.map +0 -1
  204. package/dist/dashboard/data.d.ts +0 -31
  205. package/dist/dashboard/data.d.ts.map +0 -1
  206. package/dist/dashboard/data.js +0 -81
  207. package/dist/dashboard/data.js.map +0 -1
  208. package/dist/dashboard/index.d.ts +0 -4
  209. package/dist/dashboard/index.d.ts.map +0 -1
  210. package/dist/dashboard/index.js +0 -20
  211. package/dist/dashboard/index.js.map +0 -1
  212. package/dist/dashboard/stats.d.ts +0 -20
  213. package/dist/dashboard/stats.d.ts.map +0 -1
  214. package/dist/dashboard/stats.js +0 -115
  215. package/dist/dashboard/stats.js.map +0 -1
  216. package/dist/dashboard/types.d.ts +0 -110
  217. package/dist/dashboard/types.d.ts.map +0 -1
  218. package/dist/dashboard/types.js +0 -8
  219. package/dist/dashboard/types.js.map +0 -1
  220. package/dist/monitoring/constraint-doctor.d.ts +0 -82
  221. package/dist/monitoring/constraint-doctor.d.ts.map +0 -1
  222. package/dist/monitoring/constraint-doctor.js +0 -191
  223. package/dist/monitoring/constraint-doctor.js.map +0 -1
  224. package/dist/monitoring/diagnosis-rules.d.ts +0 -18
  225. package/dist/monitoring/diagnosis-rules.d.ts.map +0 -1
  226. package/dist/monitoring/diagnosis-rules.js +0 -119
  227. package/dist/monitoring/diagnosis-rules.js.map +0 -1
  228. package/dist/monitoring/knowledge-doctor.d.ts +0 -78
  229. package/dist/monitoring/knowledge-doctor.d.ts.map +0 -1
  230. package/dist/monitoring/knowledge-doctor.js +0 -266
  231. package/dist/monitoring/knowledge-doctor.js.map +0 -1
  232. package/dist/monitoring/knowledge-evolver.d.ts +0 -72
  233. package/dist/monitoring/knowledge-evolver.d.ts.map +0 -1
  234. package/dist/monitoring/knowledge-evolver.js +0 -205
  235. package/dist/monitoring/knowledge-evolver.js.map +0 -1
  236. package/dist/monitoring/performance-analyzer.d.ts +0 -92
  237. package/dist/monitoring/performance-analyzer.d.ts.map +0 -1
  238. package/dist/monitoring/performance-analyzer.js +0 -343
  239. package/dist/monitoring/performance-analyzer.js.map +0 -1
  240. package/dist/monitoring/performance-collector.d.ts +0 -103
  241. package/dist/monitoring/performance-collector.d.ts.map +0 -1
  242. package/dist/monitoring/performance-collector.js +0 -298
  243. package/dist/monitoring/performance-collector.js.map +0 -1
  244. package/dist/safety/index.d.ts +0 -6
  245. package/dist/safety/index.d.ts.map +0 -1
  246. package/dist/safety/index.js +0 -22
  247. package/dist/safety/index.js.map +0 -1
  248. package/dist/safety/input-guardrail.d.ts +0 -36
  249. package/dist/safety/input-guardrail.d.ts.map +0 -1
  250. package/dist/safety/input-guardrail.js +0 -118
  251. package/dist/safety/input-guardrail.js.map +0 -1
  252. package/dist/safety/output-guardrail.d.ts +0 -39
  253. package/dist/safety/output-guardrail.d.ts.map +0 -1
  254. package/dist/safety/output-guardrail.js +0 -147
  255. package/dist/safety/output-guardrail.js.map +0 -1
  256. package/dist/safety/sandbox.d.ts +0 -45
  257. package/dist/safety/sandbox.d.ts.map +0 -1
  258. package/dist/safety/sandbox.js +0 -134
  259. package/dist/safety/sandbox.js.map +0 -1
  260. package/dist/safety/tool-guardrail.d.ts +0 -51
  261. package/dist/safety/tool-guardrail.d.ts.map +0 -1
  262. package/dist/safety/tool-guardrail.js +0 -147
  263. package/dist/safety/tool-guardrail.js.map +0 -1
  264. package/dist/safety/types.d.ts +0 -104
  265. package/dist/safety/types.d.ts.map +0 -1
  266. package/dist/safety/types.js +0 -6
  267. package/dist/safety/types.js.map +0 -1
  268. package/dist/spec/annotation-checker.d.ts +0 -47
  269. package/dist/spec/annotation-checker.d.ts.map +0 -1
  270. package/dist/spec/annotation-checker.js +0 -279
  271. package/dist/spec/annotation-checker.js.map +0 -1
  272. package/dist/types/enforcement.d.ts +0 -42
  273. package/dist/types/enforcement.d.ts.map +0 -1
  274. package/dist/types/enforcement.js +0 -6
  275. package/dist/types/enforcement.js.map +0 -1
  276. package/dist/types/monitoring-types.d.ts +0 -53
  277. package/dist/types/monitoring-types.d.ts.map +0 -1
  278. package/dist/types/monitoring-types.js +0 -10
  279. package/dist/types/monitoring-types.js.map +0 -1
  280. package/dist/types/performance.d.ts +0 -204
  281. package/dist/types/performance.d.ts.map +0 -1
  282. package/dist/types/performance.js +0 -12
  283. package/dist/types/performance.js.map +0 -1
  284. package/dist/verification/index.d.ts +0 -4
  285. package/dist/verification/index.d.ts.map +0 -1
  286. package/dist/verification/index.js +0 -20
  287. package/dist/verification/index.js.map +0 -1
  288. package/dist/verification/loop.d.ts +0 -30
  289. package/dist/verification/loop.d.ts.map +0 -1
  290. package/dist/verification/loop.js +0 -114
  291. package/dist/verification/loop.js.map +0 -1
  292. package/dist/verification/rules-based.d.ts +0 -40
  293. package/dist/verification/rules-based.d.ts.map +0 -1
  294. package/dist/verification/rules-based.js +0 -130
  295. package/dist/verification/rules-based.js.map +0 -1
  296. package/dist/verification/types.d.ts +0 -69
  297. package/dist/verification/types.d.ts.map +0 -1
  298. package/dist/verification/types.js +0 -6
  299. package/dist/verification/types.js.map +0 -1
  300. package/src/__tests__/annotation-checker.test.ts +0 -183
  301. package/src/__tests__/constraint-doctor.test.ts +0 -271
  302. package/src/__tests__/doctor-extra.test.ts +0 -155
  303. package/src/__tests__/extend-exceptions.test.ts +0 -149
  304. package/src/__tests__/interceptor.test.ts +0 -89
  305. package/src/__tests__/performance-analyzer.test.ts +0 -499
  306. package/src/__tests__/performance-collector.test.ts +0 -276
  307. package/src/__tests__/presets.test.ts +0 -65
  308. package/src/core/constraints/__tests__/interceptor.test.ts +0 -253
  309. package/src/core/constraints/interceptor.ts +0 -214
  310. package/src/dashboard/CONTEXT.md +0 -21
  311. package/src/dashboard/__tests__/data.test.ts +0 -111
  312. package/src/dashboard/__tests__/stats.test.ts +0 -159
  313. package/src/dashboard/data.ts +0 -103
  314. package/src/dashboard/index.ts +0 -3
  315. package/src/dashboard/stats.ts +0 -127
  316. package/src/dashboard/types.ts +0 -130
  317. package/src/monitoring/__tests__/knowledge-doctor.test.ts +0 -278
  318. package/src/monitoring/__tests__/knowledge-evolver.test.ts +0 -368
  319. package/src/monitoring/__tests__/performance-analyzer.test.ts +0 -137
  320. package/src/monitoring/__tests__/performance-collector.test.ts +0 -331
  321. package/src/monitoring/constraint-doctor.ts +0 -239
  322. package/src/monitoring/diagnosis-rules.ts +0 -132
  323. package/src/monitoring/knowledge-doctor.ts +0 -322
  324. package/src/monitoring/knowledge-evolver.ts +0 -289
  325. package/src/monitoring/performance-analyzer.ts +0 -400
  326. package/src/monitoring/performance-collector.ts +0 -326
  327. package/src/safety/CONTEXT.md +0 -23
  328. package/src/safety/__tests__/input-guardrail.test.ts +0 -105
  329. package/src/safety/__tests__/output-guardrail.test.ts +0 -108
  330. package/src/safety/__tests__/sandbox.test.ts +0 -158
  331. package/src/safety/__tests__/tool-guardrail.test.ts +0 -127
  332. package/src/safety/index.ts +0 -5
  333. package/src/safety/input-guardrail.ts +0 -133
  334. package/src/safety/output-guardrail.ts +0 -170
  335. package/src/safety/sandbox.ts +0 -148
  336. package/src/safety/tool-guardrail.ts +0 -176
  337. package/src/safety/types.ts +0 -124
  338. package/src/spec/__tests__/annotation-checker.test.ts +0 -294
  339. package/src/spec/annotation-checker.ts +0 -320
  340. package/src/types/enforcement.ts +0 -48
  341. package/src/types/monitoring-types.ts +0 -68
  342. package/src/types/performance.ts +0 -295
  343. package/src/verification/CONTEXT.md +0 -23
  344. package/src/verification/__tests__/loop.test.ts +0 -303
  345. package/src/verification/__tests__/rules-based.test.ts +0 -240
  346. package/src/verification/index.ts +0 -3
  347. package/src/verification/loop.ts +0 -137
  348. package/src/verification/rules-based.ts +0 -152
  349. 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
- });