@dommaker/harness 0.16.6 → 0.16.8

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 (641) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +54 -14
  3. package/bin/harness.js +56 -96
  4. package/dist/architecture/constraint-engine.d.ts.map +1 -1
  5. package/dist/architecture/constraint-engine.js +0 -4
  6. package/dist/architecture/constraint-engine.js.map +1 -1
  7. package/dist/architecture/cross-project-checker.d.ts.map +1 -1
  8. package/dist/architecture/cross-project-checker.js +5 -25
  9. package/dist/architecture/cross-project-checker.js.map +1 -1
  10. package/dist/cli/commands/analyze-sessions.d.ts +2 -0
  11. package/dist/cli/commands/analyze-sessions.d.ts.map +1 -1
  12. package/dist/cli/commands/analyze-sessions.js +25 -181
  13. package/dist/cli/commands/analyze-sessions.js.map +1 -1
  14. package/dist/cli/commands/check.d.ts +1 -0
  15. package/dist/cli/commands/check.d.ts.map +1 -1
  16. package/dist/cli/commands/check.js +24 -216
  17. package/dist/cli/commands/check.js.map +1 -1
  18. package/dist/cli/commands/doc-freshness-check.d.ts.map +1 -1
  19. package/dist/cli/commands/doc-freshness-check.js +14 -28
  20. package/dist/cli/commands/doc-freshness-check.js.map +1 -1
  21. package/dist/cli/commands/flow.d.ts.map +1 -1
  22. package/dist/cli/commands/flow.js +2 -1
  23. package/dist/cli/commands/flow.js.map +1 -1
  24. package/dist/cli/commands/init.js +2 -2
  25. package/dist/cli/commands/init.js.map +1 -1
  26. package/dist/cli/commands/posteval-plan.d.ts.map +1 -1
  27. package/dist/cli/commands/posteval-plan.js +0 -1
  28. package/dist/cli/commands/posteval-plan.js.map +1 -1
  29. package/dist/cli/commands/release.js +1 -1
  30. package/dist/cli/commands/release.js.map +1 -1
  31. package/dist/cli/commands/report.d.ts.map +1 -1
  32. package/dist/cli/commands/report.js +2 -0
  33. package/dist/cli/commands/report.js.map +1 -1
  34. package/dist/cli/commands/spec-baseline-check.d.ts.map +1 -1
  35. package/dist/cli/commands/spec-baseline-check.js +12 -23
  36. package/dist/cli/commands/spec-baseline-check.js.map +1 -1
  37. package/dist/cli/commands/sync-docs/agents-syncer.d.ts +19 -0
  38. package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -0
  39. package/dist/cli/commands/sync-docs/agents-syncer.js +288 -0
  40. package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -0
  41. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts +37 -0
  42. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts.map +1 -0
  43. package/dist/cli/commands/sync-docs/capabilities-syncer.js +235 -0
  44. package/dist/cli/commands/sync-docs/capabilities-syncer.js.map +1 -0
  45. package/dist/cli/commands/sync-docs/context-syncer.d.ts +17 -0
  46. package/dist/cli/commands/sync-docs/context-syncer.d.ts.map +1 -0
  47. package/dist/cli/commands/sync-docs/context-syncer.js +143 -0
  48. package/dist/cli/commands/sync-docs/context-syncer.js.map +1 -0
  49. package/dist/cli/commands/{sync-docs.d.ts → sync-docs/index.d.ts} +9 -2
  50. package/dist/cli/commands/sync-docs/index.d.ts.map +1 -0
  51. package/dist/cli/commands/sync-docs/index.js +338 -0
  52. package/dist/cli/commands/sync-docs/index.js.map +1 -0
  53. package/dist/cli/commands/sync-docs/preserve-block.d.ts +24 -0
  54. package/dist/cli/commands/sync-docs/preserve-block.d.ts.map +1 -0
  55. package/dist/cli/commands/sync-docs/preserve-block.js +55 -0
  56. package/dist/cli/commands/sync-docs/preserve-block.js.map +1 -0
  57. package/dist/cli/commands/sync-docs/project-reader.d.ts +41 -0
  58. package/dist/cli/commands/sync-docs/project-reader.d.ts.map +1 -0
  59. package/dist/cli/commands/sync-docs/project-reader.js +183 -0
  60. package/dist/cli/commands/sync-docs/project-reader.js.map +1 -0
  61. package/dist/cli/commands/update-user-model.d.ts +2 -0
  62. package/dist/cli/commands/update-user-model.d.ts.map +1 -1
  63. package/dist/cli/commands/update-user-model.js +19 -90
  64. package/dist/cli/commands/update-user-model.js.map +1 -1
  65. package/dist/cli/commands/validate.d.ts +3 -0
  66. package/dist/cli/commands/validate.d.ts.map +1 -1
  67. package/dist/cli/commands/validate.js +6 -39
  68. package/dist/cli/commands/validate.js.map +1 -1
  69. package/dist/cli/session-mining/corrections.d.ts +17 -0
  70. package/dist/cli/session-mining/corrections.d.ts.map +1 -0
  71. package/dist/cli/session-mining/corrections.js +58 -0
  72. package/dist/cli/session-mining/corrections.js.map +1 -0
  73. package/dist/cli/session-mining/index.d.ts +13 -0
  74. package/dist/cli/session-mining/index.d.ts.map +1 -0
  75. package/dist/{core/spec → cli/session-mining}/index.js +9 -3
  76. package/dist/cli/session-mining/index.js.map +1 -0
  77. package/dist/cli/session-mining/text.d.ts +31 -0
  78. package/dist/cli/session-mining/text.d.ts.map +1 -0
  79. package/dist/cli/session-mining/text.js +126 -0
  80. package/dist/cli/session-mining/text.js.map +1 -0
  81. package/dist/cli/session-mining/transcript.d.ts +28 -0
  82. package/dist/cli/session-mining/transcript.d.ts.map +1 -0
  83. package/dist/cli/session-mining/transcript.js +123 -0
  84. package/dist/cli/session-mining/transcript.js.map +1 -0
  85. package/dist/constraints/lifecycle-runner.d.ts +1 -1
  86. package/dist/constraints/lifecycle-runner.d.ts.map +1 -1
  87. package/dist/context/compaction.d.ts.map +1 -1
  88. package/dist/context/compaction.js +2 -3
  89. package/dist/context/compaction.js.map +1 -1
  90. package/dist/context/knowledge-injector.d.ts.map +1 -1
  91. package/dist/context/tool-output-budget.d.ts +1 -1
  92. package/dist/context/tool-output-budget.d.ts.map +1 -1
  93. package/dist/context/tool-output-budget.js +1 -1
  94. package/dist/context/tool-output-budget.js.map +1 -1
  95. package/dist/core/constraints/capabilities-parser.d.ts +24 -0
  96. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -0
  97. package/dist/core/constraints/capabilities-parser.js +95 -0
  98. package/dist/core/constraints/capabilities-parser.js.map +1 -0
  99. package/dist/core/constraints/checker.d.ts +37 -100
  100. package/dist/core/constraints/checker.d.ts.map +1 -1
  101. package/dist/core/constraints/checker.js +150 -737
  102. package/dist/core/constraints/checker.js.map +1 -1
  103. package/dist/core/constraints/checkers/always-pass.d.ts +17 -0
  104. package/dist/core/constraints/checkers/always-pass.d.ts.map +1 -0
  105. package/dist/core/constraints/checkers/always-pass.js +23 -0
  106. package/dist/core/constraints/checkers/always-pass.js.map +1 -0
  107. package/dist/core/constraints/checkers/capability-sync.d.ts +10 -0
  108. package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -0
  109. package/dist/core/constraints/checkers/capability-sync.js +60 -0
  110. package/dist/core/constraints/checkers/capability-sync.js.map +1 -0
  111. package/dist/core/constraints/checkers/context-doc-sync.d.ts +6 -0
  112. package/dist/core/constraints/checkers/context-doc-sync.d.ts.map +1 -0
  113. package/dist/core/constraints/checkers/context-doc-sync.js +35 -0
  114. package/dist/core/constraints/checkers/context-doc-sync.js.map +1 -0
  115. package/dist/core/constraints/checkers/docs-freshness.d.ts +10 -0
  116. package/dist/core/constraints/checkers/docs-freshness.d.ts.map +1 -0
  117. package/dist/core/constraints/checkers/docs-freshness.js +111 -0
  118. package/dist/core/constraints/checkers/docs-freshness.js.map +1 -0
  119. package/dist/core/constraints/checkers/guideline-flags.d.ts +9 -0
  120. package/dist/core/constraints/checkers/guideline-flags.d.ts.map +1 -0
  121. package/dist/core/constraints/checkers/guideline-flags.js +13 -0
  122. package/dist/core/constraints/checkers/guideline-flags.js.map +1 -0
  123. package/dist/core/constraints/checkers/index.d.ts +17 -0
  124. package/dist/core/constraints/checkers/index.d.ts.map +1 -0
  125. package/dist/core/constraints/checkers/index.js +82 -0
  126. package/dist/core/constraints/checkers/index.js.map +1 -0
  127. package/dist/core/constraints/checkers/iron-flags.d.ts +14 -0
  128. package/dist/core/constraints/checkers/iron-flags.d.ts.map +1 -0
  129. package/dist/core/constraints/checkers/iron-flags.js +24 -0
  130. package/dist/core/constraints/checkers/iron-flags.js.map +1 -0
  131. package/dist/core/constraints/checkers/no-any-type.d.ts +6 -0
  132. package/dist/core/constraints/checkers/no-any-type.d.ts.map +1 -0
  133. package/dist/core/constraints/checkers/no-any-type.js +42 -0
  134. package/dist/core/constraints/checkers/no-any-type.js.map +1 -0
  135. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts +6 -0
  136. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts.map +1 -0
  137. package/dist/core/constraints/checkers/no-bypass-checkpoint.js +40 -0
  138. package/dist/core/constraints/checkers/no-bypass-checkpoint.js.map +1 -0
  139. package/dist/core/constraints/checkers/no-excuse-patterns.d.ts +6 -0
  140. package/dist/core/constraints/checkers/no-excuse-patterns.d.ts.map +1 -0
  141. package/dist/core/constraints/checkers/no-excuse-patterns.js +25 -0
  142. package/dist/core/constraints/checkers/no-excuse-patterns.js.map +1 -0
  143. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.d.ts +6 -0
  144. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.d.ts.map +1 -0
  145. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.js +34 -0
  146. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.js.map +1 -0
  147. package/dist/core/constraints/checkers/no-performative-agreement.d.ts +8 -0
  148. package/dist/core/constraints/checkers/no-performative-agreement.d.ts.map +1 -0
  149. package/dist/core/constraints/checkers/no-performative-agreement.js +23 -0
  150. package/dist/core/constraints/checkers/no-performative-agreement.js.map +1 -0
  151. package/dist/core/constraints/checkers/no-simplification-without-approval.d.ts +6 -0
  152. package/dist/core/constraints/checkers/no-simplification-without-approval.d.ts.map +1 -0
  153. package/dist/core/constraints/checkers/no-simplification-without-approval.js +30 -0
  154. package/dist/core/constraints/checkers/no-simplification-without-approval.js.map +1 -0
  155. package/dist/core/constraints/checkers/no-test-simplification.d.ts +6 -0
  156. package/dist/core/constraints/checkers/no-test-simplification.d.ts.map +1 -0
  157. package/dist/core/constraints/checkers/no-test-simplification.js +29 -0
  158. package/dist/core/constraints/checkers/no-test-simplification.js.map +1 -0
  159. package/dist/core/constraints/checkers/test-coverage.d.ts +6 -0
  160. package/dist/core/constraints/checkers/test-coverage.d.ts.map +1 -0
  161. package/dist/core/constraints/checkers/test-coverage.js +33 -0
  162. package/dist/core/constraints/checkers/test-coverage.js.map +1 -0
  163. package/dist/core/constraints/checkers/types.d.ts +43 -0
  164. package/dist/core/constraints/checkers/types.d.ts.map +1 -0
  165. package/dist/core/constraints/checkers/types.js +23 -0
  166. package/dist/core/constraints/checkers/types.js.map +1 -0
  167. package/dist/core/constraints/checkers/yagni.d.ts +8 -0
  168. package/dist/core/constraints/checkers/yagni.d.ts.map +1 -0
  169. package/dist/core/constraints/checkers/yagni.js +96 -0
  170. package/dist/core/constraints/checkers/yagni.js.map +1 -0
  171. package/dist/core/constraints/context-builder.d.ts +67 -0
  172. package/dist/core/constraints/context-builder.d.ts.map +1 -0
  173. package/dist/core/constraints/context-builder.js +294 -0
  174. package/dist/core/constraints/context-builder.js.map +1 -0
  175. package/dist/core/constraints/definitions/guidelines.d.ts +7 -0
  176. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -0
  177. package/dist/core/constraints/definitions/guidelines.js +641 -0
  178. package/dist/core/constraints/definitions/guidelines.js.map +1 -0
  179. package/dist/core/constraints/definitions/iron-laws.d.ts +7 -0
  180. package/dist/core/constraints/definitions/iron-laws.d.ts.map +1 -0
  181. package/dist/core/constraints/definitions/iron-laws.js +322 -0
  182. package/dist/core/constraints/definitions/iron-laws.js.map +1 -0
  183. package/dist/core/constraints/definitions/tips.d.ts +7 -0
  184. package/dist/core/constraints/definitions/tips.d.ts.map +1 -0
  185. package/dist/core/constraints/definitions/tips.js +62 -0
  186. package/dist/core/constraints/definitions/tips.js.map +1 -0
  187. package/dist/core/constraints/definitions.d.ts +8 -21
  188. package/dist/core/constraints/definitions.d.ts.map +1 -1
  189. package/dist/core/constraints/definitions.js +15 -1048
  190. package/dist/core/constraints/definitions.js.map +1 -1
  191. package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
  192. package/dist/core/constraints/doc-freshness/runner.js +0 -1
  193. package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
  194. package/dist/core/constraints/index.d.ts +4 -5
  195. package/dist/core/constraints/index.d.ts.map +1 -1
  196. package/dist/core/constraints/index.js +1 -16
  197. package/dist/core/constraints/index.js.map +1 -1
  198. package/dist/core/constraints/interceptor.d.ts.map +1 -1
  199. package/dist/core/constraints/interceptor.js.map +1 -1
  200. package/dist/core/index.js +0 -1
  201. package/dist/core/index.js.map +1 -1
  202. package/dist/core/project-config-loader.d.ts +6 -4
  203. package/dist/core/project-config-loader.d.ts.map +1 -1
  204. package/dist/core/project-config-loader.js +46 -13
  205. package/dist/core/project-config-loader.js.map +1 -1
  206. package/dist/core/validators/check-handlers/command.d.ts +7 -0
  207. package/dist/core/validators/check-handlers/command.d.ts.map +1 -0
  208. package/dist/core/validators/check-handlers/command.js +58 -0
  209. package/dist/core/validators/check-handlers/command.js.map +1 -0
  210. package/dist/core/validators/check-handlers/file.d.ts +10 -0
  211. package/dist/core/validators/check-handlers/file.d.ts.map +1 -0
  212. package/dist/core/validators/check-handlers/file.js +128 -0
  213. package/dist/core/validators/check-handlers/file.js.map +1 -0
  214. package/dist/core/validators/check-handlers/http.d.ts +7 -0
  215. package/dist/core/validators/check-handlers/http.d.ts.map +1 -0
  216. package/dist/core/validators/check-handlers/http.js +88 -0
  217. package/dist/core/validators/check-handlers/http.js.map +1 -0
  218. package/dist/core/validators/check-handlers/output.d.ts +15 -0
  219. package/dist/core/validators/check-handlers/output.d.ts.map +1 -0
  220. package/dist/core/validators/check-handlers/output.js +152 -0
  221. package/dist/core/validators/check-handlers/output.js.map +1 -0
  222. package/dist/core/validators/checkpoint.d.ts +4 -72
  223. package/dist/core/validators/checkpoint.d.ts.map +1 -1
  224. package/dist/core/validators/checkpoint.js +21 -400
  225. package/dist/core/validators/checkpoint.js.map +1 -1
  226. package/dist/core/validators/cso.js +1 -1
  227. package/dist/core/validators/cso.js.map +1 -1
  228. package/dist/core/validators/passes-gate.js +2 -2
  229. package/dist/core/validators/passes-gate.js.map +1 -1
  230. package/dist/dashboard/stats.d.ts.map +1 -1
  231. package/dist/dashboard/types.d.ts.map +1 -1
  232. package/dist/evolution/auto-evolve.d.ts +1 -2
  233. package/dist/evolution/auto-evolve.d.ts.map +1 -1
  234. package/dist/evolution/auto-evolve.js +2 -1
  235. package/dist/evolution/auto-evolve.js.map +1 -1
  236. package/dist/failure/types.d.ts +5 -85
  237. package/dist/failure/types.d.ts.map +1 -1
  238. package/dist/failure/types.js +19 -115
  239. package/dist/failure/types.js.map +1 -1
  240. package/dist/gates/contract.d.ts.map +1 -1
  241. package/dist/gates/contract.js.map +1 -1
  242. package/dist/gates/index.d.ts.map +1 -1
  243. package/dist/gates/index.js.map +1 -1
  244. package/dist/gates/performance.js +1 -1
  245. package/dist/gates/performance.js.map +1 -1
  246. package/dist/gates/security.d.ts.map +1 -1
  247. package/dist/gates/security.js +1 -1
  248. package/dist/gates/security.js.map +1 -1
  249. package/dist/hooks/bootstrap.d.ts.map +1 -1
  250. package/dist/hooks/bootstrap.js +6 -48
  251. package/dist/hooks/bootstrap.js.map +1 -1
  252. package/dist/index.d.ts +0 -1
  253. package/dist/index.d.ts.map +1 -1
  254. package/dist/index.js +3 -1
  255. package/dist/index.js.map +1 -1
  256. package/dist/knowledge/audit.d.ts.map +1 -1
  257. package/dist/knowledge/doctor.d.ts.map +1 -1
  258. package/dist/knowledge/doctor.js.map +1 -1
  259. package/dist/knowledge/import.d.ts.map +1 -1
  260. package/dist/knowledge/import.js +1 -1
  261. package/dist/knowledge/import.js.map +1 -1
  262. package/dist/knowledge/index-generator.d.ts.map +1 -1
  263. package/dist/knowledge/index-generator.js +0 -1
  264. package/dist/knowledge/index-generator.js.map +1 -1
  265. package/dist/knowledge/ingest.d.ts.map +1 -1
  266. package/dist/knowledge/ingest.js +1 -1
  267. package/dist/knowledge/ingest.js.map +1 -1
  268. package/dist/knowledge/lint.d.ts +1 -1
  269. package/dist/knowledge/lint.d.ts.map +1 -1
  270. package/dist/knowledge/lint.js +2 -2
  271. package/dist/knowledge/lint.js.map +1 -1
  272. package/dist/knowledge/primitives/code-structure.d.ts.map +1 -1
  273. package/dist/knowledge/primitives/code-structure.js +29 -12
  274. package/dist/knowledge/primitives/code-structure.js.map +1 -1
  275. package/dist/knowledge/query.d.ts.map +1 -1
  276. package/dist/knowledge/query.js.map +1 -1
  277. package/dist/knowledge/store.d.ts.map +1 -1
  278. package/dist/llm/adapter.d.ts +3 -3
  279. package/dist/llm/adapter.d.ts.map +1 -1
  280. package/dist/llm/adapter.js +3 -3
  281. package/dist/llm/adapter.js.map +1 -1
  282. package/dist/monitoring/analyzer-base.d.ts +50 -0
  283. package/dist/monitoring/analyzer-base.d.ts.map +1 -0
  284. package/dist/monitoring/analyzer-base.js +146 -0
  285. package/dist/monitoring/analyzer-base.js.map +1 -0
  286. package/dist/monitoring/constraint-doctor.d.ts +3 -46
  287. package/dist/monitoring/constraint-doctor.d.ts.map +1 -1
  288. package/dist/monitoring/constraint-doctor.js +11 -113
  289. package/dist/monitoring/constraint-doctor.js.map +1 -1
  290. package/dist/monitoring/constraint-evolver.d.ts +9 -63
  291. package/dist/monitoring/constraint-evolver.d.ts.map +1 -1
  292. package/dist/monitoring/constraint-evolver.js +8 -10
  293. package/dist/monitoring/constraint-evolver.js.map +1 -1
  294. package/dist/monitoring/diagnosis-rules.d.ts +18 -0
  295. package/dist/monitoring/diagnosis-rules.d.ts.map +1 -0
  296. package/dist/monitoring/diagnosis-rules.js +119 -0
  297. package/dist/monitoring/diagnosis-rules.js.map +1 -0
  298. package/dist/monitoring/knowledge-doctor.d.ts.map +1 -1
  299. package/dist/monitoring/knowledge-doctor.js.map +1 -1
  300. package/dist/monitoring/performance-analyzer.d.ts +0 -12
  301. package/dist/monitoring/performance-analyzer.d.ts.map +1 -1
  302. package/dist/monitoring/performance-analyzer.js +13 -93
  303. package/dist/monitoring/performance-analyzer.js.map +1 -1
  304. package/dist/monitoring/performance-collector.d.ts +0 -8
  305. package/dist/monitoring/performance-collector.d.ts.map +1 -1
  306. package/dist/monitoring/performance-collector.js +0 -21
  307. package/dist/monitoring/performance-collector.js.map +1 -1
  308. package/dist/monitoring/trace-analyzer.d.ts +0 -8
  309. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  310. package/dist/monitoring/trace-analyzer.js +9 -91
  311. package/dist/monitoring/trace-analyzer.js.map +1 -1
  312. package/dist/presets/index.d.ts +1 -1
  313. package/dist/presets/index.d.ts.map +1 -1
  314. package/dist/presets/index.js +1 -4
  315. package/dist/presets/index.js.map +1 -1
  316. package/dist/presets/standard.d.ts +0 -9
  317. package/dist/presets/standard.d.ts.map +1 -1
  318. package/dist/presets/standard.js +1 -16
  319. package/dist/presets/standard.js.map +1 -1
  320. package/dist/safety/output-guardrail.d.ts +0 -1
  321. package/dist/safety/output-guardrail.d.ts.map +1 -1
  322. package/dist/safety/output-guardrail.js +0 -3
  323. package/dist/safety/output-guardrail.js.map +1 -1
  324. package/dist/tools/registry.d.ts.map +1 -1
  325. package/dist/types/constraint.d.ts +5 -59
  326. package/dist/types/constraint.d.ts.map +1 -1
  327. package/dist/types/constraint.js +1 -39
  328. package/dist/types/constraint.js.map +1 -1
  329. package/dist/types/failure.d.ts +89 -0
  330. package/dist/types/failure.d.ts.map +1 -0
  331. package/dist/types/failure.js +121 -0
  332. package/dist/types/failure.js.map +1 -0
  333. package/dist/types/index.d.ts +2 -3
  334. package/dist/types/index.d.ts.map +1 -1
  335. package/dist/types/index.js +7 -6
  336. package/dist/types/index.js.map +1 -1
  337. package/dist/types/monitoring-types.d.ts +114 -0
  338. package/dist/types/monitoring-types.d.ts.map +1 -0
  339. package/dist/types/monitoring-types.js +10 -0
  340. package/dist/types/monitoring-types.js.map +1 -0
  341. package/dist/utils/detect-source-roots.js.map +1 -1
  342. package/dist/utils/file-walk.d.ts +33 -0
  343. package/dist/utils/file-walk.d.ts.map +1 -0
  344. package/dist/utils/file-walk.js +89 -0
  345. package/dist/utils/file-walk.js.map +1 -0
  346. package/dist/verification/rules-based.d.ts.map +1 -1
  347. package/dist/verification/rules-based.js.map +1 -1
  348. package/package.json +3 -7
  349. package/src/__tests__/checker-extra.test.ts +0 -30
  350. package/src/__tests__/checker.test.ts +0 -33
  351. package/src/__tests__/checkpoint.test.ts +46 -46
  352. package/src/__tests__/constraint-evolver.test.ts +22 -21
  353. package/src/__tests__/doctor-evolver.test.ts +3 -3
  354. package/src/__tests__/iron-laws.test.ts +0 -27
  355. package/src/__tests__/presets.test.ts +1 -40
  356. package/src/architecture/constraint-engine.ts +0 -5
  357. package/src/architecture/cross-project-checker.ts +6 -24
  358. package/src/cli/commands/__tests__/check.test.ts +3 -1
  359. package/src/cli/commands/__tests__/sync-docs.test.ts +77 -0
  360. package/src/cli/commands/__tests__/validate.test.ts +5 -0
  361. package/src/cli/commands/analyze-sessions.ts +31 -185
  362. package/src/cli/commands/check.ts +26 -225
  363. package/src/cli/commands/doc-freshness-check.ts +14 -25
  364. package/src/cli/commands/flow.ts +5 -3
  365. package/src/cli/commands/init.ts +3 -3
  366. package/src/cli/commands/posteval-plan.ts +0 -1
  367. package/src/cli/commands/release.ts +1 -1
  368. package/src/cli/commands/report.ts +2 -0
  369. package/src/cli/commands/spec-baseline-check.ts +12 -19
  370. package/src/cli/commands/sync-docs/agents-syncer.ts +280 -0
  371. package/src/cli/commands/sync-docs/capabilities-syncer.ts +229 -0
  372. package/src/cli/commands/sync-docs/context-syncer.ts +108 -0
  373. package/src/cli/commands/sync-docs/index.ts +355 -0
  374. package/src/cli/commands/sync-docs/preserve-block.ts +59 -0
  375. package/src/cli/commands/sync-docs/project-reader.ts +163 -0
  376. package/src/cli/commands/update-user-model.ts +23 -87
  377. package/src/cli/commands/validate.ts +6 -40
  378. package/src/cli/session-mining/corrections.ts +56 -0
  379. package/src/cli/session-mining/index.ts +13 -0
  380. package/src/cli/session-mining/text.ts +117 -0
  381. package/src/cli/session-mining/transcript.ts +107 -0
  382. package/src/constraints/__tests__/lifecycle-runner.test.ts +1 -1
  383. package/src/constraints/lifecycle-runner.ts +1 -1
  384. package/src/context/compaction.ts +2 -3
  385. package/src/context/knowledge-injector.ts +1 -1
  386. package/src/context/tool-output-budget.ts +1 -1
  387. package/src/core/constraints/capabilities-parser.ts +70 -0
  388. package/src/core/constraints/checker.ts +170 -779
  389. package/src/core/constraints/checkers/always-pass.ts +22 -0
  390. package/src/core/constraints/checkers/capability-sync.ts +71 -0
  391. package/src/core/constraints/checkers/context-doc-sync.ts +36 -0
  392. package/src/core/constraints/checkers/docs-freshness.ts +116 -0
  393. package/src/core/constraints/checkers/guideline-flags.ts +30 -0
  394. package/src/core/constraints/checkers/index.ts +114 -0
  395. package/src/core/constraints/checkers/iron-flags.ts +62 -0
  396. package/src/core/constraints/checkers/no-any-type.ts +42 -0
  397. package/src/core/constraints/checkers/no-bypass-checkpoint.ts +40 -0
  398. package/src/core/constraints/checkers/no-excuse-patterns.ts +24 -0
  399. package/src/core/constraints/checkers/no-fuzzy-completion-claim.ts +33 -0
  400. package/src/core/constraints/checkers/no-performative-agreement.ts +22 -0
  401. package/src/core/constraints/checkers/no-simplification-without-approval.ts +29 -0
  402. package/src/core/constraints/checkers/no-test-simplification.ts +28 -0
  403. package/src/core/constraints/checkers/test-coverage.ts +35 -0
  404. package/src/core/constraints/checkers/types.ts +54 -0
  405. package/src/core/constraints/checkers/yagni.ts +65 -0
  406. package/src/core/constraints/context-builder.ts +262 -0
  407. package/src/core/constraints/definitions/guidelines.ts +668 -0
  408. package/src/core/constraints/definitions/iron-laws.ts +333 -0
  409. package/src/core/constraints/definitions/tips.ts +63 -0
  410. package/src/core/constraints/definitions.ts +9 -1086
  411. package/src/core/constraints/doc-freshness/runner.ts +2 -3
  412. package/src/core/constraints/index.ts +1 -27
  413. package/src/core/constraints/interceptor.ts +0 -2
  414. package/src/core/index.ts +1 -1
  415. package/src/core/project-config-loader.ts +49 -13
  416. package/src/core/validators/check-handlers/command.ts +58 -0
  417. package/src/core/validators/check-handlers/file.ts +104 -0
  418. package/src/core/validators/check-handlers/http.ts +88 -0
  419. package/src/core/validators/check-handlers/output.ts +165 -0
  420. package/src/core/validators/checkpoint.ts +32 -407
  421. package/src/core/validators/cso.ts +1 -1
  422. package/src/core/validators/passes-gate.ts +2 -2
  423. package/src/dashboard/stats.ts +1 -1
  424. package/src/dashboard/types.ts +1 -1
  425. package/src/evolution/__tests__/auto-evolve.test.ts +1 -2
  426. package/src/evolution/auto-evolve.ts +3 -3
  427. package/src/failure/types.ts +5 -161
  428. package/src/gates/contract.ts +0 -1
  429. package/src/gates/index.ts +0 -2
  430. package/src/gates/performance.ts +1 -1
  431. package/src/gates/security.ts +1 -3
  432. package/src/hooks/bootstrap.ts +6 -16
  433. package/src/index.ts +4 -1
  434. package/src/knowledge/__tests__/lifecycle.test.ts +4 -1
  435. package/src/knowledge/audit.ts +1 -1
  436. package/src/knowledge/doctor.ts +0 -1
  437. package/src/knowledge/import.ts +2 -2
  438. package/src/knowledge/index-generator.ts +0 -1
  439. package/src/knowledge/ingest.ts +1 -2
  440. package/src/knowledge/lint.ts +2 -2
  441. package/src/knowledge/primitives/__tests__/code-structure-degrade.test.ts +24 -0
  442. package/src/knowledge/primitives/code-structure.ts +36 -12
  443. package/src/knowledge/query.ts +0 -3
  444. package/src/knowledge/store.ts +1 -1
  445. package/src/llm/adapter.ts +3 -3
  446. package/src/monitoring/analyzer-base.ts +112 -0
  447. package/src/monitoring/constraint-doctor.ts +14 -175
  448. package/src/monitoring/constraint-evolver.ts +20 -92
  449. package/src/monitoring/diagnosis-rules.ts +132 -0
  450. package/src/monitoring/knowledge-doctor.ts +0 -1
  451. package/src/monitoring/performance-analyzer.ts +22 -72
  452. package/src/monitoring/performance-collector.ts +0 -22
  453. package/src/monitoring/trace-analyzer.ts +17 -73
  454. package/src/presets/__tests__/standard.test.ts +2 -17
  455. package/src/presets/index.ts +1 -3
  456. package/src/presets/standard.ts +1 -26
  457. package/src/safety/output-guardrail.ts +0 -4
  458. package/src/tools/registry.ts +1 -1
  459. package/src/types/__tests__/types.test.ts +1 -33
  460. package/src/types/constraint.ts +6 -75
  461. package/src/types/failure.ts +165 -0
  462. package/src/types/index.ts +7 -5
  463. package/src/types/monitoring-types.ts +150 -0
  464. package/src/utils/detect-source-roots.ts +1 -1
  465. package/src/utils/file-walk.ts +78 -0
  466. package/src/verification/rules-based.ts +0 -1
  467. package/bin/harness-knowledge-capture.js +0 -99
  468. package/bin/harness-knowledge-check.js +0 -164
  469. package/bin/harness-knowledge-track.js +0 -118
  470. package/dist/cli/commands/sync-docs.d.ts.map +0 -1
  471. package/dist/cli/commands/sync-docs.js +0 -1074
  472. package/dist/cli/commands/sync-docs.js.map +0 -1
  473. package/dist/constraints/index.d.ts +0 -4
  474. package/dist/constraints/index.d.ts.map +0 -1
  475. package/dist/constraints/index.js +0 -20
  476. package/dist/constraints/index.js.map +0 -1
  477. package/dist/core/constraints/doc-freshness/auto-fix.d.ts +0 -23
  478. package/dist/core/constraints/doc-freshness/auto-fix.d.ts.map +0 -1
  479. package/dist/core/constraints/doc-freshness/auto-fix.js +0 -59
  480. package/dist/core/constraints/doc-freshness/auto-fix.js.map +0 -1
  481. package/dist/core/constraints/prompt-injection.d.ts +0 -16
  482. package/dist/core/constraints/prompt-injection.d.ts.map +0 -1
  483. package/dist/core/constraints/prompt-injection.js +0 -69
  484. package/dist/core/constraints/prompt-injection.js.map +0 -1
  485. package/dist/core/spec/index.d.ts +0 -7
  486. package/dist/core/spec/index.d.ts.map +0 -1
  487. package/dist/core/spec/index.js.map +0 -1
  488. package/dist/governance/executor.d.ts +0 -45
  489. package/dist/governance/executor.d.ts.map +0 -1
  490. package/dist/governance/executor.js +0 -243
  491. package/dist/governance/executor.js.map +0 -1
  492. package/dist/governance/index.d.ts +0 -9
  493. package/dist/governance/index.d.ts.map +0 -1
  494. package/dist/governance/index.js +0 -13
  495. package/dist/governance/index.js.map +0 -1
  496. package/dist/governance/types.d.ts +0 -46
  497. package/dist/governance/types.d.ts.map +0 -1
  498. package/dist/governance/types.js +0 -9
  499. package/dist/governance/types.js.map +0 -1
  500. package/dist/tools/definitions/definitions/core/code/fingerprint.sh +0 -273
  501. package/dist/tools/definitions/definitions/core/code/fingerprint.yml +0 -72
  502. package/dist/tools/definitions/definitions/core/code/parse.yml +0 -68
  503. package/dist/tools/definitions/definitions/core/code/register-language.sh +0 -475
  504. package/dist/tools/definitions/definitions/core/code/register-language.yml +0 -74
  505. package/dist/tools/definitions/definitions/core/docker/build.yml +0 -73
  506. package/dist/tools/definitions/definitions/core/docker/run.yml +0 -81
  507. package/dist/tools/definitions/definitions/core/file/copy.yml +0 -88
  508. package/dist/tools/definitions/definitions/core/file/read.yml +0 -69
  509. package/dist/tools/definitions/definitions/core/file/write.yml +0 -75
  510. package/dist/tools/definitions/definitions/core/git/branch.yml +0 -61
  511. package/dist/tools/definitions/definitions/core/git/cleanup-worktree.yml +0 -50
  512. package/dist/tools/definitions/definitions/core/git/clone.yml +0 -69
  513. package/dist/tools/definitions/definitions/core/git/commit.yml +0 -65
  514. package/dist/tools/definitions/definitions/core/git/push.yml +0 -79
  515. package/dist/tools/definitions/definitions/core/git/worktree.yml +0 -96
  516. package/dist/tools/definitions/definitions/core/notification/notify.sh +0 -152
  517. package/dist/tools/definitions/definitions/core/notification/notify.yml +0 -60
  518. package/dist/tools/definitions/definitions/core/npm/build.yml +0 -75
  519. package/dist/tools/definitions/definitions/core/npm/install.yml +0 -58
  520. package/dist/tools/definitions/definitions/core/npm/test.yml +0 -75
  521. package/dist/tools/definitions/definitions/core/validation/check-reuse.yml +0 -170
  522. package/dist/tools/definitions/definitions/core/validation/validate-handlers.yml +0 -118
  523. package/dist/tools/definitions/definitions/core/validation/validate-readme-stats.yml +0 -155
  524. package/dist/tools/definitions/definitions/core/validation/validate-yaml-syntax.yml +0 -134
  525. package/dist/tools/definitions/definitions/ext/browser/browser-automate.sh +0 -255
  526. package/dist/tools/definitions/definitions/ext/browser/browser-automate.yml +0 -166
  527. package/dist/tools/definitions/definitions/ext/browser/browser-close.sh +0 -104
  528. package/dist/tools/definitions/definitions/ext/browser/browser-close.yml +0 -55
  529. package/dist/tools/definitions/definitions/ext/browser/browser-mcp-debug.sh +0 -682
  530. package/dist/tools/definitions/definitions/ext/browser/browser-mcp-debug.yml +0 -167
  531. package/dist/tools/definitions/definitions/ext/browser/browser-start.sh +0 -101
  532. package/dist/tools/definitions/definitions/ext/browser/browser-start.yml +0 -62
  533. package/dist/tools/definitions/definitions/registry.json +0 -795
  534. package/dist/tools/definitions/definitions/std/README.md +0 -350
  535. package/dist/tools/definitions/definitions/std/analysis/analyze-codebase.yml +0 -72
  536. package/dist/tools/definitions/definitions/std/analysis/analyze-diff.yml +0 -182
  537. package/dist/tools/definitions/definitions/std/analysis/analyze-git-diff.yml +0 -70
  538. package/dist/tools/definitions/definitions/std/analysis/analyze-impact.yml +0 -78
  539. package/dist/tools/definitions/definitions/std/analysis/analyze-requirements.yml +0 -105
  540. package/dist/tools/definitions/definitions/std/analysis/brainstorm-options.yml +0 -106
  541. package/dist/tools/definitions/definitions/std/analysis/build-graph.yml +0 -154
  542. package/dist/tools/definitions/definitions/std/analysis/clarify-requirements.yml +0 -90
  543. package/dist/tools/definitions/definitions/std/analysis/detect-context.yml +0 -109
  544. package/dist/tools/definitions/definitions/std/analysis/detect-layers.yml +0 -125
  545. package/dist/tools/definitions/definitions/std/analysis/generate-tour.yml +0 -102
  546. package/dist/tools/definitions/definitions/std/analysis/search-enhance.yml +0 -105
  547. package/dist/tools/definitions/definitions/std/backlog/add.yml +0 -51
  548. package/dist/tools/definitions/definitions/std/backlog/decide.yml +0 -39
  549. package/dist/tools/definitions/definitions/std/backlog/github-sync.yml +0 -161
  550. package/dist/tools/definitions/definitions/std/backlog/list.yml +0 -53
  551. package/dist/tools/definitions/definitions/std/backlog/load.yml +0 -46
  552. package/dist/tools/definitions/definitions/std/backlog/resolve.yml +0 -37
  553. package/dist/tools/definitions/definitions/std/backlog/update.yml +0 -42
  554. package/dist/tools/definitions/definitions/std/bugfix/diagnose.yml +0 -68
  555. package/dist/tools/definitions/definitions/std/bugfix/fix.yml +0 -66
  556. package/dist/tools/definitions/definitions/std/bugfix/verify.yml +0 -69
  557. package/dist/tools/definitions/definitions/std/constraint/check-decomposition.yml +0 -103
  558. package/dist/tools/definitions/definitions/std/constraint/check-feature-list.yml +0 -77
  559. package/dist/tools/definitions/definitions/std/constraint/check-progress.yml +0 -97
  560. package/dist/tools/definitions/definitions/std/constraint/generate-report.yml +0 -147
  561. package/dist/tools/definitions/definitions/std/deploy/commit-push.yml +0 -33
  562. package/dist/tools/definitions/definitions/std/deploy/deploy-backend.yml +0 -37
  563. package/dist/tools/definitions/definitions/std/deploy/deploy-frontend.yml +0 -37
  564. package/dist/tools/definitions/definitions/std/deploy/rollback.yml +0 -148
  565. package/dist/tools/definitions/definitions/std/design/analyze-architecture-impact.yml +0 -113
  566. package/dist/tools/definitions/definitions/std/design/design-api.yml +0 -55
  567. package/dist/tools/definitions/definitions/std/design/design-architecture.yml +0 -97
  568. package/dist/tools/definitions/definitions/std/design/design-db.yml +0 -81
  569. package/dist/tools/definitions/definitions/std/design/generate-spec.yml +0 -182
  570. package/dist/tools/definitions/definitions/std/development/develop-api.yml +0 -85
  571. package/dist/tools/definitions/definitions/std/development/develop-backend.yml +0 -88
  572. package/dist/tools/definitions/definitions/std/development/develop-frontend.yml +0 -87
  573. package/dist/tools/definitions/definitions/std/development/develop-shared-types.yml +0 -74
  574. package/dist/tools/definitions/definitions/std/development/develop-task.yml +0 -122
  575. package/dist/tools/definitions/definitions/std/development/develop-tests.yml +0 -76
  576. package/dist/tools/definitions/definitions/std/development/execute-batch.yml +0 -152
  577. package/dist/tools/definitions/definitions/std/development/fix-issues.yml +0 -100
  578. package/dist/tools/definitions/definitions/std/development/implement-task.yml +0 -124
  579. package/dist/tools/definitions/definitions/std/development/review-fix-cycle.yml +0 -232
  580. package/dist/tools/definitions/definitions/std/evolution/implement.yml +0 -125
  581. package/dist/tools/definitions/definitions/std/evolution/prioritize.yml +0 -112
  582. package/dist/tools/definitions/definitions/std/evolution/report-gap.yml +0 -166
  583. package/dist/tools/definitions/definitions/std/file/read.yml +0 -21
  584. package/dist/tools/definitions/definitions/std/governance/aggregate-opinions.sh +0 -201
  585. package/dist/tools/definitions/definitions/std/governance/aggregate-opinions.yml +0 -79
  586. package/dist/tools/definitions/definitions/std/governance/audit-task.yml +0 -178
  587. package/dist/tools/definitions/definitions/std/governance/cast-vote.yml +0 -129
  588. package/dist/tools/definitions/definitions/std/governance/collect-issues.yml +0 -16
  589. package/dist/tools/definitions/definitions/std/governance/create-signed-document.yml +0 -23
  590. package/dist/tools/definitions/definitions/std/governance/create-voting-session.yml +0 -101
  591. package/dist/tools/definitions/definitions/std/governance/define-stance.sh +0 -243
  592. package/dist/tools/definitions/definitions/std/governance/define-stance.yml +0 -82
  593. package/dist/tools/definitions/definitions/std/governance/generate-review-report.yml +0 -23
  594. package/dist/tools/definitions/definitions/std/governance/impeach.yml +0 -179
  595. package/dist/tools/definitions/definitions/std/governance/multi-stance-review.yml +0 -154
  596. package/dist/tools/definitions/definitions/std/governance/prepare-artifact.yml +0 -20
  597. package/dist/tools/definitions/definitions/std/governance/review-spec-approval.yml +0 -262
  598. package/dist/tools/definitions/definitions/std/governance/rollback.yml +0 -186
  599. package/dist/tools/definitions/definitions/std/governance/stance-review.yml +0 -149
  600. package/dist/tools/definitions/definitions/std/governance/track-effect.yml +0 -199
  601. package/dist/tools/definitions/definitions/std/governance/vote-tally.yml +0 -144
  602. package/dist/tools/definitions/definitions/std/patch/execute.yml +0 -51
  603. package/dist/tools/definitions/definitions/std/planning/generate-tasks.yml +0 -36
  604. package/dist/tools/definitions/definitions/std/planning/load-tasks.yml +0 -44
  605. package/dist/tools/definitions/definitions/std/planning/split-batch.yml +0 -481
  606. package/dist/tools/definitions/definitions/std/planning/split-tasks.yml +0 -359
  607. package/dist/tools/definitions/definitions/std/planning/update-tasks.yml +0 -51
  608. package/dist/tools/definitions/definitions/std/planning/validate-tasks.yml +0 -46
  609. package/dist/tools/definitions/definitions/std/project/decide-next-workflow.yml +0 -38
  610. package/dist/tools/definitions/definitions/std/project/load-state.yml +0 -31
  611. package/dist/tools/definitions/definitions/std/project/save-state.yml +0 -32
  612. package/dist/tools/definitions/definitions/std/quality/check-quality.yml +0 -241
  613. package/dist/tools/definitions/definitions/std/quality/debug-systematic.yml +0 -163
  614. package/dist/tools/definitions/definitions/std/quality/handle-feedback.yml +0 -108
  615. package/dist/tools/definitions/definitions/std/quality/review-code.yml +0 -128
  616. package/dist/tools/definitions/definitions/std/quality/review-spec.yml +0 -140
  617. package/dist/tools/definitions/definitions/std/quality/review-task.yml +0 -190
  618. package/dist/tools/definitions/definitions/std/quality/run-tests.yml +0 -80
  619. package/dist/tools/definitions/definitions/std/quick/analyze.yml +0 -56
  620. package/dist/tools/definitions/definitions/std/quick/implement.yml +0 -67
  621. package/dist/tools/definitions/definitions/std/quick/verify.yml +0 -71
  622. package/dist/tools/definitions/definitions/std/verification/verify_completion.yml +0 -113
  623. package/dist/tools/definitions/definitions/std/verification/wait-condition.yml +0 -107
  624. package/dist/types/iron-law.d.ts +0 -25
  625. package/dist/types/iron-law.d.ts.map +0 -1
  626. package/dist/types/iron-law.js +0 -16
  627. package/dist/types/iron-law.js.map +0 -1
  628. package/src/cli/commands/sync-docs.ts +0 -1175
  629. package/src/constraints/index.ts +0 -3
  630. package/src/core/constraints/__tests__/prompt-injection.test.ts +0 -89
  631. package/src/core/constraints/doc-freshness/auto-fix.ts +0 -69
  632. package/src/core/constraints/prompt-injection.ts +0 -73
  633. package/src/core/spec/index.ts +0 -7
  634. package/src/governance/CONTEXT.md +0 -22
  635. package/src/governance/__tests__/executor.test.ts +0 -249
  636. package/src/governance/executor.ts +0 -229
  637. package/src/governance/index.ts +0 -13
  638. package/src/governance/types.ts +0 -53
  639. package/src/tools/core/package.json +0 -7
  640. package/src/tools/core/pnpm-lock.yaml +0 -232
  641. package/src/types/iron-law.ts +0 -50
@@ -9,9 +9,9 @@ import { TraceCollector } from '../monitoring/traces';
9
9
  import { TraceAnalyzer } from '../monitoring/trace-analyzer';
10
10
  import { ConstraintDoctor, createDoctor } from '../monitoring/constraint-doctor';
11
11
  import { ConstraintEvolver, createEvolver } from '../monitoring/constraint-evolver';
12
+ import { getConstraint } from '../core/constraints/definitions';
12
13
  import type { ExecutionTrace, TraceAnomaly } from '../types/trace';
13
- import type { Diagnosis } from '../monitoring/constraint-doctor';
14
- import type { ConstraintProposal } from '../monitoring/constraint-evolver';
14
+ import type { Diagnosis, ConstraintProposal } from '../types/monitoring-types';
15
15
 
16
16
  describe('ConstraintDoctor', () => {
17
17
  let tempDir: string;
@@ -174,7 +174,7 @@ describe('ConstraintEvolver', () => {
174
174
  beforeEach(() => {
175
175
  tempDir = path.join(os.tmpdir(), `harness-proposals-${Date.now()}`);
176
176
  fs.mkdirSync(tempDir, { recursive: true });
177
- evolver = createEvolver(tempDir);
177
+ evolver = createEvolver(tempDir, getConstraint);
178
178
  doctor = createDoctor();
179
179
  });
180
180
 
@@ -217,30 +217,3 @@ describe('Constraint Levels', () => {
217
217
  });
218
218
  });
219
219
  });
220
-
221
- describe('IronLawViolationError (deprecated)', () => {
222
- it('should be instanceof ConstraintViolationError', () => {
223
- const { IronLawViolationError, ConstraintViolationError } = require('../types/constraint');
224
-
225
- const result = {
226
- id: 'test',
227
- level: 'iron_law',
228
- satisfied: false,
229
- constraint: {
230
- id: 'test',
231
- level: 'iron_law',
232
- rule: 'TEST',
233
- message: 'test',
234
- trigger: 'code_implementation',
235
- enforcement: 'test',
236
- },
237
- message: 'Test error',
238
- checkedAt: new Date(),
239
- };
240
-
241
- const error = new IronLawViolationError(result);
242
- expect(error).toBeInstanceOf(ConstraintViolationError);
243
- expect(error.name).toBe('IronLawViolationError');
244
- expect(error.result).toBe(result);
245
- });
246
- });
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import { describe, it, expect } from '@jest/globals';
6
- import { STRICT_PRESET, STANDARD_PRESET, RELAXED_PRESET, getPreset, getIronLawPreset, STANDARD_IRON_LAWS_CONFIG } from '../presets/standard';
6
+ import { STRICT_PRESET, STANDARD_PRESET, RELAXED_PRESET, getPreset } from '../presets/standard';
7
7
 
8
8
  describe('Presets', () => {
9
9
  describe('STRICT_PRESET', () => {
@@ -62,43 +62,4 @@ describe('Presets', () => {
62
62
  expect(preset.name).toBe('standard');
63
63
  });
64
64
  });
65
-
66
- describe('getIronLawPreset (deprecated)', () => {
67
- it('strict 应该返回所有 Iron Laws', () => {
68
- const config = getIronLawPreset('strict');
69
- expect(config.preset).toBe('strict');
70
- expect(config.enabled).toBe(true);
71
- expect(Array.isArray(config.ironLaws)).toBe(true);
72
- expect(config.ironLaws.length).toBeGreaterThan(0);
73
- });
74
-
75
- it('standard 应该返回所有 Iron Laws', () => {
76
- const config = getIronLawPreset('standard');
77
- expect(config.preset).toBe('standard');
78
- expect(config.enabled).toBe(true);
79
- expect(Array.isArray(config.ironLaws)).toBe(true);
80
- expect(config.ironLaws.length).toBeGreaterThan(0);
81
- });
82
-
83
- it('relaxed 应该返回过滤后的 Iron Laws', () => {
84
- const config = getIronLawPreset('relaxed');
85
- expect(config.preset).toBe('relaxed');
86
- expect(config.enabled).toBe(true);
87
- expect(Array.isArray(config.ironLaws)).toBe(true);
88
- expect(config.ironLaws.length).toBe(3);
89
- });
90
-
91
- it('未知预设应该返回所有 Iron Laws', () => {
92
- const config = getIronLawPreset('unknown');
93
- expect(config.preset).toBe('unknown');
94
- expect(config.enabled).toBe(true);
95
- expect(config.ironLaws.length).toBeGreaterThan(0);
96
- });
97
- });
98
-
99
- describe('STANDARD_IRON_LAWS_CONFIG (deprecated re-export)', () => {
100
- it('应该等同于 STANDARD_PRESET', () => {
101
- expect(STANDARD_IRON_LAWS_CONFIG).toBe(STANDARD_PRESET);
102
- });
103
- });
104
65
  });
@@ -289,7 +289,6 @@ function parseSimpleYaml(content: string): { rules?: ArchitectureRule[] } {
289
289
  const result: { rules?: ArchitectureRule[] } = { rules: [] };
290
290
  let currentRule: Partial<ArchitectureRule> | null = null;
291
291
  let currentArray: string[] | null = null;
292
- let indentLevel = 0;
293
292
 
294
293
  for (const line of lines) {
295
294
  const trimmed = line.trim();
@@ -297,9 +296,6 @@ function parseSimpleYaml(content: string): { rules?: ArchitectureRule[] } {
297
296
  // 跳过注释和空行
298
297
  if (!trimmed || trimmed.startsWith('#')) continue;
299
298
 
300
- // 检测缩进级别
301
- const leadingSpace = line.length - line.trimStart().length;
302
-
303
299
  // 新规则开始
304
300
  if (trimmed.startsWith('- id:')) {
305
301
  if (currentRule && result.rules) {
@@ -307,7 +303,6 @@ function parseSimpleYaml(content: string): { rules?: ArchitectureRule[] } {
307
303
  }
308
304
  currentRule = { id: trimmed.replace('- id:', '').trim() };
309
305
  currentArray = null;
310
- indentLevel = leadingSpace;
311
306
  }
312
307
  // 规则属性
313
308
  else if (currentRule && trimmed.includes(':')) {
@@ -8,7 +8,8 @@
8
8
  */
9
9
 
10
10
  import { runCommand } from '../utils/exec';
11
- import { existsSync, readFileSync, readdirSync } from 'fs';
11
+ import { findTsSourceFiles } from '../utils/file-walk';
12
+ import { existsSync, readFileSync } from 'fs';
12
13
  import * as path from 'path';
13
14
 
14
15
  export interface CrossProjectViolation {
@@ -166,7 +167,7 @@ async function checkTypeConsistency(
166
167
  ): Promise<CrossProjectViolation[]> {
167
168
  const violations: CrossProjectViolation[] = [];
168
169
 
169
- for (const [pair, locations] of Object.entries(config.contractLocations)) {
170
+ for (const [pair] of Object.entries(config.contractLocations)) {
170
171
  const [from, to] = pair.split('-');
171
172
  if (!context.changedProjects.includes(from) && !context.changedProjects.includes(to)) {
172
173
  continue;
@@ -334,25 +335,6 @@ interface ApiChange {
334
335
 
335
336
  // ============ 辅助函数实现 ============
336
337
 
337
- /**
338
- * 递归查找目录中的 .ts 文件(排除 node_modules/__tests__/dist/.d.ts)
339
- */
340
- function findTsFiles(dir: string): string[] {
341
- if (!existsSync(dir)) return [];
342
- const results: string[] = [];
343
- const entries = readdirSync(dir, { withFileTypes: true });
344
- for (const entry of entries) {
345
- const fullPath = path.join(dir, entry.name);
346
- if (entry.isDirectory()) {
347
- if (entry.name === 'node_modules' || entry.name === '__tests__' || entry.name === 'dist') continue;
348
- results.push(...findTsFiles(fullPath));
349
- } else if (entry.name.endsWith('.ts') && !entry.name.endsWith('.d.ts')) {
350
- results.push(fullPath);
351
- }
352
- }
353
- return results;
354
- }
355
-
356
338
  function extractApiName(file: string): string {
357
339
  return path.basename(file, '.ts');
358
340
  }
@@ -388,7 +370,7 @@ async function detectChangeType(file: string, baseBranch: string): Promise<ApiCh
388
370
  function extractExportedTypes(project: string): string[] {
389
371
  const projectPath = resolveProjectPath(project);
390
372
  const srcDir = path.join(projectPath, 'src');
391
- const files = findTsFiles(srcDir);
373
+ const files = findTsSourceFiles(srcDir);
392
374
  const types = new Set<string>();
393
375
 
394
376
  for (const file of files) {
@@ -410,7 +392,7 @@ function extractExportedTypes(project: string): string[] {
410
392
  function extractTypeUsage(project: string, types: string[]): Record<string, { hasMismatch: boolean; expected?: string; actual?: string }> {
411
393
  const projectPath = resolveProjectPath(project);
412
394
  const srcDir = path.join(projectPath, 'src');
413
- const files = findTsFiles(srcDir);
395
+ const files = findTsSourceFiles(srcDir);
414
396
  const result: Record<string, { hasMismatch: boolean; expected?: string; actual?: string }> = {};
415
397
 
416
398
  for (const typeName of types) {
@@ -487,7 +469,7 @@ function parseDocInterfaces(docPath: string): Record<string, Array<{name: string
487
469
  function extractExportedApis(project: string): Array<{name: string, signature: string}> {
488
470
  const projectPath = resolveProjectPath(project);
489
471
  const srcDir = path.join(projectPath, 'src');
490
- const files = findTsFiles(srcDir);
472
+ const files = findTsSourceFiles(srcDir);
491
473
  const apis: Array<{name: string, signature: string}> = [];
492
474
  const seen = new Set<string>();
493
475
 
@@ -28,7 +28,8 @@ jest.mock('child_process', () => ({
28
28
  exec: jest.fn(),
29
29
  execSync: jest.fn((cmd: string) => {
30
30
  if (cmd.includes('git ls-tree')) {
31
- return Buffer.from('040000 tree abc123\tsrc\n'); // directory exists in HEAD
31
+ // 工单 18 后为批量命令 `git ls-tree -r --name-only HEAD`,返回文件列表
32
+ return Buffer.from('src/foo.ts\nsrc/module.ts\nsrc/__tests__/module.test.ts\n');
32
33
  }
33
34
  if (cmd.includes('git diff')) {
34
35
  return Buffer.from('src/test.ts\nsrc/legacy.js');
@@ -41,6 +42,7 @@ jest.mock('child_process', () => ({
41
42
  jest.mock('../../../core/constraints/checker', () => ({
42
43
  constraintChecker: {
43
44
  setCustomConfig: jest.fn(),
45
+ setTraceRecorder: jest.fn(),
44
46
  checkConstraints: jest.fn(),
45
47
  },
46
48
  }));
@@ -169,6 +169,53 @@ describe('sync-docs command', () => {
169
169
  fs.rmSync(testDir, { recursive: true, force: true });
170
170
  });
171
171
 
172
+ it('描述以 / 结尾的表格行不应被误判为目录条目(check 必须收敛)', async () => {
173
+ // 回归:JSDoc 首行在 "gitRepo /" 处换行时,生成的描述单元格以 / 结尾,
174
+ // 旧目录条目正则将其误判为目录 → --check 永远报「包含已删除的模块」
175
+ // (2026-08-04 studio PR #44 CI Governance 不收敛事故)
176
+ const testDir = path.join(tempDir, 'trailing-slash-desc');
177
+ const srcDir = path.join(testDir, 'src');
178
+ fs.mkdirSync(srcDir, { recursive: true });
179
+
180
+ fs.writeFileSync(
181
+ path.join(srcDir, 'workspace.ts'),
182
+ '/**\n * 归属链解析 — metadata.workspaceRoot(Requirement→gitRepo /\n * 人工绑定)优先。\n */\nexport const x = 1;\n'
183
+ );
184
+
185
+ // 第一轮:生成 CAPABILITIES.md(描述行以 / 结尾)
186
+ await syncDocs({ projectPath: testDir });
187
+ const cap = fs.readFileSync(path.join(testDir, 'CAPABILITIES.md'), 'utf-8');
188
+ expect(cap).toContain('workspace.ts');
189
+ expect(cap).toMatch(/gitRepo\s*\/\s*\|/);
190
+
191
+ // 第二轮:生成后立即 --check 必须收敛(修复前此处必 false)
192
+ consoleSpy.mockClear();
193
+ const check = await syncDocs({ projectPath: testDir, check: true });
194
+ expect(check).toBe(true);
195
+
196
+ fs.rmSync(testDir, { recursive: true, force: true });
197
+ });
198
+
199
+ it('真正的目录条目(如 agents/)仍应被识别', async () => {
200
+ const testDir = path.join(tempDir, 'dir-entry');
201
+ const srcDir = path.join(testDir, 'src');
202
+ fs.mkdirSync(srcDir, { recursive: true });
203
+
204
+ fs.writeFileSync(path.join(srcDir, 'mymodule.ts'), 'export const x = 1;');
205
+
206
+ // CAPABILITIES.md 用目录条目记录 src/ 下的模块
207
+ fs.writeFileSync(
208
+ path.join(testDir, 'CAPABILITIES.md'),
209
+ '# Capabilities\n\n| 模块 | 文件 | 说明 |\n|------|------|------|\n| all | src/ | 全量记录 |'
210
+ );
211
+
212
+ // src/ 目录条目覆盖 mymodule.ts → 无 added,check 通过
213
+ const result = await syncDocs({ projectPath: testDir, check: true });
214
+ expect(result).toBe(true);
215
+
216
+ fs.rmSync(testDir, { recursive: true, force: true });
217
+ });
218
+
172
219
  it('应该检查 CONTEXT.md 是否存在', async () => {
173
220
  const testDir = path.join(tempDir, 'context-check');
174
221
  const harnessDir = path.join(testDir, '.harness');
@@ -358,5 +405,35 @@ describe('sync-docs command', () => {
358
405
 
359
406
  fs.rmSync(testDir, { recursive: true, force: true });
360
407
  });
408
+
409
+ it('basename 碰撞的幽灵条目(文件已删但同名文件存在)也应被移除', async () => {
410
+ const testDir = path.join(tempDir, 'ghost-basename-collision');
411
+ const srcA = path.join(testDir, 'src', 'a');
412
+ fs.mkdirSync(srcA, { recursive: true });
413
+
414
+ // 真实存在的同名文件
415
+ fs.writeFileSync(path.join(srcA, 'routes.ts'), 'export const routes = 1;');
416
+
417
+ // CAPABILITIES.md 另有一条指向不存在路径的 routes.ts(basename 碰撞,
418
+ // 按 basename 对比时永远不可见 —— 2026-08-08 studio CI 4 连红事故)
419
+ fs.writeFileSync(
420
+ path.join(testDir, 'CAPABILITIES.md'),
421
+ [
422
+ '# CAPABILITIES.md', '',
423
+ '> 最后更新: 2026-01-01', '', '---', '',
424
+ '| 模块 | 文件 | 说明 |', '|------|------|------|',
425
+ '| routes | src/a/routes.ts | 真实文件 |',
426
+ '| routes | src/ghost/routes.ts | 幽灵条目 |',
427
+ '',
428
+ ].join('\n'),
429
+ );
430
+
431
+ await syncDocs({ projectPath: testDir });
432
+ const content = fs.readFileSync(path.join(testDir, 'CAPABILITIES.md'), 'utf-8');
433
+ expect(content).toContain('src/a/routes.ts');
434
+ expect(content).not.toContain('src/ghost/routes.ts');
435
+
436
+ fs.rmSync(testDir, { recursive: true, force: true });
437
+ });
361
438
  });
362
439
  });
@@ -96,8 +96,13 @@ describe('validate command', () => {
96
96
  };
97
97
  (MockCheckpointValidator.getInstance as jest.Mock).mockReturnValue(mockValidator);
98
98
 
99
+ // 工单 23:检查点失败一律 exit 1(门控语义)
100
+ const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => undefined as never);
101
+
99
102
  await validate({});
100
103
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('失败'));
104
+ expect(mockExit).toHaveBeenCalledWith(1);
105
+ mockExit.mockRestore();
101
106
  });
102
107
 
103
108
  it('应该在严格模式下退出', async () => {
@@ -7,12 +7,27 @@
7
7
  * 3. 规则缺口(高频模式未被现有 memory 覆盖)
8
8
  *
9
9
  * 输出候选规则建议,供用户审核后写入 memory。
10
+ *
11
+ * 工单 19-C:transcript 解析/纠正模式/分词相似度收敛至 cli/session-mining/。
10
12
  */
11
13
 
12
14
  import chalk from 'chalk';
13
15
  import * as fs from 'fs';
14
16
  import * as path from 'path';
15
17
  import * as os from 'os';
18
+ import {
19
+ readTranscriptSessions,
20
+ type MinedSession,
21
+ extractCorrectionMatches,
22
+ cleanCorrectionConcept,
23
+ tokenize,
24
+ stripCodeBlocks,
25
+ jaccardSimilarity,
26
+ isPunctuation,
27
+ isCodeNoise,
28
+ hasSemanticContent,
29
+ STOP_WORDS,
30
+ } from '../session-mining';
16
31
 
17
32
  export interface AnalyzeSessionsOptions {
18
33
  days?: number;
@@ -35,38 +50,6 @@ interface PatternCandidate {
35
50
  suggestedRule: string; // 建议的规则名
36
51
  }
37
52
 
38
- // ── Correction pattern templates ──
39
- // Match user sentences that indicate repeating a request
40
- const CORRECTION_PATTERNS = [
41
- /你(?:又|还是)(?:在)?(?:犯|忘|没|不).{0,20}?[了]?/g,
42
- /我不是(?:说|让|让做|讲)[了过]?.{0,30}?[了吗?]?/g,
43
- /怎么(?:又|还|老)(?:是|在)?.{0,20}?[了]?/g,
44
- /我(?:一直|反复|总是)(?:在|说|强调)?.{0,20}?[了]?/g,
45
- /老(?:是|在|犯|忘)(?:了)?.{0,20}?[了]?/g,
46
- /这(?:个|种)(?:问题|模式|错误).{0,20}?[.。!]?/g,
47
- /(?:第[一二三四五六七八九十\d]+次|反复|重复)(?:说|提醒|强调).{0,20}?/g,
48
- /不(?:要|能|想|愿意).{0,20}?老.{0,10}?[了]?/g,
49
- /(?:补上|加上|记上|修复).{0,10}?[了吗??]?/g,
50
- /(?:沉淀|监控|日志|记录).{0,5}?[了吗??]?/g,
51
- ];
52
-
53
- // ── N-gram stop words ──
54
- const STOP_WORDS = new Set([
55
- '的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一',
56
- '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着',
57
- '没有', '看', '好', '自己', '这', '他', '她', '它', '们', '那',
58
- 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
59
- 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
60
- 'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',
61
- 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
62
- 'before', 'after', 'above', 'below', 'between', 'under', 'again',
63
- 'further', 'then', 'once', 'here', 'there', 'when', 'where', 'why',
64
- 'how', 'all', 'both', 'each', 'few', 'more', 'most', 'other', 'some',
65
- 'such', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 'just',
66
- '因为', '所以', '但是', '而且', '如果', '虽然', '可以', '这个', '那个',
67
- '什么', '怎么', '哪', '吗', '吧', '呢', '啊', '嗯', '哦',
68
- ]);
69
-
70
53
  // ── Main ──
71
54
 
72
55
  export async function analyzeSessions(options: AnalyzeSessionsOptions): Promise<void> {
@@ -80,9 +63,11 @@ export async function analyzeSessions(options: AnalyzeSessionsOptions): Promise<
80
63
  return;
81
64
  }
82
65
 
83
- // 1. Scan transcripts
66
+ // 1. Scan transcripts(按修改时间过滤 + 倒序)
84
67
  const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;
85
- const sessions = findSessions(transcriptDir, cutoff);
68
+ const sessions = readTranscriptSessions(transcriptDir)
69
+ .filter(s => s.mtimeMs >= cutoff)
70
+ .sort((a, b) => b.date.localeCompare(a.date));
86
71
 
87
72
  if (sessions.length === 0) {
88
73
  console.log(chalk.yellow(`No sessions found in the last ${days} days`));
@@ -108,62 +93,12 @@ export async function analyzeSessions(options: AnalyzeSessionsOptions): Promise<
108
93
  console.log(chalk.blue(`🔍 Analyzing ${sessions.length} sessions (last ${days} days)...\n`));
109
94
 
110
95
  printCorrectionSummary(corrections);
111
- printCandidates(candidates, existingRules);
112
- }
113
-
114
- // ── Scan ──
115
-
116
- interface Session {
117
- id: string;
118
- date: string;
119
- turns: Array<{ role: string; content: string }>;
120
- }
121
-
122
- function findSessions(dir: string, cutoff: number): Session[] {
123
- const sessions: Session[] = [];
124
- try {
125
- for (const file of fs.readdirSync(dir)) {
126
- if (!file.endsWith('.jsonl')) continue;
127
- const filePath = path.join(dir, file);
128
- const stat = fs.statSync(filePath);
129
- if (stat.mtimeMs < cutoff) continue;
130
-
131
- const turns: Array<{ role: string; content: string }> = [];
132
- const content = fs.readFileSync(filePath, 'utf-8');
133
- for (const line of content.split('\n')) {
134
- if (!line.trim()) continue;
135
- try {
136
- const entry = JSON.parse(line);
137
- // Claude Code transcript format: { type: "user"|"assistant", message: { role, content } }
138
- const msg = entry.message;
139
- if (msg?.role && (msg.content || entry.type === 'user')) {
140
- const text = typeof msg.content === 'string'
141
- ? msg.content
142
- : Array.isArray(msg.content)
143
- ? msg.content.filter((b: any) => b.type === 'text').map((b: any) => b.text).join(' ')
144
- : '';
145
- turns.push({ role: msg.role, content: text });
146
- }
147
- } catch {}
148
- }
149
-
150
- if (turns.length > 0) {
151
- sessions.push({
152
- id: file.replace('.jsonl', '').slice(0, 40),
153
- date: stat.mtime.toISOString().slice(0, 10),
154
- turns,
155
- });
156
- }
157
- }
158
- } catch (e) {
159
- // Directory might not exist
160
- }
161
- return sessions.sort((a, b) => b.date.localeCompare(a.date));
96
+ printCandidates(candidates);
162
97
  }
163
98
 
164
99
  // ── Correction Extraction ──
165
100
 
166
- function extractCorrections(sessions: Session[]): Correction[] {
101
+ function extractCorrections(sessions: MinedSession[]): Correction[] {
167
102
  const corrections: Correction[] = [];
168
103
 
169
104
  for (const session of sessions) {
@@ -171,18 +106,13 @@ function extractCorrections(sessions: Session[]): Correction[] {
171
106
  if (turn.role !== 'user') continue;
172
107
  const text = stripCodeBlocks(turn.content);
173
108
 
174
- for (const pattern of CORRECTION_PATTERNS) {
175
- pattern.lastIndex = 0;
176
- let match;
177
- while ((match = pattern.exec(text)) !== null) {
178
- const sentence = match[0].trim();
179
- if (sentence.length > 3 && sentence.length < 200) {
180
- corrections.push({
181
- sentence,
182
- sessionId: session.id,
183
- timestamp: session.date,
184
- });
185
- }
109
+ for (const sentence of extractCorrectionMatches(text)) {
110
+ if (sentence.length > 3 && sentence.length < 200) {
111
+ corrections.push({
112
+ sentence,
113
+ sessionId: session.id,
114
+ timestamp: session.date,
115
+ });
186
116
  }
187
117
  }
188
118
  }
@@ -205,7 +135,7 @@ interface NGramResult {
205
135
  sessions: string[];
206
136
  }
207
137
 
208
- function extractNGrams(sessions: Session[], opts: NGramOptions): NGramResult[] {
138
+ function extractNGrams(sessions: MinedSession[], opts: NGramOptions): NGramResult[] {
209
139
  const phraseMap = new Map<string, { count: number; sessions: Set<string> }>();
210
140
 
211
141
  for (const session of sessions) {
@@ -244,42 +174,6 @@ function extractNGrams(sessions: Session[], opts: NGramOptions): NGramResult[] {
244
174
  .sort((a, b) => b.frequency - a.frequency || b.sessions.length - a.sessions.length);
245
175
  }
246
176
 
247
- function tokenize(text: string): string[] {
248
- const tokens: string[] = [];
249
- let current = '';
250
- const CN = /[\u4e00-\u9fff\u3400-\u4dbf]/;
251
-
252
- for (const char of text) {
253
- if (CN.test(char)) {
254
- current += char;
255
- } else if (/[a-zA-Z0-9_\-/.]/.test(char)) {
256
- current += char;
257
- } else {
258
- pushToken(current, tokens, CN);
259
- current = '';
260
- }
261
- }
262
- pushToken(current, tokens, CN);
263
-
264
- return tokens;
265
- }
266
-
267
- function pushToken(current: string, tokens: string[], CN: RegExp): void {
268
- if (current.length < 2) return;
269
- if (CN.test(current)) {
270
- // Chinese: character bigrams + trigrams + the full sequence
271
- for (let i = 0; i <= current.length - 2; i++) {
272
- tokens.push(current.slice(i, i + 2));
273
- }
274
- for (let i = 0; i <= current.length - 3; i++) {
275
- tokens.push(current.slice(i, i + 3));
276
- }
277
- if (current.length <= 6) tokens.push(current); // keep short full sequences too
278
- } else {
279
- tokens.push(current);
280
- }
281
- }
282
-
283
177
  // ── Existing Rules ──
284
178
 
285
179
  function isInExistingRules(concept: string, existingRules: Set<string>): boolean {
@@ -401,16 +295,7 @@ function clusterCorrections(corrections: Correction[]): CorrectionCluster[] {
401
295
  function extractConcept(sentences: string[]): string {
402
296
  // Take the longest sentence and extract the noun phrase after the correction marker
403
297
  const longest = sentences.reduce((a, b) => a.length > b.length ? a : b, '');
404
- // Remove correction patterns, keep the concept
405
- const cleaned = longest
406
- .replace(/你(?:又|还是)(?:在)?(?:犯|忘|没|不)/g, '')
407
- .replace(/我不是(?:说|让|让做|讲)[了过]?/g, '')
408
- .replace(/怎么(?:又|还|老)(?:是|在)?/g, '')
409
- .replace(/我(?:一直|反复|总是)(?:在|说|强调)?/g, '')
410
- .replace(/老(?:是|在|犯|忘)(?:了)?/g, '')
411
- .replace(/[,。!?、;:""''()\s]+/g, '')
412
- .trim();
413
-
298
+ const cleaned = cleanCorrectionConcept(longest);
414
299
  return cleaned.slice(0, 60) || longest.slice(0, 60);
415
300
  }
416
301
 
@@ -425,7 +310,7 @@ function printCorrectionSummary(corrections: Correction[]): void {
425
310
  console.log(chalk.yellow(`📢 ${corrections.length} correction signals detected\n`));
426
311
  }
427
312
 
428
- function printCandidates(candidates: PatternCandidate[], existingRules: Set<string>): void {
313
+ function printCandidates(candidates: PatternCandidate[]): void {
429
314
  if (candidates.length === 0) {
430
315
  console.log(chalk.green('✅ No new pattern candidates — all recurring concepts already have rules\n'));
431
316
  return;
@@ -447,42 +332,3 @@ function printCandidates(candidates: PatternCandidate[], existingRules: Set<stri
447
332
  console.log(chalk.gray(`... and ${candidates.length - 10} more candidates. Run with --json for full list.`));
448
333
  }
449
334
  }
450
-
451
- // ── Utilities ──
452
-
453
- function stripCodeBlocks(text: string): string {
454
- return text
455
- .replace(/```[\s\S]*?```/g, '')
456
- .replace(/`[^`]+`/g, '')
457
- .replace(/\{[^{}]*"[^"]+"\s*:\s*"[^"]*"[^}]*\}/g, '') // strip JSON objects
458
- .replace(/\[[\s\S]*?\]/g, '') // strip JSON arrays
459
- .replace(/\\n/g, ' ') // strip escaped newlines
460
- .replace(/[{}[\]"':,\\]+/g, ' '); // strip JSON punctuation
461
- }
462
-
463
- function hasSemanticContent(phrase: string): boolean {
464
- // Must contain Chinese characters or be a meaningful English word (≥7 chars)
465
- if (/[\u4e00-\u9fff]/.test(phrase)) return true;
466
- if (phrase.length >= 7 && /^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z]$/.test(phrase)) return true;
467
- return false;
468
- }
469
-
470
- function isCodeNoise(phrase: string): boolean {
471
- // Pure Latin chars without Chinese → likely JSON/code artifact
472
- if (!/[\u4e00-\u9fff]/.test(phrase) && phrase.length <= 6) return true;
473
- // Common JSON field name fragments
474
- if (/^(?:clla|cood|odde|oppe|laaw|peen|enne|ennc|ddec|deco|ecod|code|type|role|name|text|file|path|tool|user|session)$/i.test(phrase)) return true;
475
- return false;
476
- }
477
-
478
- function isPunctuation(str: string): boolean {
479
- return /^[,。!?、;:""''()\[\]【】「」『』《》〈〉\s]+$/.test(str);
480
- }
481
-
482
- function jaccardSimilarity(a: string, b: string): number {
483
- const setA = new Set(tokenize(a));
484
- const setB = new Set(tokenize(b));
485
- const intersection = new Set([...setA].filter(x => setB.has(x)));
486
- const union = new Set([...setA, ...setB]);
487
- return union.size === 0 ? 0 : intersection.size / union.size;
488
- }