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,464 @@
1
+ /**
2
+ * Codex Nested Teamlead Executor.
3
+ *
4
+ * # What this module is
5
+ *
6
+ * Runs the `nested-workers` Codex path: a single outer `codex exec` worker is
7
+ * started by onto TS main as the teamlead, and that outer Codex process invokes
8
+ * `codex exec` for each lens packet.
9
+ *
10
+ * # Why it exists
11
+ *
12
+ * The main-workers path starts one Codex worker per lens from the TS process.
13
+ * The nested-workers variant delegates per-lens scheduling decisions to an
14
+ * outer Codex teamlead.
15
+ *
16
+ * Sketch v3 §9 recorded the live validation (2026-04-18, codex
17
+ * v0.120.0): outer+inner session ids are independent, both exit 0,
18
+ * responses pass through. Preconditions confirmed:
19
+ * - `codex` binary on PATH
20
+ * - `~/.codex/auth.json` valid
21
+ * - non-seatbelt sandbox (outer invoked with `--sandbox danger-full-access`
22
+ * so it can shell out to nested `codex exec`)
23
+ *
24
+ * # How it relates
25
+ *
26
+ * - `ReviewExecutionProfile.mode === "nested-workers"` selects this path.
27
+ * - `executeReviewPromptExecution()` branches on that profile.
28
+ *
29
+ * # Scope
30
+ *
31
+ * This module provides the nested worker orchestration seat.
32
+ * Deliverables:
33
+ * - `runCodexNestedTeamlead(args)` function
34
+ * - Prompt template building
35
+ * - Outer codex stdout parser
36
+ * - Error classification (outer failure vs inner-lens failure vs
37
+ * parse failure)
38
+ * # Design reference
39
+ *
40
+ * - Nested Codex validation notes under `development-records/`
41
+ */
42
+ import { spawn } from "node:child_process";
43
+ import fs from "node:fs";
44
+ // ---------------------------------------------------------------------------
45
+ // Errors
46
+ // ---------------------------------------------------------------------------
47
+ export class CodexNestedTeamleadError extends Error {
48
+ outer_exit_code;
49
+ outer_stderr;
50
+ constructor(message, outer_exit_code, outer_stderr) {
51
+ super(message);
52
+ this.outer_exit_code = outer_exit_code;
53
+ this.outer_stderr = outer_stderr;
54
+ this.name = "CodexNestedTeamleadError";
55
+ }
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // Prompt template
59
+ // ---------------------------------------------------------------------------
60
+ const SUMMARY_SENTINEL_PREFIX = "LENS_DISPATCH_SUMMARY:";
61
+ /**
62
+ * Build the meta-orchestration prompt the outer codex receives on stdin.
63
+ *
64
+ * Key protocol elements:
65
+ * 1. Declared task (nested dispatch of N lens reviews).
66
+ * 2. Per-lens triple (lens_id, packet_path, output_path).
67
+ * 3. Explicit shell commands the outer codex must execute.
68
+ * 4. Required final stdout line: `LENS_DISPATCH_SUMMARY:{json}` so the
69
+ * TS parser can find the summary regardless of other stdout noise.
70
+ *
71
+ * The sentinel prefix is load-bearing: codex exec stdout mixes model
72
+ * commentary with any direct printf output, so the parser anchors on
73
+ * the prefix rather than trying to extract "the last line".
74
+ */
75
+ export function buildNestedTeamleadPrompt(input) {
76
+ const script = buildNestedDispatchScript(input);
77
+ const teamleadModelDiag = input.teamlead_model ?? "(codex default)";
78
+ const teamleadEffortDiag = input.teamlead_reasoning_effort ?? "(codex default)";
79
+ const teamleadServiceTierDiag = input.teamlead_service_tier ?? "(codex default)";
80
+ const lensModelDiag = input.lens_model ?? "(codex default)";
81
+ const lensEffortDiag = input.lens_reasoning_effort ?? "(codex default)";
82
+ const lensServiceTierDiag = input.lens_service_tier ?? "(codex default)";
83
+ // The prompt deliberately minimizes descriptive instructions. Outer codex's
84
+ // job is to run a literal bash script — not to reason about dispatch
85
+ // strategy. Descriptive prompts ("invoke nested codex for each lens...")
86
+ // led outer to treat the task as a lens-execution assignment and use its
87
+ // own file-edit tools instead of starting nested Codex workers. By
88
+ // handing outer a literal script with a single action ("pipe to bash"),
89
+ // the interpretation freedom that caused the earlier 10-minute stall is
90
+ // removed.
91
+ return [
92
+ `Nested-codex dispatch for ${input.lenses.length} lenses ` +
93
+ `(teamlead_model=${teamleadModelDiag}, teamlead_effort=${teamleadEffortDiag}, ` +
94
+ `teamlead_service_tier=${teamleadServiceTierDiag}, lens_model=${lensModelDiag}, ` +
95
+ `lens_effort=${lensEffortDiag}, lens_service_tier=${lensServiceTierDiag}).`,
96
+ "",
97
+ "Action: Execute the bash script below by piping it to `bash -s`.",
98
+ "Do not modify it, do not substitute variables, do not use file-edit",
99
+ "tools. After the script finishes, surface its stdout verbatim — the",
100
+ `final line (starting with "${SUMMARY_SENTINEL_PREFIX}") is consumed by`,
101
+ "the parent TS process and must not be elided or reformatted.",
102
+ "",
103
+ "```bash",
104
+ script,
105
+ "```",
106
+ ].join("\n");
107
+ }
108
+ /**
109
+ * Build the literal bash script that the outer codex is asked to pipe to
110
+ * `bash -s`. Every value (lens id, packet path, output path, model, effort)
111
+ * is interpolated at build time — the outer model does not perform any
112
+ * substitution. This deterministic construction is the contract that keeps
113
+ * outer's behaviour faithful to the requested action.
114
+ *
115
+ * Structure:
116
+ * 1. bash array `LENSES` with `lens_id|packet_path|output_path` entries
117
+ * 2. per-lens background subshell that runs `codex exec` with the packet
118
+ * on stdin and `-o <OUTPUT_PATH>` for the last-message file, writing
119
+ * stderr and the ENV-BEFORE/AFTER diagnostic lines to a per-lens log
120
+ * 3. `wait` for all lenses
121
+ * 4. replay each lens's log → stdout (so outer's captured stdout carries
122
+ * the diagnostic trace even though background subshells wrote them
123
+ * to per-lens log files)
124
+ * 5. emit the LENS_DISPATCH_SUMMARY:{...} sentinel with per-lens status
125
+ */
126
+ function buildNestedDispatchScript(input) {
127
+ const modelOpt = input.lens_model ? ` -m ${shellQuote(input.lens_model)}` : "";
128
+ const effortOpt = input.lens_reasoning_effort
129
+ ? ` -c model_reasoning_effort=${shellQuote(input.lens_reasoning_effort)}`
130
+ : "";
131
+ const serviceTierOpt = input.lens_service_tier
132
+ ? ` -c service_tier=${shellQuote(input.lens_service_tier)}`
133
+ : "";
134
+ const lensEntries = input.lenses
135
+ .map((l) => {
136
+ const triple = `${l.lens_id}|${l.packet_path}|${l.output_path}`;
137
+ return ` ${shellQuote(triple)}`;
138
+ })
139
+ .join("\n");
140
+ return [
141
+ "#!/usr/bin/env bash",
142
+ "# Literal nested-codex dispatch script. Generated by onto TS",
143
+ "# (codex-nested-teamlead-executor.ts). All values are interpolated; do",
144
+ "# not edit or re-interpret.",
145
+ "set +e",
146
+ "",
147
+ "LENSES=(",
148
+ lensEntries,
149
+ ")",
150
+ "",
151
+ 'TMPDIR="$(mktemp -d -t onto-nested-dispatch-XXXXXX)"',
152
+ "trap 'rm -rf \"$TMPDIR\"' EXIT",
153
+ "",
154
+ "# Launch every lens in parallel. Each subshell:",
155
+ "# - records ENV-BEFORE / ENV-AFTER diagnostic lines in its per-lens log",
156
+ "# - pipes the packet contents into `codex exec`",
157
+ "# - writes the last-message to <output_path> via `-o`",
158
+ "# - emits a single-line status JSON object to its .status file",
159
+ "# - on failure, renames the full per-lens running log to",
160
+ "# round1/.<lens>.nested-stderr.log so post-hoc audit can answer",
161
+ "# 'what actually failed inside this lens run?' even after the",
162
+ "# outer dispatch exits. (Whole log; no bounded tail. The log",
163
+ "# already lives under sessionRoot for watcher tail -f, so rename",
164
+ "# is cheaper + preserves more context than a truncated tail.)",
165
+ 'for entry in "${LENSES[@]}"; do',
166
+ ' IFS="|" read -r LENS_ID PACKET OUTPUT <<< "$entry"',
167
+ " (",
168
+ " # Running log lives under the lens output directory (sessionRoot",
169
+ " # /round1) so the watcher pane can `tail -f` it as codex emits",
170
+ " # reasoning / tool calls / tokens-used. Hidden filename (leading",
171
+ " # dot) keeps it out of the principal-facing lens output listing.",
172
+ " # NOTE: lifecycle (keep / rename / remove) is decided by the",
173
+ " # post-wait replay loop below, not by this subshell — see C1",
174
+ " # regression guard in 3rd self-review (2026-04-22).",
175
+ ' OUTPUT_DIR="$(dirname "$OUTPUT")"',
176
+ ' mkdir -p "$OUTPUT_DIR"',
177
+ ' LOG="$OUTPUT_DIR/.$LENS_ID.running.log"',
178
+ ' STAT="$TMPDIR/$LENS_ID.status"',
179
+ ' echo "ENV-BEFORE lens=$LENS_ID packet=$PACKET output=$OUTPUT" >> "$LOG"',
180
+ ` cat "$PACKET" | codex exec \\`,
181
+ " --sandbox danger-full-access \\",
182
+ " --skip-git-repo-check \\",
183
+ " --ephemeral \\",
184
+ ` -o "$OUTPUT"${modelOpt}${effortOpt}${serviceTierOpt} \\`,
185
+ ' - >> "$LOG" 2>&1',
186
+ ' EC=$?',
187
+ ' if [ -f "$OUTPUT" ]; then',
188
+ ' SIZE=$(wc -c < "$OUTPUT" | tr -d " ")',
189
+ " else",
190
+ ' SIZE=0',
191
+ " fi",
192
+ ' echo "ENV-AFTER lens=$LENS_ID exit=$EC output_bytes=$SIZE" >> "$LOG"',
193
+ ' if [ "$EC" = "0" ] && [ "$SIZE" -gt 0 ]; then',
194
+ ' printf \'{"lens_id":"%s","status":"ok"}\' "$LENS_ID" > "$STAT"',
195
+ " else",
196
+ ' printf \'{"lens_id":"%s","status":"fail","error":"exit=%s size=%s"}\' \\',
197
+ ' "$LENS_ID" "$EC" "$SIZE" > "$STAT"',
198
+ " fi",
199
+ " ) &",
200
+ "done",
201
+ "wait",
202
+ "",
203
+ "# Replay per-lens diagnostics to stdout so outer's captured stdout",
204
+ "# carries the ENV-BEFORE/AFTER lines (picked up later by parser tests",
205
+ "# and by log readers). The LOG at OUTPUT_DIR/.<lens>.running.log must",
206
+ "# survive until this replay; cleanup (rm for ok / mv for fail) happens",
207
+ "# AFTER replay so the chain `per-lens log → outer stdout →",
208
+ "# nested-outer-stdout.log` is actually complete.",
209
+ 'for entry in "${LENSES[@]}"; do',
210
+ ' IFS="|" read -r LENS_ID _ OUTPUT <<< "$entry"',
211
+ ' OUTPUT_DIR="$(dirname "$OUTPUT")"',
212
+ ' LOG="$OUTPUT_DIR/.$LENS_ID.running.log"',
213
+ ' STAT="$TMPDIR/$LENS_ID.status"',
214
+ ' if [ -f "$LOG" ]; then',
215
+ ' grep -E "^ENV-" "$LOG" || true',
216
+ " fi",
217
+ ' if [ -f "$STAT" ] && grep -q \'"status":"ok"\' "$STAT"; then',
218
+ " # Success — running log was already replayed; remove to keep the",
219
+ " # round1/ listing to principal-facing lens outputs only.",
220
+ ' rm -f "$LOG"',
221
+ " elif [ -f \"$LOG\" ]; then",
222
+ " # Failure (or unknown status) — persist running log at the audit",
223
+ " # path so post-hoc inspection survives outer dispatch exit.",
224
+ ' mv "$LOG" "$OUTPUT_DIR/.$LENS_ID.nested-stderr.log" 2>/dev/null || true',
225
+ " fi",
226
+ "done",
227
+ "",
228
+ "# Emit the summary sentinel. The array order matches the LENSES array,",
229
+ "# which matches the TS input order — the parser relies on this.",
230
+ "SUMMARY_PARTS=()",
231
+ 'for entry in "${LENSES[@]}"; do',
232
+ ' IFS="|" read -r LENS_ID _ _ <<< "$entry"',
233
+ ' SUMMARY_PARTS+=("$(cat "$TMPDIR/$LENS_ID.status")")',
234
+ "done",
235
+ 'OLDIFS="$IFS"; IFS=","; JOINED="${SUMMARY_PARTS[*]}"; IFS="$OLDIFS"',
236
+ `echo "${SUMMARY_SENTINEL_PREFIX}{\\"lens_results\\":[$JOINED]}"`,
237
+ ].join("\n");
238
+ }
239
+ /** POSIX-ish shell quoting for option values. */
240
+ function shellQuote(value) {
241
+ if (/^[A-Za-z0-9._:/@+\-]+$/.test(value))
242
+ return value;
243
+ return `'${value.replace(/'/g, `'\\''`)}'`;
244
+ }
245
+ /**
246
+ * Scan outer codex stdout for the `LENS_DISPATCH_SUMMARY:{...}` line.
247
+ * Tolerates leading/trailing whitespace and multiple summary lines
248
+ * (last-one-wins — the final reported state is what matters).
249
+ */
250
+ export function parseNestedTeamleadSummary(stdout) {
251
+ const lines = stdout.split("\n");
252
+ let lastSummary = null;
253
+ for (const line of lines) {
254
+ const trimmed = line.trim();
255
+ if (!trimmed.startsWith(SUMMARY_SENTINEL_PREFIX))
256
+ continue;
257
+ const jsonPart = trimmed.slice(SUMMARY_SENTINEL_PREFIX.length).trim();
258
+ try {
259
+ const parsed = JSON.parse(jsonPart);
260
+ if (typeof parsed === "object" &&
261
+ parsed !== null &&
262
+ "lens_results" in parsed &&
263
+ Array.isArray(parsed.lens_results)) {
264
+ lastSummary = parsed;
265
+ }
266
+ }
267
+ catch {
268
+ // Ignore malformed summary lines; continue searching for a later one.
269
+ }
270
+ }
271
+ return lastSummary;
272
+ }
273
+ /**
274
+ * Produce ordered outcomes from a parsed summary. Lens ids missing from
275
+ * the summary are reported as `fail` with a parse-failure reason — the
276
+ * outer codex is contractually required to report every lens, so absence
277
+ * is treated as teamlead noncompliance, not silent success.
278
+ */
279
+ function reconcileOutcomes(inputs, summary) {
280
+ if (!summary) {
281
+ return inputs.map((lens) => ({
282
+ lens_id: lens.lens_id,
283
+ status: "fail",
284
+ error: "outer codex did not emit a LENS_DISPATCH_SUMMARY line",
285
+ }));
286
+ }
287
+ const byId = new Map(summary.lens_results.map((r) => [r.lens_id, r]));
288
+ return inputs.map((lens) => {
289
+ const reported = byId.get(lens.lens_id);
290
+ if (!reported) {
291
+ return {
292
+ lens_id: lens.lens_id,
293
+ status: "fail",
294
+ error: `outer codex summary missing lens_id="${lens.lens_id}"`,
295
+ };
296
+ }
297
+ if (reported.status === "ok") {
298
+ return { lens_id: lens.lens_id, status: "ok" };
299
+ }
300
+ return {
301
+ lens_id: lens.lens_id,
302
+ status: "fail",
303
+ error: reported.error ?? "no error message reported",
304
+ };
305
+ });
306
+ }
307
+ /**
308
+ * Start the outer Codex worker with the orchestration prompt on
309
+ * stdin. Isolated from `runCodexNestedTeamlead` so tests can stub it.
310
+ */
311
+ export async function spawnOuterCodex(prompt, options) {
312
+ // Outer Codex must respect `.onto/settings.json` model / effort settings —
313
+ // otherwise it inherits `~/.codex/config.toml` defaults (often `xhigh`),
314
+ // which can drastically inflate outer teamlead runtime and hit the
315
+ // orchestration timeout before inner lens dispatch even begins.
316
+ const args = [
317
+ "exec",
318
+ "--sandbox",
319
+ "danger-full-access",
320
+ "--skip-git-repo-check",
321
+ "--ephemeral",
322
+ ];
323
+ if (options.reasoning_effort) {
324
+ args.push("-c", `model_reasoning_effort="${options.reasoning_effort}"`);
325
+ }
326
+ if (options.service_tier) {
327
+ args.push("-c", `service_tier="${options.service_tier}"`);
328
+ }
329
+ if (options.model) {
330
+ args.push("-m", options.model);
331
+ }
332
+ args.push("-");
333
+ const child = spawn(options.codex_bin, args, {
334
+ cwd: options.project_root,
335
+ stdio: ["pipe", "pipe", "pipe"],
336
+ });
337
+ // Real-time tee to disk: chunks land on the on-disk log as codex emits
338
+ // them, which is what lets `tail -f` in the watcher pane render progress
339
+ // live. The in-memory buffers remain the source of truth for the final
340
+ // archive / summary parse.
341
+ const stdoutStream = options.stream_stdout_path
342
+ ? fs.createWriteStream(options.stream_stdout_path, { flags: "w" })
343
+ : null;
344
+ const stderrStream = options.stream_stderr_path
345
+ ? fs.createWriteStream(options.stream_stderr_path, { flags: "w" })
346
+ : null;
347
+ let stdout = "";
348
+ let stderr = "";
349
+ child.stdout.on("data", (chunk) => {
350
+ stdout += String(chunk);
351
+ if (stdoutStream)
352
+ stdoutStream.write(chunk);
353
+ });
354
+ child.stderr.on("data", (chunk) => {
355
+ stderr += String(chunk);
356
+ if (stderrStream)
357
+ stderrStream.write(chunk);
358
+ });
359
+ child.stdin.write(prompt);
360
+ child.stdin.end();
361
+ let timedOut = false;
362
+ const timer = setTimeout(() => {
363
+ timedOut = true;
364
+ child.kill("SIGKILL");
365
+ }, options.timeout_ms);
366
+ const exitCode = await new Promise((resolve, reject) => {
367
+ child.on("error", (err) => {
368
+ clearTimeout(timer);
369
+ if (err.code === "ENOENT") {
370
+ reject(new Error(`codex binary not found at "${options.codex_bin}". ` +
371
+ "Install codex and run `codex login`, or set a non-default codex_bin."));
372
+ }
373
+ else {
374
+ reject(err);
375
+ }
376
+ });
377
+ child.on("close", (code) => {
378
+ clearTimeout(timer);
379
+ resolve(code ?? 1);
380
+ });
381
+ });
382
+ // Flush & close real-time tee streams before returning. Calling .end()
383
+ // only requests flush — the actual on-disk write may still be pending
384
+ // in the Node stream's internal buffer. Await the `finish` event so
385
+ // downstream code (archiveOuterStreamsIfMissing) that stats these files
386
+ // sees their final size, not a partially flushed snapshot (4th self-
387
+ // review Immediate Action #1: stream finalization barrier).
388
+ await Promise.all([
389
+ awaitStreamFinish(stdoutStream),
390
+ awaitStreamFinish(stderrStream),
391
+ ]);
392
+ return { stdout, stderr, exit_code: exitCode, timed_out: timedOut };
393
+ }
394
+ function awaitStreamFinish(stream) {
395
+ if (!stream)
396
+ return Promise.resolve();
397
+ return new Promise((resolve) => {
398
+ // `finish` fires after the writable side drains AND after all bytes
399
+ // are flushed to the underlying resource. `end()` without this await
400
+ // returns before `fs.stat` would see the final size.
401
+ stream.once("finish", () => resolve());
402
+ stream.once("error", () => resolve()); // best-effort: don't block on write errors
403
+ stream.end();
404
+ });
405
+ }
406
+ /**
407
+ * Run the nested-workers Codex path for the given lens packet set.
408
+ *
409
+ * Errors are classified, not thrown:
410
+ * - Outer codex spawn failure (ENOENT) → throws
411
+ * - Outer codex timeout → all lens outcomes `fail` with timeout reason
412
+ * - Outer codex exit non-zero → all unsatisfied lenses `fail` with outer stderr
413
+ * - Summary parse failure → all lens outcomes `fail` with parse reason
414
+ * - Per-lens `fail` in summary → that lens outcome `fail` with its reported reason
415
+ *
416
+ * Returns a `CodexNestedTeamleadResult` regardless of per-lens success.
417
+ */
418
+ export async function runCodexNestedTeamlead(input, spawnImpl = spawnOuterCodex) {
419
+ const prompt = buildNestedTeamleadPrompt(input);
420
+ const spawned = await spawnImpl(prompt, {
421
+ codex_bin: input.codex_bin ?? "codex",
422
+ project_root: input.project_root ?? process.cwd(),
423
+ timeout_ms: input.timeout_ms ?? 600_000,
424
+ ...(input.teamlead_model ? { model: input.teamlead_model } : {}),
425
+ ...(input.teamlead_reasoning_effort
426
+ ? { reasoning_effort: input.teamlead_reasoning_effort }
427
+ : {}),
428
+ ...(input.teamlead_service_tier
429
+ ? { service_tier: input.teamlead_service_tier }
430
+ : {}),
431
+ ...(input.stream_stdout_path
432
+ ? { stream_stdout_path: input.stream_stdout_path }
433
+ : {}),
434
+ ...(input.stream_stderr_path
435
+ ? { stream_stderr_path: input.stream_stderr_path }
436
+ : {}),
437
+ });
438
+ if (spawned.timed_out) {
439
+ return {
440
+ outcomes: input.lenses.map((lens) => ({
441
+ lens_id: lens.lens_id,
442
+ status: "fail",
443
+ error: `outer codex timed out after ${input.timeout_ms ?? 600_000} ms`,
444
+ })),
445
+ outer_stdout: spawned.stdout,
446
+ outer_stderr: spawned.stderr,
447
+ outer_exit_code: spawned.exit_code,
448
+ summary_parsed: false,
449
+ };
450
+ }
451
+ const summary = parseNestedTeamleadSummary(spawned.stdout);
452
+ const outcomes = reconcileOutcomes(input.lenses, summary);
453
+ // When outer exit is non-zero but summary was parse-able, trust the
454
+ // per-lens summary — it's more granular than a blanket exit code.
455
+ // When outer exit is non-zero AND summary is null, the reconcile step
456
+ // already marked all lenses as fail.
457
+ return {
458
+ outcomes,
459
+ outer_stdout: spawned.stdout,
460
+ outer_stderr: spawned.stderr,
461
+ outer_exit_code: spawned.exit_code,
462
+ summary_parsed: summary !== null,
463
+ };
464
+ }