onto-mcp 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/.onto/processes/reconstruct/actionable-ontology-seed-recomposition-design.md +447 -0
  2. package/.onto/processes/reconstruct/foundry-style-ontology-seed-contract.md +934 -0
  3. package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +303 -725
  4. package/.onto/processes/reconstruct/reconstruct-contract-registry.yaml +1645 -0
  5. package/.onto/processes/reconstruct/reconstruct-execution-ux-contract.md +26 -22
  6. package/.onto/processes/reconstruct/source-profile-contract.md +49 -23
  7. package/.onto/processes/reconstruct/source-profiles/code.md +6 -3
  8. package/.onto/processes/reconstruct/source-profiles/database.md +5 -2
  9. package/.onto/processes/reconstruct/source-profiles/document.md +5 -2
  10. package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +5 -4
  11. package/.onto/processes/review/review-execution-ux-contract.md +40 -0
  12. package/.onto/processes/shared/pipeline-execution-ledger-contract.md +26 -10
  13. package/.onto/processes/shared/target-material-kind-contract.md +29 -16
  14. package/AGENTS.md +6 -4
  15. package/README.md +135 -76
  16. package/dist/cli.js +8 -8
  17. package/dist/core-api/reconstruct-api.js +117 -31
  18. package/dist/core-api/review-api.js +47 -0
  19. package/dist/core-runtime/cli/codex-review-unit-executor.js +39 -2
  20. package/dist/core-runtime/cli/complete-review-session.js +2 -2
  21. package/dist/core-runtime/cli/mock-review-unit-executor.js +1 -1
  22. package/dist/core-runtime/cli/review-invoke.js +9 -9
  23. package/dist/core-runtime/cli/run-review-prompt-execution.js +39 -5
  24. package/dist/core-runtime/cli/spawn-watcher.js +266 -47
  25. package/dist/core-runtime/cli/start-review-session.js +3 -3
  26. package/dist/core-runtime/llm/llm-caller.js +11 -0
  27. package/dist/core-runtime/llm/llm-tool-loop.js +2 -0
  28. package/dist/core-runtime/observability/runtime-stream-observation.js +118 -0
  29. package/dist/core-runtime/onboard/cli-host.js +149 -0
  30. package/dist/core-runtime/onboard/host-target.js +22 -0
  31. package/dist/core-runtime/onboard/json-config-host.js +122 -0
  32. package/dist/core-runtime/onboard/path-scan.js +26 -0
  33. package/dist/core-runtime/onboard/prompt.js +51 -0
  34. package/dist/core-runtime/onboard/register.js +207 -0
  35. package/dist/core-runtime/onboard/types.js +27 -0
  36. package/dist/core-runtime/reconstruct/actionable-seed-validation.js +1777 -0
  37. package/dist/core-runtime/reconstruct/artifact-types.js +10 -4
  38. package/dist/core-runtime/reconstruct/contract-registry.js +623 -0
  39. package/dist/core-runtime/reconstruct/domain-id.js +10 -0
  40. package/dist/core-runtime/reconstruct/governing-snapshot.js +716 -0
  41. package/dist/core-runtime/reconstruct/material-profile-validation.js +191 -0
  42. package/dist/core-runtime/reconstruct/materialize-preparation.js +49 -11
  43. package/dist/core-runtime/reconstruct/pipeline-execution-ledger.js +269 -79
  44. package/dist/core-runtime/reconstruct/post-seed-validation.js +1194 -51
  45. package/dist/core-runtime/reconstruct/record.js +104 -20
  46. package/dist/core-runtime/reconstruct/run.js +2107 -413
  47. package/dist/core-runtime/reconstruct/seed-claim-projections.js +268 -0
  48. package/dist/core-runtime/reconstruct/source-profiles.js +93 -4
  49. package/dist/core-runtime/reconstruct/terminal-validation.js +807 -0
  50. package/dist/core-runtime/review/review-invocation-runner.js +4 -4
  51. package/dist/mcp/server.js +110 -38
  52. package/dist/mcp/tool-schemas.js +20 -6
  53. package/package.json +8 -17
  54. package/scripts/onto-review-watch.sh +486 -0
  55. package/scripts/onto-runtime-watch.sh +122 -0
  56. package/scripts/postinstall-hint.js +22 -0
  57. package/.onto/processes/reconstruct/top-level-concept-discovery-contract.md +0 -387
  58. package/dist/core-runtime/cli/bootstrap-review-binding.js +0 -186
  59. package/dist/core-runtime/cli/codex-nested-dispatch.test.js +0 -390
  60. package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +0 -335
  61. package/dist/core-runtime/cli/coordinator-helpers.js +0 -583
  62. package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +0 -167
  63. package/dist/core-runtime/cli/coordinator-state-machine.js +0 -794
  64. package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +0 -615
  65. package/dist/core-runtime/cli/e2e-start-review-session.test.js +0 -312
  66. package/dist/core-runtime/cli/health.js +0 -44
  67. package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +0 -567
  68. package/dist/core-runtime/cli/materialize-review-execution-preparation.js +0 -104
  69. package/dist/core-runtime/cli/migrate-session-roots.js +0 -118
  70. package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +0 -106
  71. package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +0 -268
  72. package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +0 -136
  73. package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +0 -201
  74. package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +0 -192
  75. package/dist/core-runtime/cli/session-root-guard.js +0 -168
  76. package/dist/core-runtime/cli/spawn-watcher.test.js +0 -457
  77. package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +0 -79
  78. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +0 -412
  79. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +0 -351
  80. package/dist/core-runtime/cli/topology-executor-mapping.js +0 -139
  81. package/dist/core-runtime/cli/topology-executor-mapping.test.js +0 -173
  82. package/dist/core-runtime/cli/write-review-interpretation.js +0 -81
  83. package/dist/core-runtime/config/onto-config-cli.js +0 -278
  84. package/dist/core-runtime/config/onto-config-key-path.js +0 -288
  85. package/dist/core-runtime/config/onto-config-key-path.test.js +0 -195
  86. package/dist/core-runtime/config/onto-config-preview.js +0 -108
  87. package/dist/core-runtime/config/onto-config-preview.test.js +0 -132
  88. package/dist/core-runtime/discovery/config-chain.js +0 -118
  89. package/dist/core-runtime/discovery/config-chain.test.js +0 -103
  90. package/dist/core-runtime/discovery/config-profile.js +0 -199
  91. package/dist/core-runtime/discovery/config-profile.test.js +0 -233
  92. package/dist/core-runtime/discovery/host-detection.test.js +0 -186
  93. package/dist/core-runtime/discovery/installation-paths.test.js +0 -65
  94. package/dist/core-runtime/discovery/lens-registry.test.js +0 -81
  95. package/dist/core-runtime/discovery/path-normalization.test.js +0 -22
  96. package/dist/core-runtime/discovery/plugin-path.js +0 -72
  97. package/dist/core-runtime/discovery/plugin-path.test.js +0 -95
  98. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +0 -344
  99. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +0 -915
  100. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +0 -564
  101. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +0 -708
  102. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +0 -165
  103. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +0 -227
  104. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +0 -59
  105. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +0 -205
  106. package/dist/core-runtime/evolve/adapters/methodology/adapter.js +0 -16
  107. package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +0 -9
  108. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +0 -298
  109. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +0 -70
  110. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +0 -46
  111. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +0 -73
  112. package/dist/core-runtime/evolve/adapters/registry.js +0 -47
  113. package/dist/core-runtime/evolve/adapters/registry.test.js +0 -67
  114. package/dist/core-runtime/evolve/cli.js +0 -256
  115. package/dist/core-runtime/evolve/commands/align.js +0 -194
  116. package/dist/core-runtime/evolve/commands/align.test.js +0 -82
  117. package/dist/core-runtime/evolve/commands/apply.js +0 -161
  118. package/dist/core-runtime/evolve/commands/apply.test.js +0 -138
  119. package/dist/core-runtime/evolve/commands/close.js +0 -39
  120. package/dist/core-runtime/evolve/commands/close.test.js +0 -99
  121. package/dist/core-runtime/evolve/commands/defer.js +0 -40
  122. package/dist/core-runtime/evolve/commands/defer.test.js +0 -134
  123. package/dist/core-runtime/evolve/commands/draft.js +0 -323
  124. package/dist/core-runtime/evolve/commands/draft.test.js +0 -178
  125. package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +0 -208
  126. package/dist/core-runtime/evolve/commands/error-messages.js +0 -125
  127. package/dist/core-runtime/evolve/commands/error-messages.test.js +0 -167
  128. package/dist/core-runtime/evolve/commands/propose-align.js +0 -222
  129. package/dist/core-runtime/evolve/commands/propose-align.test.js +0 -136
  130. package/dist/core-runtime/evolve/commands/reconstruct.js +0 -330
  131. package/dist/core-runtime/evolve/commands/reconstruct.test.js +0 -278
  132. package/dist/core-runtime/evolve/commands/shared.js +0 -22
  133. package/dist/core-runtime/evolve/commands/stale-check.js +0 -103
  134. package/dist/core-runtime/evolve/commands/stale-check.test.js +0 -84
  135. package/dist/core-runtime/evolve/commands/start.js +0 -887
  136. package/dist/core-runtime/evolve/commands/start.test.js +0 -396
  137. package/dist/core-runtime/evolve/config/project-config.js +0 -99
  138. package/dist/core-runtime/evolve/config/project-config.test.js +0 -170
  139. package/dist/core-runtime/evolve/renderers/align-packet.js +0 -280
  140. package/dist/core-runtime/evolve/renderers/align-packet.test.js +0 -332
  141. package/dist/core-runtime/evolve/renderers/draft-packet.js +0 -303
  142. package/dist/core-runtime/evolve/renderers/draft-packet.test.js +0 -377
  143. package/dist/core-runtime/evolve/renderers/format.js +0 -5
  144. package/dist/core-runtime/evolve/renderers/scope-md.js +0 -237
  145. package/dist/core-runtime/evolve/renderers/scope-md.test.js +0 -306
  146. package/dist/core-runtime/govern/cli.js +0 -369
  147. package/dist/core-runtime/govern/cli.test.js +0 -314
  148. package/dist/core-runtime/govern/drift-engine.js +0 -103
  149. package/dist/core-runtime/govern/drift-engine.test.js +0 -319
  150. package/dist/core-runtime/govern/promote-principle.js +0 -206
  151. package/dist/core-runtime/govern/promote-principle.test.js +0 -368
  152. package/dist/core-runtime/govern/queue.js +0 -81
  153. package/dist/core-runtime/govern/types.js +0 -16
  154. package/dist/core-runtime/install/cli.js +0 -530
  155. package/dist/core-runtime/install/detect.js +0 -128
  156. package/dist/core-runtime/install/detect.test.js +0 -155
  157. package/dist/core-runtime/install/gitignore-update.js +0 -74
  158. package/dist/core-runtime/install/gitignore-update.test.js +0 -64
  159. package/dist/core-runtime/install/install-integration.test.js +0 -373
  160. package/dist/core-runtime/install/prompts.js +0 -389
  161. package/dist/core-runtime/install/prompts.test.js +0 -293
  162. package/dist/core-runtime/install/types.js +0 -26
  163. package/dist/core-runtime/install/validation.js +0 -295
  164. package/dist/core-runtime/install/validation.test.js +0 -313
  165. package/dist/core-runtime/install/writer.js +0 -254
  166. package/dist/core-runtime/install/writer.test.js +0 -218
  167. package/dist/core-runtime/learning/extractor.js +0 -461
  168. package/dist/core-runtime/learning/feedback.js +0 -179
  169. package/dist/core-runtime/learning/health-report.js +0 -165
  170. package/dist/core-runtime/learning/health-report.test.js +0 -169
  171. package/dist/core-runtime/learning/loader.js +0 -388
  172. package/dist/core-runtime/learning/loader.test.js +0 -102
  173. package/dist/core-runtime/learning/promote/apply-state.js +0 -240
  174. package/dist/core-runtime/learning/promote/audit-obligation.js +0 -195
  175. package/dist/core-runtime/learning/promote/collector.js +0 -432
  176. package/dist/core-runtime/learning/promote/degraded-state.js +0 -125
  177. package/dist/core-runtime/learning/promote/domain-doc-proposer.js +0 -166
  178. package/dist/core-runtime/learning/promote/e2e-promote.test.js +0 -6385
  179. package/dist/core-runtime/learning/promote/health-snapshot.js +0 -150
  180. package/dist/core-runtime/learning/promote/insight-reclassifier.js +0 -544
  181. package/dist/core-runtime/learning/promote/judgment-auditor.js +0 -517
  182. package/dist/core-runtime/learning/promote/panel-reviewer.js +0 -1158
  183. package/dist/core-runtime/learning/promote/promote-executor.js +0 -1675
  184. package/dist/core-runtime/learning/promote/promoter.js +0 -307
  185. package/dist/core-runtime/learning/promote/retirement.js +0 -122
  186. package/dist/core-runtime/learning/promote/types.js +0 -23
  187. package/dist/core-runtime/learning/prompt-sections.js +0 -51
  188. package/dist/core-runtime/learning/shared/artifact-registry-init.js +0 -45
  189. package/dist/core-runtime/learning/shared/artifact-registry.js +0 -254
  190. package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +0 -73
  191. package/dist/core-runtime/learning/shared/audit-state.js +0 -99
  192. package/dist/core-runtime/learning/shared/duplicate-check.js +0 -28
  193. package/dist/core-runtime/learning/shared/llm-caller.js +0 -831
  194. package/dist/core-runtime/learning/shared/llm-caller.test.js +0 -601
  195. package/dist/core-runtime/learning/shared/llm-tool-loop.js +0 -393
  196. package/dist/core-runtime/learning/shared/mode.js +0 -25
  197. package/dist/core-runtime/learning/shared/paths.js +0 -84
  198. package/dist/core-runtime/learning/shared/paths.test.js +0 -79
  199. package/dist/core-runtime/learning/shared/patterns.js +0 -37
  200. package/dist/core-runtime/learning/shared/recoverability.js +0 -355
  201. package/dist/core-runtime/learning/shared/recovery-context.js +0 -374
  202. package/dist/core-runtime/learning/shared/scope.js +0 -1
  203. package/dist/core-runtime/learning/shared/semantic-classifier.js +0 -94
  204. package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +0 -42
  205. package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +0 -37
  206. package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +0 -39
  207. package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +0 -41
  208. package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +0 -38
  209. package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +0 -43
  210. package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +0 -113
  211. package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +0 -36
  212. package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +0 -48
  213. package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +0 -43
  214. package/dist/core-runtime/learning/shared/specs/spec-helpers.js +0 -64
  215. package/dist/core-runtime/learning/usage-tracker.js +0 -190
  216. package/dist/core-runtime/learning/usage-tracker.test.js +0 -176
  217. package/dist/core-runtime/onboard/detect-review-axes.js +0 -122
  218. package/dist/core-runtime/onboard/detect-review-axes.test.js +0 -127
  219. package/dist/core-runtime/onboard/write-review-block.js +0 -188
  220. package/dist/core-runtime/onboard/write-review-block.test.js +0 -240
  221. package/dist/core-runtime/readers/brownfield-builder.js +0 -150
  222. package/dist/core-runtime/readers/brownfield-builder.test.js +0 -136
  223. package/dist/core-runtime/readers/code-chunk-collector.js +0 -53
  224. package/dist/core-runtime/readers/code-chunk-collector.test.js +0 -136
  225. package/dist/core-runtime/readers/file-utils.js +0 -240
  226. package/dist/core-runtime/readers/file-utils.test.js +0 -146
  227. package/dist/core-runtime/readers/lexicon-citation-check.js +0 -93
  228. package/dist/core-runtime/readers/lexicon-citation-check.test.js +0 -77
  229. package/dist/core-runtime/readers/mcp-figma.js +0 -30
  230. package/dist/core-runtime/readers/mcp-figma.test.js +0 -82
  231. package/dist/core-runtime/readers/mcp-generic.js +0 -31
  232. package/dist/core-runtime/readers/mcp-generic.test.js +0 -76
  233. package/dist/core-runtime/readers/ontology-index.js +0 -148
  234. package/dist/core-runtime/readers/ontology-index.test.js +0 -245
  235. package/dist/core-runtime/readers/ontology-query.js +0 -168
  236. package/dist/core-runtime/readers/ontology-query.test.js +0 -311
  237. package/dist/core-runtime/readers/ontology-resolve.js +0 -48
  238. package/dist/core-runtime/readers/ontology-resolve.test.js +0 -48
  239. package/dist/core-runtime/readers/patterns/index.js +0 -7
  240. package/dist/core-runtime/readers/review-log.js +0 -213
  241. package/dist/core-runtime/readers/review-log.test.js +0 -313
  242. package/dist/core-runtime/readers/scan-local.js +0 -102
  243. package/dist/core-runtime/readers/scan-local.test.js +0 -102
  244. package/dist/core-runtime/readers/scan-tarball.js +0 -121
  245. package/dist/core-runtime/readers/scan-tarball.test.js +0 -283
  246. package/dist/core-runtime/readers/scan-vault.js +0 -34
  247. package/dist/core-runtime/readers/scan-vault.test.js +0 -81
  248. package/dist/core-runtime/readers/types.js +0 -42
  249. package/dist/core-runtime/readers/types.test.js +0 -94
  250. package/dist/core-runtime/readers/viewpoint-collectors.js +0 -229
  251. package/dist/core-runtime/reconstruct/seed-candidate-validation.js +0 -385
  252. package/dist/core-runtime/review/citation-audit.test.js +0 -165
  253. package/dist/core-runtime/review/execution-plan-resolver.js +0 -247
  254. package/dist/core-runtime/review/execution-plan-resolver.test.js +0 -243
  255. package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +0 -246
  256. package/dist/core-runtime/review/execution-topology-resolver.js +0 -401
  257. package/dist/core-runtime/review/execution-topology-resolver.test.js +0 -315
  258. package/dist/core-runtime/review/inline-context-embedder.test.js +0 -154
  259. package/dist/core-runtime/review/legacy-mode-policy.js +0 -88
  260. package/dist/core-runtime/review/materializers-effort-persist.test.js +0 -79
  261. package/dist/core-runtime/review/ontology-path-classifier.js +0 -179
  262. package/dist/core-runtime/review/ontology-path-classifier.test.js +0 -216
  263. package/dist/core-runtime/review/packet-boundary-policy.test.js +0 -107
  264. package/dist/core-runtime/review/participating-lens-paths.test.js +0 -73
  265. package/dist/core-runtime/review/review-config-legacy-translate.js +0 -244
  266. package/dist/core-runtime/review/review-config-legacy-translate.test.js +0 -161
  267. package/dist/core-runtime/review/review-config-validator.js +0 -289
  268. package/dist/core-runtime/review/review-config-validator.test.js +0 -236
  269. package/dist/core-runtime/review/shape-pipeline-audit.test.js +0 -311
  270. package/dist/core-runtime/review/shape-to-topology-id.js +0 -117
  271. package/dist/core-runtime/review/shape-to-topology-id.test.js +0 -132
  272. package/dist/core-runtime/review/topology-shape-derivation.js +0 -155
  273. package/dist/core-runtime/review/topology-shape-derivation.test.js +0 -195
  274. package/dist/core-runtime/scope-runtime/constants.js +0 -12
  275. package/dist/core-runtime/scope-runtime/constraint-pool.js +0 -166
  276. package/dist/core-runtime/scope-runtime/constraint-pool.test.js +0 -674
  277. package/dist/core-runtime/scope-runtime/domain-validation-log.js +0 -135
  278. package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +0 -156
  279. package/dist/core-runtime/scope-runtime/eval-persistence.js +0 -65
  280. package/dist/core-runtime/scope-runtime/eval-persistence.test.js +0 -84
  281. package/dist/core-runtime/scope-runtime/event-pipeline.js +0 -64
  282. package/dist/core-runtime/scope-runtime/event-pipeline.test.js +0 -450
  283. package/dist/core-runtime/scope-runtime/event-store.js +0 -39
  284. package/dist/core-runtime/scope-runtime/event-store.test.js +0 -95
  285. package/dist/core-runtime/scope-runtime/gate-guard.js +0 -348
  286. package/dist/core-runtime/scope-runtime/gate-guard.test.js +0 -1047
  287. package/dist/core-runtime/scope-runtime/hash.js +0 -4
  288. package/dist/core-runtime/scope-runtime/hash.test.js +0 -33
  289. package/dist/core-runtime/scope-runtime/id.js +0 -4
  290. package/dist/core-runtime/scope-runtime/id.test.js +0 -17
  291. package/dist/core-runtime/scope-runtime/reducer.js +0 -297
  292. package/dist/core-runtime/scope-runtime/reducer.test.js +0 -759
  293. package/dist/core-runtime/scope-runtime/scope-manager.js +0 -161
  294. package/dist/core-runtime/scope-runtime/state-machine.js +0 -309
  295. package/dist/core-runtime/scope-runtime/state-machine.test.js +0 -704
  296. package/dist/core-runtime/scope-runtime/types.js +0 -116
  297. package/dist/core-runtime/scope-runtime/types.test.js +0 -69
  298. package/dist/core-runtime/translate/render-for-user.js +0 -169
  299. package/dist/core-runtime/translate/render-for-user.test.js +0 -122
  300. package/dist/providers/capability-contract.js +0 -1
@@ -1,208 +0,0 @@
1
- /**
2
- * Evolve full cycle E2E test (W-B-01).
3
- *
4
- * scope-runtime kernel 위에서 evolve 활동의 전체 lifecycle 을 검증한다:
5
- * draft → grounded → align_proposed → align_locked → surface_iterating →
6
- * surface_confirmed → constraints_resolved → target_locked → compiled →
7
- * applied → validated → closed
8
- *
9
- * 초기 scope 생성(grounding)은 appendScopeEvent 로 직접 설정하고,
10
- * align 이후는 실제 command 함수(executeAlign/executeDraft/executeApply/executeClose)를 사용.
11
- */
12
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
13
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
14
- import { join } from "node:path";
15
- import { tmpdir } from "node:os";
16
- import { createScope } from "../../scope-runtime/scope-manager.js";
17
- import { appendScopeEvent } from "../../scope-runtime/event-pipeline.js";
18
- import { readEvents } from "../../scope-runtime/event-store.js";
19
- import { reduce } from "../../scope-runtime/reducer.js";
20
- import { executeAlign } from "./align.js";
21
- import { executeDraft } from "./draft.js";
22
- import { executeApply } from "./apply.js";
23
- import { executeClose } from "./close.js";
24
- let tmpDir;
25
- beforeEach(() => { tmpDir = mkdtempSync(join(tmpdir(), "e2e-evolve-")); });
26
- afterEach(() => { rmSync(tmpDir, { recursive: true, force: true }); });
27
- describe("evolve full cycle E2E", () => {
28
- it("draft → closed: 전체 lifecycle 을 command 함수로 통과한다", () => {
29
- // ── Phase 0: Scope 생성 + Grounding ──
30
- writeFileSync(join(tmpDir, ".sprint-kit.yaml"), "apply_enabled: true\ndefault_sources: []\n", "utf-8");
31
- const paths = createScope(tmpDir, "E2E-FULL-001");
32
- appendScopeEvent(paths, {
33
- type: "scope.created",
34
- actor: "user",
35
- payload: { title: "E2E Full Cycle", description: "evolve full cycle test", entry_mode: "experience" },
36
- });
37
- appendScopeEvent(paths, {
38
- type: "grounding.started",
39
- actor: "system",
40
- payload: { sources: [{ type: "add-dir", path_or_url: "/test-project" }] },
41
- });
42
- appendScopeEvent(paths, {
43
- type: "grounding.completed",
44
- actor: "system",
45
- payload: { snapshot_revision: 1, source_hashes: { "add-dir:/test-project": "h1" }, perspective_summary: { experience: 1, code: 1, policy: 1 } },
46
- });
47
- appendScopeEvent(paths, {
48
- type: "align.proposed",
49
- actor: "system",
50
- payload: { packet_path: "build/align-packet.md", packet_hash: "ap1", snapshot_revision: 1 },
51
- });
52
- let state = reduce(readEvents(paths.events));
53
- expect(state.current_state).toBe("align_proposed");
54
- // ── Phase 1: Align (executeAlign) ──
55
- const alignResult = executeAlign({
56
- paths,
57
- verdict: {
58
- type: "approve",
59
- direction: "사용자 온보딩 흐름 개선",
60
- scope_in: ["login", "signup"],
61
- scope_out: ["admin"],
62
- },
63
- });
64
- expect(alignResult.success).toBe(true);
65
- if (!alignResult.success)
66
- return;
67
- expect(alignResult.nextState).toBe("align_locked");
68
- state = reduce(readEvents(paths.events));
69
- expect(state.current_state).toBe("align_locked");
70
- // ── Phase 2: Draft — Surface 생성 (executeDraft) ──
71
- const genResult = executeDraft({
72
- paths,
73
- action: { type: "generate_surface", surfacePath: "surface/preview/", surfaceHash: "sf1", snapshotRevision: 1 },
74
- });
75
- expect(genResult.success).toBe(true);
76
- if (!genResult.success)
77
- return;
78
- expect(genResult.nextState).toBe("surface_iterating");
79
- // ── Phase 2b: Surface 확인 ──
80
- const confirmResult = executeDraft({
81
- paths,
82
- action: { type: "confirm_surface", surfacePath: "surface/preview/", surfaceHash: "sf1" },
83
- });
84
- expect(confirmResult.success).toBe(true);
85
- if (!confirmResult.success)
86
- return;
87
- expect(confirmResult.nextState).toBe("surface_confirmed");
88
- // ── Phase 2c: Constraint 발견 + 결정 ──
89
- const constraintResult = executeDraft({
90
- paths,
91
- action: {
92
- type: "record_constraint",
93
- constraintPayload: {
94
- constraint_id: "CST-E2E-001",
95
- perspective: "code",
96
- summary: "기존 인증 모듈과 호환성 필요",
97
- severity: "required",
98
- discovery_stage: "draft_phase2",
99
- decision_owner: "product_owner",
100
- impact_if_ignored: "로그인 기능 장애",
101
- source_refs: [{ source: "auth.ts", detail: "OAuth 의존성" }],
102
- },
103
- },
104
- });
105
- expect(constraintResult.success).toBe(true);
106
- const decisionResult = executeDraft({
107
- paths,
108
- action: {
109
- type: "record_decision",
110
- decisionPayload: {
111
- constraint_id: "CST-E2E-001",
112
- decision: "inject",
113
- selected_option: "호환 래퍼 추가",
114
- decision_owner: "product_owner",
115
- rationale: "기존 모듈 변경 최소화",
116
- },
117
- },
118
- });
119
- expect(decisionResult.success).toBe(true);
120
- state = reduce(readEvents(paths.events));
121
- expect(state.current_state).toBe("constraints_resolved");
122
- // ── Phase 2d: Target 잠금 ──
123
- const lockResult = executeDraft({
124
- paths,
125
- action: { type: "lock_target" },
126
- });
127
- expect(lockResult.success).toBe(true);
128
- if (!lockResult.success)
129
- return;
130
- expect(lockResult.nextState).toBe("target_locked");
131
- // ── Phase 2e: Compile ──
132
- // compile 은 code-product adapter 를 호출하므로, compile.started/completed 를 직접 기록
133
- appendScopeEvent(paths, {
134
- type: "compile.started",
135
- actor: "system",
136
- payload: { snapshot_revision: 1, surface_hash: "sf1" },
137
- });
138
- appendScopeEvent(paths, {
139
- type: "compile.completed",
140
- actor: "system",
141
- payload: {
142
- build_spec_path: "build/build-spec.md", build_spec_hash: "bs1",
143
- brownfield_detail_path: "build/brownfield-detail.md", brownfield_detail_hash: "bf1",
144
- delta_set_path: "build/delta-set.json", delta_set_hash: "ds1",
145
- validation_plan_path: "build/validation-plan.md", validation_plan_hash: "vp1",
146
- },
147
- });
148
- state = reduce(readEvents(paths.events));
149
- expect(state.current_state).toBe("compiled");
150
- // ── Phase 3: Apply (executeApply) ──
151
- // pre-apply + PRD review gate 통과
152
- appendScopeEvent(paths, { type: "pre_apply.review_completed", actor: "agent", payload: { verdict: "pass", findings: [] } });
153
- appendScopeEvent(paths, { type: "prd.review_completed", actor: "agent", payload: { verdict: "pass", perspectives: ["prd_logic"], findings: [] } });
154
- const applyStartResult = executeApply(paths, { type: "start_apply", buildSpecHash: "bs1" }, { projectRoot: tmpDir });
155
- expect(applyStartResult.success).toBe(true);
156
- const applyCompleteResult = executeApply(paths, { type: "complete_apply", result: "success" });
157
- expect(applyCompleteResult.success).toBe(true);
158
- if (!applyCompleteResult.success)
159
- return;
160
- expect(applyCompleteResult.nextState).toBe("applied");
161
- // ── Phase 4: Validation (executeApply) ──
162
- const valStartResult = executeApply(paths, { type: "start_validation", validationPlanHash: "vp1" });
163
- expect(valStartResult.success).toBe(true);
164
- const valCompleteResult = executeApply(paths, {
165
- type: "complete_validation",
166
- plan: [{
167
- val_id: "VAL-001",
168
- related_cst: "CST-E2E-001",
169
- decision_type: "inject",
170
- target: "auth.ts",
171
- method: "수동 테스트",
172
- pass_criteria: "온보딩 흐름 정상 동작",
173
- fail_action: "호환 래퍼 재구현",
174
- }],
175
- results: [{ val_id: "VAL-001", related_cst: "CST-E2E-001", result: "pass", detail: "수동 테스트 통과" }],
176
- actualPlanHash: "vp1",
177
- });
178
- expect(valCompleteResult.success).toBe(true);
179
- if (!valCompleteResult.success)
180
- return;
181
- expect(valCompleteResult.nextState).toBe("validated");
182
- state = reduce(readEvents(paths.events));
183
- expect(state.current_state).toBe("validated");
184
- // ── Phase 5: Close (executeClose) ──
185
- const closeResult = executeClose(paths);
186
- expect(closeResult.success).toBe(true);
187
- if (!closeResult.success)
188
- return;
189
- expect(closeResult.nextState).toBe("closed");
190
- // ── Final verification ──
191
- state = reduce(readEvents(paths.events));
192
- expect(state.current_state).toBe("closed");
193
- const events = readEvents(paths.events);
194
- expect(events.length).toBeGreaterThanOrEqual(18);
195
- // 핵심 상태 전이가 모두 기록되었는지 확인
196
- const eventTypes = events.map(e => e.type);
197
- expect(eventTypes).toContain("scope.created");
198
- expect(eventTypes).toContain("grounding.completed");
199
- expect(eventTypes).toContain("align.locked");
200
- expect(eventTypes).toContain("surface.confirmed");
201
- expect(eventTypes).toContain("constraint.decision_recorded");
202
- expect(eventTypes).toContain("target.locked");
203
- expect(eventTypes).toContain("compile.completed");
204
- expect(eventTypes).toContain("apply.completed");
205
- expect(eventTypes).toContain("validation.completed");
206
- expect(eventTypes).toContain("scope.closed");
207
- });
208
- });
@@ -1,125 +0,0 @@
1
- /**
2
- * Gate-guard error wrapping — Principal-facing Korean messages.
3
- *
4
- * W-B-08 (BL-044): 기존 문자열 매칭 switch 를 .onto/authority/diagnostic-codes.yaml
5
- * 기반 code registry 로 전환. 매칭 우선순위는 registry entry 순서를 따른다.
6
- *
7
- * Registry seat: .onto/authority/diagnostic-codes.yaml (authority-adjacent data seat).
8
- * Concept SSOT 아님 — citation check 대상 아님.
9
- *
10
- * 보증:
11
- * - Registry load 시 schema validation (code 유일성 + 최소 1 matcher + matcher 형식).
12
- * violation 발견 시 load 실패 → fail-fast.
13
- * - lookupDiagnosticCode 미매칭 시 console.warn — silent fail 방지.
14
- * (영문 reason 원문이 Principal 에 노출되는 UX 버그를 즉시 감지 가능.)
15
- */
16
- import { readFileSync } from "node:fs";
17
- import { fileURLToPath } from "node:url";
18
- import { dirname, join } from "node:path";
19
- import { parse as yamlParse } from "yaml";
20
- import { resolveInstallationPath } from "../../discovery/installation-paths.js";
21
- // ─── Registry load ───
22
- let cachedRegistry = null;
23
- function resolveRegistryPath() {
24
- // dist / src 양쪽에서 작동:
25
- // src: src/core-runtime/evolve/commands/error-messages.ts
26
- // dist: dist/core-runtime/evolve/commands/error-messages.js
27
- // 양쪽 모두 4 단계 위가 repo root. Authority dir 선택은 Phase 0
28
- // 공유 resolver 에 위임 — canonical `.onto/authority/` 에서 resolve.
29
- // Phase 7 (2026-04-21) 에서 legacy fallback 제거됨.
30
- const here = dirname(fileURLToPath(import.meta.url));
31
- const repoRoot = join(here, "..", "..", "..", "..");
32
- const authorityDir = resolveInstallationPath("authority", repoRoot);
33
- return join(authorityDir, "diagnostic-codes.yaml");
34
- }
35
- function loadRegistry() {
36
- if (cachedRegistry !== null)
37
- return cachedRegistry;
38
- const raw = readFileSync(resolveRegistryPath(), "utf-8");
39
- const parsed = yamlParse(raw);
40
- if (!parsed || !Array.isArray(parsed.diagnostic_codes)) {
41
- throw new Error("[diagnostic-codes] invalid registry — diagnostic_codes 배열 없음");
42
- }
43
- validateRegistry(parsed);
44
- cachedRegistry = parsed;
45
- return parsed;
46
- }
47
- /**
48
- * Registry schema 검증 — code 유일성 + matcher 형식.
49
- * loadRegistry 내부에서 호출되며, 테스트 용도로도 export.
50
- */
51
- export function validateRegistry(registry) {
52
- const seenCodes = new Set();
53
- for (const entry of registry.diagnostic_codes) {
54
- if (seenCodes.has(entry.code)) {
55
- throw new Error(`[diagnostic-codes] duplicate code "${entry.code}" — code는 registry 내에서 유일해야 합니다.`);
56
- }
57
- seenCodes.add(entry.code);
58
- if (!Array.isArray(entry.matchers) || entry.matchers.length === 0) {
59
- throw new Error(`[diagnostic-codes] entry "${entry.code}" has no matchers — 최소 1개 matcher가 필요합니다.`);
60
- }
61
- for (let i = 0; i < entry.matchers.length; i++) {
62
- const m = entry.matchers[i];
63
- const hasIncludes = typeof m.includes === "string" && m.includes.length > 0;
64
- const hasIncludesAll = Array.isArray(m.includes_all) && m.includes_all.length > 0;
65
- if (!hasIncludes && !hasIncludesAll) {
66
- throw new Error(`[diagnostic-codes] entry "${entry.code}" matcher[${i}] — includes 또는 includes_all 중 하나를 비어있지 않은 값으로 지정해야 합니다.`);
67
- }
68
- }
69
- }
70
- }
71
- /** 테스트용 registry 초기화 */
72
- export function __resetDiagnosticRegistryCache() {
73
- cachedRegistry = null;
74
- }
75
- /** 테스트용 registry 주입 */
76
- export function __setDiagnosticRegistryForTesting(registry) {
77
- cachedRegistry = registry;
78
- }
79
- // ─── Matching ───
80
- function matcherMatches(m, reason) {
81
- if (m.includes !== undefined) {
82
- return reason.includes(m.includes);
83
- }
84
- if (Array.isArray(m.includes_all) && m.includes_all.length > 0) {
85
- return m.includes_all.every((s) => reason.includes(s));
86
- }
87
- return false;
88
- }
89
- function entryMatches(entry, reason) {
90
- return entry.matchers.some((m) => matcherMatches(m, reason));
91
- }
92
- /**
93
- * reason 문자열에 매칭되는 diagnostic entry 를 반환한다.
94
- * 매칭 없으면 null.
95
- */
96
- export function lookupDiagnosticCode(reason) {
97
- const registry = loadRegistry();
98
- for (const entry of registry.diagnostic_codes) {
99
- if (entryMatches(entry, reason)) {
100
- const message = entry.passthrough ? reason : (entry.message_ko ?? reason);
101
- return {
102
- code: entry.code,
103
- category: entry.category,
104
- message,
105
- passthrough: entry.passthrough === true,
106
- };
107
- }
108
- }
109
- // Silent failure 방지 — 매칭되지 않은 reason 은 영문 원문이 Principal 에 노출된다.
110
- // 개발자용 경고를 남겨 registry entry 누락 또는 reason 문구 drift 를 즉시 감지 가능하게.
111
- console.warn(`[diagnostic-codes] no matching entry for reason: "${reason}". Registry에 새 entry 추가 또는 기존 matcher 보강이 필요합니다.`);
112
- return null;
113
- }
114
- /**
115
- * gate-guard English reason → Principal-facing 한국어 메시지 변환.
116
- * 매칭 없으면 reason 원문을 그대로 반환.
117
- */
118
- export function wrapGateError(reason) {
119
- const hit = lookupDiagnosticCode(reason);
120
- return hit ? hit.message : reason;
121
- }
122
- /** 등록된 모든 diagnostic code 의 snapshot (telemetry / 문서화용) */
123
- export function listDiagnosticCodes() {
124
- return [...loadRegistry().diagnostic_codes];
125
- }
@@ -1,167 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi } from "vitest";
2
- import { wrapGateError, lookupDiagnosticCode, listDiagnosticCodes, validateRegistry, __resetDiagnosticRegistryCache, } from "./error-messages.js";
3
- beforeEach(() => {
4
- __resetDiagnosticRegistryCache();
5
- });
6
- describe("wrapGateError — backward-compatible behavior (기존 7 tests)", () => {
7
- it("wraps Transition denied → Korean message", () => {
8
- const reason = 'Transition denied: "draft" does not allow "align.locked"';
9
- expect(wrapGateError(reason)).toBe("현재 단계에서 이 작업을 수행할 수 없습니다.");
10
- });
11
- it("wraps Referential integrity → Korean message", () => {
12
- const reason = 'Referential integrity: constraint_id "CST-999" not found in pool';
13
- expect(wrapGateError(reason)).toBe("내부 참조 오류가 발생했습니다. 에이전트가 이벤트를 재확인해야 합니다.");
14
- });
15
- it("wraps Required constraint + rationale → Korean message", () => {
16
- const reason = 'Required constraint "CST-001" with override decision requires non-empty rationale';
17
- expect(wrapGateError(reason)).toBe("필수 제약 사항을 무시하려면 이유를 반드시 입력해야 합니다.");
18
- });
19
- it("wraps Convergence blocked → Korean message", () => {
20
- const reason = 'Convergence blocked: cannot "align.revised" until convergence.action_taken is recorded';
21
- expect(wrapGateError(reason)).toBe("수렴 차단 상태입니다. 방향 변경, scope 축소, 또는 보류 중 하나를 선택하세요.");
22
- });
23
- it("wraps Compile retry limit → Korean message", () => {
24
- const reason = "Compile retry limit exceeded (3 gap_found cycles). Consider scope.deferred or redirect.to_align.";
25
- expect(wrapGateError(reason)).toBe("compile 재시도 한도(3회)를 초과했습니다. scope를 보류하거나 방향을 재검토하세요.");
26
- });
27
- it("passes through Target lock messages (already Korean)", () => {
28
- const reason = "Target lock 불가: 미결정 2건. 모든 constraint 결정이 완료되어야 합니다.";
29
- expect(wrapGateError(reason)).toBe(reason);
30
- });
31
- it("passes through unknown error messages unchanged and warns developer", () => {
32
- const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
33
- const reason = "Some unknown error occurred";
34
- expect(wrapGateError(reason)).toBe(reason);
35
- expect(warnSpy).toHaveBeenCalledTimes(1);
36
- expect(warnSpy.mock.calls[0]?.[0]).toContain("no matching entry");
37
- expect(warnSpy.mock.calls[0]?.[0]).toContain(reason);
38
- warnSpy.mockRestore();
39
- });
40
- });
41
- describe("wrapGateError — 신규 coverage (기존 migrate 된 분기)", () => {
42
- it("wraps cannot be invalidated → Korean message", () => {
43
- const reason = "CST-007 is required and cannot be invalidated by system alone";
44
- expect(wrapGateError(reason)).toBe("필수 제약 사항은 시스템이 단독으로 무효화할 수 없습니다. 주체자의 확인이 필요합니다.");
45
- });
46
- it("wraps Compile 실패: → Korean message (Korean pattern)", () => {
47
- const reason = "Compile 실패: state mismatch at step 2";
48
- expect(wrapGateError(reason)).toBe("구현 명세 생성에 실패했습니다. 에이전트가 구현 계획을 수정한 뒤 재시도합니다.");
49
- });
50
- it("wraps Compile Defense failed → Korean message (OR branch of same code)", () => {
51
- const reason = "Compile Defense failed: shortcut not covered";
52
- expect(wrapGateError(reason)).toBe("구현 명세 생성에 실패했습니다. 에이전트가 구현 계획을 수정한 뒤 재시도합니다.");
53
- });
54
- it("wraps 'must be X state' → Korean message (AND match via includes_all)", () => {
55
- const reason = "scope must be in align_locked state before draft.surface.generated";
56
- expect(wrapGateError(reason)).toBe("현재 단계에서 이 작업을 수행할 수 없습니다.");
57
- });
58
- it("wraps compile_ready is false → Korean message", () => {
59
- const reason = "compile_ready is false: constraint decisions pending";
60
- expect(wrapGateError(reason)).toBe("아직 구현 명세를 생성할 수 없습니다. 제약 사항 결정이 완료되지 않았거나 소스가 변경되었습니다.");
61
- });
62
- it("wraps validation_plan_hash mismatch → Korean message", () => {
63
- const reason = "validation_plan_hash mismatch — recompute required";
64
- expect(wrapGateError(reason)).toBe("검증 계획이 변경되었습니다. compile을 다시 실행해야 합니다.");
65
- });
66
- it("wraps no matching injectValidation → Korean message", () => {
67
- const reason = "plan has no matching injectValidation for CST-003";
68
- expect(wrapGateError(reason)).toBe("구현 계획에 누락된 검증 항목이 있습니다. 에이전트가 수정한 뒤 재시도합니다.");
69
- });
70
- });
71
- describe("lookupDiagnosticCode — code 기반 routing", () => {
72
- it("Transition denied → DIAG-STATE-TRANSITION-01 code + category", () => {
73
- const hit = lookupDiagnosticCode('Transition denied: "draft" does not allow "x"');
74
- expect(hit).not.toBeNull();
75
- expect(hit.code).toBe("DIAG-STATE-TRANSITION-01");
76
- expect(hit.category).toBe("state-transition");
77
- expect(hit.passthrough).toBe(false);
78
- });
79
- it("Target lock → passthrough=true + 원문 message", () => {
80
- const reason = "Target lock 불가: 예시";
81
- const hit = lookupDiagnosticCode(reason);
82
- expect(hit).not.toBeNull();
83
- expect(hit.code).toBe("DIAG-TARGET-LOCK-01");
84
- expect(hit.passthrough).toBe(true);
85
- expect(hit.message).toBe(reason);
86
- });
87
- it("미매칭 reason → null (+ console.warn 발행)", () => {
88
- const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
89
- expect(lookupDiagnosticCode("totally unknown error")).toBeNull();
90
- expect(warnSpy).toHaveBeenCalledTimes(1);
91
- warnSpy.mockRestore();
92
- });
93
- it("우선순위: 가장 먼저 매칭되는 entry 가 이긴다 (registry 순서)", () => {
94
- // "Transition denied" 가 먼저, "must be ... state" 가 나중이므로
95
- // 둘 다 매칭될 수 있는 reason 에 대해 앞엣 것이 이겨야 한다.
96
- const reason = 'Transition denied: scope must be in grounded state';
97
- const hit = lookupDiagnosticCode(reason);
98
- expect(hit.code).toBe("DIAG-STATE-TRANSITION-01");
99
- });
100
- });
101
- describe("listDiagnosticCodes — registry 내용 노출", () => {
102
- it("모든 등록된 code 를 반환", () => {
103
- const codes = listDiagnosticCodes();
104
- expect(codes.length).toBeGreaterThanOrEqual(12);
105
- const codeIds = codes.map((c) => c.code);
106
- expect(codeIds).toContain("DIAG-STATE-TRANSITION-01");
107
- expect(codeIds).toContain("DIAG-TARGET-LOCK-01");
108
- expect(codeIds).toContain("DIAG-VALIDATION-MISSING-01");
109
- });
110
- it("각 entry 는 code·matchers·category 필드를 가진다", () => {
111
- const codes = listDiagnosticCodes();
112
- for (const c of codes) {
113
- expect(typeof c.code).toBe("string");
114
- expect(Array.isArray(c.matchers)).toBe(true);
115
- expect(c.matchers.length).toBeGreaterThan(0);
116
- expect(typeof c.category).toBe("string");
117
- }
118
- });
119
- });
120
- describe("validateRegistry — schema check (fail-fast on malformed registry)", () => {
121
- it("throws on duplicate code", () => {
122
- expect(() => validateRegistry({
123
- version: "test",
124
- diagnostic_codes: [
125
- { code: "DUP", matchers: [{ includes: "x" }], category: "test" },
126
- { code: "DUP", matchers: [{ includes: "y" }], category: "test" },
127
- ],
128
- })).toThrow(/duplicate code.*DUP/);
129
- });
130
- it("throws when entry has no matchers", () => {
131
- expect(() => validateRegistry({
132
- version: "test",
133
- diagnostic_codes: [
134
- { code: "C1", matchers: [], category: "test" },
135
- ],
136
- })).toThrow(/no matchers/);
137
- });
138
- it("throws on matcher without includes / includes_all", () => {
139
- expect(() => validateRegistry({
140
- version: "test",
141
- diagnostic_codes: [
142
- { code: "C1", matchers: [{}], category: "test" },
143
- ],
144
- })).toThrow(/includes.*includes_all/);
145
- });
146
- it("throws on matcher with empty includes_all array", () => {
147
- expect(() => validateRegistry({
148
- version: "test",
149
- diagnostic_codes: [
150
- { code: "C1", matchers: [{ includes_all: [] }], category: "test" },
151
- ],
152
- })).toThrow(/includes.*includes_all/);
153
- });
154
- it("passes a well-formed registry without throwing", () => {
155
- expect(() => validateRegistry({
156
- version: "test",
157
- diagnostic_codes: [
158
- { code: "C1", matchers: [{ includes: "x" }], category: "test" },
159
- { code: "C2", matchers: [{ includes_all: ["a", "b"] }], category: "test" },
160
- ],
161
- })).not.toThrow();
162
- });
163
- it("production registry (.onto/authority/diagnostic-codes.yaml) passes validation", () => {
164
- // loadRegistry 내부에서 validateRegistry 호출 — listDiagnosticCodes 로 간접 트리거
165
- expect(() => listDiagnosticCodes()).not.toThrow();
166
- });
167
- });