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,246 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
- import { resolveExecutionTopology, } from "./execution-topology-resolver.js";
3
- function args(overrides) {
4
- return {
5
- ontoConfig: {},
6
- env: {},
7
- claudeHost: false,
8
- experimentalAgentTeams: false,
9
- codexAvailable: false,
10
- codexSessionActive: false,
11
- liteLlmEndpointAvailable: false,
12
- ...overrides,
13
- };
14
- }
15
- function expectResolved(res) {
16
- if (res.type !== "resolved") {
17
- throw new Error(`expected resolved, got no_host: ${res.reason.slice(0, 120)}`);
18
- }
19
- return res;
20
- }
21
- describe("resolveExecutionTopology — axis-first happy paths", () => {
22
- let stderrSpy;
23
- beforeEach(() => {
24
- stderrSpy = vi.spyOn(process.stderr, "write").mockImplementation(() => true);
25
- });
26
- afterEach(() => {
27
- stderrSpy.mockRestore();
28
- });
29
- it("Claude host + main-native axes → cc-main-agent-subagent", () => {
30
- const res = resolveExecutionTopology(args({
31
- ontoConfig: {
32
- review: {
33
- teamlead: { model: "main" },
34
- subagent: { provider: "main-native" },
35
- },
36
- },
37
- claudeHost: true,
38
- }));
39
- const r = expectResolved(res);
40
- expect(r.topology.id).toBe("cc-main-agent-subagent");
41
- expect(r.topology.plan_trace.some((l) => l.includes("topology source=review-axes")))
42
- .toBe(true);
43
- expect(r.topology.plan_trace.some((l) => l.includes("derived TopologyId=cc-main-agent-subagent")))
44
- .toBe(true);
45
- });
46
- it("Claude host + codex subagent → cc-main-codex-subprocess", () => {
47
- const res = resolveExecutionTopology(args({
48
- ontoConfig: {
49
- review: {
50
- subagent: { provider: "codex", model_id: "gpt-5.4" },
51
- },
52
- },
53
- claudeHost: true,
54
- codexAvailable: true, // required by cc-main-codex-subprocess downstream check
55
- }));
56
- const r = expectResolved(res);
57
- expect(r.topology.id).toBe("cc-main-codex-subprocess");
58
- });
59
- it("Codex host + main-native → codex-main-subprocess", () => {
60
- const res = resolveExecutionTopology(args({
61
- ontoConfig: {
62
- review: {
63
- subagent: { provider: "main-native" },
64
- },
65
- },
66
- codexSessionActive: true,
67
- codexAvailable: true, // required by codex-main-subprocess downstream check
68
- }));
69
- const r = expectResolved(res);
70
- expect(r.topology.id).toBe("codex-main-subprocess");
71
- });
72
- it("Claude + teams + native + a2a → cc-teams-lens-agent-deliberation", () => {
73
- const res = resolveExecutionTopology(args({
74
- ontoConfig: {
75
- review: {
76
- subagent: { provider: "main-native" },
77
- lens_deliberation: "sendmessage-a2a",
78
- },
79
- // The resolver's own requirement check for the deliberation
80
- // topology ALSO inspects `lens_agent_teams_mode`. Set true so
81
- // the topology passes the downstream requirement gate.
82
- lens_agent_teams_mode: true,
83
- },
84
- claudeHost: true,
85
- experimentalAgentTeams: true,
86
- }));
87
- const r = expectResolved(res);
88
- expect(r.topology.id).toBe("cc-teams-lens-agent-deliberation");
89
- });
90
- it("external codex teamlead → codex-nested-subprocess", () => {
91
- const res = resolveExecutionTopology(args({
92
- ontoConfig: {
93
- review: {
94
- teamlead: { model: { provider: "codex", model_id: "gpt-5.4" } },
95
- subagent: { provider: "codex", model_id: "gpt-5.4" },
96
- },
97
- },
98
- // codex-nested-subprocess requires codex available + no CC session
99
- codexAvailable: true,
100
- claudeHost: false,
101
- codexSessionActive: false,
102
- }));
103
- const r = expectResolved(res);
104
- expect(r.topology.id).toBe("codex-nested-subprocess");
105
- });
106
- });
107
- describe("resolveExecutionTopology — P3 universal fallback (degrade to main_native)", () => {
108
- let stderrSpy;
109
- beforeEach(() => {
110
- stderrSpy = vi.spyOn(process.stderr, "write").mockImplementation(() => true);
111
- });
112
- afterEach(() => {
113
- stderrSpy.mockRestore();
114
- });
115
- it("invalid review block degrades to main_native (NOT legacy ladder)", () => {
116
- // Validator rejects `main-native + model_id`. Under P3, the degrade
117
- // path maps `main_native` shape against Claude host →
118
- // `cc-main-agent-subagent`. `execution_topology_priority` must NOT
119
- // be consulted (we verify by including a distinct entry that would
120
- // otherwise win).
121
- const res = resolveExecutionTopology(args({
122
- ontoConfig: {
123
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
- review: {
125
- subagent: { provider: "main-native", model_id: "x" },
126
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
- },
128
- },
129
- claudeHost: true,
130
- codexSessionActive: true,
131
- codexAvailable: true,
132
- }));
133
- const r = expectResolved(res);
134
- expect(r.topology.id).toBe("cc-main-agent-subagent");
135
- expect(r.topology.plan_trace.some((l) => l.includes("validation failed"))).toBe(true);
136
- expect(r.topology.plan_trace.some((l) => l.includes("degraded: requested=<validation-failed> → actual=main_native"))).toBe(true);
137
- // source = review-axes because the degrade produced a single-entry
138
- // TopologyId through the axis-first path; the legacy priority array
139
- // was acknowledged (see "ignored" trace line) but never consulted.
140
- expect(r.topology.plan_trace.some((l) => l.includes("topology source=review-axes"))).toBe(true);
141
- });
142
- it("derivation failure (a2a without teams) degrades to main_native", () => {
143
- // sendmessage-a2a requested but CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=0.
144
- // Derivation emits a violation — P3 degrade takes over, maps
145
- // main_native to the Claude host → cc-main-agent-subagent.
146
- const res = resolveExecutionTopology(args({
147
- ontoConfig: {
148
- review: {
149
- subagent: { provider: "main-native" },
150
- lens_deliberation: "sendmessage-a2a",
151
- },
152
- },
153
- claudeHost: true,
154
- codexSessionActive: true,
155
- codexAvailable: true,
156
- experimentalAgentTeams: false,
157
- }));
158
- const r = expectResolved(res);
159
- expect(r.topology.id).toBe("cc-main-agent-subagent");
160
- expect(r.topology.plan_trace.some((l) => l.includes("shape derivation failed"))).toBe(true);
161
- expect(r.topology.plan_trace.some((l) => l.includes("degraded: requested=a2a-deliberation → actual=main_native"))).toBe(true);
162
- expect(r.topology.plan_trace.some((l) => l.includes("topology source=review-axes"))).toBe(true);
163
- });
164
- it("axis mapping failure (main_foreign + litellm) degrades to main_native", () => {
165
- // main_foreign shape with provider=litellm has NO TopologyId in the
166
- // catalog (only codex mapped). P3 degrades to main_native, which
167
- // under Claude host maps to cc-main-agent-subagent.
168
- const res = resolveExecutionTopology(args({
169
- ontoConfig: {
170
- review: {
171
- subagent: { provider: "litellm", model_id: "gpt-4o" },
172
- },
173
- },
174
- claudeHost: true,
175
- codexSessionActive: true,
176
- codexAvailable: true,
177
- }));
178
- const r = expectResolved(res);
179
- expect(r.topology.id).toBe("cc-main-agent-subagent");
180
- expect(r.topology.plan_trace.some((l) => l.includes("mapping failed"))).toBe(true);
181
- expect(r.topology.plan_trace.some((l) => l.includes("degraded: requested=main_foreign(litellm) → actual=main_native"))).toBe(true);
182
- expect(r.topology.plan_trace.some((l) => l.includes("topology source=review-axes"))).toBe(true);
183
- });
184
- it("everything fails (main_native also unmappable) → no_host fail-fast", () => {
185
- // P9.1 (2026-04-21): legacy priority ladder is retired. When axis
186
- // derivation fails AND the `main_native` degrade cannot map (neither
187
- // Claude nor Codex host), the resolver returns `no_host`. The
188
- // `execution_topology_priority` array, even when pointing at an id
189
- // whose prerequisites are met (here: codex-nested-subprocess via
190
- // codex binary), is NOT consulted — ladder walking no longer exists.
191
- const res = resolveExecutionTopology(args({
192
- ontoConfig: {
193
- review: {
194
- subagent: { provider: "main-native" },
195
- },
196
- },
197
- claudeHost: false,
198
- codexSessionActive: false,
199
- codexAvailable: true,
200
- }));
201
- if (res.type !== "no_host") {
202
- throw new Error(`expected no_host, got resolved topology id=${res.topology.id}`);
203
- }
204
- expect(res.plan_trace.some((l) => l.includes("mapping failed"))).toBe(true);
205
- expect(res.plan_trace.some((l) => l.includes("degraded: requested=main_native → actual=main_native"))).toBe(true);
206
- expect(res.plan_trace.some((l) => l.includes("degrade-fallback: main_native unmappable"))).toBe(true);
207
- expect(res.plan_trace.some((l) => l.includes("no topology resolved (axis-first + main_native fallback both failed)"))).toBe(true);
208
- // Negative: the retired ladder's "priority source=config" log shape
209
- // must NOT surface — any regression would revive the dead path.
210
- expect(res.plan_trace.some((l) => l.includes("priority source="))).toBe(false);
211
- // Regression guard (PR #161 review): when `config.review` is present
212
- // but its internal degrade exhausts, the outer resolver must NOT
213
- // invoke a second `attemptMainNativeDegrade` with a misleading
214
- // `<review-block-absent>` label. Exactly one `degraded: requested=`
215
- // line should appear, and it must not carry that sentinel.
216
- expect(res.plan_trace.filter((l) => l.includes("degraded: requested=")).length).toBe(1);
217
- expect(res.plan_trace.some((l) => l.includes("<review-block-absent>"))).toBe(false);
218
- });
219
- });
220
- describe("resolveExecutionTopology — review absent → main_native degrade", () => {
221
- let stderrSpy;
222
- beforeEach(() => {
223
- stderrSpy = vi.spyOn(process.stderr, "write").mockImplementation(() => true);
224
- });
225
- afterEach(() => {
226
- stderrSpy.mockRestore();
227
- });
228
- it("no review block + CC host → main_native degrade → cc-main-agent-subagent", () => {
229
- // P9.1 (2026-04-21): when `config.review` is absent, the resolver
230
- // no longer walks the legacy priority ladder. It goes directly to
231
- // the universal `main_native` degrade path with
232
- // requested=<review-block-absent>. The degrade maps main_native
233
- // against the Claude host → cc-main-agent-subagent.
234
- const res = resolveExecutionTopology(args({
235
- ontoConfig: {},
236
- claudeHost: true,
237
- }));
238
- const r = expectResolved(res);
239
- expect(r.topology.id).toBe("cc-main-agent-subagent");
240
- // No axis-first trace: the review block was absent, so we never
241
- // entered the axis pipeline — only the direct degrade.
242
- expect(r.topology.plan_trace.some((l) => l.includes("review-axes: "))).toBe(false);
243
- expect(r.topology.plan_trace.some((l) => l.includes("degraded: requested=<review-block-absent>"))).toBe(true);
244
- expect(r.topology.plan_trace.some((l) => l.includes("topology source=fallback-main-native"))).toBe(true);
245
- });
246
- });
@@ -1,401 +0,0 @@
1
- /**
2
- * Execution Topology Resolver — axis-first only (P9.1, 2026-04-21).
3
- *
4
- * # What this module is
5
- *
6
- * Single seat for selecting ONE canonical execution topology for a review
7
- * session. Topology is the top-level decision — teamlead location + lens
8
- * spawn mechanism + deliberation channel.
9
- *
10
- * # Why it exists
11
- *
12
- * `config.review` is the canonical execution intent. Invalid or unsupported
13
- * axes fail loudly.
14
- *
15
- * # How it relates
16
- *
17
- * - `resolveExecutionTopology()` — run axis-first derivation →
18
- * prerequisite check → return topology or `no_host`. Emits `[topology]`
19
- * STDERR for every branch (mirrors `[plan]` pattern from PR #96).
20
- * - `TOPOLOGY_CATALOG` — metadata for the 8 canonical options.
21
- * - `DIRECT_SPAWN_SUPPORTED_TOPOLOGIES` — spawn-time support set.
22
- *
23
- * # Design reference
24
- *
25
- * - P9 handoff: `project_review_ux_redesign_p9_handoff.md` (memory)
26
- * - Completion doc: `development-records/evolve/20260421-review-ux-redesign-completion.md`
27
- * - Sketch v3: `development-records/evolve/20260418-execution-topology-priority-sketch.md`
28
- */
29
- import { detectClaudeCodeEnvSignal, detectCodexBinaryAvailable, detectCodexEnvSignal, } from "../discovery/host-detection.js";
30
- import { validateReviewConfig } from "./review-config-validator.js";
31
- import { deriveTopologyShape, } from "./topology-shape-derivation.js";
32
- import { shapeToTopologyId } from "./shape-to-topology-id.js";
33
- /**
34
- * Canonical metadata for each topology option.
35
- *
36
- * Per sketch v3 §3: once a topology id is chosen, all other attributes
37
- * (teamlead location, spawn mechanism, max concurrency, transport rank,
38
- * deliberation channel) are static. Principal cannot override them
39
- * individually — they must change the topology id.
40
- *
41
- * `execution_topology_overrides` in config allows per-topology
42
- * `max_concurrent_lenses` adjustment only. Other fields are immutable.
43
- */
44
- export const TOPOLOGY_CATALOG = {
45
- "cc-teams-lens-agent-deliberation": {
46
- id: "cc-teams-lens-agent-deliberation",
47
- teamlead_location: "claude-teamcreate",
48
- lens_spawn_mechanism: "claude-teamcreate-member",
49
- max_concurrent_lenses: 10,
50
- transport_rank: "S2",
51
- deliberation_channel: "controlled-lens-deliberation",
52
- },
53
- "cc-teams-agent-subagent": {
54
- id: "cc-teams-agent-subagent",
55
- teamlead_location: "claude-teamcreate",
56
- lens_spawn_mechanism: "claude-agent-tool",
57
- max_concurrent_lenses: 10,
58
- transport_rank: "S2",
59
- deliberation_channel: "controlled-lens-deliberation",
60
- },
61
- "cc-teams-codex-subprocess": {
62
- id: "cc-teams-codex-subprocess",
63
- teamlead_location: "claude-teamcreate",
64
- lens_spawn_mechanism: "codex-subprocess",
65
- max_concurrent_lenses: 5,
66
- transport_rank: "S0",
67
- deliberation_channel: "controlled-lens-deliberation",
68
- },
69
- "cc-main-agent-subagent": {
70
- id: "cc-main-agent-subagent",
71
- teamlead_location: "onto-main",
72
- lens_spawn_mechanism: "claude-agent-tool",
73
- max_concurrent_lenses: 10,
74
- transport_rank: "S2",
75
- deliberation_channel: "controlled-lens-deliberation",
76
- },
77
- "cc-main-codex-subprocess": {
78
- id: "cc-main-codex-subprocess",
79
- teamlead_location: "onto-main",
80
- lens_spawn_mechanism: "codex-subprocess",
81
- max_concurrent_lenses: 5,
82
- transport_rank: "S0",
83
- deliberation_channel: "controlled-lens-deliberation",
84
- },
85
- "codex-nested-subprocess": {
86
- id: "codex-nested-subprocess",
87
- teamlead_location: "codex-subprocess",
88
- lens_spawn_mechanism: "codex-subprocess",
89
- max_concurrent_lenses: 5,
90
- transport_rank: "S0",
91
- deliberation_channel: "controlled-lens-deliberation",
92
- },
93
- "codex-main-subprocess": {
94
- id: "codex-main-subprocess",
95
- teamlead_location: "onto-main",
96
- lens_spawn_mechanism: "codex-subprocess",
97
- max_concurrent_lenses: 5,
98
- transport_rank: "S0",
99
- deliberation_channel: "controlled-lens-deliberation",
100
- },
101
- };
102
- /**
103
- * Topology ids whose spawn path is implemented in the direct executor path.
104
- */
105
- export const DIRECT_SPAWN_SUPPORTED_TOPOLOGIES = new Set([
106
- "cc-main-agent-subagent",
107
- "cc-main-codex-subprocess",
108
- "codex-main-subprocess",
109
- ]);
110
- // ---------------------------------------------------------------------------
111
- // Observability
112
- // ---------------------------------------------------------------------------
113
- /**
114
- * Emit a `[topology]` prefixed decision line to STDERR.
115
- *
116
- * Parallels the `[plan]`, `[model-call]`, `[plan:executor]` prefixes.
117
- * `[topology]` sits at the top
118
- * of the layer stack: a reviewer scanning STDERR sees `[topology]` first
119
- * (macro decision) then `[plan]` (projection details) then `[model-call]`
120
- * (per-request invocation).
121
- *
122
- * No suppressor env var: topology decisions are load-bearing for review
123
- * reproducibility. Tests capture via `vi.spyOn(process.stderr, "write")`.
124
- */
125
- function emitTopologyLog(line) {
126
- process.stderr.write(`[topology] ${line}\n`);
127
- }
128
- /**
129
- * Evaluate whether the given topology id's prerequisites are satisfied by
130
- * the current detection signals. Returns a `{ ok, reason }` pair: `reason`
131
- * is populated for both branches so trace output explains matches AND skips.
132
- */
133
- function checkTopologyRequirements(id, signals) {
134
- switch (id) {
135
- case "cc-teams-lens-agent-deliberation": {
136
- if (!signals.claudeHost)
137
- return { ok: false, reason: "need CLAUDECODE=1" };
138
- if (!signals.experimentalAgentTeams) {
139
- return { ok: false, reason: "need CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1" };
140
- }
141
- if (!signals.lensAgentTeamsMode) {
142
- return { ok: false, reason: "need config.lens_agent_teams_mode=true" };
143
- }
144
- return { ok: true, reason: "CLAUDECODE + experimental-teams + lens_agent_teams_mode all set" };
145
- }
146
- case "cc-teams-agent-subagent": {
147
- if (!signals.claudeHost)
148
- return { ok: false, reason: "need CLAUDECODE=1" };
149
- if (!signals.experimentalAgentTeams) {
150
- return { ok: false, reason: "need CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1" };
151
- }
152
- return { ok: true, reason: "CLAUDECODE + experimental-teams set" };
153
- }
154
- case "cc-teams-codex-subprocess": {
155
- if (!signals.claudeHost)
156
- return { ok: false, reason: "need CLAUDECODE=1" };
157
- if (!signals.experimentalAgentTeams) {
158
- return { ok: false, reason: "need CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1" };
159
- }
160
- if (!signals.codexAvailable) {
161
- return { ok: false, reason: "need codex binary + ~/.codex/auth.json" };
162
- }
163
- return { ok: true, reason: "CLAUDECODE + experimental-teams + codex binary all set" };
164
- }
165
- case "cc-main-agent-subagent": {
166
- if (!signals.claudeHost)
167
- return { ok: false, reason: "need CLAUDECODE=1" };
168
- return { ok: true, reason: "CLAUDECODE=1 detected" };
169
- }
170
- case "cc-main-codex-subprocess": {
171
- if (!signals.claudeHost)
172
- return { ok: false, reason: "need CLAUDECODE=1" };
173
- if (!signals.codexAvailable) {
174
- return { ok: false, reason: "need codex binary + ~/.codex/auth.json" };
175
- }
176
- return { ok: true, reason: "CLAUDECODE + codex binary both present" };
177
- }
178
- case "codex-nested-subprocess": {
179
- if (!signals.codexAvailable) {
180
- return { ok: false, reason: "need codex binary + ~/.codex/auth.json" };
181
- }
182
- return { ok: true, reason: "codex binary present (host-agnostic)" };
183
- }
184
- case "codex-main-subprocess": {
185
- if (!signals.codexSessionActive) {
186
- return { ok: false, reason: "need Codex execution request or CLI session signal (CODEX_THREAD_ID / CODEX_CI)" };
187
- }
188
- if (!signals.codexAvailable) {
189
- return { ok: false, reason: "need codex binary + ~/.codex/auth.json" };
190
- }
191
- return { ok: true, reason: "codex execution/session + codex binary both present" };
192
- }
193
- }
194
- }
195
- // ---------------------------------------------------------------------------
196
- // Main resolver
197
- // ---------------------------------------------------------------------------
198
- /**
199
- * Derive a single ExecutionTopology for this review session.
200
- *
201
- * Decision surface:
202
- * 1. `config.review` must be present.
203
- * 2. The axis block must validate and map to a known topology.
204
- * 3. The chosen topology must satisfy its environment requirements.
205
- *
206
- * After a TopologyId is resolved, `checkTopologyRequirements` still runs
207
- * against it — the axis/shape pipeline gates on host presence only, while
208
- * `checkTopologyRequirements` covers the full signal set (codex binary,
209
- * experimental flag, etc). A requirement miss yields `no_host`.
210
- *
211
- * Returns:
212
- * - `{ type: "resolved", topology }` — resolved id passed its requirements.
213
- * - `{ type: "no_host", plan_trace, reason }`
214
- */
215
- export function resolveExecutionTopology(args) {
216
- const env = args.env ?? process.env;
217
- const trace = [];
218
- const log = (line) => {
219
- emitTopologyLog(line);
220
- trace.push(line);
221
- };
222
- const signals = {
223
- claudeHost: args.claudeHost ?? detectClaudeCodeEnvSignal(),
224
- experimentalAgentTeams: args.experimentalAgentTeams ?? env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1",
225
- lensAgentTeamsMode: args.ontoConfig.lens_agent_teams_mode === true,
226
- codexAvailable: args.codexAvailable ?? detectCodexBinaryAvailable(),
227
- codexSessionActive: (args.codexSessionActive ?? detectCodexEnvSignal()) ||
228
- args.codexExecutionRequested === true,
229
- };
230
- log(`signals: claudeHost=${signals.claudeHost} experimental=${signals.experimentalAgentTeams} ` +
231
- `lens_agent_teams_mode=${signals.lensAgentTeamsMode} codex=${signals.codexAvailable} ` +
232
- `codex_session=${signals.codexSessionActive}`);
233
- const axisFirstId = resolveAxisFirstTopology(args.ontoConfig, signals, log);
234
- if (!axisFirstId) {
235
- log("no topology resolved");
236
- return {
237
- type: "no_host",
238
- plan_trace: trace,
239
- reason: buildNoTopologyReason(signals),
240
- };
241
- }
242
- log(`topology source=review-axes id=${axisFirstId}`);
243
- const check = checkTopologyRequirements(axisFirstId, signals);
244
- if (!check.ok) {
245
- log(`${axisFirstId}: skip — ${check.reason}`);
246
- log("derived topology failed detailed requirements check");
247
- return {
248
- type: "no_host",
249
- plan_trace: trace,
250
- reason: buildNoTopologyReason(signals),
251
- };
252
- }
253
- log(`${axisFirstId}: matched — ${check.reason}`);
254
- const metadata = applyReviewConcurrencyOverride(TOPOLOGY_CATALOG[axisFirstId], args.ontoConfig.review?.max_concurrent_lenses, log);
255
- return {
256
- type: "resolved",
257
- topology: { ...metadata, plan_trace: trace },
258
- };
259
- }
260
- /**
261
- * Apply `review.max_concurrent_lenses` (Axis C) on top of the catalog
262
- * default. P9.2 (2026-04-21) made this the canonical override seat — the
263
- * previous `execution_topology_overrides` map was removed. Non-positive
264
- * values are ignored (fall back to catalog default) with a warning log.
265
- */
266
- function applyReviewConcurrencyOverride(metadata, requested, log) {
267
- if (requested === undefined)
268
- return metadata;
269
- // The TypeScript type already narrows `requested` to `number`, but
270
- // YAML parsing can yield `"6"` (string) or other non-numeric shapes
271
- // for this field. The runtime typeof check is defensive against that
272
- // parse-time coercion, not against typed in-process call sites.
273
- if (typeof requested !== "number" || requested <= 0) {
274
- log(`${metadata.id}: review.max_concurrent_lenses=${requested} ignored (must be positive integer)`);
275
- return metadata;
276
- }
277
- if (requested === metadata.max_concurrent_lenses)
278
- return metadata;
279
- log(`${metadata.id}: override max_concurrent_lenses ${metadata.max_concurrent_lenses} → ${requested} (via review.max_concurrent_lenses)`);
280
- return { ...metadata, max_concurrent_lenses: requested };
281
- }
282
- // ---------------------------------------------------------------------------
283
- // Error message composition
284
- // ---------------------------------------------------------------------------
285
- function buildNoTopologyReason(signals) {
286
- const lines = [];
287
- lines.push("Execution topology 를 도출할 수 없습니다.");
288
- lines.push("");
289
- lines.push("현재 환경 시그널:");
290
- lines.push(` - Claude Code 세션 (CLAUDECODE=1): ${signals.claudeHost}`);
291
- lines.push(` - Experimental Agent Teams: ${signals.experimentalAgentTeams}`);
292
- lines.push(` - Lens Agent Teams mode (config): ${signals.lensAgentTeamsMode}`);
293
- lines.push(` - Codex 바이너리 + ~/.codex/auth.json: ${signals.codexAvailable}`);
294
- lines.push(` - Codex 실행 요청 / CLI 세션 (CODEX_THREAD_ID / CODEX_CI): ${signals.codexSessionActive}`);
295
- lines.push("");
296
- lines.push("해결 방법 (한 가지 선택):");
297
- lines.push(" 1. Claude Code 세션에서 실행");
298
- lines.push(" 2. codex CLI 설치 + `codex login` 구성");
299
- lines.push(" 3. `.onto/config.yml` 의 `review:` axis block 을 현재 환경에서 실행 가능한 형태로 조정");
300
- return lines.join("\n");
301
- }
302
- // ---------------------------------------------------------------------------
303
- // Spawn-time support check
304
- // ---------------------------------------------------------------------------
305
- /**
306
- * Error thrown when a resolver picks an option this install cannot spawn.
307
- *
308
- * The resolver itself never throws — it always returns a resolution.
309
- * Callers dispatching to executors call `assertDirectSpawnSupported(topology)`
310
- * before attempting to spawn.
311
- */
312
- export class UnsupportedTopologyError extends Error {
313
- topologyId;
314
- constructor(topologyId) {
315
- super(buildUnsupportedTopologyMessage(topologyId));
316
- this.topologyId = topologyId;
317
- this.name = "UnsupportedTopologyError";
318
- }
319
- }
320
- function buildUnsupportedTopologyMessage(id) {
321
- const supported = [...DIRECT_SPAWN_SUPPORTED_TOPOLOGIES].join(", ");
322
- const requiredSurface = id === "cc-teams-agent-subagent" ||
323
- id === "cc-teams-codex-subprocess"
324
- ? "TeamCreate coordinator execution"
325
- : id === "codex-nested-subprocess"
326
- ? "external codex teamlead execution"
327
- : id === "cc-teams-lens-agent-deliberation"
328
- ? "controlled deliberation transport"
329
- : "provider adapter design";
330
- return [
331
- `ExecutionTopology id="${id}" 는 현 설치에서 직접 spawn 할 수 없습니다. 필요한 실행 표면: ${requiredSurface}.`,
332
- "지원되는 topology:",
333
- ...[...DIRECT_SPAWN_SUPPORTED_TOPOLOGIES].map((s) => ` - ${s}`),
334
- "",
335
- `Direct spawn 지원 옵션: ${supported}`,
336
- ].join("\n");
337
- }
338
- /**
339
- * Guard used by spawn-time code. Throws `UnsupportedTopologyError` when the
340
- * resolved topology is not wired for direct spawn in the current install.
341
- */
342
- export function assertDirectSpawnSupported(topology) {
343
- if (!DIRECT_SPAWN_SUPPORTED_TOPOLOGIES.has(topology.id)) {
344
- throw new UnsupportedTopologyError(topology.id);
345
- }
346
- }
347
- // ---------------------------------------------------------------------------
348
- // P2 axis-first helper (Review UX Redesign)
349
- // ---------------------------------------------------------------------------
350
- /**
351
- * Attempt to derive a `TopologyId` from the `review:` axis block.
352
- */
353
- function resolveAxisFirstTopology(config, signals, log) {
354
- const reviewBlock = config.review;
355
- if (reviewBlock === undefined) {
356
- return null;
357
- }
358
- const validation = validateReviewConfig(reviewBlock);
359
- if (!validation.ok) {
360
- log("review-axes: validation failed");
361
- for (const err of validation.errors) {
362
- log(`review-axes: invalid — ${err.path}: ${err.message}`);
363
- }
364
- return null;
365
- }
366
- const derivationSignals = {
367
- claudeHost: signals.claudeHost,
368
- codexSessionActive: signals.codexSessionActive,
369
- experimentalAgentTeams: signals.experimentalAgentTeams,
370
- lensAgentTeamsMode: signals.lensAgentTeamsMode,
371
- };
372
- const derivation = deriveTopologyShape(validation.config, derivationSignals);
373
- for (const line of derivation.ok ? derivation.derived.trace : derivation.trace) {
374
- log(`review-axes: ${line}`);
375
- }
376
- if (!derivation.ok) {
377
- log("review-axes: shape derivation failed");
378
- for (const reason of derivation.reasons) {
379
- log(`review-axes: ${reason}`);
380
- }
381
- return null;
382
- }
383
- const mapping = shapeToTopologyId({
384
- shape: derivation.derived.shape,
385
- subagent_provider: derivation.derived.subagent_provider,
386
- signals: {
387
- claudeHost: signals.claudeHost,
388
- codexSessionActive: signals.codexSessionActive,
389
- },
390
- });
391
- for (const line of mapping.trace) {
392
- log(`review-axes: ${line}`);
393
- }
394
- if (!mapping.ok) {
395
- log("review-axes: shape→TopologyId mapping failed");
396
- log(`review-axes: ${mapping.reason}`);
397
- return null;
398
- }
399
- log(`review-axes: derived TopologyId=${mapping.topology_id}`);
400
- return mapping.topology_id;
401
- }