@dommaker/harness 1.7.0 → 1.8.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 (563) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/bin/harness.js +17 -1
  3. package/dist/agents/index.d.ts +6 -2
  4. package/dist/agents/index.d.ts.map +1 -1
  5. package/dist/agents/index.js +6 -16
  6. package/dist/agents/index.js.map +1 -1
  7. package/dist/cli/commands/__tests__/gate-decision.d.ts +18 -0
  8. package/dist/cli/commands/__tests__/gate-decision.d.ts.map +1 -0
  9. package/dist/cli/commands/__tests__/gate-decision.js +26 -0
  10. package/dist/cli/commands/__tests__/gate-decision.js.map +1 -0
  11. package/dist/cli/commands/acceptance.d.ts.map +1 -1
  12. package/dist/cli/commands/acceptance.js +17 -28
  13. package/dist/cli/commands/acceptance.js.map +1 -1
  14. package/dist/cli/commands/check.d.ts +19 -3
  15. package/dist/cli/commands/check.d.ts.map +1 -1
  16. package/dist/cli/commands/check.js +36 -22
  17. package/dist/cli/commands/check.js.map +1 -1
  18. package/dist/cli/commands/command.d.ts +0 -1
  19. package/dist/cli/commands/command.d.ts.map +1 -1
  20. package/dist/cli/commands/command.js +8 -6
  21. package/dist/cli/commands/command.js.map +1 -1
  22. package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
  23. package/dist/cli/commands/constraints-retire.js +36 -57
  24. package/dist/cli/commands/constraints-retire.js.map +1 -1
  25. package/dist/cli/commands/contract.d.ts.map +1 -1
  26. package/dist/cli/commands/contract.js +36 -42
  27. package/dist/cli/commands/contract.js.map +1 -1
  28. package/dist/cli/commands/definitions.d.ts +2 -0
  29. package/dist/cli/commands/definitions.d.ts.map +1 -1
  30. package/dist/cli/commands/definitions.js +11 -6
  31. package/dist/cli/commands/definitions.js.map +1 -1
  32. package/dist/cli/commands/failure.d.ts.map +1 -1
  33. package/dist/cli/commands/failure.js +16 -2
  34. package/dist/cli/commands/failure.js.map +1 -1
  35. package/dist/cli/commands/init.d.ts +14 -8
  36. package/dist/cli/commands/init.d.ts.map +1 -1
  37. package/dist/cli/commands/init.js +172 -364
  38. package/dist/cli/commands/init.js.map +1 -1
  39. package/dist/cli/commands/knowledge-view.d.ts +90 -0
  40. package/dist/cli/commands/knowledge-view.d.ts.map +1 -0
  41. package/dist/cli/commands/knowledge-view.js +198 -0
  42. package/dist/cli/commands/knowledge-view.js.map +1 -0
  43. package/dist/cli/commands/knowledge.d.ts +137 -52
  44. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  45. package/dist/cli/commands/knowledge.js +534 -400
  46. package/dist/cli/commands/knowledge.js.map +1 -1
  47. package/dist/cli/commands/passes-gate.d.ts +4 -1
  48. package/dist/cli/commands/passes-gate.d.ts.map +1 -1
  49. package/dist/cli/commands/passes-gate.js +11 -2
  50. package/dist/cli/commands/passes-gate.js.map +1 -1
  51. package/dist/cli/commands/performance.d.ts.map +1 -1
  52. package/dist/cli/commands/performance.js +19 -31
  53. package/dist/cli/commands/performance.js.map +1 -1
  54. package/dist/cli/commands/report.d.ts.map +1 -1
  55. package/dist/cli/commands/report.js +2 -1
  56. package/dist/cli/commands/report.js.map +1 -1
  57. package/dist/cli/commands/review.d.ts.map +1 -1
  58. package/dist/cli/commands/review.js +13 -25
  59. package/dist/cli/commands/review.js.map +1 -1
  60. package/dist/cli/commands/scaffold-templates.d.ts +73 -0
  61. package/dist/cli/commands/scaffold-templates.d.ts.map +1 -0
  62. package/dist/cli/commands/scaffold-templates.js +424 -0
  63. package/dist/cli/commands/scaffold-templates.js.map +1 -0
  64. package/dist/cli/commands/scaffold.d.ts +105 -0
  65. package/dist/cli/commands/scaffold.d.ts.map +1 -0
  66. package/dist/cli/commands/scaffold.js +263 -0
  67. package/dist/cli/commands/scaffold.js.map +1 -0
  68. package/dist/cli/commands/security.d.ts.map +1 -1
  69. package/dist/cli/commands/security.js +22 -24
  70. package/dist/cli/commands/security.js.map +1 -1
  71. package/dist/cli/commands/spec-baseline-check.d.ts +43 -0
  72. package/dist/cli/commands/spec-baseline-check.d.ts.map +1 -1
  73. package/dist/cli/commands/spec-baseline-check.js +109 -34
  74. package/dist/cli/commands/spec-baseline-check.js.map +1 -1
  75. package/dist/cli/commands/status.d.ts +8 -0
  76. package/dist/cli/commands/status.d.ts.map +1 -1
  77. package/dist/cli/commands/status.js +5 -7
  78. package/dist/cli/commands/status.js.map +1 -1
  79. package/dist/cli/commands/sync-docs/context-syncer.d.ts +21 -2
  80. package/dist/cli/commands/sync-docs/context-syncer.d.ts.map +1 -1
  81. package/dist/cli/commands/sync-docs/context-syncer.js +112 -28
  82. package/dist/cli/commands/sync-docs/context-syncer.js.map +1 -1
  83. package/dist/cli/commands/sync-docs/index.d.ts +1 -1
  84. package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
  85. package/dist/cli/commands/sync-docs/index.js +86 -27
  86. package/dist/cli/commands/sync-docs/index.js.map +1 -1
  87. package/dist/cli/commands/sync-docs/project-reader.d.ts +24 -1
  88. package/dist/cli/commands/sync-docs/project-reader.d.ts.map +1 -1
  89. package/dist/cli/commands/sync-docs/project-reader.js +33 -7
  90. package/dist/cli/commands/sync-docs/project-reader.js.map +1 -1
  91. package/dist/cli/commands/validate.d.ts +0 -16
  92. package/dist/cli/commands/validate.d.ts.map +1 -1
  93. package/dist/cli/commands/validate.js +2 -97
  94. package/dist/cli/commands/validate.js.map +1 -1
  95. package/dist/cli/gate-command.d.ts +37 -0
  96. package/dist/cli/gate-command.d.ts.map +1 -0
  97. package/dist/cli/gate-command.js +64 -0
  98. package/dist/cli/gate-command.js.map +1 -0
  99. package/dist/cli/state-io.d.ts +34 -0
  100. package/dist/cli/state-io.d.ts.map +1 -0
  101. package/dist/cli/state-io.js +71 -0
  102. package/dist/cli/state-io.js.map +1 -0
  103. package/dist/completion-checkers/index.d.ts +1 -1
  104. package/dist/completion-checkers/index.d.ts.map +1 -1
  105. package/dist/completion-checkers/index.js +0 -15
  106. package/dist/completion-checkers/index.js.map +1 -1
  107. package/dist/context/knowledge-injector.d.ts +4 -2
  108. package/dist/context/knowledge-injector.d.ts.map +1 -1
  109. package/dist/context/knowledge-injector.js +13 -6
  110. package/dist/context/knowledge-injector.js.map +1 -1
  111. package/dist/core/constraints/agent-prompt-renderer.js +2 -2
  112. package/dist/core/constraints/agent-prompt-renderer.js.map +1 -1
  113. package/dist/core/constraints/capabilities-reconcile.d.ts +20 -0
  114. package/dist/core/constraints/capabilities-reconcile.d.ts.map +1 -1
  115. package/dist/core/constraints/capabilities-reconcile.js +26 -4
  116. package/dist/core/constraints/capabilities-reconcile.js.map +1 -1
  117. package/dist/core/constraints/check-cache.d.ts +1 -1
  118. package/dist/core/constraints/check-cache.js +1 -1
  119. package/dist/core/constraints/checker.d.ts +8 -3
  120. package/dist/core/constraints/checker.d.ts.map +1 -1
  121. package/dist/core/constraints/checker.js +30 -19
  122. package/dist/core/constraints/checker.js.map +1 -1
  123. package/dist/core/constraints/checkers/capability-sync.d.ts +3 -1
  124. package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
  125. package/dist/core/constraints/checkers/capability-sync.js +17 -24
  126. package/dist/core/constraints/checkers/capability-sync.js.map +1 -1
  127. package/dist/core/constraints/checkers/context-doc-sync.d.ts +1 -1
  128. package/dist/core/constraints/checkers/context-doc-sync.d.ts.map +1 -1
  129. package/dist/core/constraints/checkers/context-doc-sync.js +9 -6
  130. package/dist/core/constraints/checkers/context-doc-sync.js.map +1 -1
  131. package/dist/core/constraints/checkers/docs-freshness.d.ts.map +1 -1
  132. package/dist/core/constraints/checkers/docs-freshness.js +24 -30
  133. package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
  134. package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
  135. package/dist/core/constraints/checkers/governance-presence.js +10 -4
  136. package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
  137. package/dist/core/constraints/checkers/types.d.ts +10 -6
  138. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  139. package/dist/core/constraints/checkers/types.js +7 -3
  140. package/dist/core/constraints/checkers/types.js.map +1 -1
  141. package/dist/core/constraints/context-builder.d.ts +11 -10
  142. package/dist/core/constraints/context-builder.d.ts.map +1 -1
  143. package/dist/core/constraints/context-builder.js +31 -27
  144. package/dist/core/constraints/context-builder.js.map +1 -1
  145. package/dist/core/constraints/context-reconcile.d.ts +75 -0
  146. package/dist/core/constraints/context-reconcile.d.ts.map +1 -0
  147. package/dist/core/constraints/context-reconcile.js +161 -0
  148. package/dist/core/constraints/context-reconcile.js.map +1 -0
  149. package/dist/core/constraints/doc-freshness/runner.d.ts +7 -0
  150. package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
  151. package/dist/core/constraints/doc-freshness/runner.js +8 -3
  152. package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
  153. package/dist/core/constraints/git-evidence.js +1 -1
  154. package/dist/core/constraints/git-evidence.js.map +1 -1
  155. package/dist/core/constraints/injection-drift.d.ts +7 -2
  156. package/dist/core/constraints/injection-drift.d.ts.map +1 -1
  157. package/dist/core/constraints/injection-drift.js +13 -7
  158. package/dist/core/constraints/injection-drift.js.map +1 -1
  159. package/dist/core/constraints/run-env.d.ts +92 -0
  160. package/dist/core/constraints/run-env.d.ts.map +1 -0
  161. package/dist/core/constraints/run-env.js +175 -0
  162. package/dist/core/constraints/run-env.js.map +1 -0
  163. package/dist/core/constraints/triggers.d.ts +22 -0
  164. package/dist/core/constraints/triggers.d.ts.map +1 -0
  165. package/dist/core/constraints/triggers.js +31 -0
  166. package/dist/core/constraints/triggers.js.map +1 -0
  167. package/dist/core/effective-constraints.d.ts +13 -4
  168. package/dist/core/effective-constraints.d.ts.map +1 -1
  169. package/dist/core/effective-constraints.js +16 -6
  170. package/dist/core/effective-constraints.js.map +1 -1
  171. package/dist/core/effective-set.d.ts +8 -15
  172. package/dist/core/effective-set.d.ts.map +1 -1
  173. package/dist/core/effective-set.js +7 -12
  174. package/dist/core/effective-set.js.map +1 -1
  175. package/dist/core/index.d.ts +1 -0
  176. package/dist/core/index.d.ts.map +1 -1
  177. package/dist/core/index.js.map +1 -1
  178. package/dist/core/project-config-loader.d.ts +39 -17
  179. package/dist/core/project-config-loader.d.ts.map +1 -1
  180. package/dist/core/project-config-loader.js +51 -122
  181. package/dist/core/project-config-loader.js.map +1 -1
  182. package/dist/core/validators/check-handlers/http.d.ts +2 -2
  183. package/dist/core/validators/check-handlers/http.d.ts.map +1 -1
  184. package/dist/core/validators/check-handlers/http.js +12 -7
  185. package/dist/core/validators/check-handlers/http.js.map +1 -1
  186. package/dist/failure/classifier.d.ts +1 -1
  187. package/dist/failure/classifier.d.ts.map +1 -1
  188. package/dist/failure/classifier.js +8 -8
  189. package/dist/failure/classifier.js.map +1 -1
  190. package/dist/failure/index.d.ts +2 -1
  191. package/dist/failure/index.d.ts.map +1 -1
  192. package/dist/failure/index.js +9 -17
  193. package/dist/failure/index.js.map +1 -1
  194. package/dist/failure/recorder.d.ts +1 -1
  195. package/dist/failure/recorder.d.ts.map +1 -1
  196. package/dist/gates/checker-gate.d.ts +2 -1
  197. package/dist/gates/checker-gate.d.ts.map +1 -1
  198. package/dist/gates/checker-gate.js +3 -2
  199. package/dist/gates/checker-gate.js.map +1 -1
  200. package/dist/gates/command.d.ts +10 -4
  201. package/dist/gates/command.d.ts.map +1 -1
  202. package/dist/gates/command.js +36 -62
  203. package/dist/gates/command.js.map +1 -1
  204. package/dist/gates/contract.d.ts.map +1 -1
  205. package/dist/gates/contract.js +0 -4
  206. package/dist/gates/contract.js.map +1 -1
  207. package/dist/gates/definitions.d.ts +2 -1
  208. package/dist/gates/definitions.d.ts.map +1 -1
  209. package/dist/gates/definitions.js +6 -5
  210. package/dist/gates/definitions.js.map +1 -1
  211. package/dist/gates/index.d.ts +0 -4
  212. package/dist/gates/index.d.ts.map +1 -1
  213. package/dist/gates/index.js +1 -6
  214. package/dist/gates/index.js.map +1 -1
  215. package/dist/gates/performance.d.ts.map +1 -1
  216. package/dist/gates/performance.js +0 -4
  217. package/dist/gates/performance.js.map +1 -1
  218. package/dist/gates/runner.d.ts +1 -1
  219. package/dist/gates/runner.js +1 -1
  220. package/dist/gates/security.d.ts +1 -1
  221. package/dist/gates/security.d.ts.map +1 -1
  222. package/dist/gates/security.js +5 -6
  223. package/dist/gates/security.js.map +1 -1
  224. package/dist/gates/types.d.ts +14 -17
  225. package/dist/gates/types.d.ts.map +1 -1
  226. package/dist/gates/types.js.map +1 -1
  227. package/dist/hooks/bootstrap.d.ts +6 -4
  228. package/dist/hooks/bootstrap.d.ts.map +1 -1
  229. package/dist/hooks/bootstrap.js +25 -13
  230. package/dist/hooks/bootstrap.js.map +1 -1
  231. package/dist/hooks/config.d.ts +6 -2
  232. package/dist/hooks/config.d.ts.map +1 -1
  233. package/dist/hooks/config.js +5 -1
  234. package/dist/hooks/config.js.map +1 -1
  235. package/dist/hooks/index.d.ts +1 -1
  236. package/dist/hooks/index.d.ts.map +1 -1
  237. package/dist/hooks/index.js +0 -15
  238. package/dist/hooks/index.js.map +1 -1
  239. package/dist/hooks/pipeline.d.ts +19 -1
  240. package/dist/hooks/pipeline.d.ts.map +1 -1
  241. package/dist/hooks/pipeline.js +42 -4
  242. package/dist/hooks/pipeline.js.map +1 -1
  243. package/dist/hooks/registry.d.ts +11 -8
  244. package/dist/hooks/registry.d.ts.map +1 -1
  245. package/dist/hooks/registry.js +22 -7
  246. package/dist/hooks/registry.js.map +1 -1
  247. package/dist/hooks/types.d.ts +25 -7
  248. package/dist/hooks/types.d.ts.map +1 -1
  249. package/dist/index.d.ts +3 -3
  250. package/dist/index.d.ts.map +1 -1
  251. package/dist/index.js +3 -4
  252. package/dist/index.js.map +1 -1
  253. package/dist/knowledge/audit-scoring.d.ts +87 -0
  254. package/dist/knowledge/audit-scoring.d.ts.map +1 -0
  255. package/dist/knowledge/audit-scoring.js +470 -0
  256. package/dist/knowledge/audit-scoring.js.map +1 -0
  257. package/dist/knowledge/audit.d.ts +11 -59
  258. package/dist/knowledge/audit.d.ts.map +1 -1
  259. package/dist/knowledge/audit.js +47 -522
  260. package/dist/knowledge/audit.js.map +1 -1
  261. package/dist/knowledge/import.d.ts.map +1 -1
  262. package/dist/knowledge/import.js +2 -0
  263. package/dist/knowledge/import.js.map +1 -1
  264. package/dist/knowledge/index-generator.d.ts.map +1 -1
  265. package/dist/knowledge/index-generator.js +4 -5
  266. package/dist/knowledge/index-generator.js.map +1 -1
  267. package/dist/knowledge/index.d.ts +3 -2
  268. package/dist/knowledge/index.d.ts.map +1 -1
  269. package/dist/knowledge/index.js +3 -16
  270. package/dist/knowledge/index.js.map +1 -1
  271. package/dist/knowledge/ingest.js +1 -1
  272. package/dist/knowledge/ingest.js.map +1 -1
  273. package/dist/knowledge/lifecycle.d.ts.map +1 -1
  274. package/dist/knowledge/lifecycle.js +4 -2
  275. package/dist/knowledge/lifecycle.js.map +1 -1
  276. package/dist/knowledge/migration.d.ts +3 -0
  277. package/dist/knowledge/migration.d.ts.map +1 -1
  278. package/dist/knowledge/migration.js +8 -2
  279. package/dist/knowledge/migration.js.map +1 -1
  280. package/dist/knowledge/query.d.ts +6 -0
  281. package/dist/knowledge/query.d.ts.map +1 -1
  282. package/dist/knowledge/query.js +8 -2
  283. package/dist/knowledge/query.js.map +1 -1
  284. package/dist/knowledge/reference-tracker.d.ts.map +1 -1
  285. package/dist/knowledge/reference-tracker.js +4 -6
  286. package/dist/knowledge/reference-tracker.js.map +1 -1
  287. package/dist/knowledge/store.d.ts +22 -16
  288. package/dist/knowledge/store.d.ts.map +1 -1
  289. package/dist/knowledge/store.js +53 -12
  290. package/dist/knowledge/store.js.map +1 -1
  291. package/dist/knowledge/tree-walker.d.ts +19 -0
  292. package/dist/knowledge/tree-walker.d.ts.map +1 -0
  293. package/dist/knowledge/tree-walker.js +30 -0
  294. package/dist/knowledge/tree-walker.js.map +1 -0
  295. package/dist/knowledge/types.d.ts +16 -0
  296. package/dist/knowledge/types.d.ts.map +1 -1
  297. package/dist/monitoring/traces.d.ts +5 -3
  298. package/dist/monitoring/traces.d.ts.map +1 -1
  299. package/dist/monitoring/traces.js +19 -5
  300. package/dist/monitoring/traces.js.map +1 -1
  301. package/dist/test-setup/jsonl-fake-fs.d.ts +30 -0
  302. package/dist/test-setup/jsonl-fake-fs.d.ts.map +1 -0
  303. package/dist/test-setup/jsonl-fake-fs.js +49 -0
  304. package/dist/test-setup/jsonl-fake-fs.js.map +1 -0
  305. package/dist/tools/index.d.ts +4 -1
  306. package/dist/tools/index.d.ts.map +1 -1
  307. package/dist/tools/index.js +7 -15
  308. package/dist/tools/index.js.map +1 -1
  309. package/dist/types/checkpoint.d.ts +5 -0
  310. package/dist/types/checkpoint.d.ts.map +1 -1
  311. package/dist/types/project-config.d.ts +18 -0
  312. package/dist/types/project-config.d.ts.map +1 -1
  313. package/dist/types/trace.d.ts +13 -4
  314. package/dist/types/trace.d.ts.map +1 -1
  315. package/dist/types/trace.js +4 -3
  316. package/dist/types/trace.js.map +1 -1
  317. package/dist/utils/exec.d.ts +4 -27
  318. package/dist/utils/exec.d.ts.map +1 -1
  319. package/dist/utils/exec.js +4 -94
  320. package/dist/utils/exec.js.map +1 -1
  321. package/dist/utils/jsonl.d.ts +17 -7
  322. package/dist/utils/jsonl.d.ts.map +1 -1
  323. package/dist/utils/jsonl.js +144 -17
  324. package/dist/utils/jsonl.js.map +1 -1
  325. package/dist/utils/numeric-flag.d.ts +44 -0
  326. package/dist/utils/numeric-flag.d.ts.map +1 -0
  327. package/dist/utils/numeric-flag.js +62 -0
  328. package/dist/utils/numeric-flag.js.map +1 -0
  329. package/package.json +1 -1
  330. package/src/CONTEXT.md +5 -2
  331. package/src/__tests__/acceptance-gate.test.ts +7 -4
  332. package/src/__tests__/checker-extra.test.ts +3 -2
  333. package/src/__tests__/checker.test.ts +4 -3
  334. package/src/__tests__/checkpoint.test.ts +26 -9
  335. package/src/__tests__/context-files-resolution.test.ts +29 -15
  336. package/src/__tests__/contract-gate.test.ts +19 -40
  337. package/src/__tests__/error-classifier.test.ts +1 -1
  338. package/src/__tests__/exec.test.ts +45 -107
  339. package/src/__tests__/failure-recorder.test.ts +7 -5
  340. package/src/__tests__/hooks-pipeline.test.ts +34 -47
  341. package/src/__tests__/layering.test.ts +217 -25
  342. package/src/__tests__/passes-gate.test.ts +9 -4
  343. package/src/__tests__/performance-gate.test.ts +3 -15
  344. package/src/__tests__/project-config-loader-extra.test.ts +31 -57
  345. package/src/__tests__/project-config-loader.test.ts +6 -3
  346. package/src/__tests__/public-exports.test.ts +0 -1
  347. package/src/__tests__/public-type-surface.test.ts +5 -4
  348. package/src/__tests__/public-value-surface.test.ts +182 -0
  349. package/src/__tests__/review-gate.test.ts +4 -6
  350. package/src/__tests__/security-gate.test.ts +5 -20
  351. package/src/__tests__/skip-semantics.test.ts +5 -3
  352. package/src/__tests__/spec-validator.test.ts +3 -2
  353. package/src/__tests__/sub-barrels-explicit.test.ts +87 -0
  354. package/src/__tests__/test-fixture-hygiene.test.ts +53 -0
  355. package/src/__tests__/trace-analyzer-extra.test.ts +5 -3
  356. package/src/__tests__/trace-analyzer.test.ts +5 -3
  357. package/src/__tests__/trace-collector.test.ts +5 -3
  358. package/src/agents/index.ts +13 -2
  359. package/src/cli/__tests__/gate-command.test.ts +162 -0
  360. package/src/cli/__tests__/state-io.test.ts +50 -0
  361. package/src/cli/commands/CONTEXT.md +30 -5
  362. package/src/cli/commands/__tests__/acceptance.test.ts +24 -25
  363. package/src/cli/commands/__tests__/bin-exit-mapping.test.ts +15 -0
  364. package/src/cli/commands/__tests__/check-drift.test.ts +42 -1
  365. package/src/cli/commands/__tests__/check-read-count.test.ts +170 -0
  366. package/src/cli/commands/__tests__/check-skip-output.test.ts +4 -1
  367. package/src/cli/commands/__tests__/check.test.ts +63 -44
  368. package/src/cli/commands/__tests__/command-gate-dead-options.test.ts +60 -0
  369. package/src/cli/commands/__tests__/command.test.ts +33 -17
  370. package/src/cli/commands/__tests__/constraints-retire.test.ts +52 -0
  371. package/src/cli/commands/__tests__/context-syncer.test.ts +141 -0
  372. package/src/cli/commands/__tests__/contract.test.ts +20 -20
  373. package/src/cli/commands/__tests__/failure.test.ts +5 -4
  374. package/src/cli/commands/__tests__/gate-decision.ts +30 -0
  375. package/src/cli/commands/__tests__/init-dead-options.test.ts +50 -0
  376. package/src/cli/commands/__tests__/init-governance-io.test.ts +139 -0
  377. package/src/cli/commands/__tests__/init-injection.test.ts +3 -3
  378. package/src/cli/commands/__tests__/init-ondisk.test.ts +867 -0
  379. package/src/cli/commands/__tests__/init.test.ts +82 -6
  380. package/src/cli/commands/__tests__/knowledge-audit-threshold.test.ts +146 -0
  381. package/src/cli/commands/__tests__/knowledge-flywheel-consistency.test.ts +1 -1
  382. package/src/cli/commands/__tests__/knowledge-tone-mapping.test.ts +244 -0
  383. package/src/cli/commands/__tests__/knowledge-view.test.ts +839 -0
  384. package/src/cli/commands/__tests__/knowledge.test.ts +33 -15
  385. package/src/cli/commands/__tests__/numeric-flag-assembly.test.ts +368 -0
  386. package/src/cli/commands/__tests__/performance.test.ts +19 -21
  387. package/src/cli/commands/__tests__/posteval-plan.test.ts +5 -3
  388. package/src/cli/commands/__tests__/pre-push-hook.test.ts +181 -0
  389. package/src/cli/commands/__tests__/project-path-anchoring.test.ts +95 -2
  390. package/src/cli/commands/__tests__/project-path-convention.test.ts +103 -25
  391. package/src/cli/commands/__tests__/registry.test.ts +2 -0
  392. package/src/cli/commands/__tests__/report.test.ts +23 -1
  393. package/src/cli/commands/__tests__/review.test.ts +10 -17
  394. package/src/cli/commands/__tests__/scaffold.test.ts +505 -0
  395. package/src/cli/commands/__tests__/security-default-scan.test.ts +75 -0
  396. package/src/cli/commands/__tests__/security.test.ts +21 -24
  397. package/src/cli/commands/__tests__/spec-baseline-check.test.ts +3 -2
  398. package/src/cli/commands/__tests__/spec-baseline-index-cap.test.ts +131 -0
  399. package/src/cli/commands/__tests__/spec-baseline-read-count.test.ts +325 -0
  400. package/src/cli/commands/__tests__/status-extra.test.ts +25 -8
  401. package/src/cli/commands/__tests__/status.test.ts +46 -18
  402. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +19 -4
  403. package/src/cli/commands/__tests__/sync-docs-context-drift.test.ts +232 -0
  404. package/src/cli/commands/__tests__/sync-docs-module-order.test.ts +111 -0
  405. package/src/cli/commands/__tests__/sync-docs-read-count.test.ts +192 -0
  406. package/src/cli/commands/__tests__/sync-docs.test.ts +3 -2
  407. package/src/cli/commands/__tests__/validate.test.ts +1 -48
  408. package/src/cli/commands/acceptance.ts +24 -29
  409. package/src/cli/commands/check.ts +60 -35
  410. package/src/cli/commands/command.ts +9 -8
  411. package/src/cli/commands/constraints-retire.ts +57 -70
  412. package/src/cli/commands/contract.ts +44 -47
  413. package/src/cli/commands/definitions.ts +12 -6
  414. package/src/cli/commands/failure.ts +16 -3
  415. package/src/cli/commands/init.ts +242 -389
  416. package/src/cli/commands/knowledge-view.ts +224 -0
  417. package/src/cli/commands/knowledge.ts +643 -448
  418. package/src/cli/commands/passes-gate.ts +12 -3
  419. package/src/cli/commands/performance.ts +31 -38
  420. package/src/cli/commands/report.ts +3 -2
  421. package/src/cli/commands/review.ts +22 -28
  422. package/src/cli/commands/scaffold-templates.ts +406 -0
  423. package/src/cli/commands/scaffold.ts +302 -0
  424. package/src/cli/commands/security.ts +27 -23
  425. package/src/cli/commands/spec-baseline-check.ts +158 -33
  426. package/src/cli/commands/status.ts +12 -7
  427. package/src/cli/commands/sync-docs/__tests__/context-export-surface.test.ts +102 -0
  428. package/src/cli/commands/sync-docs/__tests__/module-descriptions.test.ts +196 -0
  429. package/src/cli/commands/sync-docs/context-syncer.ts +137 -31
  430. package/src/cli/commands/sync-docs/index.ts +103 -28
  431. package/src/cli/commands/sync-docs/project-reader.ts +51 -7
  432. package/src/cli/commands/validate.ts +1 -104
  433. package/src/cli/gate-command.ts +87 -0
  434. package/src/cli/state-io.ts +53 -0
  435. package/src/completion-checkers/index.ts +10 -1
  436. package/src/context/CONTEXT.md +2 -1
  437. package/src/context/__tests__/knowledge-injector.test.ts +27 -0
  438. package/src/context/__tests__/session-manager.test.ts +19 -12
  439. package/src/context/knowledge-injector.ts +14 -7
  440. package/src/core/CONTEXT.md +10 -7
  441. package/src/core/__tests__/effective-set.test.ts +36 -60
  442. package/src/core/constraints/__tests__/context-reconcile.test.ts +246 -0
  443. package/src/core/constraints/__tests__/run-env.test.ts +377 -0
  444. package/src/core/constraints/__tests__/triggers.test.ts +70 -0
  445. package/src/core/constraints/agent-prompt-renderer.ts +1 -1
  446. package/src/core/constraints/capabilities-reconcile.ts +28 -4
  447. package/src/core/constraints/check-cache.ts +1 -1
  448. package/src/core/constraints/checker.ts +30 -14
  449. package/src/core/constraints/checkers/__tests__/context-doc-sync.test.ts +8 -3
  450. package/src/core/constraints/checkers/__tests__/governance-presence.test.ts +16 -7
  451. package/src/core/constraints/checkers/__tests__/no-hardcoded-credentials.test.ts +2 -1
  452. package/src/core/constraints/checkers/capability-sync.ts +27 -28
  453. package/src/core/constraints/checkers/context-doc-sync.ts +9 -7
  454. package/src/core/constraints/checkers/docs-freshness.ts +28 -33
  455. package/src/core/constraints/checkers/governance-presence.ts +10 -6
  456. package/src/core/constraints/checkers/types.ts +14 -8
  457. package/src/core/constraints/context-builder.ts +35 -26
  458. package/src/core/constraints/context-reconcile.ts +200 -0
  459. package/src/core/constraints/doc-freshness/__tests__/runner.test.ts +25 -0
  460. package/src/core/constraints/doc-freshness/runner.ts +18 -4
  461. package/src/core/constraints/git-evidence.ts +1 -1
  462. package/src/core/constraints/injection-drift.ts +19 -8
  463. package/src/core/constraints/run-env.ts +207 -0
  464. package/src/core/constraints/triggers.ts +33 -0
  465. package/src/core/effective-constraints.ts +17 -6
  466. package/src/core/effective-set.ts +8 -24
  467. package/src/core/index.ts +2 -0
  468. package/src/core/project-config-loader.ts +54 -102
  469. package/src/core/validators/__tests__/http-retry-sleep.test.ts +231 -0
  470. package/src/core/validators/check-handlers/http.ts +18 -7
  471. package/src/failure/CONTEXT.md +2 -1
  472. package/src/failure/classifier.ts +2 -2
  473. package/src/failure/index.ts +14 -2
  474. package/src/failure/recorder.ts +1 -1
  475. package/src/gates/CONTEXT.md +13 -7
  476. package/src/gates/__tests__/checker-gate.test.ts +1 -1
  477. package/src/gates/__tests__/command-single-predicate.test.ts +135 -0
  478. package/src/gates/__tests__/command.test.ts +8 -15
  479. package/src/gates/__tests__/contract.test.ts +5 -5
  480. package/src/gates/__tests__/gate-interface.test.ts +0 -17
  481. package/src/gates/__tests__/performance.test.ts +0 -13
  482. package/src/gates/__tests__/review.test.ts +0 -1
  483. package/src/gates/__tests__/runner.test.ts +1 -1
  484. package/src/gates/__tests__/security-default-scan.test.ts +97 -0
  485. package/src/gates/__tests__/security.test.ts +0 -13
  486. package/src/gates/checker-gate.ts +3 -2
  487. package/src/gates/command.ts +51 -74
  488. package/src/gates/contract.ts +0 -5
  489. package/src/gates/definitions.ts +6 -5
  490. package/src/gates/index.ts +0 -5
  491. package/src/gates/performance.ts +1 -6
  492. package/src/gates/runner.ts +1 -1
  493. package/src/gates/security.ts +9 -11
  494. package/src/gates/types.ts +20 -23
  495. package/src/hooks/CONTEXT.md +10 -9
  496. package/src/hooks/__tests__/bootstrap.test.ts +29 -6
  497. package/src/hooks/__tests__/pipeline.test.ts +133 -17
  498. package/src/hooks/__tests__/registry.test.ts +51 -3
  499. package/src/hooks/bootstrap.ts +35 -15
  500. package/src/hooks/config.ts +6 -2
  501. package/src/hooks/index.ts +10 -1
  502. package/src/hooks/pipeline.ts +51 -6
  503. package/src/hooks/registry.ts +31 -12
  504. package/src/hooks/types.ts +26 -7
  505. package/src/index.ts +1 -2
  506. package/src/knowledge/CONTEXT.md +14 -7
  507. package/src/knowledge/__tests__/audit-labels.test.ts +8 -5
  508. package/src/knowledge/__tests__/audit-scoring.test.ts +230 -0
  509. package/src/knowledge/__tests__/audit-write-count.test.ts +131 -0
  510. package/src/knowledge/__tests__/audit.test.ts +291 -208
  511. package/src/knowledge/__tests__/doctor.test.ts +3 -2
  512. package/src/knowledge/__tests__/ingest.test.ts +3 -2
  513. package/src/knowledge/__tests__/lifecycle.test.ts +57 -2
  514. package/src/knowledge/__tests__/migration.test.ts +35 -6
  515. package/src/knowledge/__tests__/query.test.ts +3 -2
  516. package/src/knowledge/__tests__/reference-tracker.test.ts +23 -2
  517. package/src/knowledge/__tests__/store.test.ts +149 -4
  518. package/src/knowledge/__tests__/tree-walker.test.ts +132 -0
  519. package/src/knowledge/audit-scoring.ts +589 -0
  520. package/src/knowledge/audit.ts +55 -599
  521. package/src/knowledge/import.ts +2 -0
  522. package/src/knowledge/index-generator.ts +4 -6
  523. package/src/knowledge/index.ts +27 -2
  524. package/src/knowledge/ingest.ts +1 -1
  525. package/src/knowledge/lifecycle.ts +5 -2
  526. package/src/knowledge/migration.ts +8 -2
  527. package/src/knowledge/query.ts +8 -1
  528. package/src/knowledge/reference-tracker.ts +5 -7
  529. package/src/knowledge/store.ts +75 -16
  530. package/src/knowledge/tree-walker.ts +29 -0
  531. package/src/knowledge/types.ts +19 -0
  532. package/src/monitoring/CONTEXT.md +5 -2
  533. package/src/monitoring/__tests__/context-tracker.test.ts +16 -8
  534. package/src/monitoring/__tests__/trace-file-anchoring.test.ts +80 -0
  535. package/src/monitoring/traces.ts +19 -5
  536. package/src/release/CONTEXT.md +1 -1
  537. package/src/release/__tests__/integrity.test.ts +21 -12
  538. package/src/test-setup/__tests__/jsonl-fake-fs.test.ts +98 -0
  539. package/src/test-setup/jsonl-fake-fs.ts +59 -0
  540. package/src/tools/index.ts +5 -1
  541. package/src/types/checkpoint.ts +6 -0
  542. package/src/types/project-config.ts +21 -0
  543. package/src/types/trace.ts +14 -4
  544. package/src/utils/__tests__/file-walk.test.ts +3 -2
  545. package/src/utils/__tests__/jsonl-bounded-read.test.ts +106 -0
  546. package/src/utils/__tests__/jsonl-skip-disposition.test.ts +10 -6
  547. package/src/utils/__tests__/jsonl.test.ts +61 -14
  548. package/src/utils/__tests__/numeric-flag.test.ts +80 -0
  549. package/src/utils/__tests__/package-version.test.ts +2 -2
  550. package/src/utils/exec.ts +4 -64
  551. package/src/utils/jsonl.ts +159 -20
  552. package/src/utils/numeric-flag.ts +64 -0
  553. package/dist/failure/types.d.ts +0 -9
  554. package/dist/failure/types.d.ts.map +0 -1
  555. package/dist/failure/types.js +0 -25
  556. package/dist/failure/types.js.map +0 -1
  557. package/dist/gates/effective-gates.d.ts +0 -30
  558. package/dist/gates/effective-gates.d.ts.map +0 -1
  559. package/dist/gates/effective-gates.js +0 -81
  560. package/dist/gates/effective-gates.js.map +0 -1
  561. package/src/failure/types.ts +0 -9
  562. package/src/gates/__tests__/effective-gates.test.ts +0 -77
  563. package/src/gates/effective-gates.ts +0 -99
@@ -6,15 +6,19 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/glo
6
6
  import { ContractGate } from '../gates/contract';
7
7
  import * as fs from 'fs';
8
8
  import * as path from 'path';
9
+ import * as os from 'os';
9
10
 
10
11
  describe('ContractGate', () => {
11
- const tempDir = path.join(process.cwd(), 'temp-test-contract');
12
- const contractFile = path.join(tempDir, 'openapi.yaml');
13
- const oldContractFile = path.join(tempDir, 'openapi-old.yaml');
14
- const jsonContractFile = path.join(tempDir, 'openapi.json');
12
+ let tempDir: string;
13
+ let contractFile: string;
14
+ let oldContractFile: string;
15
+ let jsonContractFile: string;
15
16
 
16
17
  beforeAll(() => {
17
- fs.mkdirSync(tempDir, { recursive: true });
18
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'temp-test-contract-'));
19
+ contractFile = path.join(tempDir, 'openapi.yaml');
20
+ oldContractFile = path.join(tempDir, 'openapi-old.yaml');
21
+ jsonContractFile = path.join(tempDir, 'openapi.json');
18
22
  });
19
23
 
20
24
  afterAll(() => {
@@ -37,23 +41,10 @@ describe('ContractGate', () => {
37
41
  });
38
42
 
39
43
  describe('check', () => {
40
- it('禁用时应该返回通过', async () => {
41
- const gate = new ContractGate({ enabled: false });
42
-
43
- const result = await gate.check({
44
- projectId: 'test',
45
- projectPath: tempDir,
46
- });
47
-
48
- expect(result.passed).toBe(true);
49
- expect(result.message).toContain('禁用');
50
- });
51
-
52
44
  it('无契约文件时应该通过', async () => {
53
- const gate = new ContractGate({ enabled: true });
45
+ const gate = new ContractGate();
54
46
 
55
47
  const result = await gate.check({
56
- projectId: 'test',
57
48
  projectPath: tempDir,
58
49
  });
59
50
 
@@ -76,10 +67,9 @@ paths:
76
67
  summary: Create user
77
68
  `);
78
69
 
79
- const gate = new ContractGate({ enabled: true });
70
+ const gate = new ContractGate();
80
71
 
81
72
  const result = await gate.check({
82
- projectId: 'test',
83
73
  projectPath: tempDir,
84
74
  });
85
75
 
@@ -98,10 +88,9 @@ paths:
98
88
  summary: Test
99
89
  `);
100
90
 
101
- const gate = new ContractGate({ enabled: true });
91
+ const gate = new ContractGate();
102
92
 
103
93
  const result = await gate.check({
104
- projectId: 'test',
105
94
  projectPath: tempDir,
106
95
  });
107
96
 
@@ -118,10 +107,9 @@ info:
118
107
  paths:
119
108
  `);
120
109
 
121
- const gate = new ContractGate({ enabled: true });
110
+ const gate = new ContractGate();
122
111
 
123
112
  const result = await gate.check({
124
- projectId: 'test',
125
113
  projectPath: tempDir,
126
114
  });
127
115
 
@@ -139,10 +127,9 @@ paths:
139
127
  },
140
128
  }));
141
129
 
142
- const gate = new ContractGate({ enabled: true, contractPath: 'openapi.json' });
130
+ const gate = new ContractGate({contractPath: 'openapi.json' });
143
131
 
144
132
  const result = await gate.check({
145
- projectId: 'test',
146
133
  projectPath: tempDir,
147
134
  });
148
135
 
@@ -172,10 +159,9 @@ paths:
172
159
  summary: Test
173
160
  `);
174
161
 
175
- const gate = new ContractGate({ enabled: true, allowBreakingChanges: false });
162
+ const gate = new ContractGate({allowBreakingChanges: false });
176
163
 
177
164
  const result = await gate.check({
178
- projectId: 'test',
179
165
  projectPath: tempDir,
180
166
  oldContractPath: oldContractFile,
181
167
  });
@@ -205,10 +191,9 @@ paths:
205
191
  summary: Test
206
192
  `);
207
193
 
208
- const gate = new ContractGate({ enabled: true, allowBreakingChanges: true });
194
+ const gate = new ContractGate({allowBreakingChanges: true });
209
195
 
210
196
  const result = await gate.check({
211
- projectId: 'test',
212
197
  projectPath: tempDir,
213
198
  oldContractPath: oldContractFile,
214
199
  });
@@ -237,10 +222,9 @@ paths:
237
222
  summary: New endpoint
238
223
  `);
239
224
 
240
- const gate = new ContractGate({ enabled: true });
225
+ const gate = new ContractGate();
241
226
 
242
227
  const result = await gate.check({
243
- projectId: 'test',
244
228
  projectPath: tempDir,
245
229
  oldContractPath: oldContractFile,
246
230
  });
@@ -258,10 +242,9 @@ paths:
258
242
  summary: Custom
259
243
  `);
260
244
 
261
- const gate = new ContractGate({ enabled: true });
245
+ const gate = new ContractGate();
262
246
 
263
247
  const result = await gate.check({
264
- projectId: 'test',
265
248
  projectPath: tempDir,
266
249
  newContractPath: customContract,
267
250
  });
@@ -272,10 +255,9 @@ paths:
272
255
  it('无效 YAML 应该返回解析失败', async () => {
273
256
  fs.writeFileSync(contractFile, 'invalid: yaml: content: [broken');
274
257
 
275
- const gate = new ContractGate({ enabled: true });
258
+ const gate = new ContractGate();
276
259
 
277
260
  const result = await gate.check({
278
- projectId: 'test',
279
261
  projectPath: tempDir,
280
262
  });
281
263
 
@@ -295,14 +277,12 @@ paths:
295
277
 
296
278
  it('getConfig 应该返回当前配置', () => {
297
279
  const gate = new ContractGate({
298
- enabled: true,
299
280
  strict: false,
300
281
  allowBreakingChanges: true,
301
282
  contractPath: 'api.yaml',
302
283
  });
303
284
 
304
285
  const config = gate.getConfig();
305
- expect(config.enabled).toBe(true);
306
286
  expect(config.strict).toBe(false);
307
287
  expect(config.allowBreakingChanges).toBe(true);
308
288
  expect(config.contractPath).toBe('api.yaml');
@@ -312,7 +292,6 @@ paths:
312
292
  const gate = new ContractGate();
313
293
  const config = gate.getConfig();
314
294
 
315
- expect(config.enabled).toBe(true);
316
295
  expect(config.strict).toBe(true);
317
296
  expect(config.allowBreakingChanges).toBe(false);
318
297
  expect(config.contractPath).toBe('openapi.yaml');
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { describe, it, expect } from '@jest/globals';
6
6
  import { ErrorClassifier } from '../failure/classifier';
7
- import { ErrorType, FailureLevel } from '../failure/types';
7
+ import { ErrorType, FailureLevel } from '../types/failure';
8
8
 
9
9
  describe('ErrorClassifier', () => {
10
10
  const classifier = new ErrorClassifier();
@@ -1,117 +1,55 @@
1
1
  /**
2
2
  * exec 工具测试
3
+ *
4
+ * 零消费者与跨 seam 谓词的收缩记录(harness#137 / #162,判据同 ADR-0022):
5
+ * - `isCommandAvailable` / `delay` 双仓零生产消费者,已删(#137);
6
+ * - `normalizeTriggers` / `matchesTrigger` 是约束域谓词(harness#105),已迁
7
+ * `src/core/constraints/triggers.ts`,用例正本见 `core/constraints/__tests__/triggers.test.ts`;
8
+ * - `runCommand` 已删(#162):#137 头注原记「`core/constraints/check-cache.ts`、`git-evidence.ts`
9
+ * 有生产消费者」,实测两处均为**注释**引用(示例用法与缓冲上限说明),非测试代码里
10
+ * `runCommand(` 调用点为 0,且它不在包公共面(`src/index.ts` 与 `package.json` 五个
11
+ * exports 入口均无)——与 `isCommandAvailable`/`delay` 同属「测试为假想消费者站岗」,
12
+ * 按 ADR-0022 同判据删除,外部不可达故零迁移成本。
13
+ * 下列 `@ts-expect-error` 与运行时键断言双向钉住:删多(指令失效即红)与复活(键重新出现即红)。
3
14
  */
4
15
 
5
16
  import { describe, it, expect } from '@jest/globals';
6
- import { runCommand, isCommandAvailable, normalizeTriggers, matchesTrigger, delay } from '../utils/exec';
17
+ // @ts-expect-error isCommandAvailable 零生产消费者,随 harness#137 删除
18
+ import { isCommandAvailable } from '../utils/exec';
19
+ // @ts-expect-error delay 零生产消费者,随 harness#137 删除
20
+ import { delay } from '../utils/exec';
21
+ // @ts-expect-error normalizeTriggers 是约束域谓词,已迁 core/constraints/triggers(harness#137)
22
+ import { normalizeTriggers } from '../utils/exec';
23
+ // @ts-expect-error matchesTrigger 是约束域谓词,已迁 core/constraints/triggers(harness#137)
24
+ import { matchesTrigger } from '../utils/exec';
25
+ // @ts-expect-error runCommand 零生产消费者且不在包公共面,随 harness#162 删除(判据见头注)
26
+ import { runCommand } from '../utils/exec';
7
27
 
8
28
  describe('exec utils', () => {
9
- describe('runCommand', () => {
10
- it('应该执行命令并返回 stdout', async () => {
11
- const result = await runCommand('echo hello');
12
- expect(result).toBe('hello');
13
- });
14
-
15
- it('不存在的命令应该返回空字符串', async () => {
16
- const result = await runCommand('nonexistent_command_xyz');
17
- expect(result).toBe('');
18
- });
19
-
20
- it('应该支持 cwd 参数', async () => {
21
- const result = await runCommand('pwd', '/tmp');
22
- expect(result).toContain('tmp');
23
- });
24
-
25
- it('多行输出应该保留换行', async () => {
26
- const result = await runCommand('echo -e "line1\\nline2"');
27
- expect(result).toContain('line1');
28
- expect(result).toContain('line2');
29
- });
30
- });
31
-
32
- describe('isCommandAvailable', () => {
33
- it('存在的命令应该返回 true', async () => {
34
- const result = await isCommandAvailable('ls');
35
- expect(result).toBe(true);
36
- });
37
-
38
- it('不存在的命令应该返回 false', async () => {
39
- const result = await isCommandAvailable('nonexistent_command_xyz');
40
- expect(result).toBe(false);
41
- });
42
-
43
- it('常见命令应该可用', async () => {
44
- expect(await isCommandAvailable('cat')).toBe(true);
45
- expect(await isCommandAvailable('grep')).toBe(true);
46
- });
47
- });
48
-
49
- describe('normalizeTriggers', () => {
50
- it('应该返回 fallback 当值为 null', () => {
51
- const result = normalizeTriggers(null, ['default']);
52
- expect(result).toEqual(['default']);
53
- });
54
-
55
- it('应该返回 fallback 当值为 undefined', () => {
56
- const result = normalizeTriggers(undefined, ['default']);
57
- expect(result).toEqual(['default']);
58
- });
59
-
60
- it('应该将单值包装为数组', () => {
61
- const result = normalizeTriggers('single');
62
- expect(result).toEqual(['single']);
63
- });
64
-
65
- it('应该直接返回数组', () => {
66
- const result = normalizeTriggers(['a', 'b']);
67
- expect(result).toEqual(['a', 'b']);
68
- });
69
-
70
- it('应该使用空数组作为默认 fallback', () => {
71
- const result = normalizeTriggers(undefined);
72
- expect(result).toEqual([]);
73
- });
74
- });
75
-
76
- describe('matchesTrigger', () => {
77
- it('单值 trigger 命中操作返回 true', () => {
78
- expect(matchesTrigger({ trigger: 'a' }, ['a'])).toBe(true);
79
- });
80
-
81
- it('单值 trigger 未命中返回 false', () => {
82
- expect(matchesTrigger({ trigger: 'a' }, ['b'])).toBe(false);
83
- });
84
-
85
- it('数组 trigger 任一命中即返回 true', () => {
86
- expect(matchesTrigger({ trigger: ['a', 'b'] }, ['b'])).toBe(true);
87
- });
88
-
89
- it('数组 trigger 全部未命中返回 false', () => {
90
- expect(matchesTrigger({ trigger: ['a', 'b'] }, ['c', 'd'])).toBe(false);
91
- });
92
-
93
- it('operations 中任一命中即返回 true', () => {
94
- expect(matchesTrigger({ trigger: 'a' }, ['x', 'a'])).toBe(true);
95
- });
96
-
97
- it('trigger 为 undefined 时不匹配任何操作', () => {
98
- expect(matchesTrigger({ trigger: undefined }, ['a'])).toBe(false);
99
- });
100
-
101
- it('trigger 为空数组时不匹配任何操作', () => {
102
- expect(matchesTrigger({ trigger: [] }, ['a'])).toBe(false);
103
- });
104
-
105
- it('operations 为空数组时返回 false', () => {
106
- expect(matchesTrigger({ trigger: 'a' }, [])).toBe(false);
107
- });
108
- });
109
-
110
- describe('delay', () => {
111
- it('应该延迟指定时间', async () => {
112
- const start = Date.now();
113
- await delay(10);
114
- expect(Date.now() - start).toBeGreaterThanOrEqual(8);
29
+ describe('零消费者与跨 seam 收缩(harness#137 / #162)', () => {
30
+ it('已删/已迁的五个名字在模块运行时键里都不存在', async () => {
31
+ const mod = await import('../utils/exec');
32
+ expect(Object.keys(mod).sort()).toEqual(['execAsync']);
33
+ for (const gone of [
34
+ 'isCommandAvailable',
35
+ 'delay',
36
+ 'normalizeTriggers',
37
+ 'matchesTrigger',
38
+ 'runCommand',
39
+ ]) {
40
+ expect(mod).not.toHaveProperty(gone);
41
+ }
42
+ });
43
+
44
+ it('编译期钉:五个名字不再是 utils/exec 的导出(复活即 TS2578 红)', () => {
45
+ // 上面的 @ts-expect-error 只在名字**不存在**时成立;此处消费导入名让指令进入生效路径
46
+ expect([isCommandAvailable, delay, normalizeTriggers, matchesTrigger, runCommand]).toEqual([
47
+ undefined,
48
+ undefined,
49
+ undefined,
50
+ undefined,
51
+ undefined,
52
+ ]);
115
53
  });
116
54
  });
117
55
  });
@@ -4,18 +4,20 @@
4
4
 
5
5
  import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
6
6
  import { FailureRecorder, createFailureRecorder } from '../failure/recorder';
7
- import { ErrorType, FailureLevel } from '../failure/types';
7
+ import { ErrorType, FailureLevel } from '../types/failure';
8
8
  import * as fs from 'fs';
9
9
  import * as path from 'path';
10
- import type { FailureRecord } from '../failure/types';
10
+ import * as os from 'os';
11
+ import type { FailureRecord } from '../types/failure';
11
12
 
12
13
  describe('FailureRecorder', () => {
13
- const tempDir = path.join(process.cwd(), 'temp-test-recorder');
14
- const logFile = path.join(tempDir, 'failures.log');
14
+ let tempDir: string;
15
+ let logFile: string;
15
16
  let recorder: FailureRecorder;
16
17
 
17
18
  beforeAll(() => {
18
- fs.mkdirSync(tempDir, { recursive: true });
19
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'temp-test-recorder-'));
20
+ logFile = path.join(tempDir, 'failures.log');
19
21
  });
20
22
 
21
23
  afterAll(() => {
@@ -1,10 +1,13 @@
1
1
  /**
2
2
  * HookRegistry + HookPipeline 测试(Phase 1)
3
+ *
4
+ * #159 起 `enabled` / `errorStrategy` 由 HookConfig 唯一声明,
5
+ * 注册时以配置填充有效值;HookDefinition 不再携带这两个字段。
3
6
  */
4
7
  import { describe, it, expect, beforeEach } from '@jest/globals';
5
8
  import { HookRegistry } from '../hooks/registry';
6
9
  import { HookPipeline } from '../hooks/pipeline';
7
- import type { HookDefinition } from '../hooks/types';
10
+ import type { HookConfig, HookDefinition } from '../hooks/types';
8
11
 
9
12
  interface TestContext {
10
13
  value: string;
@@ -19,7 +22,6 @@ function makeHook(
19
22
  name,
20
23
  phase: 'before',
21
24
  priority: 100,
22
- errorStrategy: 'block',
23
25
  execute: async (ctx) => {
24
26
  ctx.calls.push(name);
25
27
  return { passed: true };
@@ -28,6 +30,10 @@ function makeHook(
28
30
  };
29
31
  }
30
32
 
33
+ function makeConfig(name: string, overrides: Partial<HookConfig> = {}): HookConfig {
34
+ return { name, enabled: true, errorStrategy: 'block', ...overrides };
35
+ }
36
+
31
37
  describe('HookRegistry', () => {
32
38
  let registry: HookRegistry<TestContext, unknown>;
33
39
 
@@ -36,34 +42,34 @@ describe('HookRegistry', () => {
36
42
  });
37
43
 
38
44
  it('应注册 hook', () => {
39
- registry.register(makeHook('test'));
45
+ registry.register(makeHook('test'), makeConfig('test'));
40
46
  expect(registry.get('test')).toBeDefined();
41
47
  });
42
48
 
43
49
  it('同名注册应覆盖', () => {
44
- registry.register(makeHook('test', { priority: 50 }));
45
- registry.register(makeHook('test', { priority: 90 }));
50
+ registry.register(makeHook('test', { priority: 50 }), makeConfig('test'));
51
+ registry.register(makeHook('test', { priority: 90 }), makeConfig('test'));
46
52
  expect(registry.get('test')?.priority).toBe(90);
47
53
  });
48
54
 
49
55
  it('应获取已启用的 hook 按优先级排序', () => {
50
- registry.register(makeHook('low', { priority: 200 }));
51
- registry.register(makeHook('high', { priority: 10 }));
52
- registry.register(makeHook('mid', { priority: 100 }));
53
- registry.register(makeHook('disabled', { enabled: false }));
56
+ registry.register(makeHook('low', { priority: 200 }), makeConfig('low'));
57
+ registry.register(makeHook('high', { priority: 10 }), makeConfig('high'));
58
+ registry.register(makeHook('mid', { priority: 100 }), makeConfig('mid'));
59
+ registry.register(makeHook('disabled'), makeConfig('disabled', { enabled: false }));
54
60
 
55
61
  const enabled = registry.getEnabled('before');
56
62
  expect(enabled.map(h => h.name)).toEqual(['high', 'mid', 'low']);
57
63
  });
58
64
 
59
65
  it('应注销 hook', () => {
60
- registry.register(makeHook('test'));
66
+ registry.register(makeHook('test'), makeConfig('test'));
61
67
  expect(registry.unregister('test')).toBe(true);
62
68
  expect(registry.get('test')).toBeUndefined();
63
69
  });
64
70
 
65
71
  it('应设置启用/禁用', () => {
66
- registry.register(makeHook('test'));
72
+ registry.register(makeHook('test'), makeConfig('test'));
67
73
  expect(registry.setEnabled('test', false)).toBe(true);
68
74
  expect(registry.getEnabled('before').length).toBe(0);
69
75
  expect(registry.setEnabled('test', true)).toBe(true);
@@ -72,8 +78,8 @@ describe('HookRegistry', () => {
72
78
 
73
79
  it('应正确统计数量', () => {
74
80
  expect(registry.size).toBe(0);
75
- registry.register(makeHook('a'));
76
- registry.register(makeHook('b'));
81
+ registry.register(makeHook('a'), makeConfig('a'));
82
+ registry.register(makeHook('b'), makeConfig('b'));
77
83
  expect(registry.size).toBe(2);
78
84
  });
79
85
  });
@@ -89,8 +95,8 @@ describe('HookPipeline', () => {
89
95
 
90
96
  it('应执行所有 before hook', async () => {
91
97
  const ctx: TestContext = { value: '', calls: [] };
92
- registry.register(makeHook('h1'));
93
- registry.register(makeHook('h2'));
98
+ registry.register(makeHook('h1'), makeConfig('h1'));
99
+ registry.register(makeHook('h2'), makeConfig('h2'));
94
100
 
95
101
  const result = await pipeline.run('before', ctx);
96
102
 
@@ -101,12 +107,11 @@ describe('HookPipeline', () => {
101
107
 
102
108
  it('blocking hook 失败应停止后续', async () => {
103
109
  const ctx: TestContext = { value: '', calls: [] };
104
- registry.register(makeHook('pass1'));
110
+ registry.register(makeHook('pass1'), makeConfig('pass1'));
105
111
  registry.register(makeHook('block', {
106
112
  execute: async () => ({ passed: false, error: 'blocked' }),
107
- errorStrategy: 'block',
108
- }));
109
- registry.register(makeHook('never_runs'));
113
+ }), makeConfig('block', { errorStrategy: 'block' }));
114
+ registry.register(makeHook('never_runs'), makeConfig('never_runs'));
110
115
 
111
116
  const result = await pipeline.run('before', ctx);
112
117
 
@@ -121,9 +126,8 @@ describe('HookPipeline', () => {
121
126
  const ctx: TestContext = { value: '', calls: [] };
122
127
  registry.register(makeHook('warn_hook', {
123
128
  execute: async () => ({ passed: false, error: 'warning' }),
124
- errorStrategy: 'warn',
125
- }));
126
- registry.register(makeHook('should_still_run'));
129
+ }), makeConfig('warn_hook', { errorStrategy: 'warn' }));
130
+ registry.register(makeHook('should_still_run'), makeConfig('should_still_run'));
127
131
 
128
132
  const result = await pipeline.run('before', ctx);
129
133
 
@@ -132,28 +136,12 @@ describe('HookPipeline', () => {
132
136
  expect(ctx.calls).toContain('should_still_run');
133
137
  });
134
138
 
135
- it('ignore hook 失败应静默继续', async () => {
136
- const ctx: TestContext = { value: '', calls: [] };
137
- registry.register(makeHook('ignore_hook', {
138
- execute: async () => ({ passed: false, error: 'ignored' }),
139
- errorStrategy: 'ignore',
140
- }));
141
- registry.register(makeHook('still_runs'));
142
-
143
- const result = await pipeline.run('before', ctx);
144
-
145
- expect(result.passed).toBe(true);
146
- expect(result.warnings).toEqual([]);
147
- expect(ctx.calls).toContain('still_runs');
148
- });
149
-
150
139
  it('hook 抛异常应被捕获', async () => {
151
140
  const ctx: TestContext = { value: '', calls: [] };
152
141
  registry.register(makeHook('throws', {
153
142
  execute: async () => { throw new Error('crash'); },
154
- errorStrategy: 'warn',
155
- }));
156
- registry.register(makeHook('after_crash', { priority: 200 }));
143
+ }), makeConfig('throws', { errorStrategy: 'warn' }));
144
+ registry.register(makeHook('after_crash', { priority: 200 }), makeConfig('after_crash'));
157
145
 
158
146
  const result = await pipeline.run('before', ctx);
159
147
 
@@ -163,10 +151,10 @@ describe('HookPipeline', () => {
163
151
 
164
152
  it('runFull 应在 before/after 之间执行操作', async () => {
165
153
  const ctx: TestContext = { value: '', calls: [] };
166
- registry.register(makeHook('before_hook'));
154
+ registry.register(makeHook('before_hook'), makeConfig('before_hook'));
167
155
 
168
156
  const afterHook = makeHook('after_hook', { phase: 'after' });
169
- registry.register(afterHook);
157
+ registry.register(afterHook, makeConfig('after_hook'));
170
158
 
171
159
  const { pipelineResult, operationResult } = await pipeline.runFull(ctx, async () => {
172
160
  ctx.calls.push('operation');
@@ -182,8 +170,7 @@ describe('HookPipeline', () => {
182
170
  const ctx: TestContext = { value: '', calls: [] };
183
171
  registry.register(makeHook('block', {
184
172
  execute: async () => ({ passed: false }),
185
- errorStrategy: 'block',
186
- }));
173
+ }), makeConfig('block', { errorStrategy: 'block' }));
187
174
 
188
175
  const { pipelineResult, operationResult } = await pipeline.runFull(ctx, async () => {
189
176
  ctx.calls.push('should_not_run');
@@ -201,10 +188,10 @@ describe('HookPipeline', () => {
201
188
  expect(result.records).toEqual([]);
202
189
  });
203
190
 
204
- it('应忽略 disabled hook', async () => {
191
+ it('应忽略配置禁用的 hook', async () => {
205
192
  const ctx: TestContext = { value: '', calls: [] };
206
- registry.register(makeHook('enabled'));
207
- registry.register(makeHook('disabled', { enabled: false }));
193
+ registry.register(makeHook('enabled'), makeConfig('enabled'));
194
+ registry.register(makeHook('disabled'), makeConfig('disabled', { enabled: false }));
208
195
 
209
196
  await pipeline.run('before', ctx);
210
197