onto-mcp 0.3.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 (447) hide show
  1. package/.onto/authority/core-lens-registry.yaml +134 -0
  2. package/.onto/authority/core-lexicon.yaml +1562 -0
  3. package/.onto/authority/diagnostic-codes.yaml +94 -0
  4. package/.onto/domains/accounting/competency_qs.md +384 -0
  5. package/.onto/domains/accounting/concepts.md +186 -0
  6. package/.onto/domains/accounting/conciseness_rules.md +160 -0
  7. package/.onto/domains/accounting/dependency_rules.md +239 -0
  8. package/.onto/domains/accounting/domain_scope.md +213 -0
  9. package/.onto/domains/accounting/extension_cases.md +416 -0
  10. package/.onto/domains/accounting/logic_rules.md +226 -0
  11. package/.onto/domains/accounting/structure_spec.md +298 -0
  12. package/.onto/domains/accounting-kr/competency_qs.md +562 -0
  13. package/.onto/domains/accounting-kr/concepts.md +187 -0
  14. package/.onto/domains/accounting-kr/conciseness_rules.md +125 -0
  15. package/.onto/domains/accounting-kr/dependency_rules.md +93 -0
  16. package/.onto/domains/accounting-kr/domain_scope.md +140 -0
  17. package/.onto/domains/accounting-kr/extension_cases.md +343 -0
  18. package/.onto/domains/accounting-kr/logic_rules.md +160 -0
  19. package/.onto/domains/accounting-kr/structure_spec.md +85 -0
  20. package/.onto/domains/business/competency_qs.md +263 -0
  21. package/.onto/domains/business/concepts.md +200 -0
  22. package/.onto/domains/business/conciseness_rules.md +135 -0
  23. package/.onto/domains/business/dependency_rules.md +113 -0
  24. package/.onto/domains/business/domain_scope.md +240 -0
  25. package/.onto/domains/business/extension_cases.md +249 -0
  26. package/.onto/domains/business/logic_rules.md +134 -0
  27. package/.onto/domains/business/structure_spec.md +114 -0
  28. package/.onto/domains/finance/competency_qs.md +362 -0
  29. package/.onto/domains/finance/concepts.md +194 -0
  30. package/.onto/domains/finance/conciseness_rules.md +155 -0
  31. package/.onto/domains/finance/dependency_rules.md +171 -0
  32. package/.onto/domains/finance/domain_scope.md +215 -0
  33. package/.onto/domains/finance/extension_cases.md +350 -0
  34. package/.onto/domains/finance/logic_rules.md +191 -0
  35. package/.onto/domains/finance/structure_spec.md +182 -0
  36. package/.onto/domains/llm-native-development/competency_qs.md +430 -0
  37. package/.onto/domains/llm-native-development/concepts.md +242 -0
  38. package/.onto/domains/llm-native-development/conciseness_rules.md +163 -0
  39. package/.onto/domains/llm-native-development/dependency_rules.md +216 -0
  40. package/.onto/domains/llm-native-development/domain_scope.md +197 -0
  41. package/.onto/domains/llm-native-development/extension_cases.md +474 -0
  42. package/.onto/domains/llm-native-development/logic_rules.md +123 -0
  43. package/.onto/domains/llm-native-development/prompt_interface.md +49 -0
  44. package/.onto/domains/llm-native-development/structure_spec.md +245 -0
  45. package/.onto/domains/market-intelligence/competency_qs.md +274 -0
  46. package/.onto/domains/market-intelligence/concepts.md +233 -0
  47. package/.onto/domains/market-intelligence/conciseness_rules.md +165 -0
  48. package/.onto/domains/market-intelligence/dependency_rules.md +197 -0
  49. package/.onto/domains/market-intelligence/domain_scope.md +231 -0
  50. package/.onto/domains/market-intelligence/extension_cases.md +425 -0
  51. package/.onto/domains/market-intelligence/logic_rules.md +247 -0
  52. package/.onto/domains/market-intelligence/structure_spec.md +209 -0
  53. package/.onto/domains/ontology/competency_qs.md +394 -0
  54. package/.onto/domains/ontology/concepts.md +172 -0
  55. package/.onto/domains/ontology/conciseness_rules.md +134 -0
  56. package/.onto/domains/ontology/dependency_rules.md +125 -0
  57. package/.onto/domains/ontology/domain_scope.md +114 -0
  58. package/.onto/domains/ontology/extension_cases.md +501 -0
  59. package/.onto/domains/ontology/logic_rules.md +114 -0
  60. package/.onto/domains/ontology/problem_framing_profile.md +67 -0
  61. package/.onto/domains/ontology/structure_spec.md +115 -0
  62. package/.onto/domains/palantir-foundry/RESEARCH_NOTES.md +911 -0
  63. package/.onto/domains/palantir-foundry/competency_qs.md +191 -0
  64. package/.onto/domains/palantir-foundry/competitive_comparison.md +329 -0
  65. package/.onto/domains/palantir-foundry/concepts.md +197 -0
  66. package/.onto/domains/palantir-foundry/conciseness_rules.md +245 -0
  67. package/.onto/domains/palantir-foundry/dependency_rules.md +135 -0
  68. package/.onto/domains/palantir-foundry/domain_scope.md +395 -0
  69. package/.onto/domains/palantir-foundry/extension_cases.md +210 -0
  70. package/.onto/domains/palantir-foundry/logic_rules.md +172 -0
  71. package/.onto/domains/palantir-foundry/structure_spec.md +291 -0
  72. package/.onto/domains/software-engineering/competency_qs.md +538 -0
  73. package/.onto/domains/software-engineering/concepts.md +238 -0
  74. package/.onto/domains/software-engineering/conciseness_rules.md +167 -0
  75. package/.onto/domains/software-engineering/dependency_rules.md +216 -0
  76. package/.onto/domains/software-engineering/domain_scope.md +183 -0
  77. package/.onto/domains/software-engineering/extension_cases.md +551 -0
  78. package/.onto/domains/software-engineering/logic_rules.md +240 -0
  79. package/.onto/domains/software-engineering/problem_framing_profile.md +68 -0
  80. package/.onto/domains/software-engineering/structure_spec.md +185 -0
  81. package/.onto/domains/ui-design/competency_qs.md +567 -0
  82. package/.onto/domains/ui-design/concepts.md +194 -0
  83. package/.onto/domains/ui-design/conciseness_rules.md +190 -0
  84. package/.onto/domains/ui-design/dependency_rules.md +323 -0
  85. package/.onto/domains/ui-design/domain_scope.md +340 -0
  86. package/.onto/domains/ui-design/extension_cases.md +563 -0
  87. package/.onto/domains/ui-design/logic_rules.md +349 -0
  88. package/.onto/domains/ui-design/structure_spec.md +252 -0
  89. package/.onto/domains/visual-design/competency_qs.md +472 -0
  90. package/.onto/domains/visual-design/concepts.md +147 -0
  91. package/.onto/domains/visual-design/conciseness_rules.md +186 -0
  92. package/.onto/domains/visual-design/dependency_rules.md +282 -0
  93. package/.onto/domains/visual-design/domain_scope.md +290 -0
  94. package/.onto/domains/visual-design/extension_cases.md +480 -0
  95. package/.onto/domains/visual-design/logic_rules.md +232 -0
  96. package/.onto/domains/visual-design/structure_spec.md +213 -0
  97. package/.onto/principles/llm-native-development-guideline.md +401 -0
  98. package/.onto/principles/llm-runtime-interface-principles.md +665 -0
  99. package/.onto/principles/non-specialist-communication-guideline.md +74 -0
  100. package/.onto/principles/ontology-as-code-guideline.md +243 -0
  101. package/.onto/principles/ontology-as-code-naming-charter.md +130 -0
  102. package/.onto/principles/product-locality-principle.md +129 -0
  103. package/.onto/principles/productization-charter.md +569 -0
  104. package/.onto/processes/evolve/material-kind-adapter-contract.md +113 -0
  105. package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +366 -0
  106. package/.onto/processes/reconstruct/source-profile-contract.md +107 -0
  107. package/.onto/processes/reconstruct/source-profiles/code.md +72 -0
  108. package/.onto/processes/reconstruct/source-profiles/database.md +74 -0
  109. package/.onto/processes/reconstruct/source-profiles/document.md +71 -0
  110. package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +79 -0
  111. package/.onto/processes/review/binding-contract.md +270 -0
  112. package/.onto/processes/review/execution-preparation-artifacts.md +281 -0
  113. package/.onto/processes/review/interpretation-contract.md +245 -0
  114. package/.onto/processes/review/issue-stance-deliberation-contract.md +761 -0
  115. package/.onto/processes/review/lens-prompt-contract.md +402 -0
  116. package/.onto/processes/review/lens-registry.md +127 -0
  117. package/.onto/processes/review/pre-dispatch-contracts.md +428 -0
  118. package/.onto/processes/review/productized-live-path.md +398 -0
  119. package/.onto/processes/review/prompt-execution-runner-contract.md +187 -0
  120. package/.onto/processes/review/record-contract.md +427 -0
  121. package/.onto/processes/review/record-field-mapping.md +337 -0
  122. package/.onto/processes/review/review-context-manifest-contract.md +356 -0
  123. package/.onto/processes/review/review-execution-ux-contract.md +809 -0
  124. package/.onto/processes/review/review-target-profile-contract.md +259 -0
  125. package/.onto/processes/review/shared-phenomenon-contract.md +129 -0
  126. package/.onto/processes/review/synthesize-prompt-contract.md +343 -0
  127. package/.onto/processes/shared/target-material-kind-contract.md +198 -0
  128. package/.onto/roles/axiology.md +81 -0
  129. package/.onto/roles/conciseness.md +36 -0
  130. package/.onto/roles/coverage.md +34 -0
  131. package/.onto/roles/dependency.md +37 -0
  132. package/.onto/roles/evolution.md +35 -0
  133. package/.onto/roles/logic.md +104 -0
  134. package/.onto/roles/pragmatics.md +32 -0
  135. package/.onto/roles/semantics.md +36 -0
  136. package/.onto/roles/structure.md +33 -0
  137. package/.onto/roles/synthesize.md +92 -0
  138. package/AGENTS.md +240 -0
  139. package/CLAUDE.md +39 -0
  140. package/README.md +287 -0
  141. package/bin/onto +92 -0
  142. package/dist/cli.js +101 -0
  143. package/dist/core-api/reconstruct-api.js +222 -0
  144. package/dist/core-api/review-api.js +1271 -0
  145. package/dist/core-runtime/cli/assemble-review-record.js +431 -0
  146. package/dist/core-runtime/cli/bootstrap-review-binding.js +186 -0
  147. package/dist/core-runtime/cli/codex-nested-dispatch.js +226 -0
  148. package/dist/core-runtime/cli/codex-nested-dispatch.test.js +390 -0
  149. package/dist/core-runtime/cli/codex-nested-teamlead-executor.js +464 -0
  150. package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +335 -0
  151. package/dist/core-runtime/cli/codex-review-unit-executor.js +228 -0
  152. package/dist/core-runtime/cli/complete-review-session.js +64 -0
  153. package/dist/core-runtime/cli/complexity-assessment.js +153 -0
  154. package/dist/core-runtime/cli/coordinator-helpers.js +583 -0
  155. package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +167 -0
  156. package/dist/core-runtime/cli/coordinator-state-machine.js +794 -0
  157. package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +615 -0
  158. package/dist/core-runtime/cli/e2e-start-review-session.test.js +312 -0
  159. package/dist/core-runtime/cli/health.js +44 -0
  160. package/dist/core-runtime/cli/inline-http-review-unit-executor.js +656 -0
  161. package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +567 -0
  162. package/dist/core-runtime/cli/materialize-review-execution-preparation.js +104 -0
  163. package/dist/core-runtime/cli/materialize-review-prompt-packets.js +952 -0
  164. package/dist/core-runtime/cli/migrate-session-roots.js +118 -0
  165. package/dist/core-runtime/cli/mock-review-unit-executor.js +285 -0
  166. package/dist/core-runtime/cli/onto-tools.js +369 -0
  167. package/dist/core-runtime/cli/prepare-review-session.js +272 -0
  168. package/dist/core-runtime/cli/render-review-final-output.js +350 -0
  169. package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +106 -0
  170. package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +268 -0
  171. package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +136 -0
  172. package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +201 -0
  173. package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +192 -0
  174. package/dist/core-runtime/cli/review-invoke.js +2030 -0
  175. package/dist/core-runtime/cli/run-review-prompt-execution.js +2152 -0
  176. package/dist/core-runtime/cli/session-root-guard.js +168 -0
  177. package/dist/core-runtime/cli/spawn-watcher.js +173 -0
  178. package/dist/core-runtime/cli/spawn-watcher.test.js +457 -0
  179. package/dist/core-runtime/cli/start-review-session.js +68 -0
  180. package/dist/core-runtime/cli/strip-wrapping-code-fence.js +56 -0
  181. package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +79 -0
  182. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +412 -0
  183. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +351 -0
  184. package/dist/core-runtime/cli/topology-executor-mapping.js +139 -0
  185. package/dist/core-runtime/cli/topology-executor-mapping.test.js +173 -0
  186. package/dist/core-runtime/cli/write-review-interpretation.js +81 -0
  187. package/dist/core-runtime/config/onto-config-cli.js +278 -0
  188. package/dist/core-runtime/config/onto-config-key-path.js +288 -0
  189. package/dist/core-runtime/config/onto-config-key-path.test.js +195 -0
  190. package/dist/core-runtime/config/onto-config-preview.js +108 -0
  191. package/dist/core-runtime/config/onto-config-preview.test.js +132 -0
  192. package/dist/core-runtime/discovery/config-chain.js +118 -0
  193. package/dist/core-runtime/discovery/config-chain.test.js +103 -0
  194. package/dist/core-runtime/discovery/config-profile.js +199 -0
  195. package/dist/core-runtime/discovery/config-profile.test.js +233 -0
  196. package/dist/core-runtime/discovery/host-detection.js +33 -0
  197. package/dist/core-runtime/discovery/host-detection.test.js +186 -0
  198. package/dist/core-runtime/discovery/installation-paths.js +21 -0
  199. package/dist/core-runtime/discovery/installation-paths.test.js +65 -0
  200. package/dist/core-runtime/discovery/lens-registry.js +60 -0
  201. package/dist/core-runtime/discovery/lens-registry.test.js +81 -0
  202. package/dist/core-runtime/discovery/onto-home.js +71 -0
  203. package/dist/core-runtime/discovery/path-normalization.js +28 -0
  204. package/dist/core-runtime/discovery/path-normalization.test.js +22 -0
  205. package/dist/core-runtime/discovery/plugin-path.js +72 -0
  206. package/dist/core-runtime/discovery/plugin-path.test.js +95 -0
  207. package/dist/core-runtime/discovery/project-root.js +47 -0
  208. package/dist/core-runtime/discovery/settings-chain.js +353 -0
  209. package/dist/core-runtime/discovery/walk-up.js +17 -0
  210. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +344 -0
  211. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +915 -0
  212. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +564 -0
  213. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +708 -0
  214. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +165 -0
  215. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +227 -0
  216. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +59 -0
  217. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +205 -0
  218. package/dist/core-runtime/evolve/adapters/methodology/adapter.js +16 -0
  219. package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +9 -0
  220. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +298 -0
  221. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +70 -0
  222. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +46 -0
  223. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +73 -0
  224. package/dist/core-runtime/evolve/adapters/registry.js +47 -0
  225. package/dist/core-runtime/evolve/adapters/registry.test.js +67 -0
  226. package/dist/core-runtime/evolve/cli.js +256 -0
  227. package/dist/core-runtime/evolve/commands/align.js +194 -0
  228. package/dist/core-runtime/evolve/commands/align.test.js +82 -0
  229. package/dist/core-runtime/evolve/commands/apply.js +161 -0
  230. package/dist/core-runtime/evolve/commands/apply.test.js +138 -0
  231. package/dist/core-runtime/evolve/commands/close.js +39 -0
  232. package/dist/core-runtime/evolve/commands/close.test.js +99 -0
  233. package/dist/core-runtime/evolve/commands/defer.js +40 -0
  234. package/dist/core-runtime/evolve/commands/defer.test.js +134 -0
  235. package/dist/core-runtime/evolve/commands/draft.js +323 -0
  236. package/dist/core-runtime/evolve/commands/draft.test.js +178 -0
  237. package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +208 -0
  238. package/dist/core-runtime/evolve/commands/error-messages.js +125 -0
  239. package/dist/core-runtime/evolve/commands/error-messages.test.js +167 -0
  240. package/dist/core-runtime/evolve/commands/propose-align.js +222 -0
  241. package/dist/core-runtime/evolve/commands/propose-align.test.js +136 -0
  242. package/dist/core-runtime/evolve/commands/reconstruct.js +330 -0
  243. package/dist/core-runtime/evolve/commands/reconstruct.test.js +278 -0
  244. package/dist/core-runtime/evolve/commands/shared.js +22 -0
  245. package/dist/core-runtime/evolve/commands/stale-check.js +103 -0
  246. package/dist/core-runtime/evolve/commands/stale-check.test.js +84 -0
  247. package/dist/core-runtime/evolve/commands/start.js +887 -0
  248. package/dist/core-runtime/evolve/commands/start.test.js +396 -0
  249. package/dist/core-runtime/evolve/config/project-config.js +99 -0
  250. package/dist/core-runtime/evolve/config/project-config.test.js +170 -0
  251. package/dist/core-runtime/evolve/renderers/align-packet.js +280 -0
  252. package/dist/core-runtime/evolve/renderers/align-packet.test.js +332 -0
  253. package/dist/core-runtime/evolve/renderers/draft-packet.js +303 -0
  254. package/dist/core-runtime/evolve/renderers/draft-packet.test.js +377 -0
  255. package/dist/core-runtime/evolve/renderers/format.js +5 -0
  256. package/dist/core-runtime/evolve/renderers/scope-md.js +237 -0
  257. package/dist/core-runtime/evolve/renderers/scope-md.test.js +306 -0
  258. package/dist/core-runtime/govern/cli.js +369 -0
  259. package/dist/core-runtime/govern/cli.test.js +314 -0
  260. package/dist/core-runtime/govern/drift-engine.js +103 -0
  261. package/dist/core-runtime/govern/drift-engine.test.js +319 -0
  262. package/dist/core-runtime/govern/promote-principle.js +206 -0
  263. package/dist/core-runtime/govern/promote-principle.test.js +368 -0
  264. package/dist/core-runtime/govern/queue.js +81 -0
  265. package/dist/core-runtime/govern/types.js +16 -0
  266. package/dist/core-runtime/install/cli.js +530 -0
  267. package/dist/core-runtime/install/detect.js +128 -0
  268. package/dist/core-runtime/install/detect.test.js +155 -0
  269. package/dist/core-runtime/install/gitignore-update.js +74 -0
  270. package/dist/core-runtime/install/gitignore-update.test.js +64 -0
  271. package/dist/core-runtime/install/install-integration.test.js +373 -0
  272. package/dist/core-runtime/install/prompts.js +389 -0
  273. package/dist/core-runtime/install/prompts.test.js +293 -0
  274. package/dist/core-runtime/install/types.js +26 -0
  275. package/dist/core-runtime/install/validation.js +295 -0
  276. package/dist/core-runtime/install/validation.test.js +313 -0
  277. package/dist/core-runtime/install/writer.js +254 -0
  278. package/dist/core-runtime/install/writer.test.js +218 -0
  279. package/dist/core-runtime/learning/extractor.js +461 -0
  280. package/dist/core-runtime/learning/feedback.js +179 -0
  281. package/dist/core-runtime/learning/health-report.js +165 -0
  282. package/dist/core-runtime/learning/health-report.test.js +169 -0
  283. package/dist/core-runtime/learning/loader.js +388 -0
  284. package/dist/core-runtime/learning/loader.test.js +102 -0
  285. package/dist/core-runtime/learning/promote/apply-state.js +240 -0
  286. package/dist/core-runtime/learning/promote/audit-obligation.js +195 -0
  287. package/dist/core-runtime/learning/promote/collector.js +432 -0
  288. package/dist/core-runtime/learning/promote/degraded-state.js +125 -0
  289. package/dist/core-runtime/learning/promote/domain-doc-proposer.js +166 -0
  290. package/dist/core-runtime/learning/promote/e2e-promote.test.js +6385 -0
  291. package/dist/core-runtime/learning/promote/health-snapshot.js +150 -0
  292. package/dist/core-runtime/learning/promote/insight-reclassifier.js +544 -0
  293. package/dist/core-runtime/learning/promote/judgment-auditor.js +517 -0
  294. package/dist/core-runtime/learning/promote/panel-reviewer.js +1158 -0
  295. package/dist/core-runtime/learning/promote/promote-executor.js +1675 -0
  296. package/dist/core-runtime/learning/promote/promoter.js +307 -0
  297. package/dist/core-runtime/learning/promote/retirement.js +122 -0
  298. package/dist/core-runtime/learning/promote/types.js +23 -0
  299. package/dist/core-runtime/learning/prompt-sections.js +51 -0
  300. package/dist/core-runtime/learning/shared/artifact-registry-init.js +45 -0
  301. package/dist/core-runtime/learning/shared/artifact-registry.js +254 -0
  302. package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +73 -0
  303. package/dist/core-runtime/learning/shared/audit-state.js +99 -0
  304. package/dist/core-runtime/learning/shared/duplicate-check.js +28 -0
  305. package/dist/core-runtime/learning/shared/llm-caller.js +831 -0
  306. package/dist/core-runtime/learning/shared/llm-caller.test.js +601 -0
  307. package/dist/core-runtime/learning/shared/llm-tool-loop.js +393 -0
  308. package/dist/core-runtime/learning/shared/mode.js +25 -0
  309. package/dist/core-runtime/learning/shared/paths.js +84 -0
  310. package/dist/core-runtime/learning/shared/paths.test.js +79 -0
  311. package/dist/core-runtime/learning/shared/patterns.js +37 -0
  312. package/dist/core-runtime/learning/shared/recoverability.js +355 -0
  313. package/dist/core-runtime/learning/shared/recovery-context.js +374 -0
  314. package/dist/core-runtime/learning/shared/scope.js +1 -0
  315. package/dist/core-runtime/learning/shared/semantic-classifier.js +94 -0
  316. package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +42 -0
  317. package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +37 -0
  318. package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +39 -0
  319. package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +41 -0
  320. package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +38 -0
  321. package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +43 -0
  322. package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +113 -0
  323. package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +36 -0
  324. package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +48 -0
  325. package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +43 -0
  326. package/dist/core-runtime/learning/shared/specs/spec-helpers.js +64 -0
  327. package/dist/core-runtime/learning/usage-tracker.js +190 -0
  328. package/dist/core-runtime/learning/usage-tracker.test.js +176 -0
  329. package/dist/core-runtime/llm/llm-caller.js +649 -0
  330. package/dist/core-runtime/llm/llm-tool-loop.js +401 -0
  331. package/dist/core-runtime/llm/model-switcher.js +62 -0
  332. package/dist/core-runtime/logger.js +22 -0
  333. package/dist/core-runtime/onboard/detect-review-axes.js +122 -0
  334. package/dist/core-runtime/onboard/detect-review-axes.test.js +127 -0
  335. package/dist/core-runtime/onboard/write-review-block.js +188 -0
  336. package/dist/core-runtime/onboard/write-review-block.test.js +240 -0
  337. package/dist/core-runtime/readers/brownfield-builder.js +150 -0
  338. package/dist/core-runtime/readers/brownfield-builder.test.js +136 -0
  339. package/dist/core-runtime/readers/code-chunk-collector.js +53 -0
  340. package/dist/core-runtime/readers/code-chunk-collector.test.js +136 -0
  341. package/dist/core-runtime/readers/file-utils.js +240 -0
  342. package/dist/core-runtime/readers/file-utils.test.js +146 -0
  343. package/dist/core-runtime/readers/lexicon-citation-check.js +93 -0
  344. package/dist/core-runtime/readers/lexicon-citation-check.test.js +77 -0
  345. package/dist/core-runtime/readers/mcp-figma.js +30 -0
  346. package/dist/core-runtime/readers/mcp-figma.test.js +82 -0
  347. package/dist/core-runtime/readers/mcp-generic.js +31 -0
  348. package/dist/core-runtime/readers/mcp-generic.test.js +76 -0
  349. package/dist/core-runtime/readers/ontology-index.js +148 -0
  350. package/dist/core-runtime/readers/ontology-index.test.js +245 -0
  351. package/dist/core-runtime/readers/ontology-query.js +168 -0
  352. package/dist/core-runtime/readers/ontology-query.test.js +311 -0
  353. package/dist/core-runtime/readers/ontology-resolve.js +48 -0
  354. package/dist/core-runtime/readers/ontology-resolve.test.js +48 -0
  355. package/dist/core-runtime/readers/patterns/index.js +7 -0
  356. package/dist/core-runtime/readers/review-log.js +213 -0
  357. package/dist/core-runtime/readers/review-log.test.js +313 -0
  358. package/dist/core-runtime/readers/scan-local.js +102 -0
  359. package/dist/core-runtime/readers/scan-local.test.js +102 -0
  360. package/dist/core-runtime/readers/scan-tarball.js +121 -0
  361. package/dist/core-runtime/readers/scan-tarball.test.js +283 -0
  362. package/dist/core-runtime/readers/scan-vault.js +34 -0
  363. package/dist/core-runtime/readers/scan-vault.test.js +81 -0
  364. package/dist/core-runtime/readers/types.js +42 -0
  365. package/dist/core-runtime/readers/types.test.js +94 -0
  366. package/dist/core-runtime/readers/viewpoint-collectors.js +229 -0
  367. package/dist/core-runtime/reconstruct/artifact-types.js +1 -0
  368. package/dist/core-runtime/reconstruct/directive-validation.js +123 -0
  369. package/dist/core-runtime/reconstruct/materialize-preparation.js +251 -0
  370. package/dist/core-runtime/reconstruct/record.js +198 -0
  371. package/dist/core-runtime/reconstruct/run.js +578 -0
  372. package/dist/core-runtime/reconstruct/seed-candidate-validation.js +356 -0
  373. package/dist/core-runtime/reconstruct/source-observations.js +62 -0
  374. package/dist/core-runtime/reconstruct/source-profiles.js +73 -0
  375. package/dist/core-runtime/release-channel/release-channel.js +90 -0
  376. package/dist/core-runtime/review/artifact-types.js +13 -0
  377. package/dist/core-runtime/review/citation-audit.js +204 -0
  378. package/dist/core-runtime/review/citation-audit.test.js +165 -0
  379. package/dist/core-runtime/review/controlled-lens-deliberation.js +125 -0
  380. package/dist/core-runtime/review/execution-plan-resolver.js +247 -0
  381. package/dist/core-runtime/review/execution-plan-resolver.test.js +243 -0
  382. package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +246 -0
  383. package/dist/core-runtime/review/execution-topology-resolver.js +401 -0
  384. package/dist/core-runtime/review/execution-topology-resolver.test.js +315 -0
  385. package/dist/core-runtime/review/failure-records.js +57 -0
  386. package/dist/core-runtime/review/inline-context-embedder.js +141 -0
  387. package/dist/core-runtime/review/inline-context-embedder.test.js +154 -0
  388. package/dist/core-runtime/review/issue-artifact-runtime.js +859 -0
  389. package/dist/core-runtime/review/legacy-mode-policy.js +88 -0
  390. package/dist/core-runtime/review/lens-completion-policy.js +17 -0
  391. package/dist/core-runtime/review/materializers-effort-persist.test.js +79 -0
  392. package/dist/core-runtime/review/materializers.js +963 -0
  393. package/dist/core-runtime/review/ontology-path-classifier.js +179 -0
  394. package/dist/core-runtime/review/ontology-path-classifier.test.js +216 -0
  395. package/dist/core-runtime/review/packet-boundary-policy.js +215 -0
  396. package/dist/core-runtime/review/packet-boundary-policy.test.js +107 -0
  397. package/dist/core-runtime/review/participating-lens-paths.js +61 -0
  398. package/dist/core-runtime/review/participating-lens-paths.test.js +73 -0
  399. package/dist/core-runtime/review/review-artifact-utils.js +287 -0
  400. package/dist/core-runtime/review/review-config-legacy-translate.js +244 -0
  401. package/dist/core-runtime/review/review-config-legacy-translate.test.js +161 -0
  402. package/dist/core-runtime/review/review-config-validator.js +289 -0
  403. package/dist/core-runtime/review/review-config-validator.test.js +236 -0
  404. package/dist/core-runtime/review/review-execution-profile.js +193 -0
  405. package/dist/core-runtime/review/review-execution-route.js +52 -0
  406. package/dist/core-runtime/review/review-progress-contract.js +123 -0
  407. package/dist/core-runtime/review/review-record-validation.js +251 -0
  408. package/dist/core-runtime/review/review-result-classification.js +379 -0
  409. package/dist/core-runtime/review/review-state-machine.js +39 -0
  410. package/dist/core-runtime/review/route-visibility.js +125 -0
  411. package/dist/core-runtime/review/shape-pipeline-audit.test.js +311 -0
  412. package/dist/core-runtime/review/shape-to-topology-id.js +117 -0
  413. package/dist/core-runtime/review/shape-to-topology-id.test.js +132 -0
  414. package/dist/core-runtime/review/topology-shape-derivation.js +155 -0
  415. package/dist/core-runtime/review/topology-shape-derivation.test.js +195 -0
  416. package/dist/core-runtime/scope-runtime/constants.js +12 -0
  417. package/dist/core-runtime/scope-runtime/constraint-pool.js +166 -0
  418. package/dist/core-runtime/scope-runtime/constraint-pool.test.js +674 -0
  419. package/dist/core-runtime/scope-runtime/domain-validation-log.js +135 -0
  420. package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +156 -0
  421. package/dist/core-runtime/scope-runtime/eval-persistence.js +65 -0
  422. package/dist/core-runtime/scope-runtime/eval-persistence.test.js +84 -0
  423. package/dist/core-runtime/scope-runtime/event-pipeline.js +64 -0
  424. package/dist/core-runtime/scope-runtime/event-pipeline.test.js +450 -0
  425. package/dist/core-runtime/scope-runtime/event-store.js +39 -0
  426. package/dist/core-runtime/scope-runtime/event-store.test.js +95 -0
  427. package/dist/core-runtime/scope-runtime/gate-guard.js +348 -0
  428. package/dist/core-runtime/scope-runtime/gate-guard.test.js +1047 -0
  429. package/dist/core-runtime/scope-runtime/hash.js +4 -0
  430. package/dist/core-runtime/scope-runtime/hash.test.js +33 -0
  431. package/dist/core-runtime/scope-runtime/id.js +4 -0
  432. package/dist/core-runtime/scope-runtime/id.test.js +17 -0
  433. package/dist/core-runtime/scope-runtime/reducer.js +297 -0
  434. package/dist/core-runtime/scope-runtime/reducer.test.js +759 -0
  435. package/dist/core-runtime/scope-runtime/scope-manager.js +161 -0
  436. package/dist/core-runtime/scope-runtime/state-machine.js +309 -0
  437. package/dist/core-runtime/scope-runtime/state-machine.test.js +704 -0
  438. package/dist/core-runtime/scope-runtime/types.js +116 -0
  439. package/dist/core-runtime/scope-runtime/types.test.js +69 -0
  440. package/dist/core-runtime/target-material-kind.js +256 -0
  441. package/dist/core-runtime/translate/render-for-user.js +169 -0
  442. package/dist/core-runtime/translate/render-for-user.test.js +122 -0
  443. package/dist/mcp/server.js +1011 -0
  444. package/dist/mcp/tool-schemas.js +93 -0
  445. package/dist/providers/capability-contract.js +1 -0
  446. package/package.json +68 -0
  447. package/settings.example.json +33 -0
@@ -0,0 +1,1271 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { resolveOntoHome } from "../core-runtime/discovery/onto-home.js";
5
+ import { loadCoreLensRegistry } from "../core-runtime/discovery/lens-registry.js";
6
+ import { fileExists, isoFromTimestamp, isoNow, readYamlDocument, } from "../core-runtime/review/review-artifact-utils.js";
7
+ import { buildReviewRouteVisibilityFromSession, } from "../core-runtime/review/route-visibility.js";
8
+ import { readValidatedReviewRecord } from "../core-runtime/review/review-record-validation.js";
9
+ import { readReviewResultClassification } from "../core-runtime/review/review-result-classification.js";
10
+ import { REVIEW_EXECUTION_STEP_IDS, REVIEW_PROGRESS_STEPS, REVIEW_PROGRESS_TOTAL_STEPS, reviewProgressStepById, reviewProgressStepIdFromHalt, } from "../core-runtime/review/review-progress-contract.js";
11
+ import { reviewPrepareOnly, runReviewInvokeCli } from "../core-runtime/cli/review-invoke.js";
12
+ function stringifyConsoleArgs(args) {
13
+ return args
14
+ .map((arg) => {
15
+ if (typeof arg === "string")
16
+ return arg;
17
+ if (arg instanceof Error)
18
+ return arg.stack ?? arg.message;
19
+ try {
20
+ return JSON.stringify(arg);
21
+ }
22
+ catch {
23
+ return String(arg);
24
+ }
25
+ })
26
+ .join(" ");
27
+ }
28
+ async function withCapturedConsole(action, observer) {
29
+ const originalLog = console.log;
30
+ const originalWarn = console.warn;
31
+ const originalError = console.error;
32
+ const stdout = [];
33
+ const stderr = [];
34
+ console.log = (...args) => {
35
+ const line = stringifyConsoleArgs(args);
36
+ stdout.push(line);
37
+ try {
38
+ observer?.stdout?.(line);
39
+ }
40
+ catch {
41
+ // Progress observers are transport-only and must not affect execution.
42
+ }
43
+ };
44
+ console.warn = (...args) => {
45
+ const line = stringifyConsoleArgs(args);
46
+ stderr.push(line);
47
+ try {
48
+ observer?.stderr?.(line);
49
+ }
50
+ catch {
51
+ // Progress observers are transport-only and must not affect execution.
52
+ }
53
+ };
54
+ console.error = (...args) => {
55
+ const line = stringifyConsoleArgs(args);
56
+ stderr.push(line);
57
+ try {
58
+ observer?.stderr?.(line);
59
+ }
60
+ catch {
61
+ // Progress observers are transport-only and must not affect execution.
62
+ }
63
+ };
64
+ try {
65
+ const result = await action();
66
+ return { result, stdout, stderr };
67
+ }
68
+ finally {
69
+ console.log = originalLog;
70
+ console.warn = originalWarn;
71
+ console.error = originalError;
72
+ }
73
+ }
74
+ function resolveRequiredOntoHome(explicit) {
75
+ return resolveOntoHome(explicit);
76
+ }
77
+ function appendCommonReviewArgs(args, request, ontoHome) {
78
+ const result = [
79
+ ...args,
80
+ request.target,
81
+ request.intent,
82
+ "--project-root",
83
+ path.resolve(request.projectRoot),
84
+ ];
85
+ result.push("--onto-home", ontoHome);
86
+ if (request.domain && request.noDomain) {
87
+ throw new Error("Use either domain or noDomain, not both.");
88
+ }
89
+ if (request.domain) {
90
+ result.push("--domain", request.domain);
91
+ }
92
+ if (request.noDomain) {
93
+ result.push("--no-domain");
94
+ }
95
+ if (request.reviewMode) {
96
+ result.push("--review-mode", request.reviewMode);
97
+ }
98
+ if (request.targetScopeKind) {
99
+ result.push("--target-scope-kind", request.targetScopeKind);
100
+ }
101
+ if (request.primaryRef) {
102
+ result.push("--primary-ref", request.primaryRef);
103
+ }
104
+ for (const memberRef of request.memberRefs ?? []) {
105
+ result.push("--member-ref", memberRef);
106
+ }
107
+ if (request.bundleKind) {
108
+ result.push("--bundle-kind", request.bundleKind);
109
+ }
110
+ if (request.diffRange) {
111
+ result.push("--diff-range", request.diffRange);
112
+ }
113
+ if (request.executorRealization) {
114
+ result.push("--executor-realization", request.executorRealization);
115
+ }
116
+ for (const lensId of request.lensIds ?? []) {
117
+ result.push("--lens-id", lensId);
118
+ }
119
+ if (request.confirmValueAlignment) {
120
+ result.push("--confirm-value-alignment");
121
+ }
122
+ return result;
123
+ }
124
+ function basenameSessionId(sessionRoot) {
125
+ return path.basename(path.resolve(sessionRoot));
126
+ }
127
+ async function readOptionalYaml(filePath) {
128
+ if (!(await fileExists(filePath)))
129
+ return null;
130
+ return readYamlDocument(filePath);
131
+ }
132
+ async function readOptionalReviewRecord(filePath) {
133
+ if (!(await fileExists(filePath)))
134
+ return null;
135
+ return readValidatedReviewRecord(filePath);
136
+ }
137
+ async function readOptionalText(filePath) {
138
+ if (!(await fileExists(filePath)))
139
+ return undefined;
140
+ return fs.readFile(filePath, "utf8");
141
+ }
142
+ function buildOpeningBriefPresentation(input) {
143
+ return {
144
+ prompt: [
145
+ "Explain this onto review opening brief to the user before execution.",
146
+ "Use only the provided input facts. Do not infer or invent target scope, boundary, domain, lens set, model, provider, or execution mode.",
147
+ "Cover: what is being reviewed, why, filesystem boundary, selected domain, review mode and lens set, execution path, model/provider settings, and where the user can change configuration.",
148
+ "Keep it structured and concise. Use the user's conversation language.",
149
+ ].join("\n"),
150
+ input,
151
+ };
152
+ }
153
+ function buildFinalResultPresentation(input) {
154
+ return {
155
+ prompt: [
156
+ "Explain this onto review result to the user after execution.",
157
+ "Use only the provided input facts and referenced final result fields. Do not invent new findings or silently resolve unresolved disagreement.",
158
+ "Cover: outcome, deliberation status, coverage, final review result, highest severity, material issues, non-material findings, action candidates, and primary artifacts.",
159
+ "Make the result comprehensive enough for the user to understand what to do next, but keep operational detail bounded. Use the user's conversation language.",
160
+ ].join("\n"),
161
+ input,
162
+ };
163
+ }
164
+ const REVIEW_PRESENTATION_CONTRACT_VERSION = "1";
165
+ const PRESENTATION_SOURCE_REF_KEYS = [
166
+ "execution_plan",
167
+ "review_run_manifest",
168
+ "execution_result",
169
+ "review_record",
170
+ "review_target_profile",
171
+ "finding_ledger",
172
+ "issue_ledger",
173
+ "problem_framing",
174
+ "final_output",
175
+ ];
176
+ const OPENING_PRESENTATION_SOURCE_REF_KEYS = [
177
+ "interpretation",
178
+ "binding",
179
+ "execution_plan",
180
+ "review_target_profile",
181
+ "review_context_manifest",
182
+ ];
183
+ function compactSeverityCounts(summary) {
184
+ return [
185
+ `blocker=${summary.severity_counts.blocker}`,
186
+ `high=${summary.severity_counts.high}`,
187
+ `medium=${summary.severity_counts.medium}`,
188
+ `low=${summary.severity_counts.low}`,
189
+ `info=${summary.severity_counts.info}`,
190
+ ].join(", ");
191
+ }
192
+ function compactClassificationSignal(summary) {
193
+ return `highest=${summary.highest_severity ?? "none"}, material=${summary.material_issue_count}, severity_counts=${compactSeverityCounts(summary)}`;
194
+ }
195
+ function buildProgressPresentation(input) {
196
+ return {
197
+ prompt: [
198
+ "Render a concise onto review progress update from bounded runtime facts.",
199
+ "Use only the provided input facts. Do not invent findings, severity, elapsed time, halt state, artifacts, or pending units.",
200
+ "Show a compact stepwise/progress-bar style status, the liveness state, latest review signal, artifact refs that matter now, and the next expected event.",
201
+ "Use the user's conversation language.",
202
+ ].join("\n"),
203
+ input,
204
+ };
205
+ }
206
+ function buildHaltPresentation(input) {
207
+ return {
208
+ prompt: [
209
+ "Render a concise halted-partial onto review update from bounded runtime facts.",
210
+ "Use only the provided input facts. Lead with halt identity, produced artifacts, absent artifacts, and available action candidates.",
211
+ "Do not present partial findings as a completed review. Use the user's conversation language.",
212
+ ].join("\n"),
213
+ input,
214
+ };
215
+ }
216
+ function progressEvent(args) {
217
+ return {
218
+ presentation_contract_version: REVIEW_PRESENTATION_CONTRACT_VERSION,
219
+ event_kind: "mcp_progress",
220
+ sequence: args.sequence,
221
+ generated_at: isoNow(),
222
+ source: args.source,
223
+ stage: args.stage,
224
+ session_root: args.sessionRoot,
225
+ message: args.message,
226
+ progress: {
227
+ current: args.current,
228
+ total: args.total ?? 100,
229
+ ...(args.exactStep !== undefined ? { exact_step: args.exactStep } : {}),
230
+ ...(args.exactTotal !== undefined ? { exact_total: args.exactTotal } : {}),
231
+ ...(args.label !== undefined ? { label: args.label } : {}),
232
+ },
233
+ };
234
+ }
235
+ function progressUnitsForInvokeStep(step) {
236
+ switch (step) {
237
+ case 1:
238
+ return 5;
239
+ case 2:
240
+ return 10;
241
+ case 3:
242
+ return 90;
243
+ default:
244
+ return 0;
245
+ }
246
+ }
247
+ function progressUnitsForRuntimeStep(step, total) {
248
+ if (total <= 0)
249
+ return 10;
250
+ return Math.min(89, 10 + Math.round((step / total) * 75));
251
+ }
252
+ function parseSessionRootLine(projectRoot, line) {
253
+ const match = /^\s*session_root:\s+(.+?)\s*$/.exec(line);
254
+ if (!match?.[1])
255
+ return null;
256
+ const rawSessionRoot = match[1];
257
+ return path.isAbsolute(rawSessionRoot)
258
+ ? rawSessionRoot
259
+ : path.resolve(projectRoot, rawSessionRoot);
260
+ }
261
+ function consoleLineProgressEvent(args) {
262
+ const plannedSessionRoot = parseSessionRootLine(args.projectRoot, args.line);
263
+ if (plannedSessionRoot) {
264
+ return {
265
+ sessionRoot: plannedSessionRoot,
266
+ event: progressEvent({
267
+ sequence: args.sequence,
268
+ source: "review_invoke_console",
269
+ stage: "session_planned",
270
+ sessionRoot: plannedSessionRoot,
271
+ message: `Review session planned at ${plannedSessionRoot}.`,
272
+ current: 1,
273
+ label: "session planned",
274
+ }),
275
+ };
276
+ }
277
+ if (args.line.trim() === "[review start]") {
278
+ return {
279
+ sessionRoot: args.sessionRoot,
280
+ event: progressEvent({
281
+ sequence: args.sequence,
282
+ source: "review_invoke_console",
283
+ stage: "start_preview",
284
+ sessionRoot: args.sessionRoot,
285
+ message: "Review start preview generated.",
286
+ current: 0,
287
+ label: "start preview",
288
+ }),
289
+ };
290
+ }
291
+ const invokeStepMatch = /^\[review invoke\] step (\d+)\/3\s+(.+?)\s*$/.exec(args.line);
292
+ if (invokeStepMatch?.[1] && invokeStepMatch[2]) {
293
+ const step = Number.parseInt(invokeStepMatch[1], 10);
294
+ const label = invokeStepMatch[2];
295
+ return {
296
+ sessionRoot: args.sessionRoot,
297
+ event: progressEvent({
298
+ sequence: args.sequence,
299
+ source: "review_invoke_console",
300
+ stage: "invoke_step",
301
+ sessionRoot: args.sessionRoot,
302
+ message: label,
303
+ current: progressUnitsForInvokeStep(step),
304
+ exactStep: step,
305
+ exactTotal: 3,
306
+ label,
307
+ }),
308
+ };
309
+ }
310
+ const runtimeStepMatch = /^\[review progress\]\s+(\d+)\/(\d+)\s+(.+?)\s*$/.exec(args.line);
311
+ if (runtimeStepMatch?.[1] && runtimeStepMatch[2] && runtimeStepMatch[3]) {
312
+ const step = Number.parseInt(runtimeStepMatch[1], 10);
313
+ const total = Number.parseInt(runtimeStepMatch[2], 10);
314
+ const label = runtimeStepMatch[3];
315
+ return {
316
+ sessionRoot: args.sessionRoot,
317
+ event: progressEvent({
318
+ sequence: args.sequence,
319
+ source: "review_invoke_console",
320
+ stage: "runtime_step",
321
+ sessionRoot: args.sessionRoot,
322
+ message: label,
323
+ current: progressUnitsForRuntimeStep(step, total),
324
+ exactStep: step,
325
+ exactTotal: total,
326
+ label,
327
+ }),
328
+ };
329
+ }
330
+ const completedMatch = /^\[review invoke\] completed 3\/3\s+(.+?)\s*$/.exec(args.line);
331
+ if (completedMatch?.[1]) {
332
+ const label = completedMatch[1];
333
+ return {
334
+ sessionRoot: args.sessionRoot,
335
+ event: progressEvent({
336
+ sequence: args.sequence,
337
+ source: "review_invoke_console",
338
+ stage: "completed",
339
+ sessionRoot: args.sessionRoot,
340
+ message: label,
341
+ current: 98,
342
+ exactStep: 3,
343
+ exactTotal: 3,
344
+ label,
345
+ }),
346
+ };
347
+ }
348
+ return null;
349
+ }
350
+ function generatedFromArtifactRefs(artifactRefs, keys = PRESENTATION_SOURCE_REF_KEYS) {
351
+ const refs = {};
352
+ for (const key of keys) {
353
+ refs[key] = artifactRefs[key] ?? null;
354
+ }
355
+ return refs;
356
+ }
357
+ function stepById(stepId) {
358
+ return reviewProgressStepById(stepId);
359
+ }
360
+ function totalProgressSteps(manifest) {
361
+ const fromManifest = manifest?.execution_contract?.progress_total_steps;
362
+ return typeof fromManifest === "number" && fromManifest > 0
363
+ ? fromManifest
364
+ : REVIEW_PROGRESS_TOTAL_STEPS;
365
+ }
366
+ function stepIdsFromManifestOrDefault(manifest) {
367
+ const ids = manifest?.execution_contract?.execution_step_ids;
368
+ if (!Array.isArray(ids))
369
+ return [...REVIEW_EXECUTION_STEP_IDS];
370
+ const knownIds = new Set(REVIEW_EXECUTION_STEP_IDS);
371
+ return ids.filter((id) => knownIds.has(id));
372
+ }
373
+ function elapsedSeconds(executionResult) {
374
+ const durationMs = executionResult?.total_duration_ms;
375
+ return typeof durationMs === "number" ? Math.round(durationMs / 1000) : null;
376
+ }
377
+ function parseTimestampMs(value) {
378
+ if (typeof value !== "string" || value.trim().length === 0)
379
+ return null;
380
+ const parsed = Date.parse(value);
381
+ return Number.isFinite(parsed) ? parsed : null;
382
+ }
383
+ function secondsBetween(nowMs, beforeMs) {
384
+ if (beforeMs === null)
385
+ return null;
386
+ return Math.max(0, Math.round((nowMs - beforeMs) / 1000));
387
+ }
388
+ async function artifactObservation(artifactRefs) {
389
+ let latest = null;
390
+ for (const [key, ref] of Object.entries(artifactRefs)) {
391
+ try {
392
+ const stat = await fs.stat(ref);
393
+ if (!latest || stat.mtimeMs > latest.mtimeMs) {
394
+ latest = { key, ref, mtimeMs: stat.mtimeMs };
395
+ }
396
+ }
397
+ catch {
398
+ // Artifact refs are best-effort presentation facts; missing files are
399
+ // already filtered by collectArtifactRefs and should not break status.
400
+ }
401
+ }
402
+ return latest ?? { key: null, ref: null, mtimeMs: null };
403
+ }
404
+ function livenessStateKind(args) {
405
+ if (args.status === "completed" || args.status === "completed_with_degradation") {
406
+ return "completed";
407
+ }
408
+ if (args.status === "halted_partial" || args.status === "failed") {
409
+ return "halted";
410
+ }
411
+ if (args.status === "prepared")
412
+ return "prepared";
413
+ if (args.status === "unknown")
414
+ return "unknown";
415
+ if (args.secondsSinceLastArtifact === null)
416
+ return "running_waiting";
417
+ if (args.secondsSinceLastArtifact <= 60)
418
+ return "running_recent_signal";
419
+ if (args.secondsSinceLastArtifact <= 300)
420
+ return "running_waiting";
421
+ return "running_stale";
422
+ }
423
+ function livenessPollAfterSeconds(state) {
424
+ switch (state) {
425
+ case "completed":
426
+ case "halted":
427
+ return null;
428
+ case "running_stale":
429
+ return 15;
430
+ case "running_recent_signal":
431
+ case "running_waiting":
432
+ return 30;
433
+ case "prepared":
434
+ case "unknown":
435
+ return 60;
436
+ }
437
+ }
438
+ function livenessSummary(args) {
439
+ const active = args.activeUnits.length > 0
440
+ ? ` active_units=${args.activeUnits.join(", ")}`
441
+ : "";
442
+ const lastArtifact = args.lastArtifactKey
443
+ ? ` last_artifact=${args.lastArtifactKey}`
444
+ : "";
445
+ const since = args.secondsSinceLastArtifact === null
446
+ ? ""
447
+ : ` seconds_since_last_artifact=${args.secondsSinceLastArtifact}`;
448
+ switch (args.state) {
449
+ case "completed":
450
+ return "Review reached a terminal completed state; no further polling is required.";
451
+ case "halted":
452
+ return "Review reached a terminal halted/failed state; operator action is required before progress can continue.";
453
+ case "prepared":
454
+ return "Review is prepared for dispatch; polling can continue after execution starts.";
455
+ case "unknown":
456
+ return "Review status is unknown; polling can continue while artifacts appear.";
457
+ case "running_recent_signal":
458
+ return `Review is still active at ${args.currentLabel ?? "unknown step"} with a recent artifact signal.${active}${lastArtifact}${since}`;
459
+ case "running_waiting":
460
+ return `Review is still active at ${args.currentLabel ?? "unknown step"}; no new final signal is available yet.${active}${lastArtifact}${since}`;
461
+ case "running_stale":
462
+ return `Review is still active at ${args.currentLabel ?? "unknown step"}, but no artifact change has been observed for the stale threshold.${active}${lastArtifact}${since}`;
463
+ }
464
+ }
465
+ async function existingSeatIds(seats) {
466
+ const existing = [];
467
+ for (const seat of seats ?? []) {
468
+ if (await fileExists(seat.output_path))
469
+ existing.push(seat.lens_id);
470
+ }
471
+ return existing;
472
+ }
473
+ async function completedProgressStepIds(params) {
474
+ if (params.status === "completed" || params.status === "completed_with_degradation") {
475
+ return REVIEW_PROGRESS_STEPS.map((step) => step.id);
476
+ }
477
+ const completed = [];
478
+ if (params.executionPlan)
479
+ completed.push("manifest_validation");
480
+ const plannedLensIds = params.executionPlan?.lens_execution_seats.map((seat) => seat.lens_id) ?? [];
481
+ const completedLensIds = await existingSeatIds(params.executionPlan?.lens_execution_seats);
482
+ const allPlannedLensesCompleted = plannedLensIds.length > 0 && completedLensIds.length >= plannedLensIds.length;
483
+ if (allPlannedLensesCompleted || params.artifactRefs.lens_completion_barrier) {
484
+ completed.push("lens_dispatch");
485
+ }
486
+ if (params.artifactRefs.lens_completion_barrier)
487
+ completed.push("lens_completion_barrier");
488
+ if (params.artifactRefs.finding_ledger)
489
+ completed.push("finding_ledger");
490
+ if (params.artifactRefs.finding_relation_graph)
491
+ completed.push("finding_relation_graph");
492
+ if (params.artifactRefs.issue_ledger)
493
+ completed.push("issue_ledger");
494
+ if (params.artifactRefs.issue_stance_matrix)
495
+ completed.push("issue_stance_matrix");
496
+ if (params.artifactRefs.deliberation_plan)
497
+ completed.push("deliberation_plan");
498
+ const deliberationIds = await existingSeatIds(params.executionPlan?.lens_deliberation_prompt_packet_seats);
499
+ const plannedDeliberationIds = params.executionPlan?.lens_deliberation_prompt_packet_seats.map((seat) => seat.lens_id) ??
500
+ [];
501
+ if ((plannedDeliberationIds.length > 0 &&
502
+ deliberationIds.length >= plannedDeliberationIds.length) ||
503
+ params.artifactRefs.deliberation_output) {
504
+ completed.push("lens_deliberation_responses");
505
+ }
506
+ if (params.artifactRefs.deliberation_output)
507
+ completed.push("controlled_deliberation");
508
+ if (params.artifactRefs.problem_framing)
509
+ completed.push("problem_framing");
510
+ if (params.artifactRefs.synthesis_output) {
511
+ completed.push("synthesize");
512
+ }
513
+ return [...new Set(completed)];
514
+ }
515
+ function currentStepIdFromHalt(executionResult) {
516
+ return reviewProgressStepIdFromHalt({
517
+ haltPhase: executionResult?.halt_phase ?? null,
518
+ haltUnitId: executionResult?.halt_unit_id ?? null,
519
+ haltUnitKind: executionResult?.halt_unit_kind ?? null,
520
+ });
521
+ }
522
+ async function activeUnits(params) {
523
+ if (params.status === "prepared" ||
524
+ params.status === "completed" ||
525
+ params.status === "completed_with_degradation" ||
526
+ params.status === "unknown") {
527
+ return [];
528
+ }
529
+ if (params.status === "halted_partial") {
530
+ const unitId = params.executionResult?.halt_unit_id;
531
+ return typeof unitId === "string" && unitId.length > 0 ? [unitId] : [];
532
+ }
533
+ if (params.currentStepId === "lens_dispatch") {
534
+ const planned = params.executionPlan?.lens_execution_seats.map((seat) => seat.lens_id) ?? [];
535
+ const completed = new Set(await existingSeatIds(params.executionPlan?.lens_execution_seats));
536
+ const pending = planned.filter((lensId) => !completed.has(lensId));
537
+ return (pending.length > 0 ? pending : planned).map((lensId) => `lens:${lensId}`);
538
+ }
539
+ if (params.currentStepId === "lens_deliberation_responses") {
540
+ const planned = params.executionPlan?.lens_deliberation_prompt_packet_seats.map((seat) => seat.lens_id) ??
541
+ [];
542
+ const completed = new Set(await existingSeatIds(params.executionPlan?.lens_deliberation_prompt_packet_seats));
543
+ return planned
544
+ .filter((lensId) => !completed.has(lensId))
545
+ .map((lensId) => `deliberation:${lensId}`);
546
+ }
547
+ if (params.currentStepId === "controlled_deliberation")
548
+ return ["controlled-deliberation"];
549
+ return params.currentStepId ? [params.currentStepId] : [];
550
+ }
551
+ function latestProgressUpdate(params) {
552
+ if (params.status === "completed" || params.status === "completed_with_degradation") {
553
+ return {
554
+ interim_signal_status: "finalized",
555
+ summary: `Review completed; final output and ReviewRecord are available. ${compactClassificationSignal(params.resultClassificationSummary)}.`,
556
+ evidence_refs: [
557
+ params.artifactRefs.final_output,
558
+ params.artifactRefs.review_record,
559
+ ].filter((ref) => typeof ref === "string"),
560
+ };
561
+ }
562
+ if (params.status === "halted_partial") {
563
+ return {
564
+ interim_signal_status: null,
565
+ summary: params.executionResult?.halt_reason ?? "Review halted before completion.",
566
+ evidence_refs: [
567
+ params.artifactRefs.execution_result,
568
+ params.artifactRefs.review_run_manifest,
569
+ ].filter((ref) => typeof ref === "string"),
570
+ };
571
+ }
572
+ if (params.artifactRefs.problem_framing) {
573
+ return {
574
+ interim_signal_status: "deliberated",
575
+ summary: `Problem framing is available; synthesize/final rendering is next. ${compactClassificationSignal(params.resultClassificationSummary)}.`,
576
+ evidence_refs: [params.artifactRefs.problem_framing],
577
+ };
578
+ }
579
+ if (params.artifactRefs.deliberation_output) {
580
+ return {
581
+ interim_signal_status: "deliberated",
582
+ summary: "Controlled deliberation output is available.",
583
+ evidence_refs: [params.artifactRefs.deliberation_output],
584
+ };
585
+ }
586
+ if (params.artifactRefs.deliberation_plan) {
587
+ return {
588
+ interim_signal_status: "deliberation_pending",
589
+ summary: "Deliberation plan is available; lens deliberation or teamlead consolidation remains.",
590
+ evidence_refs: [params.artifactRefs.deliberation_plan],
591
+ };
592
+ }
593
+ if (params.artifactRefs.issue_ledger || params.artifactRefs.issue_stance_matrix) {
594
+ return {
595
+ interim_signal_status: "issue_candidate",
596
+ summary: `Issue-stage artifacts are available for inspection. issue_count=${params.resultClassificationSummary.issue_count}, ${compactClassificationSignal(params.resultClassificationSummary)}.`,
597
+ evidence_refs: [
598
+ params.artifactRefs.issue_ledger,
599
+ params.artifactRefs.issue_stance_matrix,
600
+ ].filter((ref) => typeof ref === "string"),
601
+ };
602
+ }
603
+ if (params.artifactRefs.finding_ledger || params.completedLensIds.length > 0) {
604
+ return {
605
+ interim_signal_status: "lens_local",
606
+ summary: params.artifactRefs.finding_ledger
607
+ ? `Finding ledger is available from completed lens outputs. finding_count=${params.resultClassificationSummary.finding_count}, ${compactClassificationSignal(params.resultClassificationSummary)}.`
608
+ : `${params.completedLensIds.length} lens output(s) are available.`,
609
+ evidence_refs: [
610
+ params.artifactRefs.finding_ledger,
611
+ ...params.completedLensIds.map((lensId) => `round1/${lensId}.md`),
612
+ ].filter((ref) => typeof ref === "string"),
613
+ };
614
+ }
615
+ return {
616
+ interim_signal_status: null,
617
+ summary: "Review session is prepared; worker dispatch has not produced review signals yet.",
618
+ evidence_refs: [
619
+ params.artifactRefs.execution_plan,
620
+ params.artifactRefs.review_target_profile,
621
+ ].filter((ref) => typeof ref === "string"),
622
+ };
623
+ }
624
+ function expectedCompletedArtifactRefs(sessionRoot) {
625
+ return {
626
+ synthesis_output: path.join(sessionRoot, "synthesis.md"),
627
+ deliberation_output: path.join(sessionRoot, "deliberation.md"),
628
+ final_output: path.join(sessionRoot, "final-output.md"),
629
+ review_record: path.join(sessionRoot, "review-record.yaml"),
630
+ };
631
+ }
632
+ function haltPresentation(params) {
633
+ const reason = params.executionResult?.halt_reason;
634
+ if (!reason)
635
+ return null;
636
+ const absentArtifactRefs = Object.fromEntries(Object.entries(expectedCompletedArtifactRefs(params.sessionRoot)).filter(([key]) => params.artifactRefs[key] === undefined));
637
+ return {
638
+ phase: params.executionResult?.halt_phase ?? null,
639
+ unit_id: params.executionResult?.halt_unit_id ?? null,
640
+ unit_kind: params.executionResult?.halt_unit_kind ?? null,
641
+ lens_id: params.executionResult?.halt_lens_id ?? null,
642
+ reason,
643
+ produced_artifact_refs: params.artifactRefs,
644
+ absent_artifact_refs: absentArtifactRefs,
645
+ action_candidates: ["retry_execution", "continue_review"],
646
+ };
647
+ }
648
+ async function buildReviewStatusPresentationInput(params) {
649
+ const nowMs = Date.now();
650
+ const manifest = await readOptionalYaml(path.join(params.sessionRoot, "review-run-manifest.yaml"));
651
+ const sessionMetadata = await readOptionalYaml(path.join(params.sessionRoot, "session-metadata.yaml"));
652
+ const completedSteps = await completedProgressStepIds(params);
653
+ const stepIds = stepIdsFromManifestOrDefault(manifest);
654
+ const totalSteps = totalProgressSteps(manifest);
655
+ const completedStepSet = new Set(completedSteps);
656
+ const firstIncompleteIndex = stepIds.findIndex((stepId) => !completedStepSet.has(stepId));
657
+ const haltedStepId = currentStepIdFromHalt(params.executionResult);
658
+ const currentStepId = params.status === "prepared" || params.status === "unknown"
659
+ ? null
660
+ : haltedStepId ??
661
+ (firstIncompleteIndex >= 0 ? stepIds[firstIncompleteIndex] ?? null : null);
662
+ const currentStepIndex = currentStepId
663
+ ? stepIds.findIndex((stepId) => stepId === currentStepId)
664
+ : -1;
665
+ const completedStatus = params.status === "completed" || params.status === "completed_with_degradation";
666
+ const sessionStartMs = parseTimestampMs(params.executionResult?.execution_started_at) ??
667
+ parseTimestampMs(sessionMetadata?.created_at);
668
+ const progress = {
669
+ current_step: completedStatus
670
+ ? totalSteps
671
+ : currentStepIndex >= 0
672
+ ? currentStepIndex + 1
673
+ : 0,
674
+ total_steps: totalSteps,
675
+ current_label: completedStatus
676
+ ? "completed"
677
+ : params.status === "prepared"
678
+ ? "prepared for dispatch"
679
+ : params.status === "halted_partial"
680
+ ? `halted during ${currentStepId ? stepById(currentStepId).label : "unknown"}`
681
+ : currentStepId
682
+ ? stepById(currentStepId).label
683
+ : "unknown",
684
+ completed_steps: params.status === "prepared"
685
+ ? [
686
+ params.artifactRefs.interpretation ? "interpretation" : null,
687
+ params.artifactRefs.binding ? "binding" : null,
688
+ params.artifactRefs.execution_plan ? "execution_plan" : null,
689
+ ].filter((step) => step !== null)
690
+ : completedSteps,
691
+ active_units: await activeUnits({
692
+ status: params.status,
693
+ currentStepId,
694
+ executionPlan: params.executionPlan,
695
+ executionResult: params.executionResult,
696
+ }),
697
+ pending_units: completedStatus
698
+ ? []
699
+ : params.status === "prepared"
700
+ ? REVIEW_PROGRESS_STEPS.map((step) => step.label)
701
+ : currentStepIndex >= 0
702
+ ? stepIds.slice(currentStepIndex + 1).map((stepId) => stepById(stepId).label)
703
+ : [],
704
+ elapsed_seconds: elapsedSeconds(params.executionResult) ??
705
+ secondsBetween(nowMs, sessionStartMs),
706
+ next_expected_event: completedStatus
707
+ ? null
708
+ : params.status === "halted_partial"
709
+ ? "operator action on halted partial result"
710
+ : params.status === "prepared"
711
+ ? "worker dispatch or review execution start"
712
+ : currentStepId
713
+ ? `next ${stepById(currentStepId).label} artifact or timeout`
714
+ : null,
715
+ };
716
+ const completedLensIds = await existingSeatIds(params.executionPlan?.lens_execution_seats);
717
+ const halt = haltPresentation({
718
+ sessionRoot: params.sessionRoot,
719
+ artifactRefs: params.artifactRefs,
720
+ executionResult: params.executionResult,
721
+ });
722
+ const resultClassificationSummary = await readReviewResultClassification(params.sessionRoot);
723
+ const observedArtifact = await artifactObservation(params.artifactRefs);
724
+ const secondsSinceLastArtifact = secondsBetween(nowMs, observedArtifact.mtimeMs);
725
+ const livenessState = livenessStateKind({
726
+ status: params.status,
727
+ secondsSinceLastArtifact,
728
+ });
729
+ const liveness = {
730
+ generated_at: isoNow(),
731
+ poll_after_seconds: livenessPollAfterSeconds(livenessState),
732
+ state: livenessState,
733
+ last_observed_artifact_key: observedArtifact.key,
734
+ last_observed_artifact_ref: observedArtifact.ref,
735
+ last_observed_artifact_mtime: observedArtifact.mtimeMs === null
736
+ ? null
737
+ : isoFromTimestamp(observedArtifact.mtimeMs),
738
+ seconds_since_last_observed_artifact: secondsSinceLastArtifact,
739
+ summary: livenessSummary({
740
+ state: livenessState,
741
+ currentLabel: progress.current_label,
742
+ activeUnits: progress.active_units,
743
+ lastArtifactKey: observedArtifact.key,
744
+ secondsSinceLastArtifact,
745
+ }),
746
+ };
747
+ return {
748
+ presentation_contract_version: REVIEW_PRESENTATION_CONTRACT_VERSION,
749
+ presentation_kind: "progress",
750
+ session_id: params.reviewRecord?.session_id ?? basenameSessionId(params.sessionRoot),
751
+ session_root: params.sessionRoot,
752
+ status: params.status,
753
+ generated_from_artifact_refs: generatedFromArtifactRefs(params.artifactRefs),
754
+ progress,
755
+ liveness,
756
+ latest_update: latestProgressUpdate({
757
+ status: params.status,
758
+ artifactRefs: params.artifactRefs,
759
+ executionResult: params.executionResult,
760
+ completedLensIds,
761
+ resultClassificationSummary,
762
+ }),
763
+ result_classification_summary: resultClassificationSummary,
764
+ halt,
765
+ };
766
+ }
767
+ async function buildPreparedOpeningBriefInput(sessionRoot, executionPlan) {
768
+ const artifactRefs = await collectArtifactRefs(sessionRoot);
769
+ const interpretation = await readOptionalYaml(path.join(sessionRoot, "interpretation.yaml"));
770
+ const binding = await readOptionalYaml(path.join(sessionRoot, "binding.yaml"));
771
+ const reviewTargetProfile = await readOptionalYaml(executionPlan.review_target_profile_path);
772
+ return {
773
+ presentation_contract_version: REVIEW_PRESENTATION_CONTRACT_VERSION,
774
+ presentation_kind: "opening_brief",
775
+ session_id: executionPlan.session_id,
776
+ session_root: sessionRoot,
777
+ status: "prepared",
778
+ generated_from_artifact_refs: generatedFromArtifactRefs(artifactRefs, OPENING_PRESENTATION_SOURCE_REF_KEYS),
779
+ interpretation: interpretation
780
+ ? {
781
+ entrypoint: interpretation.entrypoint,
782
+ target_scope_candidate: interpretation.target_scope_candidate,
783
+ intent_summary: interpretation.intent_summary,
784
+ domain_recommendation: interpretation.domain_recommendation,
785
+ domain_selection_required: interpretation.domain_selection_required,
786
+ review_mode_recommendation: interpretation.review_mode_recommendation,
787
+ lens_selection_plan: interpretation.lens_selection_plan,
788
+ ambiguity_notes: interpretation.ambiguity_notes,
789
+ }
790
+ : null,
791
+ binding: binding
792
+ ? {
793
+ resolved_target_scope: binding.resolved_target_scope,
794
+ resolved_session_domain: binding.resolved_session_domain,
795
+ resolved_review_mode: binding.resolved_review_mode,
796
+ resolved_lens_set: binding.resolved_lens_set,
797
+ resolved_execution_realization: binding.resolved_execution_realization,
798
+ resolved_host_runtime: binding.resolved_host_runtime,
799
+ boundary_policy: binding.boundary_policy,
800
+ effective_boundary_state: binding.effective_boundary_state,
801
+ }
802
+ : null,
803
+ review_target_profile: reviewTargetProfile
804
+ ? {
805
+ target_input_kind: reviewTargetProfile.target_input_kind,
806
+ target_material_kind: reviewTargetProfile.target_material_kind,
807
+ material_profile: reviewTargetProfile.material_profile,
808
+ artifact_roles: reviewTargetProfile.artifact_roles,
809
+ domain: reviewTargetProfile.domain,
810
+ maturity: reviewTargetProfile.maturity,
811
+ closure_level: reviewTargetProfile.closure_level,
812
+ review_goal: reviewTargetProfile.review_goal,
813
+ closure_obligation_policy: reviewTargetProfile.closure_obligation_policy,
814
+ target_refs: reviewTargetProfile.target_refs,
815
+ inference: reviewTargetProfile.inference,
816
+ }
817
+ : null,
818
+ execution_plan: {
819
+ review_mode: executionPlan.review_mode,
820
+ execution_realization: executionPlan.execution_realization,
821
+ host_runtime: executionPlan.host_runtime,
822
+ lens_ids: executionPlan.lens_execution_seats.map((seat) => seat.lens_id),
823
+ prompt_packets_root: executionPlan.prompt_packets_root,
824
+ review_run_manifest_path: path.join(sessionRoot, "review-run-manifest.yaml"),
825
+ },
826
+ };
827
+ }
828
+ function parseReviewInvokeOutput(stdout) {
829
+ for (const line of [...stdout].reverse()) {
830
+ const trimmed = line.trim();
831
+ if (!trimmed.startsWith("{"))
832
+ continue;
833
+ try {
834
+ return JSON.parse(trimmed);
835
+ }
836
+ catch {
837
+ // Keep looking: progress messages are not JSON.
838
+ }
839
+ }
840
+ throw new Error("review invocation completed without a structured JSON result.");
841
+ }
842
+ function isReviewInvokeShape(value) {
843
+ if (value === null || typeof value !== "object")
844
+ return false;
845
+ const reviewResult = value.review_result;
846
+ return reviewResult !== null && typeof reviewResult === "object";
847
+ }
848
+ async function collectArtifactRefs(sessionRoot) {
849
+ const candidates = {
850
+ session_metadata: path.join(sessionRoot, "session-metadata.yaml"),
851
+ interpretation: path.join(sessionRoot, "interpretation.yaml"),
852
+ binding: path.join(sessionRoot, "binding.yaml"),
853
+ execution_plan: path.join(sessionRoot, "execution-plan.yaml"),
854
+ execution_result: path.join(sessionRoot, "execution-result.yaml"),
855
+ actor_invocation_profiles: path.join(sessionRoot, "execution-preparation", "actor-invocation-profiles.yaml"),
856
+ actor_consumer_bindings: path.join(sessionRoot, "execution-preparation", "actor-consumer-bindings.yaml"),
857
+ domain_binding: path.join(sessionRoot, "execution-preparation", "domain-binding.yaml"),
858
+ review_value_alignment_criteria: path.join(sessionRoot, "execution-preparation", "review-value-alignment-criteria.yaml"),
859
+ review_target_profile: path.join(sessionRoot, "execution-preparation", "review-target-profile.yaml"),
860
+ review_context_manifest: path.join(sessionRoot, "execution-preparation", "review-context-manifest.yaml"),
861
+ lens_completion_barrier: path.join(sessionRoot, "lens-completion-barrier.yaml"),
862
+ finding_ledger: path.join(sessionRoot, "finding-ledger.yaml"),
863
+ finding_relation_graph: path.join(sessionRoot, "finding-relation-graph.yaml"),
864
+ issue_ledger: path.join(sessionRoot, "issue-ledger.yaml"),
865
+ issue_stance_matrix: path.join(sessionRoot, "issue-stance-matrix.yaml"),
866
+ deliberation_plan: path.join(sessionRoot, "deliberation-plan.yaml"),
867
+ problem_framing: path.join(sessionRoot, "problem-framing.yaml"),
868
+ deliberation_output: path.join(sessionRoot, "deliberation.md"),
869
+ synthesis_output: path.join(sessionRoot, "synthesis.md"),
870
+ review_run_manifest: path.join(sessionRoot, "review-run-manifest.yaml"),
871
+ degradation_summary: path.join(sessionRoot, "degradation-summary.yaml"),
872
+ error_log: path.join(sessionRoot, "error-log.md"),
873
+ final_output: path.join(sessionRoot, "final-output.md"),
874
+ review_record: path.join(sessionRoot, "review-record.yaml"),
875
+ };
876
+ const entries = [];
877
+ for (const [key, filePath] of Object.entries(candidates)) {
878
+ if (await fileExists(filePath))
879
+ entries.push([key, filePath]);
880
+ }
881
+ return Object.fromEntries(entries);
882
+ }
883
+ async function directoryHasMarkdownFiles(directoryPath) {
884
+ try {
885
+ const entries = await fs.readdir(directoryPath);
886
+ return entries.some((entry) => entry.endsWith(".md"));
887
+ }
888
+ catch {
889
+ return false;
890
+ }
891
+ }
892
+ async function hasRunArtifacts(sessionRoot, artifactRefs) {
893
+ const runRefKeys = [
894
+ "review_run_manifest",
895
+ "execution_result",
896
+ "degradation_summary",
897
+ "lens_completion_barrier",
898
+ "finding_ledger",
899
+ "finding_relation_graph",
900
+ "issue_ledger",
901
+ "issue_stance_matrix",
902
+ "deliberation_plan",
903
+ "problem_framing",
904
+ "deliberation_output",
905
+ "synthesis_output",
906
+ "final_output",
907
+ "review_record",
908
+ ];
909
+ if (runRefKeys.some((key) => artifactRefs[key] !== undefined))
910
+ return true;
911
+ return ((await directoryHasMarkdownFiles(path.join(sessionRoot, "round1"))) ||
912
+ (await directoryHasMarkdownFiles(path.join(sessionRoot, "deliberation", "round1"))));
913
+ }
914
+ async function collectStructuredFailures(sessionRoot) {
915
+ const failuresRoot = path.join(sessionRoot, "failures");
916
+ let filenames;
917
+ try {
918
+ filenames = await fs.readdir(failuresRoot);
919
+ }
920
+ catch {
921
+ return { failureRefs: [], structuredFailures: [] };
922
+ }
923
+ const failureRefs = filenames
924
+ .filter((filename) => filename.endsWith(".yaml"))
925
+ .map((filename) => path.join(failuresRoot, filename))
926
+ .sort();
927
+ const structuredFailures = [];
928
+ for (const failureRef of failureRefs) {
929
+ structuredFailures.push(await readYamlDocument(failureRef));
930
+ }
931
+ return { failureRefs, structuredFailures };
932
+ }
933
+ async function listDomainDirs(root) {
934
+ try {
935
+ const entries = await fs.readdir(root, { withFileTypes: true });
936
+ return entries
937
+ .filter((entry) => entry.isDirectory())
938
+ .map((entry) => entry.name)
939
+ .sort();
940
+ }
941
+ catch {
942
+ return [];
943
+ }
944
+ }
945
+ export function createOntoReviewCoreApi(options = {}) {
946
+ const ontoHome = resolveRequiredOntoHome(options.ontoHome);
947
+ return {
948
+ async prepareReview(request) {
949
+ const argv = appendCommonReviewArgs([], request, ontoHome);
950
+ const { result } = await withCapturedConsole(() => reviewPrepareOnly(argv));
951
+ const sessionRoot = path.resolve(result.session_root);
952
+ const executionPlan = await readYamlDocument(path.join(sessionRoot, "execution-plan.yaml"));
953
+ const openingBriefInput = await buildPreparedOpeningBriefInput(sessionRoot, executionPlan);
954
+ return {
955
+ sessionId: executionPlan.session_id,
956
+ sessionRoot,
957
+ executionPlan,
958
+ routeVisibility: await buildReviewRouteVisibilityFromSession(sessionRoot),
959
+ llmPresentation: {
960
+ openingBrief: buildOpeningBriefPresentation(openingBriefInput),
961
+ },
962
+ };
963
+ },
964
+ async runReview(request) {
965
+ const argv = appendCommonReviewArgs(["--no-watch"], request, ontoHome);
966
+ let progressSequence = 0;
967
+ let observedSessionRoot = null;
968
+ const emitProgress = (event) => {
969
+ const observer = request.progressObserver;
970
+ if (!observer)
971
+ return;
972
+ progressSequence += 1;
973
+ try {
974
+ observer({
975
+ presentation_contract_version: REVIEW_PRESENTATION_CONTRACT_VERSION,
976
+ event_kind: "mcp_progress",
977
+ sequence: progressSequence,
978
+ generated_at: isoNow(),
979
+ ...event,
980
+ });
981
+ }
982
+ catch {
983
+ // Progress notifications are transport-only and must not affect review execution.
984
+ }
985
+ };
986
+ const captureObserver = request.progressObserver
987
+ ? {
988
+ stdout: (text) => {
989
+ for (const line of text.split(/\r?\n/)) {
990
+ const parsed = consoleLineProgressEvent({
991
+ line,
992
+ projectRoot: request.projectRoot,
993
+ sessionRoot: observedSessionRoot,
994
+ sequence: progressSequence + 1,
995
+ });
996
+ if (!parsed)
997
+ continue;
998
+ observedSessionRoot = parsed.sessionRoot ?? observedSessionRoot;
999
+ try {
1000
+ request.progressObserver?.(parsed.event);
1001
+ }
1002
+ catch {
1003
+ // Progress notifications are transport-only and must not affect review execution.
1004
+ }
1005
+ progressSequence = parsed.event.sequence;
1006
+ }
1007
+ },
1008
+ }
1009
+ : undefined;
1010
+ const captured = await withCapturedConsole(async () => {
1011
+ const exitCode = await runReviewInvokeCli(argv);
1012
+ if (exitCode !== 0) {
1013
+ throw new Error(`review invocation failed with exit code ${exitCode}`);
1014
+ }
1015
+ return exitCode;
1016
+ }, captureObserver);
1017
+ const parsed = parseReviewInvokeOutput(captured.stdout);
1018
+ if (!isReviewInvokeShape(parsed)) {
1019
+ throw new Error("review invocation returned an unexpected result shape.");
1020
+ }
1021
+ const result = parsed.review_result;
1022
+ const status = result.record_status ?? "halted_partial";
1023
+ const startPreview = {
1024
+ entrypointPlan: parsed.entrypoint_plan,
1025
+ routeSummary: parsed.route_summary,
1026
+ ...(parsed.bounded_invoke_steps !== undefined
1027
+ ? { boundedInvokeSteps: parsed.bounded_invoke_steps }
1028
+ : {}),
1029
+ };
1030
+ const resolvedResultSessionRoot = path.resolve(result.session_root);
1031
+ const artifactRefs = await collectArtifactRefs(resolvedResultSessionRoot);
1032
+ const failures = await collectStructuredFailures(resolvedResultSessionRoot);
1033
+ const executionPlan = await readOptionalYaml(path.join(resolvedResultSessionRoot, "execution-plan.yaml"));
1034
+ const executionResult = await readOptionalYaml(path.join(resolvedResultSessionRoot, "execution-result.yaml"));
1035
+ const reviewRecord = await readOptionalReviewRecord(path.join(resolvedResultSessionRoot, "review-record.yaml"));
1036
+ const resultClassificationSummary = await readReviewResultClassification(resolvedResultSessionRoot);
1037
+ const progressInput = await buildReviewStatusPresentationInput({
1038
+ sessionRoot: resolvedResultSessionRoot,
1039
+ status,
1040
+ artifactRefs,
1041
+ executionPlan,
1042
+ executionResult,
1043
+ reviewRecord,
1044
+ });
1045
+ const openingBriefInput = executionPlan
1046
+ ? await buildPreparedOpeningBriefInput(resolvedResultSessionRoot, executionPlan)
1047
+ : {
1048
+ presentation_contract_version: REVIEW_PRESENTATION_CONTRACT_VERSION,
1049
+ presentation_kind: "opening_brief",
1050
+ session_id: basenameSessionId(resolvedResultSessionRoot),
1051
+ session_root: resolvedResultSessionRoot,
1052
+ status,
1053
+ generated_from_artifact_refs: generatedFromArtifactRefs(artifactRefs),
1054
+ start_preview: startPreview,
1055
+ };
1056
+ const finalResultInput = {
1057
+ presentation_contract_version: REVIEW_PRESENTATION_CONTRACT_VERSION,
1058
+ presentation_kind: "final_result",
1059
+ session_id: basenameSessionId(resolvedResultSessionRoot),
1060
+ session_root: resolvedResultSessionRoot,
1061
+ status,
1062
+ generated_from_artifact_refs: generatedFromArtifactRefs(artifactRefs),
1063
+ result_overview: parsed.result_overview ?? null,
1064
+ result_classification_summary: resultClassificationSummary,
1065
+ review_result: result,
1066
+ };
1067
+ const llmPresentation = {
1068
+ openingBrief: buildOpeningBriefPresentation(openingBriefInput),
1069
+ progress: buildProgressPresentation(progressInput),
1070
+ ...(progressInput.halt
1071
+ ? {
1072
+ halt: buildHaltPresentation({
1073
+ ...progressInput,
1074
+ presentation_kind: "halt",
1075
+ }),
1076
+ }
1077
+ : {}),
1078
+ finalResult: buildFinalResultPresentation(finalResultInput),
1079
+ };
1080
+ emitProgress({
1081
+ source: "artifact_status",
1082
+ stage: "final_status",
1083
+ session_root: resolvedResultSessionRoot,
1084
+ message: `Review finished with status ${status}.`,
1085
+ progress: {
1086
+ current: 100,
1087
+ total: 100,
1088
+ label: "final status",
1089
+ },
1090
+ });
1091
+ return {
1092
+ sessionId: basenameSessionId(result.session_root),
1093
+ sessionRoot: resolvedResultSessionRoot,
1094
+ status,
1095
+ finalOutputPath: result.final_output_path,
1096
+ reviewRecordPath: result.review_record_path,
1097
+ executionResultPath: result.execution_result_path,
1098
+ reviewRunManifestPath: result.review_run_manifest_path ??
1099
+ path.join(resolvedResultSessionRoot, "review-run-manifest.yaml"),
1100
+ deliberationStatus: result.deliberation_status ?? null,
1101
+ participatingLensIds: result.participating_lens_ids ?? [],
1102
+ degradedLensIds: result.degraded_lens_ids ?? [],
1103
+ ...(result.summary !== undefined ? { summary: result.summary } : {}),
1104
+ ...(parsed.result_overview !== undefined
1105
+ ? { resultOverview: parsed.result_overview }
1106
+ : {}),
1107
+ artifactRefs,
1108
+ resultClassificationSummary,
1109
+ ...failures,
1110
+ routeVisibility: await buildReviewRouteVisibilityFromSession(resolvedResultSessionRoot),
1111
+ startPreview,
1112
+ llmPresentation,
1113
+ };
1114
+ },
1115
+ async getReviewStatus(sessionRoot) {
1116
+ const resolvedSessionRoot = path.resolve(sessionRoot);
1117
+ const artifactRefs = await collectArtifactRefs(resolvedSessionRoot);
1118
+ const failures = await collectStructuredFailures(resolvedSessionRoot);
1119
+ const executionPlan = await readOptionalYaml(path.join(resolvedSessionRoot, "execution-plan.yaml"));
1120
+ const executionResult = await readOptionalYaml(path.join(resolvedSessionRoot, "execution-result.yaml"));
1121
+ const reviewRecord = await readOptionalReviewRecord(path.join(resolvedSessionRoot, "review-record.yaml"));
1122
+ const status = reviewRecord
1123
+ ? reviewRecord.record_status
1124
+ : executionResult?.execution_status === "halted_partial"
1125
+ ? "halted_partial"
1126
+ : executionPlan
1127
+ ? await hasRunArtifacts(resolvedSessionRoot, artifactRefs)
1128
+ ? "running"
1129
+ : "prepared"
1130
+ : "unknown";
1131
+ const progressInput = await buildReviewStatusPresentationInput({
1132
+ sessionRoot: resolvedSessionRoot,
1133
+ status,
1134
+ artifactRefs,
1135
+ executionPlan,
1136
+ executionResult,
1137
+ reviewRecord,
1138
+ });
1139
+ const llmPresentation = {
1140
+ progress: buildProgressPresentation(progressInput),
1141
+ };
1142
+ if (executionPlan) {
1143
+ llmPresentation.openingBrief = buildOpeningBriefPresentation(await buildPreparedOpeningBriefInput(resolvedSessionRoot, executionPlan));
1144
+ }
1145
+ if (progressInput.halt) {
1146
+ llmPresentation.halt = buildHaltPresentation({
1147
+ ...progressInput,
1148
+ presentation_kind: "halt",
1149
+ });
1150
+ }
1151
+ if (reviewRecord) {
1152
+ return {
1153
+ sessionId: reviewRecord.session_id,
1154
+ sessionRoot: resolvedSessionRoot,
1155
+ status,
1156
+ artifactRefs,
1157
+ ...failures,
1158
+ routeVisibility: await buildReviewRouteVisibilityFromSession(resolvedSessionRoot),
1159
+ llmPresentation,
1160
+ };
1161
+ }
1162
+ if (executionResult?.execution_status === "halted_partial") {
1163
+ return {
1164
+ sessionId: basenameSessionId(resolvedSessionRoot),
1165
+ sessionRoot: resolvedSessionRoot,
1166
+ status,
1167
+ artifactRefs,
1168
+ ...failures,
1169
+ routeVisibility: await buildReviewRouteVisibilityFromSession(resolvedSessionRoot),
1170
+ llmPresentation,
1171
+ };
1172
+ }
1173
+ if (executionPlan) {
1174
+ return {
1175
+ sessionId: basenameSessionId(resolvedSessionRoot),
1176
+ sessionRoot: resolvedSessionRoot,
1177
+ status,
1178
+ artifactRefs,
1179
+ ...failures,
1180
+ routeVisibility: await buildReviewRouteVisibilityFromSession(resolvedSessionRoot),
1181
+ llmPresentation,
1182
+ };
1183
+ }
1184
+ return {
1185
+ sessionId: basenameSessionId(resolvedSessionRoot),
1186
+ sessionRoot: resolvedSessionRoot,
1187
+ status: "unknown",
1188
+ artifactRefs,
1189
+ ...failures,
1190
+ routeVisibility: await buildReviewRouteVisibilityFromSession(resolvedSessionRoot),
1191
+ llmPresentation,
1192
+ };
1193
+ },
1194
+ async getReviewResult(sessionRoot) {
1195
+ const resolvedSessionRoot = path.resolve(sessionRoot);
1196
+ const artifactRefs = await collectArtifactRefs(resolvedSessionRoot);
1197
+ const { failureRefs } = await collectStructuredFailures(resolvedSessionRoot);
1198
+ const reviewRecordPath = path.join(resolvedSessionRoot, "review-record.yaml");
1199
+ const reviewRecord = await readValidatedReviewRecord(reviewRecordPath);
1200
+ const finalOutputPath = reviewRecord.final_output_ref ?? path.join(resolvedSessionRoot, "final-output.md");
1201
+ const finalOutputText = await readOptionalText(finalOutputPath);
1202
+ const executionPlan = await readOptionalYaml(path.join(resolvedSessionRoot, "execution-plan.yaml"));
1203
+ const executionResult = await readOptionalYaml(path.join(resolvedSessionRoot, "execution-result.yaml"));
1204
+ const resultClassificationSummary = await readReviewResultClassification(resolvedSessionRoot);
1205
+ const status = reviewRecord.record_status;
1206
+ const progressInput = await buildReviewStatusPresentationInput({
1207
+ sessionRoot: resolvedSessionRoot,
1208
+ status,
1209
+ artifactRefs,
1210
+ executionPlan,
1211
+ executionResult,
1212
+ reviewRecord,
1213
+ });
1214
+ const finalResultInput = {
1215
+ presentation_contract_version: REVIEW_PRESENTATION_CONTRACT_VERSION,
1216
+ presentation_kind: "final_result",
1217
+ session_id: reviewRecord.session_id,
1218
+ session_root: resolvedSessionRoot,
1219
+ status,
1220
+ generated_from_artifact_refs: generatedFromArtifactRefs(artifactRefs),
1221
+ result_classification_summary: resultClassificationSummary,
1222
+ review_record: reviewRecord,
1223
+ };
1224
+ return {
1225
+ sessionId: reviewRecord.session_id,
1226
+ sessionRoot: resolvedSessionRoot,
1227
+ reviewRecord,
1228
+ finalOutputPath,
1229
+ reviewRunManifestPath: path.join(resolvedSessionRoot, "review-run-manifest.yaml"),
1230
+ artifactRefs,
1231
+ resultClassificationSummary,
1232
+ failureRefs,
1233
+ routeVisibility: await buildReviewRouteVisibilityFromSession(resolvedSessionRoot),
1234
+ llmPresentation: {
1235
+ progress: buildProgressPresentation(progressInput),
1236
+ ...(progressInput.halt
1237
+ ? {
1238
+ halt: buildHaltPresentation({
1239
+ ...progressInput,
1240
+ presentation_kind: "halt",
1241
+ }),
1242
+ }
1243
+ : {}),
1244
+ finalResult: buildFinalResultPresentation(finalResultInput),
1245
+ },
1246
+ ...(finalOutputText !== undefined ? { finalOutputText } : {}),
1247
+ };
1248
+ },
1249
+ async listLenses() {
1250
+ const registry = loadCoreLensRegistry();
1251
+ return {
1252
+ full: registry.full_review_lens_ids,
1253
+ coreAxis: registry.core_axis_lens_ids,
1254
+ };
1255
+ },
1256
+ async listDomains(projectRoot) {
1257
+ const roots = [
1258
+ ...(projectRoot ? [path.join(path.resolve(projectRoot), ".onto", "domains")] : []),
1259
+ path.join(os.homedir(), ".onto", "domains"),
1260
+ ...(ontoHome ? [path.join(ontoHome, ".onto", "domains")] : []),
1261
+ ];
1262
+ const names = new Set();
1263
+ for (const root of roots) {
1264
+ for (const name of await listDomainDirs(root)) {
1265
+ names.add(name);
1266
+ }
1267
+ }
1268
+ return [...names].sort();
1269
+ },
1270
+ };
1271
+ }