@kbediako/codex-orchestrator 0.1.38 → 0.2.1

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 (311) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/README.md +46 -317
  3. package/bin/codex-orchestrator.js +161 -0
  4. package/codex.orchestrator.json +149 -13
  5. package/dist/bin/codex-orchestrator.js +797 -1154
  6. package/dist/orchestrator/src/cli/adapters/CommandBuilder.js +50 -0
  7. package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
  8. package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
  9. package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
  10. package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +295 -11
  11. package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
  12. package/dist/orchestrator/src/cli/coStatusCliShell.js +451 -0
  13. package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
  14. package/dist/orchestrator/src/cli/codexCliShell.js +119 -0
  15. package/dist/orchestrator/src/cli/codexDefaultsSetup.js +265 -36
  16. package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
  17. package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
  18. package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
  19. package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
  20. package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
  21. package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
  22. package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
  23. package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
  24. package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
  25. package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
  26. package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
  27. package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
  28. package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
  29. package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
  30. package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
  31. package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
  32. package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
  33. package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
  34. package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
  35. package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
  36. package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
  37. package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
  38. package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
  39. package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
  40. package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
  41. package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
  42. package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
  43. package/dist/orchestrator/src/cli/control/controlHostSupervision.js +630 -0
  44. package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
  45. package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
  46. package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
  47. package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
  48. package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
  49. package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
  50. package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
  51. package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
  52. package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
  53. package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
  54. package/dist/orchestrator/src/cli/control/controlRuntime.js +1003 -0
  55. package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
  56. package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
  57. package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
  58. package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
  59. package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
  60. package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
  61. package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
  62. package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
  63. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
  64. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
  65. package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
  66. package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
  67. package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
  68. package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
  69. package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
  70. package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
  71. package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
  72. package/dist/orchestrator/src/cli/control/controlState.js +233 -2
  73. package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1904 -0
  74. package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
  75. package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
  76. package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
  77. package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
  78. package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
  79. package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
  80. package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
  81. package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
  82. package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
  83. package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
  84. package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
  85. package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
  86. package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
  87. package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
  88. package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
  89. package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
  90. package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
  91. package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
  92. package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
  93. package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
  94. package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
  95. package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
  96. package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
  97. package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
  98. package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
  99. package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
  100. package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
  101. package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
  102. package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
  103. package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
  104. package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
  105. package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
  106. package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
  107. package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
  108. package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
  109. package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
  110. package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
  111. package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
  112. package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
  113. package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
  114. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
  115. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
  116. package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
  117. package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
  118. package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
  119. package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
  120. package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
  121. package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
  122. package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
  123. package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
  124. package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
  125. package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1885 -0
  126. package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
  127. package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
  128. package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
  129. package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
  130. package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
  131. package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
  132. package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
  133. package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
  134. package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
  135. package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
  136. package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
  137. package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
  138. package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
  139. package/dist/orchestrator/src/cli/delegationServer.js +567 -678
  140. package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
  141. package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
  142. package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
  143. package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
  144. package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
  145. package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
  146. package/dist/orchestrator/src/cli/doctor.js +678 -164
  147. package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
  148. package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
  149. package/dist/orchestrator/src/cli/doctorUsage.js +119 -15
  150. package/dist/orchestrator/src/cli/exec/experience.js +16 -2
  151. package/dist/orchestrator/src/cli/exec/summary.js +3 -0
  152. package/dist/orchestrator/src/cli/execCliShell.js +51 -0
  153. package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
  154. package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
  155. package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
  156. package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
  157. package/dist/orchestrator/src/cli/init.js +95 -1
  158. package/dist/orchestrator/src/cli/initCliShell.js +50 -0
  159. package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
  160. package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
  161. package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
  162. package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
  163. package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
  164. package/dist/orchestrator/src/cli/planCliShell.js +19 -0
  165. package/dist/orchestrator/src/cli/prCliShell.js +41 -0
  166. package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
  167. package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1835 -0
  168. package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
  169. package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
  170. package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +6834 -0
  171. package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
  172. package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
  173. package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
  174. package/dist/orchestrator/src/cli/rlm/context.js +94 -7
  175. package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
  176. package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
  177. package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
  178. package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
  179. package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
  180. package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
  181. package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
  182. package/dist/orchestrator/src/cli/run/manifest.js +410 -73
  183. package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
  184. package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
  185. package/dist/orchestrator/src/cli/run/source0.js +690 -0
  186. package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
  187. package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
  188. package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
  189. package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
  190. package/dist/orchestrator/src/cli/services/commandRunner.js +698 -18
  191. package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
  192. package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
  193. package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
  194. package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
  195. package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
  196. package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
  197. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
  198. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
  199. package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
  200. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
  201. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
  202. package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
  203. package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
  204. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
  205. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
  206. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
  207. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
  208. package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
  209. package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
  210. package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
  211. package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
  212. package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
  213. package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
  214. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
  215. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
  216. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
  217. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
  218. package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
  219. package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
  220. package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
  221. package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
  222. package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
  223. package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
  224. package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
  225. package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
  226. package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
  227. package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
  228. package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
  229. package/dist/orchestrator/src/cli/startCliShell.js +68 -0
  230. package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
  231. package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
  232. package/dist/orchestrator/src/cli/utils/cloudPreflight.js +285 -7
  233. package/dist/orchestrator/src/cli/utils/codexFeatures.js +60 -0
  234. package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
  235. package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
  236. package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
  237. package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
  238. package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
  239. package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
  240. package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
  241. package/dist/orchestrator/src/learning/crystalizer.js +2 -2
  242. package/dist/orchestrator/src/manager.js +74 -4
  243. package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
  244. package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
  245. package/dist/orchestrator/src/persistence/lockFile.js +70 -4
  246. package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
  247. package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
  248. package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
  249. package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
  250. package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
  251. package/dist/packages/sdk-node/src/orchestrator.js +137 -13
  252. package/dist/packages/shared/config/designConfig.js +8 -1
  253. package/dist/packages/shared/streams/stdio.js +1 -1
  254. package/dist/scripts/design/pipeline/permit.js +15 -0
  255. package/dist/scripts/lib/docs-catalog.js +399 -0
  256. package/dist/scripts/lib/docs-helpers.js +87 -5
  257. package/dist/scripts/lib/pr-watch-merge.js +1088 -80
  258. package/dist/scripts/lib/provider-run-contract.js +26 -0
  259. package/dist/scripts/lib/review-command-intent-classification.js +532 -0
  260. package/dist/scripts/lib/review-command-probe-classification.js +385 -0
  261. package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
  262. package/dist/scripts/lib/review-execution-runtime.js +753 -0
  263. package/dist/scripts/lib/review-execution-state.js +1144 -0
  264. package/dist/scripts/lib/review-execution-telemetry.js +215 -0
  265. package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
  266. package/dist/scripts/lib/review-launch-attempt.js +601 -0
  267. package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
  268. package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
  269. package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
  270. package/dist/scripts/lib/review-prompt-context.js +376 -0
  271. package/dist/scripts/lib/review-scope-advisory.js +286 -0
  272. package/dist/scripts/lib/review-scope-paths.js +123 -0
  273. package/dist/scripts/lib/review-shell-command-parser.js +389 -0
  274. package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
  275. package/dist/scripts/lib/run-manifests.js +192 -36
  276. package/dist/scripts/lib/spark-policy-classifier.js +593 -0
  277. package/dist/scripts/run-review.js +507 -1777
  278. package/docs/README.md +43 -20
  279. package/docs/book/README.md +19 -0
  280. package/docs/book/codex-cli-0124-adoption.md +68 -0
  281. package/docs/book/local-hook-impact.md +73 -0
  282. package/docs/book/operations.md +60 -0
  283. package/docs/book/public-posture.md +34 -0
  284. package/docs/book/setup.md +91 -0
  285. package/docs/book/skills.md +11 -0
  286. package/docs/guides/codex-version-policy.md +104 -0
  287. package/docs/public/downstream-setup.md +113 -0
  288. package/docs/public/provider-onboarding.md +173 -0
  289. package/package.json +23 -10
  290. package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
  291. package/plugins/codex-orchestrator/.mcp.json +13 -0
  292. package/plugins/codex-orchestrator/launcher.mjs +361 -0
  293. package/schemas/manifest.json +411 -0
  294. package/skills/README.md +26 -0
  295. package/skills/collab-subagents-first/SKILL.md +1 -1
  296. package/skills/delegation-usage/DELEGATION_GUIDE.md +30 -12
  297. package/skills/delegation-usage/SKILL.md +25 -14
  298. package/skills/land/SKILL.md +77 -0
  299. package/skills/linear/SKILL.md +255 -0
  300. package/skills/release/SKILL.md +47 -3
  301. package/skills/standalone-review/SKILL.md +6 -1
  302. package/templates/README.md +4 -2
  303. package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
  304. package/templates/codex/.codex/agents/worker-complex.toml +1 -1
  305. package/templates/codex/.codex/config.toml +3 -4
  306. package/templates/codex/.codex/providers/README.md +13 -0
  307. package/templates/codex/.codex/providers/control.example.json +18 -0
  308. package/templates/codex/.codex/providers/provider.env.example +15 -0
  309. package/templates/codex/AGENTS.md +15 -8
  310. package/templates/codex/mcp-client.json +5 -1
  311. package/docs/assets/setup.gif +0 -0
@@ -0,0 +1,753 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createWriteStream } from 'node:fs';
3
+ import { ReviewExecutionState } from './review-execution-state.js';
4
+ const BENIGN_STDIO_ERROR_CODES = new Set(['EPIPE', 'ERR_STREAM_DESTROYED']);
5
+ const REVIEW_ALLOW_HEAVY_COMMANDS_ENV_KEY = 'CODEX_REVIEW_ALLOW_HEAVY_COMMANDS';
6
+ const REVIEW_LOW_SIGNAL_TIMEOUT_ENV_KEY = 'CODEX_REVIEW_LOW_SIGNAL_TIMEOUT_SECONDS';
7
+ const REVIEW_VERDICT_STABILITY_TIMEOUT_ENV_KEY = 'CODEX_REVIEW_VERDICT_STABILITY_TIMEOUT_SECONDS';
8
+ const REVIEW_META_SURFACE_TIMEOUT_ENV_KEY = 'CODEX_REVIEW_META_SURFACE_TIMEOUT_SECONDS';
9
+ const REVIEW_TELEMETRY_DEBUG_ENV_KEY = 'CODEX_REVIEW_DEBUG_TELEMETRY';
10
+ export class CodexReviewError extends Error {
11
+ exitCode;
12
+ signal;
13
+ timedOut;
14
+ outputPreview;
15
+ reviewState;
16
+ terminationBoundary;
17
+ constructor(message, options) {
18
+ super(message);
19
+ this.name = 'CodexReviewError';
20
+ this.exitCode = options.exitCode;
21
+ this.signal = options.signal;
22
+ this.timedOut = options.timedOut;
23
+ this.outputPreview = options.outputPreview;
24
+ this.reviewState = options.reviewState ?? null;
25
+ this.terminationBoundary = options.terminationBoundary ?? null;
26
+ }
27
+ }
28
+ function installSignalForwarders(child, detached) {
29
+ const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
30
+ const handlers = new Map();
31
+ const uninstall = () => {
32
+ for (const [signal, handler] of handlers.entries()) {
33
+ process.removeListener(signal, handler);
34
+ }
35
+ handlers.clear();
36
+ };
37
+ for (const signal of signals) {
38
+ const handler = () => {
39
+ signalChildProcess(child, signal, detached);
40
+ uninstall();
41
+ try {
42
+ process.kill(process.pid, signal);
43
+ }
44
+ catch {
45
+ process.exitCode = signal === 'SIGINT' ? 130 : 143;
46
+ }
47
+ };
48
+ handlers.set(signal, handler);
49
+ process.once(signal, handler);
50
+ }
51
+ return uninstall;
52
+ }
53
+ function writeToStreamSafely(target, chunk) {
54
+ if (target.destroyed || target.writableEnded) {
55
+ return;
56
+ }
57
+ try {
58
+ target.write(chunk, (error) => {
59
+ if (!error) {
60
+ return;
61
+ }
62
+ const code = error?.code;
63
+ if (typeof code === 'string' && BENIGN_STDIO_ERROR_CODES.has(code)) {
64
+ return;
65
+ }
66
+ // Best effort only; stdout/stderr mirroring should not fail the run.
67
+ });
68
+ }
69
+ catch (error) {
70
+ const code = error?.code;
71
+ if (typeof code === 'string' && BENIGN_STDIO_ERROR_CODES.has(code)) {
72
+ return;
73
+ }
74
+ throw error;
75
+ }
76
+ }
77
+ export async function runCodexReview(options) {
78
+ const detached = process.platform !== 'win32';
79
+ const child = spawn(options.command, options.args, {
80
+ stdio: options.stdio,
81
+ env: options.env,
82
+ cwd: options.repoRoot,
83
+ detached
84
+ });
85
+ const outputStream = createWriteStream(options.outputLogPath, { flags: 'w' });
86
+ const outputClosed = new Promise((resolve) => {
87
+ outputStream.once('close', () => resolve());
88
+ outputStream.once('error', () => resolve());
89
+ });
90
+ const uninstallSignalForwarders = installSignalForwarders(child, detached);
91
+ const executionState = new ReviewExecutionState({
92
+ blockHeavyCommands: options.blockHeavyCommands,
93
+ allowValidationCommandIntents: options.allowValidationCommandIntents,
94
+ activeCloseoutBundleRoots: options.activeCloseoutBundleRoots,
95
+ lowSignalTimeoutMs: options.lowSignalTimeoutMs,
96
+ verdictStabilityTimeoutMs: options.verdictStabilityTimeoutMs,
97
+ metaSurfaceTimeoutMs: options.metaSurfaceTimeoutMs,
98
+ enforceStartupAnchorBoundary: options.enforceStartupAnchorBoundary,
99
+ enforceActiveCloseoutBundleRereadBoundary: options.enforceActiveCloseoutBundleRereadBoundary,
100
+ enforceRelevantReinspectionDwellBoundary: options.enforceRelevantReinspectionDwellBoundary,
101
+ allowedMetaSurfaceKinds: options.allowedMetaSurfaceKinds,
102
+ scopeMode: options.scopeMode,
103
+ startupAnchorMode: options.startupAnchorMode,
104
+ auditStartupAnchorPaths: options.auditStartupAnchorPaths,
105
+ allowedMetaSurfacePaths: options.allowedMetaSurfacePaths,
106
+ auditStartupAnchorEnvVarPaths: options.auditStartupAnchorEnvVarPaths,
107
+ allowedMetaSurfaceEnvVarPaths: options.allowedMetaSurfaceEnvVarPaths,
108
+ repoRoot: options.repoRoot,
109
+ touchedPaths: options.touchedPaths
110
+ });
111
+ const capture = (chunk, target, stream) => {
112
+ if (!outputStream.writableEnded && !outputStream.destroyed) {
113
+ outputStream.write(chunk);
114
+ }
115
+ writeToStreamSafely(target, chunk);
116
+ executionState.observeChunk(chunk, stream);
117
+ };
118
+ const onStdout = (chunk) => capture(chunk, process.stdout, 'stdout');
119
+ const onStderr = (chunk) => capture(chunk, process.stderr, 'stderr');
120
+ child.stdout?.on('data', onStdout);
121
+ child.stderr?.on('data', onStderr);
122
+ const outputDrainPromise = Promise.all([
123
+ waitForReadableClosure(child.stdout),
124
+ waitForReadableClosure(child.stderr)
125
+ ]).then(() => undefined);
126
+ let cleanedUp = false;
127
+ const cleanup = () => {
128
+ if (cleanedUp) {
129
+ return;
130
+ }
131
+ cleanedUp = true;
132
+ uninstallSignalForwarders();
133
+ child.stdout?.off('data', onStdout);
134
+ child.stderr?.off('data', onStderr);
135
+ try {
136
+ outputStream.end();
137
+ }
138
+ catch {
139
+ // ignore best-effort close
140
+ }
141
+ };
142
+ try {
143
+ const terminationBoundary = await waitForChildExit(child, {
144
+ timeoutMs: options.timeoutMs,
145
+ stallTimeoutMs: options.stallTimeoutMs,
146
+ startupLoopTimeoutMs: options.startupLoopTimeoutMs,
147
+ startupLoopMinEvents: options.startupLoopMinEvents,
148
+ monitorIntervalMs: options.monitorIntervalMs,
149
+ lowSignalTimeoutMs: options.lowSignalTimeoutMs,
150
+ verdictStabilityTimeoutMs: options.verdictStabilityTimeoutMs,
151
+ metaSurfaceTimeoutMs: options.metaSurfaceTimeoutMs,
152
+ enforceStartupAnchorBoundary: options.enforceStartupAnchorBoundary,
153
+ enforceActiveCloseoutBundleRereadBoundary: options.enforceActiveCloseoutBundleRereadBoundary,
154
+ enforceRelevantReinspectionDwellBoundary: options.enforceRelevantReinspectionDwellBoundary,
155
+ blockHeavyCommands: options.blockHeavyCommands,
156
+ getLastOutputAtMs: () => executionState.getLastOutputAtMs(),
157
+ getStartupLoopState: () => executionState.getStartupLoopState(),
158
+ getBlockedHeavyCommand: () => executionState.getBlockedHeavyCommand(),
159
+ getLowSignalDriftReason: () => executionState.getLowSignalDriftState().reason,
160
+ getVerdictStabilityState: () => executionState.getVerdictStabilityState(),
161
+ getMetaSurfaceExpansionReason: () => executionState.getMetaSurfaceExpansionState().reason,
162
+ getStartupAnchorBoundaryState: () => executionState.getStartupAnchorBoundaryState(),
163
+ getActiveCloseoutBundleRereadBoundaryState: () => executionState.getActiveCloseoutBundleRereadBoundaryState(),
164
+ getRelevantReinspectionDwellBoundaryState: () => executionState.getRelevantReinspectionDwellBoundaryState(),
165
+ getCommandIntentBoundaryState: () => executionState.getCommandIntentBoundaryState(),
166
+ getShellProbeBoundaryState: () => executionState.getShellProbeBoundaryState(),
167
+ getTerminationBoundaryRecord: (kind) => executionState.getTerminationBoundaryRecordForKind(kind),
168
+ waitForOutputDrain: () => outputDrainPromise,
169
+ formatCheckpoint: () => executionState.formatCheckpoint(),
170
+ detached,
171
+ onCleanup: cleanup
172
+ });
173
+ await outputClosed;
174
+ return {
175
+ preview: executionState.getPreview(),
176
+ state: executionState,
177
+ terminationBoundary
178
+ };
179
+ }
180
+ catch (error) {
181
+ cleanup();
182
+ await outputClosed;
183
+ if (error instanceof CodexReviewError) {
184
+ error.outputPreview = executionState.getPreview() || error.outputPreview;
185
+ error.reviewState = executionState;
186
+ throw error;
187
+ }
188
+ const wrappedError = new CodexReviewError(error instanceof Error ? error.message : String(error), {
189
+ exitCode: null,
190
+ signal: null,
191
+ timedOut: false,
192
+ outputPreview: executionState.getPreview(),
193
+ reviewState: executionState
194
+ });
195
+ if (error instanceof Error && 'cause' in Error.prototype) {
196
+ Object.defineProperty(wrappedError, 'cause', {
197
+ value: error,
198
+ configurable: true,
199
+ enumerable: false,
200
+ writable: true
201
+ });
202
+ }
203
+ throw wrappedError;
204
+ }
205
+ }
206
+ function waitForReadableClosure(stream) {
207
+ if (!stream) {
208
+ return Promise.resolve();
209
+ }
210
+ const readable = stream;
211
+ if (readable.readableEnded || readable.destroyed) {
212
+ return Promise.resolve();
213
+ }
214
+ return new Promise((resolve) => {
215
+ const finish = () => {
216
+ readable.off('end', finish);
217
+ readable.off('close', finish);
218
+ readable.off('error', finish);
219
+ resolve();
220
+ };
221
+ readable.once('end', finish);
222
+ readable.once('close', finish);
223
+ readable.once('error', finish);
224
+ });
225
+ }
226
+ async function waitForOutputSettlement(getLastOutputAtMs) {
227
+ let lastOutputAtMs = getLastOutputAtMs();
228
+ let stablePasses = 0;
229
+ for (let attempt = 0; attempt < 8; attempt += 1) {
230
+ await new Promise((resolve) => setTimeout(resolve, 25));
231
+ const currentLastOutputAtMs = getLastOutputAtMs();
232
+ if (currentLastOutputAtMs === lastOutputAtMs) {
233
+ stablePasses += 1;
234
+ if (stablePasses >= 2) {
235
+ return;
236
+ }
237
+ continue;
238
+ }
239
+ lastOutputAtMs = currentLastOutputAtMs;
240
+ stablePasses = 0;
241
+ }
242
+ }
243
+ function envFlagEnabled(value) {
244
+ if (!value) {
245
+ return false;
246
+ }
247
+ const normalized = value.trim().toLowerCase();
248
+ return normalized === '1' || normalized === 'true' || normalized === 'yes';
249
+ }
250
+ function formatBoundedHeavyCommandFailure(blockedCommand) {
251
+ const guidance = `Set ${REVIEW_ALLOW_HEAVY_COMMANDS_ENV_KEY}=1 to allow full validation commands.`;
252
+ if (!envFlagEnabled(process.env[REVIEW_TELEMETRY_DEBUG_ENV_KEY])) {
253
+ return `codex review attempted heavy command in bounded mode. ${guidance}`;
254
+ }
255
+ return `codex review attempted heavy command in bounded mode: ${blockedCommand}. ${guidance}`;
256
+ }
257
+ function formatCommandIntentBoundaryFailure(boundaryState) {
258
+ const guidance = 'Bounded review should inspect and report, not launch explicit validation suites, direct validation runners, nested review flows, or mutating delegation control.';
259
+ if (!boundaryState.violationKind) {
260
+ return `codex review crossed the bounded command-intent boundary. ${guidance}`;
261
+ }
262
+ const kindLabel = boundaryState.violationKind === 'validation-suite'
263
+ ? 'validation suite launch'
264
+ : boundaryState.violationKind === 'validation-runner'
265
+ ? 'direct validation runner launch'
266
+ : boundaryState.violationKind === 'review-orchestration'
267
+ ? 'nested review or pipeline launch'
268
+ : 'delegation control activity';
269
+ if (!envFlagEnabled(process.env[REVIEW_TELEMETRY_DEBUG_ENV_KEY]) ||
270
+ !boundaryState.violationSample) {
271
+ return `codex review crossed the bounded command-intent boundary (${kindLabel}). ${guidance}`;
272
+ }
273
+ return `codex review crossed the bounded command-intent boundary (${kindLabel}): ${boundaryState.violationSample}. ${guidance}`;
274
+ }
275
+ const SIGTERM_EXIT_CODE = 128 + 15;
276
+ function isAcceptableSuccessfulBoundaryExit(code, signal, requestedTermination) {
277
+ if (code === 0) {
278
+ return true;
279
+ }
280
+ if (!requestedTermination) {
281
+ return false;
282
+ }
283
+ return signal === 'SIGTERM' || code === SIGTERM_EXIT_CODE;
284
+ }
285
+ function formatExitOutcome(code, signal) {
286
+ if (typeof code === 'number') {
287
+ return signal ? `code ${code} (signal ${signal})` : `code ${code}`;
288
+ }
289
+ if (signal) {
290
+ return `signal ${signal}`;
291
+ }
292
+ return 'without a clean exit signal';
293
+ }
294
+ function buildSuccessfulBoundaryExitFailure(code, signal, terminationBoundary) {
295
+ return new CodexReviewError(`codex review reached a bounded success stop but exited with ${formatExitOutcome(code, signal)}`, {
296
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
297
+ signal,
298
+ timedOut: false,
299
+ outputPreview: '',
300
+ terminationBoundary
301
+ });
302
+ }
303
+ async function waitForChildExit(child, options) {
304
+ return await new Promise((resolve, reject) => {
305
+ let settled = false;
306
+ let handlesCleared = false;
307
+ let cleanupCompleted = false;
308
+ let pendingTermination = null;
309
+ let pendingSuccessfulTerminationBoundary = null;
310
+ let timeoutHandle;
311
+ let stallHandle;
312
+ let startupLoopHandle;
313
+ let monitorHandle;
314
+ let lowSignalHandle;
315
+ let verdictStabilityHandle;
316
+ let metaSurfaceHandle;
317
+ let startupAnchorHandle;
318
+ let activeCloseoutBundleHandle;
319
+ let relevantReinspectionHandle;
320
+ let commandIntentHandle;
321
+ let shellProbeHandle;
322
+ let heavyCommandHandle;
323
+ let killHandle;
324
+ let hardKillArmed = false;
325
+ const startMs = Date.now();
326
+ const clearHandles = () => {
327
+ if (handlesCleared) {
328
+ return;
329
+ }
330
+ handlesCleared = true;
331
+ if (timeoutHandle) {
332
+ clearTimeout(timeoutHandle);
333
+ }
334
+ if (stallHandle) {
335
+ clearInterval(stallHandle);
336
+ }
337
+ if (startupLoopHandle) {
338
+ clearInterval(startupLoopHandle);
339
+ }
340
+ if (monitorHandle) {
341
+ clearInterval(monitorHandle);
342
+ }
343
+ if (lowSignalHandle) {
344
+ clearInterval(lowSignalHandle);
345
+ }
346
+ if (verdictStabilityHandle) {
347
+ clearInterval(verdictStabilityHandle);
348
+ }
349
+ if (metaSurfaceHandle) {
350
+ clearInterval(metaSurfaceHandle);
351
+ }
352
+ if (startupAnchorHandle) {
353
+ clearInterval(startupAnchorHandle);
354
+ }
355
+ if (activeCloseoutBundleHandle) {
356
+ clearInterval(activeCloseoutBundleHandle);
357
+ }
358
+ if (relevantReinspectionHandle) {
359
+ clearInterval(relevantReinspectionHandle);
360
+ }
361
+ if (commandIntentHandle) {
362
+ clearInterval(commandIntentHandle);
363
+ }
364
+ if (shellProbeHandle) {
365
+ clearInterval(shellProbeHandle);
366
+ }
367
+ if (heavyCommandHandle) {
368
+ clearInterval(heavyCommandHandle);
369
+ }
370
+ if (killHandle) {
371
+ clearTimeout(killHandle);
372
+ killHandle = undefined;
373
+ }
374
+ child.removeListener('error', onError);
375
+ child.removeListener('close', onClose);
376
+ };
377
+ const cleanup = () => {
378
+ if (cleanupCompleted) {
379
+ return;
380
+ }
381
+ cleanupCompleted = true;
382
+ clearHandles();
383
+ options.onCleanup?.();
384
+ };
385
+ const settleWithError = (error) => {
386
+ if (settled) {
387
+ return;
388
+ }
389
+ settled = true;
390
+ cleanup();
391
+ reject(error);
392
+ };
393
+ const onError = (error) => {
394
+ settleWithError(error instanceof Error ? error : new Error(String(error)));
395
+ };
396
+ const onClose = (code, signal) => {
397
+ if (settled) {
398
+ return;
399
+ }
400
+ settled = true;
401
+ clearHandles();
402
+ void (async () => {
403
+ try {
404
+ await options.waitForOutputDrain();
405
+ }
406
+ catch {
407
+ // Best-effort drain only; fall through to current runtime state.
408
+ }
409
+ await waitForOutputSettlement(options.getLastOutputAtMs);
410
+ cleanup();
411
+ if (pendingTermination) {
412
+ reject(pendingTermination);
413
+ return;
414
+ }
415
+ const commandIntentBoundaryState = options.getCommandIntentBoundaryState();
416
+ if (commandIntentBoundaryState.triggered) {
417
+ reject(new CodexReviewError(formatCommandIntentBoundaryFailure(commandIntentBoundaryState), {
418
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
419
+ signal,
420
+ timedOut: false,
421
+ outputPreview: '',
422
+ terminationBoundary: options.getTerminationBoundaryRecord('command-intent')
423
+ }));
424
+ return;
425
+ }
426
+ const startupAnchorBoundaryState = options.getStartupAnchorBoundaryState();
427
+ if (startupAnchorBoundaryState.triggered) {
428
+ reject(new CodexReviewError(startupAnchorBoundaryState.reason ?? 'bounded review startup-anchor boundary violated', {
429
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
430
+ signal,
431
+ timedOut: false,
432
+ outputPreview: '',
433
+ terminationBoundary: options.getTerminationBoundaryRecord('startup-anchor')
434
+ }));
435
+ return;
436
+ }
437
+ if (options.enforceActiveCloseoutBundleRereadBoundary) {
438
+ const activeCloseoutBundleBoundaryState = options.getActiveCloseoutBundleRereadBoundaryState();
439
+ if (activeCloseoutBundleBoundaryState.triggered) {
440
+ reject(new CodexReviewError(activeCloseoutBundleBoundaryState.reason ??
441
+ 'bounded review active-closeout-bundle reread boundary violated', {
442
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
443
+ signal,
444
+ timedOut: false,
445
+ outputPreview: '',
446
+ terminationBoundary: options.getTerminationBoundaryRecord('active-closeout-bundle-reread')
447
+ }));
448
+ return;
449
+ }
450
+ }
451
+ if (options.enforceRelevantReinspectionDwellBoundary) {
452
+ const relevantReinspectionBoundaryState = options.getRelevantReinspectionDwellBoundaryState();
453
+ if (relevantReinspectionBoundaryState.triggered) {
454
+ const relevantReinspectionBoundary = pendingSuccessfulTerminationBoundary ??
455
+ options.getTerminationBoundaryRecord('relevant-reinspection-dwell');
456
+ if (relevantReinspectionBoundaryState.anchorObserved) {
457
+ if (isAcceptableSuccessfulBoundaryExit(code, signal, pendingSuccessfulTerminationBoundary !== null)) {
458
+ pendingSuccessfulTerminationBoundary = relevantReinspectionBoundary;
459
+ }
460
+ else {
461
+ reject(buildSuccessfulBoundaryExitFailure(code, signal, relevantReinspectionBoundary));
462
+ return;
463
+ }
464
+ }
465
+ else {
466
+ reject(new CodexReviewError(relevantReinspectionBoundaryState.reason ??
467
+ 'bounded review relevant-reinspection dwell boundary violated', {
468
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
469
+ signal,
470
+ timedOut: false,
471
+ outputPreview: '',
472
+ terminationBoundary: relevantReinspectionBoundary
473
+ }));
474
+ return;
475
+ }
476
+ }
477
+ }
478
+ const verdictStabilityState = options.getVerdictStabilityState();
479
+ if (verdictStabilityState.triggered) {
480
+ reject(new CodexReviewError(verdictStabilityState.reason ?? 'bounded review verdict-stability drift detected', {
481
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
482
+ signal,
483
+ timedOut: false,
484
+ outputPreview: '',
485
+ terminationBoundary: options.getTerminationBoundaryRecord('verdict-stability')
486
+ }));
487
+ return;
488
+ }
489
+ const shellProbeBoundaryState = options.getShellProbeBoundaryState();
490
+ if (shellProbeBoundaryState.triggered) {
491
+ reject(new CodexReviewError(shellProbeBoundaryState.reason ?? 'bounded review shell-probe boundary violated', {
492
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
493
+ signal,
494
+ timedOut: false,
495
+ outputPreview: '',
496
+ terminationBoundary: options.getTerminationBoundaryRecord('shell-probe')
497
+ }));
498
+ return;
499
+ }
500
+ const metaSurfaceReason = options.getMetaSurfaceExpansionReason();
501
+ if (metaSurfaceReason) {
502
+ reject(new CodexReviewError(`${metaSurfaceReason} (set ${REVIEW_META_SURFACE_TIMEOUT_ENV_KEY}=0 to disable).`, {
503
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
504
+ signal,
505
+ timedOut: false,
506
+ outputPreview: '',
507
+ terminationBoundary: options.getTerminationBoundaryRecord('meta-surface-expansion')
508
+ }));
509
+ return;
510
+ }
511
+ const blockedCommand = options.getBlockedHeavyCommand();
512
+ if (options.blockHeavyCommands && blockedCommand) {
513
+ reject(new CodexReviewError(formatBoundedHeavyCommandFailure(blockedCommand), {
514
+ exitCode: typeof code === 'number' && code > 0 ? code : 1,
515
+ signal,
516
+ timedOut: false,
517
+ outputPreview: ''
518
+ }));
519
+ return;
520
+ }
521
+ if (pendingSuccessfulTerminationBoundary) {
522
+ if (isAcceptableSuccessfulBoundaryExit(code, signal, true)) {
523
+ resolve(pendingSuccessfulTerminationBoundary);
524
+ return;
525
+ }
526
+ reject(buildSuccessfulBoundaryExitFailure(code, signal, pendingSuccessfulTerminationBoundary));
527
+ return;
528
+ }
529
+ if (code === 0) {
530
+ resolve(null);
531
+ return;
532
+ }
533
+ const suffix = signal ? ` (signal ${signal})` : '';
534
+ reject(new CodexReviewError(`codex review exited with code ${code}${suffix}`, {
535
+ exitCode: code,
536
+ signal,
537
+ timedOut: false,
538
+ outputPreview: ''
539
+ }));
540
+ })();
541
+ };
542
+ child.once('error', onError);
543
+ child.once('close', onClose);
544
+ const requestTermination = (message, timedOut = true, terminationBoundary = null) => {
545
+ if (settled ||
546
+ pendingTermination ||
547
+ pendingSuccessfulTerminationBoundary ||
548
+ child.exitCode !== null) {
549
+ return;
550
+ }
551
+ pendingTermination = new CodexReviewError(message, {
552
+ exitCode: 1,
553
+ signal: null,
554
+ timedOut,
555
+ outputPreview: '',
556
+ terminationBoundary
557
+ });
558
+ signalChildProcess(child, 'SIGTERM', options.detached);
559
+ hardKillArmed = true;
560
+ killHandle = setTimeout(() => {
561
+ if (child.exitCode === null) {
562
+ signalChildProcess(child, 'SIGKILL', options.detached);
563
+ }
564
+ }, 5000);
565
+ killHandle.unref();
566
+ };
567
+ const requestSuccessfulTermination = (terminationBoundary) => {
568
+ if (settled ||
569
+ pendingTermination ||
570
+ pendingSuccessfulTerminationBoundary ||
571
+ child.exitCode !== null) {
572
+ return;
573
+ }
574
+ pendingSuccessfulTerminationBoundary = terminationBoundary;
575
+ signalChildProcess(child, 'SIGTERM', options.detached);
576
+ hardKillArmed = true;
577
+ killHandle = setTimeout(() => {
578
+ if (child.exitCode === null) {
579
+ signalChildProcess(child, 'SIGKILL', options.detached);
580
+ }
581
+ }, 5000);
582
+ killHandle.unref();
583
+ };
584
+ const timeoutMs = options.timeoutMs;
585
+ if (timeoutMs !== null) {
586
+ timeoutHandle = setTimeout(() => {
587
+ const message = `codex review timed out after ${Math.round(timeoutMs / 1000)}s (set CODEX_REVIEW_TIMEOUT_SECONDS=0 to disable).`;
588
+ requestTermination(message, true, {
589
+ kind: 'timeout',
590
+ provenance: 'review-timeout',
591
+ reason: message,
592
+ sample: null
593
+ });
594
+ }, timeoutMs);
595
+ timeoutHandle.unref();
596
+ }
597
+ const stallTimeoutMs = options.stallTimeoutMs;
598
+ if (stallTimeoutMs !== null) {
599
+ const checkIntervalMs = Math.min(5000, Math.max(1000, Math.round(stallTimeoutMs / 4)));
600
+ stallHandle = setInterval(() => {
601
+ const idleMs = Date.now() - options.getLastOutputAtMs();
602
+ if (idleMs < stallTimeoutMs) {
603
+ return;
604
+ }
605
+ const message = `codex review stalled with no output for ${Math.round(stallTimeoutMs / 1000)}s (set CODEX_REVIEW_STALL_TIMEOUT_SECONDS=0 to disable).`;
606
+ requestTermination(message, true, {
607
+ kind: 'stall',
608
+ provenance: 'output-stall',
609
+ reason: message,
610
+ sample: null
611
+ });
612
+ }, checkIntervalMs);
613
+ stallHandle.unref();
614
+ }
615
+ const startupLoopTimeoutMs = options.startupLoopTimeoutMs;
616
+ if (startupLoopTimeoutMs !== null && options.startupLoopMinEvents > 0) {
617
+ const loopCheckIntervalMs = Math.min(5000, Math.max(1000, Math.round(startupLoopTimeoutMs / 6)));
618
+ startupLoopHandle = setInterval(() => {
619
+ if (Date.now() - startMs < startupLoopTimeoutMs) {
620
+ return;
621
+ }
622
+ const state = options.getStartupLoopState();
623
+ if (state.reviewProgressObserved || state.startupEvents < options.startupLoopMinEvents) {
624
+ return;
625
+ }
626
+ const message = `codex review appears stuck in delegation startup loop after ${Math.round(startupLoopTimeoutMs / 1000)}s (${state.startupEvents} startup events, no review progress). Set CODEX_REVIEW_STARTUP_LOOP_TIMEOUT_SECONDS=0 to disable.`;
627
+ requestTermination(message, true, {
628
+ kind: 'startup-loop',
629
+ provenance: 'delegation-startup-loop',
630
+ reason: message,
631
+ sample: null
632
+ });
633
+ }, loopCheckIntervalMs);
634
+ startupLoopHandle.unref();
635
+ }
636
+ if (options.blockHeavyCommands) {
637
+ heavyCommandHandle = setInterval(() => {
638
+ const blockedCommand = options.getBlockedHeavyCommand();
639
+ if (!blockedCommand) {
640
+ return;
641
+ }
642
+ requestTermination(formatBoundedHeavyCommandFailure(blockedCommand), false);
643
+ }, 250);
644
+ heavyCommandHandle.unref();
645
+ }
646
+ if (options.lowSignalTimeoutMs !== null) {
647
+ lowSignalHandle = setInterval(() => {
648
+ const lowSignalReason = options.getLowSignalDriftReason();
649
+ if (!lowSignalReason) {
650
+ return;
651
+ }
652
+ requestTermination(`${lowSignalReason} (set ${REVIEW_LOW_SIGNAL_TIMEOUT_ENV_KEY}=0 to disable).`, false);
653
+ }, 1000);
654
+ lowSignalHandle.unref();
655
+ }
656
+ if (options.verdictStabilityTimeoutMs !== null) {
657
+ verdictStabilityHandle = setInterval(() => {
658
+ const verdictStabilityState = options.getVerdictStabilityState();
659
+ if (!verdictStabilityState.triggered) {
660
+ return;
661
+ }
662
+ requestTermination(`${verdictStabilityState.reason ?? 'bounded review verdict-stability drift detected'} (set ${REVIEW_VERDICT_STABILITY_TIMEOUT_ENV_KEY}=0 to disable).`, false, options.getTerminationBoundaryRecord('verdict-stability'));
663
+ }, 1000);
664
+ verdictStabilityHandle.unref();
665
+ }
666
+ if (options.metaSurfaceTimeoutMs !== null) {
667
+ metaSurfaceHandle = setInterval(() => {
668
+ const metaSurfaceReason = options.getMetaSurfaceExpansionReason();
669
+ if (!metaSurfaceReason) {
670
+ return;
671
+ }
672
+ requestTermination(`${metaSurfaceReason} (set ${REVIEW_META_SURFACE_TIMEOUT_ENV_KEY}=0 to disable).`, false, options.getTerminationBoundaryRecord('meta-surface-expansion'));
673
+ }, 1000);
674
+ metaSurfaceHandle.unref();
675
+ }
676
+ if (options.enforceStartupAnchorBoundary) {
677
+ startupAnchorHandle = setInterval(() => {
678
+ const boundaryState = options.getStartupAnchorBoundaryState();
679
+ if (!boundaryState.triggered) {
680
+ return;
681
+ }
682
+ requestTermination(boundaryState.reason ?? 'bounded review startup-anchor boundary violated', false, options.getTerminationBoundaryRecord('startup-anchor'));
683
+ }, 250);
684
+ startupAnchorHandle.unref();
685
+ }
686
+ if (options.enforceActiveCloseoutBundleRereadBoundary) {
687
+ activeCloseoutBundleHandle = setInterval(() => {
688
+ const boundaryState = options.getActiveCloseoutBundleRereadBoundaryState();
689
+ if (!boundaryState.triggered) {
690
+ return;
691
+ }
692
+ requestTermination(boundaryState.reason ?? 'bounded review active-closeout-bundle reread boundary violated', false, options.getTerminationBoundaryRecord('active-closeout-bundle-reread'));
693
+ }, 250);
694
+ activeCloseoutBundleHandle.unref();
695
+ }
696
+ if (options.enforceRelevantReinspectionDwellBoundary) {
697
+ relevantReinspectionHandle = setInterval(() => {
698
+ const boundaryState = options.getRelevantReinspectionDwellBoundaryState();
699
+ if (!boundaryState.triggered) {
700
+ return;
701
+ }
702
+ const terminationBoundary = options.getTerminationBoundaryRecord('relevant-reinspection-dwell');
703
+ if (boundaryState.anchorObserved) {
704
+ requestSuccessfulTermination(terminationBoundary);
705
+ return;
706
+ }
707
+ requestTermination(`${boundaryState.reason ?? 'bounded review relevant-reinspection dwell boundary violated'} (set ${REVIEW_LOW_SIGNAL_TIMEOUT_ENV_KEY}=0 to disable).`, false, terminationBoundary);
708
+ }, 250);
709
+ relevantReinspectionHandle.unref();
710
+ }
711
+ commandIntentHandle = setInterval(() => {
712
+ const boundaryState = options.getCommandIntentBoundaryState();
713
+ if (!boundaryState.triggered) {
714
+ return;
715
+ }
716
+ requestTermination(formatCommandIntentBoundaryFailure(boundaryState), false, options.getTerminationBoundaryRecord('command-intent'));
717
+ }, 250);
718
+ commandIntentHandle.unref();
719
+ shellProbeHandle = setInterval(() => {
720
+ const boundaryState = options.getShellProbeBoundaryState();
721
+ if (!boundaryState.triggered) {
722
+ return;
723
+ }
724
+ requestTermination(boundaryState.reason ?? 'bounded review shell-probe boundary violated', false, options.getTerminationBoundaryRecord('shell-probe'));
725
+ }, 250);
726
+ shellProbeHandle.unref();
727
+ const monitorIntervalMs = options.monitorIntervalMs;
728
+ if (monitorIntervalMs !== null) {
729
+ const checkpointIntervalMs = Math.max(1000, monitorIntervalMs);
730
+ monitorHandle = setInterval(() => {
731
+ console.log(options.formatCheckpoint());
732
+ }, checkpointIntervalMs);
733
+ monitorHandle.unref();
734
+ }
735
+ });
736
+ }
737
+ export function signalChildProcess(child, signal, detached) {
738
+ if (detached && typeof child.pid === 'number' && child.pid > 0) {
739
+ try {
740
+ process.kill(-child.pid, signal);
741
+ return;
742
+ }
743
+ catch {
744
+ // Fallback to direct child signal below.
745
+ }
746
+ }
747
+ try {
748
+ child.kill(signal);
749
+ }
750
+ catch {
751
+ // Best effort only.
752
+ }
753
+ }