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,794 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Coordinator State Machine — Deterministic State Enforcer for review process.
4
- *
5
- * 9 states (auto 3, await 3, terminal 3), 12 edges.
6
- * Auto state transitions are recorded in two phases:
7
- * 1. Entry transition recorded in memory (not flushed to disk)
8
- * 2. Exit transition recorded and flushed after auto state completes
9
- * On crash, the on-disk state file points to the previous await state.
10
- *
11
- * Design authority: .onto/temp/coordinator-state-machine-v3.md
12
- */
13
- import path from "node:path";
14
- import { parseArgs } from "node:util";
15
- import { pathToFileURL } from "node:url";
16
- import { ALLOWED_TRANSITIONS } from "../review/artifact-types.js";
17
- import fs from "node:fs/promises";
18
- import { isoNow, readYamlDocument, requireString, writeYamlDocument, fileExists, appendMarkdownLogEntry, parseMarkdownFrontmatter, } from "../review/review-artifact-utils.js";
19
- import { readExtractMode } from "../learning/shared/mode.js";
20
- import { initCoordinatorLog, buildSynthesizeRuntimePacket, writeExecutionResult, } from "./coordinator-helpers.js";
21
- import { buildLensControlledDeliberationPrompt, buildTeamleadControlledDeliberationPrompt, } from "../review/controlled-lens-deliberation.js";
22
- import { resolveRequiredParticipatingLensCount } from "../review/lens-completion-policy.js";
23
- import { PRE_DELIBERATION_ISSUE_ARTIFACT_IDS, renderIssueArtifactContext, resolveProblemFramingProfileRef, validateIssueArtifactOnDisk, writeIssueArtifactPromptPacket, } from "../review/issue-artifact-runtime.js";
24
- // ─────────────────────────────────────────────
25
- // Derived constants
26
- // ─────────────────────────────────────────────
27
- /** Derived from ALLOWED_TRANSITIONS: states with no outgoing edges. */
28
- const TERMINAL_STATES = Object.entries(ALLOWED_TRANSITIONS)
29
- .filter(([key, targets]) => key !== "(init)" && targets.length === 0)
30
- .map(([key]) => key);
31
- const AGENT_PROMPT_TEMPLATE = `You are a single bounded review unit executing as an Agent Teams-style ContextIsolatedReasoningUnit.
32
-
33
- Unit id: {unit_id}
34
- Unit kind: {unit_kind}
35
- Authoritative prompt packet path: {packet_path}
36
- Canonical output path: {output_path}
37
-
38
- Rules:
39
- - Read the prompt packet file at {packet_path}. Treat it as the authoritative contract.
40
- - Treat the Boundary Policy and Effective Boundary State in the packet as hard constraints.
41
- - Read the files referenced by the prompt packet when needed.
42
- - Stay within the smallest sufficient file set implied by the packet.
43
- - Do not recursively follow reference chains beyond the files explicitly listed in the packet unless the packet requires it.
44
- - Do not use web research when the packet says web research is denied.
45
- - Do not read outside the allowed filesystem scope described in the packet.
46
- - Produce only the final content for the canonical output path.
47
- - Do not wrap the answer in code fences.
48
- - Do not add commentary before or after the markdown.
49
- - Do not modify repository files yourself.
50
- - Do not change the required output structure from the packet.
51
- - Preserve disagreement and uncertainty explicitly when present.
52
- - If you cannot complete the task within the declared boundary, preserve that limitation explicitly as insufficient access or insufficient evidence within boundary instead of broadening the search.
53
-
54
- Read the prompt packet, execute the review, then write the complete output to {output_path}.`;
55
- function buildAgentPrompt(unitId, unitKind, packetPath, outputPath) {
56
- return AGENT_PROMPT_TEMPLATE.replace(/\{unit_id\}/g, unitId)
57
- .replace(/\{unit_kind\}/g, unitKind)
58
- .replace(/\{packet_path\}/g, packetPath)
59
- .replace(/\{output_path\}/g, outputPath);
60
- }
61
- // ─────────────────────────────────────────────
62
- // State file I/O
63
- // ─────────────────────────────────────────────
64
- function stateFilePath(sessionRoot) {
65
- return path.join(sessionRoot, "coordinator-state.yaml");
66
- }
67
- async function readStateFile(sessionRoot) {
68
- return readYamlDocument(stateFilePath(sessionRoot));
69
- }
70
- async function writeStateFile(sessionRoot, state) {
71
- await writeYamlDocument(stateFilePath(sessionRoot), state);
72
- }
73
- /**
74
- * Validates transition legality, updates current_state, and appends to
75
- * the transitions log. Does NOT flush to disk — caller decides when to write.
76
- *
77
- * Validates both:
78
- * - State-position: `from` must match `state.current_state` (except "(init)")
79
- * - Edge-existence: `from → to` must be in ALLOWED_TRANSITIONS
80
- */
81
- function applyTransition(state, from, to) {
82
- // State-position validation
83
- if (from !== "(init)" && state.current_state !== from) {
84
- throw new Error(`State position mismatch: current_state is "${state.current_state}" but transition starts from "${from}"`);
85
- }
86
- // Edge-existence validation
87
- const allowed = ALLOWED_TRANSITIONS[from];
88
- if (!allowed || !allowed.includes(to)) {
89
- throw new Error(`Invalid state transition: ${from} → ${to}. Allowed: ${(allowed ?? []).join(", ")}`);
90
- }
91
- state.current_state = to;
92
- state.transitions.push({ from, to, at: isoNow() });
93
- }
94
- // ─────────────────────────────────────────────
95
- // Build agent instructions from execution plan
96
- // ─────────────────────────────────────────────
97
- function buildLensAgentInstructions(executionPlan) {
98
- return executionPlan.lens_prompt_packet_seats.map((seat) => ({
99
- lens_id: seat.lens_id,
100
- description: `Review lens: ${seat.lens_id}`,
101
- prompt: buildAgentPrompt(seat.lens_id, "lens", seat.packet_path, seat.output_path),
102
- output_path: seat.output_path,
103
- packet_path: seat.packet_path,
104
- }));
105
- }
106
- function buildSynthesizeAgentInstruction(executionPlan, runtimePacketPath) {
107
- return {
108
- lens_id: "synthesize",
109
- description: "Synthesize lens findings",
110
- prompt: buildAgentPrompt("synthesize", "synthesize", runtimePacketPath, executionPlan.synthesis_output_path),
111
- output_path: executionPlan.synthesis_output_path,
112
- packet_path: runtimePacketPath,
113
- };
114
- }
115
- async function readLensOutputsForDeliberation(executionPlan) {
116
- const lensOutputs = [];
117
- for (const seat of executionPlan.lens_prompt_packet_seats) {
118
- if (!(await fileExists(seat.output_path))) {
119
- continue;
120
- }
121
- const content = await fs.readFile(seat.output_path, "utf8");
122
- if (content.trim().length === 0) {
123
- continue;
124
- }
125
- lensOutputs.push({
126
- lens_id: seat.lens_id,
127
- output_path: seat.output_path,
128
- content,
129
- });
130
- }
131
- const minimumParticipating = resolveRequiredParticipatingLensCount(executionPlan);
132
- if (lensOutputs.length < minimumParticipating) {
133
- throw new Error(`Fewer than ${minimumParticipating} participating lens outputs are available for deliberation.`);
134
- }
135
- return lensOutputs;
136
- }
137
- function requireDeliberationSeat(executionPlan, lensId) {
138
- const seat = executionPlan.lens_deliberation_prompt_packet_seats.find((candidate) => candidate.lens_id === lensId);
139
- if (!seat) {
140
- throw new Error(`Missing deliberation prompt seat for lens: ${lensId}`);
141
- }
142
- return seat;
143
- }
144
- async function buildLensDeliberationAgentInstructions(executionPlan, projectRoot) {
145
- if (executionPlan.deliberation_mode !== "controlled-lens-deliberation") {
146
- throw new Error(`Unsupported review deliberation mode: ${executionPlan.deliberation_mode}`);
147
- }
148
- const lensOutputs = await readLensOutputsForDeliberation(executionPlan);
149
- const issueArtifactContext = await renderIssueArtifactContext({
150
- projectRoot,
151
- executionPlan,
152
- });
153
- const lensOutputById = new Map(lensOutputs.map((lensOutput) => [lensOutput.lens_id, lensOutput]));
154
- const instructions = [];
155
- for (const lensOutput of lensOutputs) {
156
- const seat = requireDeliberationSeat(executionPlan, lensOutput.lens_id);
157
- const packetText = buildLensControlledDeliberationPrompt({
158
- session_id: executionPlan.session_id,
159
- lens_id: lensOutput.lens_id,
160
- output_path: seat.output_path,
161
- own_output: lensOutput,
162
- other_outputs: lensOutputs.filter((candidate) => candidate.lens_id !== lensOutput.lens_id),
163
- issue_artifact_context: issueArtifactContext,
164
- });
165
- await fs.mkdir(path.dirname(seat.packet_path), { recursive: true });
166
- await fs.writeFile(seat.packet_path, `${packetText.trimEnd()}\n`, "utf8");
167
- instructions.push({
168
- lens_id: `deliberation-${lensOutput.lens_id}`,
169
- description: `Controlled deliberation response: ${lensOutput.lens_id}`,
170
- prompt: buildAgentPrompt(`deliberation-${lensOutput.lens_id}`, "deliberation", seat.packet_path, seat.output_path),
171
- output_path: seat.output_path,
172
- packet_path: seat.packet_path,
173
- });
174
- if (!lensOutputById.has(lensOutput.lens_id)) {
175
- throw new Error(`Missing deliberation lens output: ${lensOutput.lens_id}`);
176
- }
177
- }
178
- return instructions;
179
- }
180
- async function buildTeamleadDeliberationAgentInstruction(executionPlan, projectRoot) {
181
- const lensOutputs = await readLensOutputsForDeliberation(executionPlan);
182
- const issueArtifactContext = await renderIssueArtifactContext({
183
- projectRoot,
184
- executionPlan,
185
- });
186
- const responses = [];
187
- for (const lensOutput of lensOutputs) {
188
- const seat = requireDeliberationSeat(executionPlan, lensOutput.lens_id);
189
- if (!(await fileExists(seat.output_path))) {
190
- throw new Error(`Missing lens deliberation response for teamlead result: ${seat.output_path}`);
191
- }
192
- const content = await fs.readFile(seat.output_path, "utf8");
193
- if (content.trim().length === 0) {
194
- throw new Error(`Empty lens deliberation response for teamlead result: ${seat.output_path}`);
195
- }
196
- responses.push({
197
- lens_id: lensOutput.lens_id,
198
- response_path: seat.output_path,
199
- content,
200
- });
201
- }
202
- const packetText = buildTeamleadControlledDeliberationPrompt({
203
- session_id: executionPlan.session_id,
204
- output_path: executionPlan.deliberation_output_path,
205
- lens_outputs: lensOutputs,
206
- lens_deliberation_responses: responses,
207
- issue_artifact_context: issueArtifactContext,
208
- });
209
- await fs.writeFile(executionPlan.teamlead_deliberation_prompt_packet_path, `${packetText.trimEnd()}\n`, "utf8");
210
- return {
211
- lens_id: "controlled-deliberation",
212
- description: "Teamlead controlled lens deliberation result",
213
- prompt: buildAgentPrompt("controlled-deliberation", "deliberation", executionPlan.teamlead_deliberation_prompt_packet_path, executionPlan.deliberation_output_path),
214
- output_path: executionPlan.deliberation_output_path,
215
- packet_path: executionPlan.teamlead_deliberation_prompt_packet_path,
216
- };
217
- }
218
- async function hasNonEmptyFile(filePath) {
219
- if (!(await fileExists(filePath)))
220
- return false;
221
- const text = await fs.readFile(filePath, "utf8");
222
- return text.trim().length > 0;
223
- }
224
- async function getParticipatingLensRefs(executionPlan) {
225
- const lensOutputs = await readLensOutputsForDeliberation(executionPlan);
226
- return {
227
- lensIds: lensOutputs.map((lensOutput) => lensOutput.lens_id),
228
- outputPaths: lensOutputs.map((lensOutput) => lensOutput.output_path),
229
- };
230
- }
231
- async function validatePreDeliberationIssueArtifacts(args) {
232
- for (const artifactId of PRE_DELIBERATION_ISSUE_ARTIFACT_IDS) {
233
- await validateIssueArtifactOnDisk({
234
- executionPlan: args.executionPlan,
235
- artifactId,
236
- participatingLensIds: args.participatingLensIds,
237
- });
238
- }
239
- }
240
- async function buildIssueArtifactAgentInstruction(args) {
241
- const seat = await writeIssueArtifactPromptPacket({
242
- artifactId: args.artifactId,
243
- sessionId: args.executionPlan.session_id,
244
- projectRoot: args.projectRoot,
245
- executionPlan: args.executionPlan,
246
- lensOutputPaths: args.lensOutputPaths,
247
- ...(args.deliberationResponsePaths
248
- ? { deliberationResponsePaths: args.deliberationResponsePaths }
249
- : {}),
250
- ...(args.deliberationOutputPath
251
- ? { deliberationOutputPath: args.deliberationOutputPath }
252
- : {}),
253
- ...(args.problemFramingProfileRef !== undefined
254
- ? { problemFramingProfileRef: args.problemFramingProfileRef }
255
- : {}),
256
- });
257
- return {
258
- lens_id: args.artifactId,
259
- description: `Issue closure artifact: ${args.artifactId}`,
260
- prompt: buildAgentPrompt(args.artifactId, "issue_artifact", seat.packet_path, seat.output_path),
261
- output_path: seat.output_path,
262
- packet_path: seat.packet_path,
263
- };
264
- }
265
- async function buildNextPreDeliberationIssueArtifactAgent(args) {
266
- const { lensIds, outputPaths } = await getParticipatingLensRefs(args.executionPlan);
267
- for (const artifactId of PRE_DELIBERATION_ISSUE_ARTIFACT_IDS) {
268
- const seat = args.executionPlan.issue_artifact_prompt_packet_seats.find((candidate) => candidate.artifact_id === artifactId);
269
- if (!seat) {
270
- throw new Error(`Missing issue artifact prompt seat: ${artifactId}`);
271
- }
272
- if (!(await hasNonEmptyFile(seat.output_path))) {
273
- return buildIssueArtifactAgentInstruction({
274
- executionPlan: args.executionPlan,
275
- projectRoot: args.projectRoot,
276
- artifactId,
277
- lensOutputPaths: outputPaths,
278
- });
279
- }
280
- await validateIssueArtifactOnDisk({
281
- executionPlan: args.executionPlan,
282
- artifactId,
283
- participatingLensIds: lensIds,
284
- });
285
- }
286
- return null;
287
- }
288
- async function readLensDeliberationResponsePaths(executionPlan) {
289
- const lensOutputs = await readLensOutputsForDeliberation(executionPlan);
290
- const paths = [];
291
- for (const lensOutput of lensOutputs) {
292
- const seat = requireDeliberationSeat(executionPlan, lensOutput.lens_id);
293
- if (!(await hasNonEmptyFile(seat.output_path))) {
294
- throw new Error(`Missing lens deliberation response: ${seat.output_path}`);
295
- }
296
- paths.push(seat.output_path);
297
- }
298
- return paths;
299
- }
300
- async function buildProblemFramingAgentIfNeeded(args) {
301
- const { lensIds, outputPaths } = await getParticipatingLensRefs(args.executionPlan);
302
- await validatePreDeliberationIssueArtifacts({
303
- executionPlan: args.executionPlan,
304
- participatingLensIds: lensIds,
305
- });
306
- const problemFramingSeat = args.executionPlan.issue_artifact_prompt_packet_seats.find((candidate) => candidate.artifact_id === "problem-framing");
307
- if (!problemFramingSeat) {
308
- throw new Error("Missing issue artifact prompt seat: problem-framing");
309
- }
310
- if (await hasNonEmptyFile(problemFramingSeat.output_path)) {
311
- await validateIssueArtifactOnDisk({
312
- executionPlan: args.executionPlan,
313
- artifactId: "problem-framing",
314
- participatingLensIds: lensIds,
315
- });
316
- return null;
317
- }
318
- return buildIssueArtifactAgentInstruction({
319
- executionPlan: args.executionPlan,
320
- projectRoot: args.projectRoot,
321
- artifactId: "problem-framing",
322
- lensOutputPaths: outputPaths,
323
- deliberationResponsePaths: await readLensDeliberationResponsePaths(args.executionPlan),
324
- deliberationOutputPath: args.executionPlan.deliberation_output_path,
325
- problemFramingProfileRef: await resolveProblemFramingProfileRef({
326
- projectRoot: args.projectRoot,
327
- executionPlan: args.executionPlan,
328
- }),
329
- });
330
- }
331
- // ─────────────────────────────────────────────
332
- // coordinator start
333
- // ─────────────────────────────────────────────
334
- export async function coordinatorStart(argv) {
335
- let sessionRoot;
336
- let requestText = "";
337
- try {
338
- // Phase 1: Create session via reviewPrepareOnly
339
- const { reviewPrepareOnly } = await import("./review-invoke.js");
340
- const enrichedArgv = [...argv];
341
- if (!enrichedArgv.includes("--prepare-only")) {
342
- enrichedArgv.push("--prepare-only");
343
- }
344
- const prepareResult = await reviewPrepareOnly(enrichedArgv);
345
- sessionRoot = path.resolve(prepareResult.session_root);
346
- requestText = prepareResult.request_text;
347
- // State file created immediately after session directory exists (CCON-1).
348
- // current_state="preparing" — auto state is still running (initCoordinatorLog pending).
349
- const stateFile = {
350
- schema_version: "1",
351
- current_state: "preparing",
352
- session_root: sessionRoot,
353
- request_text: requestText,
354
- started_at: isoNow(),
355
- halt_reason: null,
356
- error_message: null,
357
- transitions: [{ from: "(init)", to: "preparing", at: isoNow() }],
358
- };
359
- await writeStateFile(sessionRoot, stateFile);
360
- // Phase 2: Initialize coordinator log (still within "preparing" auto state)
361
- await initCoordinatorLog(["--session-root", sessionRoot]);
362
- // Read execution plan
363
- const executionPlan = await readYamlDocument(path.join(sessionRoot, "execution-plan.yaml"));
364
- // preparing complete → transition to awaiting_lens_dispatch
365
- applyTransition(stateFile, "preparing", "awaiting_lens_dispatch");
366
- await writeStateFile(sessionRoot, stateFile);
367
- return {
368
- state: "awaiting_lens_dispatch",
369
- session_root: sessionRoot,
370
- request_text: requestText,
371
- agents: buildLensAgentInstructions(executionPlan),
372
- max_concurrent_lenses: executionPlan.max_concurrent_lenses ??
373
- executionPlan.lens_prompt_packet_seats.length,
374
- };
375
- }
376
- catch (error) {
377
- if (sessionRoot) {
378
- try {
379
- // State file may exist (created after Phase 1) — update it
380
- const existing = await readStateFile(sessionRoot);
381
- existing.error_message =
382
- error instanceof Error ? error.message : String(error);
383
- applyTransition(existing, "preparing", "failed");
384
- await writeStateFile(sessionRoot, existing);
385
- }
386
- catch {
387
- // State file doesn't exist (Phase 1 failed) — create one
388
- const failedState = {
389
- schema_version: "1",
390
- current_state: "failed",
391
- session_root: sessionRoot,
392
- request_text: requestText,
393
- started_at: isoNow(),
394
- halt_reason: null,
395
- error_message: error instanceof Error ? error.message : String(error),
396
- transitions: [
397
- { from: "(init)", to: "preparing", at: isoNow() },
398
- { from: "preparing", to: "failed", at: isoNow() },
399
- ],
400
- };
401
- await writeStateFile(sessionRoot, failedState);
402
- }
403
- }
404
- throw error;
405
- }
406
- }
407
- // ─────────────────────────────────────────────
408
- // coordinator next
409
- // ─────────────────────────────────────────────
410
- export async function coordinatorNext(sessionRoot, projectRoot, orchestratorReportedRealization) {
411
- const stateFile = await readStateFile(sessionRoot);
412
- // Orchestrator self-reporting: record on first provided value (idempotent).
413
- // Closes the gap between binding.yaml's plan-time resolved_execution_realization
414
- // and the caller's actual dispatch mechanism. Contract §18.
415
- if (orchestratorReportedRealization &&
416
- !stateFile.orchestrator_reported_realization) {
417
- stateFile.orchestrator_reported_realization = orchestratorReportedRealization;
418
- await writeStateFile(sessionRoot, stateFile);
419
- }
420
- const currentState = stateFile.current_state;
421
- if (TERMINAL_STATES.includes(currentState)) {
422
- throw new Error(`Session already terminated (state: ${currentState})`);
423
- }
424
- switch (currentState) {
425
- case "awaiting_lens_dispatch": {
426
- try {
427
- // Record auto state entry in memory (not flushed — crash-safe)
428
- applyTransition(stateFile, "awaiting_lens_dispatch", "validating_lenses");
429
- // Run validating_lenses auto state
430
- const result = await buildSynthesizeRuntimePacket([
431
- "--session-root",
432
- sessionRoot,
433
- "--project-root",
434
- projectRoot,
435
- "--validate-lenses-only",
436
- ]);
437
- if (result.halt) {
438
- stateFile.halt_reason = result.halt_reason ?? null;
439
- applyTransition(stateFile, "validating_lenses", "halted_partial");
440
- await writeStateFile(sessionRoot, stateFile);
441
- return {
442
- state: "halted_partial",
443
- session_root: sessionRoot,
444
- halt_reason: result.halt_reason,
445
- participating_lens_ids: result.participating_lens_ids,
446
- degraded_lens_ids: result.degraded_lens_ids,
447
- };
448
- }
449
- const executionPlan = await readYamlDocument(path.join(sessionRoot, "execution-plan.yaml"));
450
- const issueArtifactAgent = await buildNextPreDeliberationIssueArtifactAgent({
451
- executionPlan,
452
- projectRoot,
453
- });
454
- applyTransition(stateFile, "validating_lenses", "awaiting_adjudication");
455
- if (!issueArtifactAgent) {
456
- const deliberationAgents = await buildLensDeliberationAgentInstructions(executionPlan, projectRoot);
457
- applyTransition(stateFile, "awaiting_adjudication", "awaiting_deliberation");
458
- await writeStateFile(sessionRoot, stateFile);
459
- return {
460
- state: "awaiting_deliberation",
461
- session_root: sessionRoot,
462
- agents: deliberationAgents,
463
- participating_lens_ids: result.participating_lens_ids,
464
- degraded_lens_ids: result.degraded_lens_ids,
465
- };
466
- }
467
- await writeStateFile(sessionRoot, stateFile);
468
- return {
469
- state: "awaiting_adjudication",
470
- session_root: sessionRoot,
471
- ...(issueArtifactAgent ? { agent: issueArtifactAgent } : {}),
472
- participating_lens_ids: result.participating_lens_ids,
473
- degraded_lens_ids: result.degraded_lens_ids,
474
- };
475
- }
476
- catch (error) {
477
- // Reload from disk — in-memory state may have partial transitions
478
- const diskState = await readStateFile(sessionRoot);
479
- diskState.error_message =
480
- error instanceof Error ? error.message : String(error);
481
- // If still at awaiting_lens_dispatch on disk, record the full path
482
- if (diskState.current_state === "awaiting_lens_dispatch") {
483
- applyTransition(diskState, "awaiting_lens_dispatch", "validating_lenses");
484
- }
485
- applyTransition(diskState, "validating_lenses", "failed");
486
- await writeStateFile(sessionRoot, diskState);
487
- return {
488
- state: "failed",
489
- session_root: sessionRoot,
490
- error_message: diskState.error_message,
491
- };
492
- }
493
- }
494
- case "awaiting_synthesize_dispatch": {
495
- // Controlled lens deliberation is a required pre-synthesize stage.
496
- // Completing may proceed only when both artifacts agree that the
497
- // deliberation stage ran and synthesize consumed it.
498
- try {
499
- // Record auto state entry in memory (not flushed — crash-safe)
500
- applyTransition(stateFile, "awaiting_synthesize_dispatch", "completing");
501
- // Run completing auto state
502
- // Step 1: Check synthesis output
503
- const executionPlan = await readYamlDocument(path.join(sessionRoot, "execution-plan.yaml"));
504
- if (!(await fileExists(executionPlan.synthesis_output_path))) {
505
- throw new Error("completing step 1: synthesis output missing");
506
- }
507
- // Step 2: Deliberation-status guard. Completed review requires the
508
- // synthesize stage to acknowledge the pre-synthesize controlled
509
- // deliberation artifact.
510
- const synthesisText = await fs.readFile(executionPlan.synthesis_output_path, "utf8");
511
- const synthesisFrontmatter = parseMarkdownFrontmatter(synthesisText).metadata;
512
- const synthesisDeliberationStatus = synthesisFrontmatter?.deliberation_status;
513
- if (synthesisDeliberationStatus !== "performed") {
514
- throw new Error("completing step 2: synthesis output must declare " +
515
- "`deliberation_status: performed` because controlled lens " +
516
- "deliberation is a required pre-synthesize stage.");
517
- }
518
- if (!(await fileExists(executionPlan.deliberation_output_path))) {
519
- throw new Error(`completing step 2: controlled deliberation output missing: ${executionPlan.deliberation_output_path}`);
520
- }
521
- // Step 2.5: Learning extraction (Phase 2)
522
- const sessionMetadata = await readYamlDocument(path.join(sessionRoot, "session-metadata.yaml"));
523
- const extractMode = readExtractMode(sessionMetadata);
524
- if (extractMode !== "disabled") {
525
- try {
526
- const { runLearningExtraction } = await import("../learning/extractor.js");
527
- const extractionManifest = await runLearningExtraction({
528
- sessionRoot,
529
- projectRoot,
530
- executionPlan,
531
- mode: extractMode,
532
- sessionId: executionPlan.session_id,
533
- sessionDomain: sessionMetadata.requested_domain_token || null,
534
- });
535
- // Persist manifest (shadow and production both)
536
- await writeYamlDocument(path.join(sessionRoot, "execution-preparation", "learning-extraction-manifest.yaml"), extractionManifest);
537
- }
538
- catch (error) {
539
- // Non-blocking: extraction failure must not prevent review completion
540
- await appendMarkdownLogEntry(path.join(sessionRoot, "error-log.md"), "learning extraction failed (non-blocking)", error instanceof Error ? error.message : String(error));
541
- }
542
- }
543
- // Step 3: write-execution-result
544
- const startedAt = stateFile.transitions.find((t) => t.to === "preparing")?.at ??
545
- stateFile.started_at;
546
- const writeOutput = await writeExecutionResult([
547
- "--session-root",
548
- sessionRoot,
549
- "--started-at",
550
- startedAt,
551
- ]);
552
- // Step 4: complete-session
553
- const { completeReviewSession } = await import("./complete-review-session.js");
554
- const stateForRequest = await readStateFile(sessionRoot);
555
- await completeReviewSession([
556
- "--project-root",
557
- projectRoot,
558
- "--session-root",
559
- sessionRoot,
560
- "--request-text",
561
- stateForRequest.request_text,
562
- ]);
563
- applyTransition(stateFile, "completing", "completed");
564
- await writeStateFile(sessionRoot, stateFile);
565
- // Read review record status
566
- const reviewRecordPath = executionPlan.review_record_path ??
567
- path.join(sessionRoot, "review-record.yaml");
568
- let recordStatus;
569
- if (await fileExists(reviewRecordPath)) {
570
- const record = await readYamlDocument(reviewRecordPath);
571
- recordStatus = record.record_status;
572
- }
573
- return {
574
- state: "completed",
575
- session_root: sessionRoot,
576
- final_output_path: executionPlan.final_output_path ??
577
- path.join(sessionRoot, "final-output.md"),
578
- review_record_path: reviewRecordPath,
579
- record_status: recordStatus,
580
- };
581
- }
582
- catch (error) {
583
- // Reload from disk — in-memory state may have partial transitions
584
- const diskState = await readStateFile(sessionRoot);
585
- diskState.error_message =
586
- error instanceof Error ? error.message : String(error);
587
- if (diskState.current_state === "awaiting_synthesize_dispatch") {
588
- applyTransition(diskState, "awaiting_synthesize_dispatch", "completing");
589
- }
590
- applyTransition(diskState, "completing", "failed");
591
- await writeStateFile(sessionRoot, diskState);
592
- return {
593
- state: "failed",
594
- session_root: sessionRoot,
595
- error_message: diskState.error_message,
596
- };
597
- }
598
- }
599
- case "awaiting_adjudication": {
600
- try {
601
- const executionPlan = await readYamlDocument(path.join(sessionRoot, "execution-plan.yaml"));
602
- const issueArtifactAgent = await buildNextPreDeliberationIssueArtifactAgent({
603
- executionPlan,
604
- projectRoot,
605
- });
606
- if (issueArtifactAgent) {
607
- return {
608
- state: "awaiting_adjudication",
609
- session_root: sessionRoot,
610
- agent: issueArtifactAgent,
611
- };
612
- }
613
- const deliberationAgents = await buildLensDeliberationAgentInstructions(executionPlan, projectRoot);
614
- applyTransition(stateFile, "awaiting_adjudication", "awaiting_deliberation");
615
- await writeStateFile(sessionRoot, stateFile);
616
- return {
617
- state: "awaiting_deliberation",
618
- session_root: sessionRoot,
619
- agents: deliberationAgents,
620
- };
621
- }
622
- catch (error) {
623
- const diskState = await readStateFile(sessionRoot);
624
- diskState.error_message =
625
- error instanceof Error ? error.message : String(error);
626
- if (diskState.current_state === "awaiting_adjudication") {
627
- applyTransition(diskState, "awaiting_adjudication", "failed");
628
- }
629
- await writeStateFile(sessionRoot, diskState);
630
- return {
631
- state: "failed",
632
- session_root: sessionRoot,
633
- error_message: diskState.error_message,
634
- };
635
- }
636
- }
637
- case "awaiting_deliberation": {
638
- try {
639
- const executionPlan = await readYamlDocument(path.join(sessionRoot, "execution-plan.yaml"));
640
- if (!(await fileExists(executionPlan.deliberation_output_path))) {
641
- return {
642
- state: "awaiting_deliberation",
643
- session_root: sessionRoot,
644
- agent: await buildTeamleadDeliberationAgentInstruction(executionPlan, projectRoot),
645
- };
646
- }
647
- const problemFramingAgent = await buildProblemFramingAgentIfNeeded({
648
- executionPlan,
649
- projectRoot,
650
- });
651
- if (problemFramingAgent) {
652
- return {
653
- state: "awaiting_deliberation",
654
- session_root: sessionRoot,
655
- agent: problemFramingAgent,
656
- };
657
- }
658
- const result = await buildSynthesizeRuntimePacket([
659
- "--session-root",
660
- sessionRoot,
661
- "--project-root",
662
- projectRoot,
663
- "--require-deliberation",
664
- ]);
665
- if (result.halt) {
666
- stateFile.halt_reason = result.halt_reason ?? null;
667
- applyTransition(stateFile, "awaiting_deliberation", "failed");
668
- await writeStateFile(sessionRoot, stateFile);
669
- return {
670
- state: "failed",
671
- session_root: sessionRoot,
672
- halt_reason: result.halt_reason,
673
- };
674
- }
675
- const runtimePacketPath = result.runtime_packet_path ??
676
- path.join(executionPlan.prompt_packets_root ??
677
- path.join(sessionRoot, "prompt-packets"), "synthesize.runtime.prompt.md");
678
- applyTransition(stateFile, "awaiting_deliberation", "awaiting_synthesize_dispatch");
679
- await writeStateFile(sessionRoot, stateFile);
680
- return {
681
- state: "awaiting_synthesize_dispatch",
682
- session_root: sessionRoot,
683
- agent: buildSynthesizeAgentInstruction(executionPlan, runtimePacketPath),
684
- };
685
- }
686
- catch (error) {
687
- const diskState = await readStateFile(sessionRoot);
688
- diskState.error_message =
689
- error instanceof Error ? error.message : String(error);
690
- if (diskState.current_state === "awaiting_deliberation") {
691
- applyTransition(diskState, "awaiting_deliberation", "failed");
692
- }
693
- await writeStateFile(sessionRoot, diskState);
694
- return {
695
- state: "failed",
696
- session_root: sessionRoot,
697
- error_message: diskState.error_message,
698
- };
699
- }
700
- }
701
- default:
702
- throw new Error(`Unexpected state for next: ${currentState}`);
703
- }
704
- }
705
- // ─────────────────────────────────────────────
706
- // coordinator status
707
- // ─────────────────────────────────────────────
708
- export async function coordinatorStatus(sessionRoot) {
709
- return readStateFile(sessionRoot);
710
- }
711
- // ─────────────────────────────────────────────
712
- // Runtime dispatch entrypoints
713
- // ─────────────────────────────────────────────
714
- async function cliStart(argv) {
715
- try {
716
- const result = await coordinatorStart(argv);
717
- console.log(JSON.stringify(result, null, 2));
718
- return 0;
719
- }
720
- catch (error) {
721
- console.error(`[coordinator] start failed: ${error instanceof Error ? error.message : String(error)}`);
722
- return 1;
723
- }
724
- }
725
- async function cliNext(argv) {
726
- const { values } = parseArgs({
727
- options: {
728
- "session-root": { type: "string" },
729
- "project-root": { type: "string", default: "." },
730
- "orchestrator-reported-realization": { type: "string" },
731
- },
732
- strict: true,
733
- allowPositionals: false,
734
- args: argv,
735
- });
736
- const sessionRoot = path.resolve(requireString(values["session-root"], "session-root"));
737
- const projectRoot = path.resolve(requireString(values["project-root"], "project-root"));
738
- const orchestratorReportedRealization = values["orchestrator-reported-realization"];
739
- try {
740
- const result = await coordinatorNext(sessionRoot, projectRoot, orchestratorReportedRealization);
741
- console.log(JSON.stringify(result, null, 2));
742
- return 0;
743
- }
744
- catch (error) {
745
- console.error(`[coordinator] next failed: ${error instanceof Error ? error.message : String(error)}`);
746
- return 1;
747
- }
748
- }
749
- async function cliStatus(argv) {
750
- const { values } = parseArgs({
751
- options: {
752
- "session-root": { type: "string" },
753
- },
754
- strict: true,
755
- allowPositionals: false,
756
- args: argv,
757
- });
758
- const sessionRoot = path.resolve(requireString(values["session-root"], "session-root"));
759
- try {
760
- const state = await coordinatorStatus(sessionRoot);
761
- console.log(JSON.stringify(state, null, 2));
762
- return 0;
763
- }
764
- catch (error) {
765
- console.error(`[coordinator] status failed: ${error instanceof Error ? error.message : String(error)}`);
766
- return 1;
767
- }
768
- }
769
- // ─────────────────────────────────────────────
770
- // Runtime dispatch
771
- // ─────────────────────────────────────────────
772
- async function main() {
773
- const subcommand = process.argv[2];
774
- const subArgv = process.argv.slice(3);
775
- switch (subcommand) {
776
- case "start":
777
- return cliStart(subArgv);
778
- case "next":
779
- return cliNext(subArgv);
780
- case "status":
781
- return cliStatus(subArgv);
782
- default:
783
- console.error(`Unknown coordinator subcommand: ${subcommand}`);
784
- console.error("Available: start, next, status");
785
- return 1;
786
- }
787
- }
788
- if (process.argv[1] &&
789
- import.meta.url === pathToFileURL(process.argv[1]).href) {
790
- main().then((exitCode) => process.exit(exitCode), (error) => {
791
- console.error(error instanceof Error ? error.message : String(error));
792
- process.exit(1);
793
- });
794
- }