@kbediako/codex-orchestrator 0.1.38 → 0.2.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 (299) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/README.md +70 -301
  3. package/bin/codex-orchestrator.js +161 -0
  4. package/codex.orchestrator.json +149 -13
  5. package/dist/bin/codex-orchestrator.js +795 -1154
  6. package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
  7. package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
  8. package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
  9. package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +183 -11
  10. package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
  11. package/dist/orchestrator/src/cli/coStatusCliShell.js +429 -0
  12. package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
  13. package/dist/orchestrator/src/cli/codexCliShell.js +72 -0
  14. package/dist/orchestrator/src/cli/codexDefaultsSetup.js +49 -11
  15. package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
  16. package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
  17. package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
  18. package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
  19. package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
  20. package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
  21. package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
  22. package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
  23. package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
  24. package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
  25. package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
  26. package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
  27. package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
  28. package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
  29. package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
  30. package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
  31. package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
  32. package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
  33. package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
  34. package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
  35. package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
  36. package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
  37. package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
  38. package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
  39. package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
  40. package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
  41. package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
  42. package/dist/orchestrator/src/cli/control/controlHostSupervision.js +608 -0
  43. package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
  44. package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
  45. package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
  46. package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
  47. package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
  48. package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
  49. package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
  50. package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
  51. package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
  52. package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
  53. package/dist/orchestrator/src/cli/control/controlRuntime.js +992 -0
  54. package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
  55. package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
  56. package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
  57. package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
  58. package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
  59. package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
  60. package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
  61. package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
  62. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
  63. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
  64. package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
  65. package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
  66. package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
  67. package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
  68. package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
  69. package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
  70. package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
  71. package/dist/orchestrator/src/cli/control/controlState.js +233 -2
  72. package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1899 -0
  73. package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
  74. package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
  75. package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
  76. package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
  77. package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
  78. package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
  79. package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
  80. package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
  81. package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
  82. package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
  83. package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
  84. package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
  85. package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
  86. package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
  87. package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
  88. package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
  89. package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
  90. package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
  91. package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
  92. package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
  93. package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
  94. package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
  95. package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
  96. package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
  97. package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
  98. package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
  99. package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
  100. package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
  101. package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
  102. package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
  103. package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
  104. package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
  105. package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
  106. package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
  107. package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
  108. package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
  109. package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
  110. package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
  111. package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
  112. package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
  113. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
  114. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
  115. package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
  116. package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
  117. package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
  118. package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
  119. package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
  120. package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
  121. package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
  122. package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
  123. package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
  124. package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1838 -0
  125. package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
  126. package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
  127. package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
  128. package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
  129. package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
  130. package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
  131. package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
  132. package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
  133. package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
  134. package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
  135. package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
  136. package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
  137. package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
  138. package/dist/orchestrator/src/cli/delegationServer.js +567 -678
  139. package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
  140. package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
  141. package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
  142. package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
  143. package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
  144. package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
  145. package/dist/orchestrator/src/cli/doctor.js +542 -122
  146. package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
  147. package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
  148. package/dist/orchestrator/src/cli/doctorUsage.js +119 -15
  149. package/dist/orchestrator/src/cli/exec/experience.js +16 -2
  150. package/dist/orchestrator/src/cli/exec/summary.js +3 -0
  151. package/dist/orchestrator/src/cli/execCliShell.js +51 -0
  152. package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
  153. package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
  154. package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
  155. package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
  156. package/dist/orchestrator/src/cli/init.js +1 -0
  157. package/dist/orchestrator/src/cli/initCliShell.js +50 -0
  158. package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
  159. package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
  160. package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
  161. package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
  162. package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
  163. package/dist/orchestrator/src/cli/planCliShell.js +19 -0
  164. package/dist/orchestrator/src/cli/prCliShell.js +41 -0
  165. package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
  166. package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1772 -0
  167. package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
  168. package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
  169. package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +5738 -0
  170. package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
  171. package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
  172. package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
  173. package/dist/orchestrator/src/cli/rlm/context.js +94 -7
  174. package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
  175. package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
  176. package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
  177. package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
  178. package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
  179. package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
  180. package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
  181. package/dist/orchestrator/src/cli/run/manifest.js +410 -73
  182. package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
  183. package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
  184. package/dist/orchestrator/src/cli/run/source0.js +690 -0
  185. package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
  186. package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
  187. package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
  188. package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
  189. package/dist/orchestrator/src/cli/services/commandRunner.js +667 -18
  190. package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
  191. package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
  192. package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
  193. package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
  194. package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
  195. package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
  196. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
  197. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
  198. package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
  199. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
  200. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
  201. package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
  202. package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
  203. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
  204. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
  205. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
  206. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
  207. package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
  208. package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
  209. package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
  210. package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
  211. package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
  212. package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
  213. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
  214. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
  215. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
  216. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
  217. package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
  218. package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
  219. package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
  220. package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
  221. package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
  222. package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
  223. package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
  224. package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
  225. package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
  226. package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
  227. package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
  228. package/dist/orchestrator/src/cli/startCliShell.js +68 -0
  229. package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
  230. package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
  231. package/dist/orchestrator/src/cli/utils/cloudPreflight.js +83 -1
  232. package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
  233. package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
  234. package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
  235. package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
  236. package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
  237. package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
  238. package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
  239. package/dist/orchestrator/src/learning/crystalizer.js +2 -2
  240. package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
  241. package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
  242. package/dist/orchestrator/src/persistence/lockFile.js +70 -4
  243. package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
  244. package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
  245. package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
  246. package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
  247. package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
  248. package/dist/packages/sdk-node/src/orchestrator.js +137 -13
  249. package/dist/packages/shared/config/designConfig.js +8 -1
  250. package/dist/packages/shared/streams/stdio.js +1 -1
  251. package/dist/scripts/design/pipeline/permit.js +15 -0
  252. package/dist/scripts/lib/docs-catalog.js +365 -0
  253. package/dist/scripts/lib/docs-helpers.js +87 -5
  254. package/dist/scripts/lib/pr-watch-merge.js +1088 -80
  255. package/dist/scripts/lib/provider-run-contract.js +26 -0
  256. package/dist/scripts/lib/review-command-intent-classification.js +532 -0
  257. package/dist/scripts/lib/review-command-probe-classification.js +385 -0
  258. package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
  259. package/dist/scripts/lib/review-execution-runtime.js +753 -0
  260. package/dist/scripts/lib/review-execution-state.js +1144 -0
  261. package/dist/scripts/lib/review-execution-telemetry.js +215 -0
  262. package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
  263. package/dist/scripts/lib/review-launch-attempt.js +601 -0
  264. package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
  265. package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
  266. package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
  267. package/dist/scripts/lib/review-prompt-context.js +376 -0
  268. package/dist/scripts/lib/review-scope-advisory.js +286 -0
  269. package/dist/scripts/lib/review-scope-paths.js +123 -0
  270. package/dist/scripts/lib/review-shell-command-parser.js +389 -0
  271. package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
  272. package/dist/scripts/lib/run-manifests.js +192 -36
  273. package/dist/scripts/lib/spark-policy-classifier.js +593 -0
  274. package/dist/scripts/run-review.js +507 -1777
  275. package/docs/public/downstream-setup.md +106 -0
  276. package/docs/public/provider-onboarding.md +173 -0
  277. package/package.json +20 -10
  278. package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
  279. package/plugins/codex-orchestrator/.mcp.json +13 -0
  280. package/plugins/codex-orchestrator/launcher.mjs +359 -0
  281. package/schemas/manifest.json +394 -0
  282. package/skills/collab-subagents-first/SKILL.md +1 -1
  283. package/skills/delegation-usage/DELEGATION_GUIDE.md +24 -11
  284. package/skills/delegation-usage/SKILL.md +19 -13
  285. package/skills/land/SKILL.md +77 -0
  286. package/skills/linear/SKILL.md +255 -0
  287. package/skills/release/SKILL.md +47 -3
  288. package/skills/standalone-review/SKILL.md +6 -1
  289. package/templates/README.md +4 -2
  290. package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
  291. package/templates/codex/.codex/agents/worker-complex.toml +1 -1
  292. package/templates/codex/.codex/config.toml +3 -4
  293. package/templates/codex/.codex/providers/README.md +13 -0
  294. package/templates/codex/.codex/providers/control.example.json +18 -0
  295. package/templates/codex/.codex/providers/provider.env.example +15 -0
  296. package/templates/codex/AGENTS.md +12 -7
  297. package/templates/codex/mcp-client.json +5 -1
  298. package/docs/README.md +0 -310
  299. package/docs/assets/setup.gif +0 -0
@@ -0,0 +1,608 @@
1
+ import { homedir } from 'node:os';
2
+ import { isAbsolute, join, resolve } from 'node:path';
3
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_LABEL = 'com.kbediako.co.control-host';
4
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_TASK_ID = 'local-mcp';
5
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_RUN_ID = 'control-host';
6
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_PIPELINE_ID = 'provider-linear-worker';
7
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_HEALTH_INTERVAL_SECONDS = 30;
8
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_UNHEALTHY_THRESHOLD = 3;
9
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_LAUNCHD_THROTTLE_SECONDS = 15;
10
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_KILL_TIMEOUT_SECONDS = 10;
11
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_RESTART_EXIT_CODE = 75;
12
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_SHELL_PATH = '/bin/zsh';
13
+ export const DEFAULT_CONTROL_HOST_SUPERVISION_ACTIVE_WORKER_RESTART_QUARANTINE_MS = 10 * 60 * 1000;
14
+ export const CONTROL_HOST_SUPERVISION_RESTART_HISTORY_LIMIT = 20;
15
+ export const CONTROL_HOST_SUPERVISION_MAX_NODE_TIMER_SECONDS = Math.floor(2_147_483_647 / 1_000);
16
+ export function resolveDefaultControlHostSupervisionEnvFiles(homeDir = homedir()) {
17
+ return [join(homeDir, '.local', 'bin', 'env'), join(homeDir, '.co_provider_env')];
18
+ }
19
+ export function resolveDefaultControlHostSupervisionEntrypoint(currentArgvEntry, packageRoot) {
20
+ const bootstrapEntrypoint = join(packageRoot, 'bin', 'codex-orchestrator.js');
21
+ const currentEntry = typeof currentArgvEntry === 'string' && currentArgvEntry.trim().length > 0
22
+ ? resolve(currentArgvEntry)
23
+ : null;
24
+ if (currentEntry === bootstrapEntrypoint) {
25
+ return currentEntry;
26
+ }
27
+ return bootstrapEntrypoint;
28
+ }
29
+ export function resolveControlHostSupervisionPaths(input) {
30
+ const resolvedHomeDir = resolve(input?.homeDir ?? homedir());
31
+ const label = normalizeLabel(input?.label);
32
+ const slug = sanitizeControlHostSupervisionPathSegment(label);
33
+ const supportDir = resolve(input?.supportDir ??
34
+ join(resolvedHomeDir, 'Library', 'Application Support', 'codex-orchestrator', 'control-host-supervision', slug));
35
+ const logsDir = resolve(input?.logsDir ?? join(resolvedHomeDir, 'Library', 'Logs', 'co-control-host', slug));
36
+ return {
37
+ supportDir,
38
+ configPath: join(supportDir, 'config.json'),
39
+ statePath: join(supportDir, 'state.json'),
40
+ plistPath: join(resolvedHomeDir, 'Library', 'LaunchAgents', `${label}.plist`),
41
+ logsDir,
42
+ stdoutLogPath: join(logsDir, 'stdout.log'),
43
+ stderrLogPath: join(logsDir, 'stderr.log')
44
+ };
45
+ }
46
+ export function buildControlHostSupervisionConfig(input) {
47
+ const homeDir = resolve(input.homeDir ?? homedir());
48
+ const cwd = resolve(input.cwd ?? process.cwd());
49
+ const label = normalizeLabel(input.label);
50
+ const repoRoot = resolve(input.repoRoot ?? cwd);
51
+ const nodePath = resolveRequiredPath(input.nodePath ?? process.execPath, cwd, 'node path');
52
+ const cliEntrypoint = resolveRequiredPath(input.cliEntrypoint ?? join(repoRoot, 'dist', 'bin', 'codex-orchestrator.js'), cwd, 'CLI entrypoint');
53
+ const taskId = normalizeNonEmptyValue(input.taskId, DEFAULT_CONTROL_HOST_SUPERVISION_TASK_ID);
54
+ const runId = normalizeNonEmptyValue(input.runId, DEFAULT_CONTROL_HOST_SUPERVISION_RUN_ID);
55
+ const pipelineId = normalizeNonEmptyValue(input.pipelineId, DEFAULT_CONTROL_HOST_SUPERVISION_PIPELINE_ID);
56
+ const healthIntervalSeconds = coercePositiveTimerSeconds(input.healthIntervalSeconds, DEFAULT_CONTROL_HOST_SUPERVISION_HEALTH_INTERVAL_SECONDS, 'health interval');
57
+ const unhealthyThreshold = coercePositiveInteger(input.unhealthyThreshold, DEFAULT_CONTROL_HOST_SUPERVISION_UNHEALTHY_THRESHOLD, 'unhealthy threshold');
58
+ const launchdThrottleSeconds = coerceNonNegativeInteger(input.launchdThrottleSeconds, DEFAULT_CONTROL_HOST_SUPERVISION_LAUNCHD_THROTTLE_SECONDS, 'launchd throttle');
59
+ const killTimeoutSeconds = coercePositiveTimerSeconds(input.killTimeoutSeconds, DEFAULT_CONTROL_HOST_SUPERVISION_KILL_TIMEOUT_SECONDS, 'kill timeout');
60
+ const shellPath = resolveRequiredPath(input.shellPath ?? process.env.SHELL ?? DEFAULT_CONTROL_HOST_SUPERVISION_SHELL_PATH, cwd, 'shell path');
61
+ const envFiles = (input.envFiles ?? resolveDefaultControlHostSupervisionEnvFiles(homeDir)).map((value, index) => {
62
+ const trimmed = value.trim();
63
+ if (trimmed.length === 0) {
64
+ throw new Error(`env file entry at index ${index} must be non-empty.`);
65
+ }
66
+ return resolveOptionalPath(trimmed, cwd);
67
+ });
68
+ const paths = resolveControlHostSupervisionPaths({
69
+ homeDir,
70
+ label,
71
+ supportDir: input.supportDir,
72
+ logsDir: input.logsDir
73
+ });
74
+ return {
75
+ version: 1,
76
+ label,
77
+ repoRoot,
78
+ nodePath,
79
+ cliEntrypoint,
80
+ taskId,
81
+ runId,
82
+ pipelineId,
83
+ healthIntervalSeconds,
84
+ unhealthyThreshold,
85
+ launchdThrottleSeconds,
86
+ killTimeoutSeconds,
87
+ shellPath,
88
+ envFiles,
89
+ homeDir,
90
+ paths
91
+ };
92
+ }
93
+ export function buildControlHostSupervisionPlist(config) {
94
+ const programArguments = [
95
+ config.nodePath,
96
+ config.cliEntrypoint,
97
+ 'control-host',
98
+ 'supervise',
99
+ 'run',
100
+ '--config',
101
+ config.paths.configPath
102
+ ];
103
+ const argumentLines = programArguments
104
+ .map((value) => ` <string>${escapeXml(value)}</string>`)
105
+ .join('\n');
106
+ return `<?xml version="1.0" encoding="UTF-8"?>
107
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
108
+ <plist version="1.0">
109
+ <dict>
110
+ <key>Label</key>
111
+ <string>${escapeXml(config.label)}</string>
112
+ <key>ProgramArguments</key>
113
+ <array>
114
+ ${argumentLines}
115
+ </array>
116
+ <key>WorkingDirectory</key>
117
+ <string>${escapeXml(config.repoRoot)}</string>
118
+ <key>KeepAlive</key>
119
+ <true/>
120
+ <key>RunAtLoad</key>
121
+ <true/>
122
+ <key>ThrottleInterval</key>
123
+ <integer>${config.launchdThrottleSeconds}</integer>
124
+ <key>StandardOutPath</key>
125
+ <string>${escapeXml(config.paths.stdoutLogPath)}</string>
126
+ <key>StandardErrorPath</key>
127
+ <string>${escapeXml(config.paths.stderrLogPath)}</string>
128
+ </dict>
129
+ </plist>
130
+ `;
131
+ }
132
+ export function buildInitialControlHostSupervisionState(input) {
133
+ return {
134
+ version: 1,
135
+ status: normalizeNonEmptyValue(input.status, 'installed'),
136
+ updated_at: input.updatedAt,
137
+ label: input.config.label,
138
+ repo_root: input.config.repoRoot,
139
+ service_target: input.serviceTarget ?? null,
140
+ child_pid: null,
141
+ last_started_at: null,
142
+ last_exit_at: null,
143
+ last_exit_code: null,
144
+ last_signal: null,
145
+ last_health_check_at: null,
146
+ last_health_status: null,
147
+ last_probe_duration_ms: null,
148
+ consecutive_unhealthy_samples: 0,
149
+ restart_count: input.restartCount ?? 0,
150
+ unhealthy_threshold: input.config.unhealthyThreshold,
151
+ health_interval_seconds: input.config.healthIntervalSeconds,
152
+ last_restart_reason: input.lastRestartReason ?? null,
153
+ last_restart_requested_at: input.lastRestartRequestedAt ?? null,
154
+ restart_history: normalizeControlHostSupervisionRestartHistory(input.restartHistory ?? null),
155
+ message: input.message ?? null
156
+ };
157
+ }
158
+ export function readControlHostSupervisionHealthDiagnostic(payload) {
159
+ if (!isRecord(payload)) {
160
+ return null;
161
+ }
162
+ const counts = isRecord(payload.counts) ? payload.counts : null;
163
+ const polling = isRecord(payload.polling) ? payload.polling : null;
164
+ const running = Array.isArray(payload.running) ? payload.running : [];
165
+ return {
166
+ counts: {
167
+ running: readFiniteNumber(counts?.running),
168
+ retrying: readFiniteNumber(counts?.retrying),
169
+ max_allowed: readFiniteNumber(counts?.max_allowed)
170
+ },
171
+ polling: polling ? buildControlHostSupervisionPollingDiagnostic(polling) : null,
172
+ running_workers: running
173
+ .map((entry) => buildControlHostSupervisionRunningWorkerSnapshot(entry))
174
+ .filter((entry) => entry !== null)
175
+ };
176
+ }
177
+ function normalizeStoredControlHostSupervisionHealthDiagnostic(value) {
178
+ if (!isRecord(value)) {
179
+ return null;
180
+ }
181
+ const counts = isRecord(value.counts) ? value.counts : null;
182
+ const polling = isRecord(value.polling) ? value.polling : null;
183
+ const runningWorkers = Array.isArray(value.running_workers) ? value.running_workers : [];
184
+ return {
185
+ counts: {
186
+ running: readFiniteNumber(counts?.running),
187
+ retrying: readFiniteNumber(counts?.retrying),
188
+ max_allowed: readFiniteNumber(counts?.max_allowed)
189
+ },
190
+ polling: polling ? buildControlHostSupervisionPollingDiagnostic(polling) : null,
191
+ running_workers: runningWorkers
192
+ .map((entry) => buildControlHostSupervisionRunningWorkerSnapshot(entry))
193
+ .filter((entry) => entry !== null)
194
+ };
195
+ }
196
+ export function evaluateControlHostSupervisionHealthPayload(payload, options = {}) {
197
+ if (!isRecord(payload)) {
198
+ return {
199
+ healthy: false,
200
+ reason: 'invalid_payload',
201
+ message: 'co-status returned a non-object payload.'
202
+ };
203
+ }
204
+ const polling = isRecord(payload.polling) ? payload.polling : null;
205
+ const diagnostic = readControlHostSupervisionHealthDiagnostic(payload);
206
+ if (!polling) {
207
+ return {
208
+ healthy: true,
209
+ reason: 'ok',
210
+ message: 'co-status payload omitted polling state; treating it as healthy.'
211
+ };
212
+ }
213
+ if (polling.restart_required === true) {
214
+ if (isStaleRecoverableProviderRestartRequiredPolling(polling, {
215
+ minPollingUpdatedAt: options.minPollingUpdatedAt,
216
+ staleRestartRequiredGraceMs: options.staleRestartRequiredGraceMs,
217
+ now: options.now
218
+ })) {
219
+ const graceSeconds = typeof options.staleRestartRequiredGraceMs === 'number' &&
220
+ Number.isFinite(options.staleRestartRequiredGraceMs)
221
+ ? Math.max(0, Math.round(options.staleRestartRequiredGraceMs / 1_000))
222
+ : null;
223
+ return {
224
+ healthy: true,
225
+ reason: 'stale_restart_required',
226
+ message: `co-status reported a stale provider_refresh_lifecycle_stuck restart_required snapshot from before the current supervised child start; treating it as quiescent${graceSeconds === null ? '' : ` for the bounded ${graceSeconds}s startup grace window`} while the current host refreshes.`
227
+ };
228
+ }
229
+ const repeatedRestartQuarantine = resolveRepeatedActiveWorkerRestartQuarantine({
230
+ polling,
231
+ diagnostic,
232
+ restartHistory: options.restartHistory ?? null,
233
+ activeWorkerRestartQuarantineMs: options.activeWorkerRestartQuarantineMs ??
234
+ DEFAULT_CONTROL_HOST_SUPERVISION_ACTIVE_WORKER_RESTART_QUARANTINE_MS,
235
+ now: options.now
236
+ });
237
+ if (repeatedRestartQuarantine) {
238
+ return repeatedRestartQuarantine;
239
+ }
240
+ return {
241
+ healthy: false,
242
+ reason: 'restart_required',
243
+ message: 'co-status reported restart_required=true.'
244
+ };
245
+ }
246
+ return {
247
+ healthy: true,
248
+ reason: 'ok',
249
+ message: 'co-status reported a healthy polling state.'
250
+ };
251
+ }
252
+ function isStaleRecoverableProviderRestartRequiredPolling(polling, options) {
253
+ if (polling.reason !== 'provider_refresh_lifecycle_stuck' &&
254
+ polling.last_error !== 'provider_refresh_lifecycle_stuck') {
255
+ return false;
256
+ }
257
+ const pollingUpdatedAt = parseIsoTimestampToMs(polling.updated_at);
258
+ const minimumUpdatedAt = parseIsoTimestampToMs(options.minPollingUpdatedAt);
259
+ if (pollingUpdatedAt === null || minimumUpdatedAt === null || pollingUpdatedAt >= minimumUpdatedAt) {
260
+ return false;
261
+ }
262
+ if (typeof options.staleRestartRequiredGraceMs !== 'number' ||
263
+ !Number.isFinite(options.staleRestartRequiredGraceMs)) {
264
+ return true;
265
+ }
266
+ const now = parseIsoTimestampToMs(options.now ?? new Date().toISOString());
267
+ return now !== null && now - minimumUpdatedAt <= Math.max(0, options.staleRestartRequiredGraceMs);
268
+ }
269
+ function resolveRepeatedActiveWorkerRestartQuarantine(input) {
270
+ if (!isProviderRefreshLifecycleRestartRequired(input.polling)) {
271
+ return null;
272
+ }
273
+ const diagnostic = input.diagnostic;
274
+ if (!diagnostic || diagnostic.running_workers.length === 0) {
275
+ return null;
276
+ }
277
+ if (hasAvailableProviderWorkerCapacity(diagnostic)) {
278
+ return null;
279
+ }
280
+ const restartHistory = normalizeControlHostSupervisionRestartHistory(input.restartHistory);
281
+ if (restartHistory.length === 0) {
282
+ return null;
283
+ }
284
+ const currentSignature = buildControlHostSupervisionRestartSignature(diagnostic);
285
+ if (currentSignature === null) {
286
+ return null;
287
+ }
288
+ const nowMs = parseIsoTimestampToMs(input.now ?? new Date().toISOString());
289
+ const quarantineMs = typeof input.activeWorkerRestartQuarantineMs === 'number' &&
290
+ Number.isFinite(input.activeWorkerRestartQuarantineMs)
291
+ ? Math.max(0, input.activeWorkerRestartQuarantineMs)
292
+ : null;
293
+ for (let index = restartHistory.length - 1; index >= 0; index -= 1) {
294
+ const record = restartHistory[index];
295
+ const requestedAtMs = parseIsoTimestampToMs(record.requested_at);
296
+ if (quarantineMs !== null &&
297
+ nowMs !== null &&
298
+ requestedAtMs !== null &&
299
+ nowMs - requestedAtMs > quarantineMs) {
300
+ break;
301
+ }
302
+ const recordSignature = buildControlHostSupervisionRestartSignature(record.diagnostic);
303
+ if (recordSignature === null || recordSignature !== currentSignature) {
304
+ return null;
305
+ }
306
+ return {
307
+ healthy: true,
308
+ reason: 'active_worker_restart_quarantine',
309
+ message: `co-status reported restart_required=true for the same provider refresh stuck series already restarted at ${record.requested_at}; ${diagnostic.running_workers.length} active provider worker(s) remain visible, so supervision is quarantining repeated restart churn while retaining restart_required in co-status.`
310
+ };
311
+ }
312
+ return null;
313
+ }
314
+ export function evaluateControlHostSupervisionProbeTimeoutDiagnostic(diagnostic, options = {}) {
315
+ if (!diagnostic || diagnostic.running_workers.length === 0) {
316
+ return null;
317
+ }
318
+ if (!isProviderRefreshLifecycleRestartRequiredDiagnostic(diagnostic.polling)) {
319
+ return null;
320
+ }
321
+ if (!isCurrentControlHostSupervisionPollingDiagnostic(diagnostic.polling, options.minPollingUpdatedAt)) {
322
+ return null;
323
+ }
324
+ const pollingReason = diagnostic.polling?.reason ?? diagnostic.polling?.last_error ?? null;
325
+ if (!pollingReason) {
326
+ return null;
327
+ }
328
+ if (hasAvailableProviderWorkerCapacity(diagnostic)) {
329
+ return null;
330
+ }
331
+ const restartHistory = normalizeControlHostSupervisionRestartHistory(options.restartHistory);
332
+ if (restartHistory.length === 0) {
333
+ return null;
334
+ }
335
+ const currentSignature = buildControlHostSupervisionRestartSignature(diagnostic);
336
+ if (currentSignature === null) {
337
+ return null;
338
+ }
339
+ const nowMs = parseIsoTimestampToMs(options.now ?? new Date().toISOString());
340
+ const quarantineMs = typeof options.activeWorkerRestartQuarantineMs === 'number' &&
341
+ Number.isFinite(options.activeWorkerRestartQuarantineMs)
342
+ ? Math.max(0, options.activeWorkerRestartQuarantineMs)
343
+ : DEFAULT_CONTROL_HOST_SUPERVISION_ACTIVE_WORKER_RESTART_QUARANTINE_MS;
344
+ for (let index = restartHistory.length - 1; index >= 0; index -= 1) {
345
+ const record = restartHistory[index];
346
+ const requestedAtMs = parseIsoTimestampToMs(record.requested_at);
347
+ if (nowMs !== null &&
348
+ requestedAtMs !== null &&
349
+ nowMs - requestedAtMs > quarantineMs) {
350
+ break;
351
+ }
352
+ if (record.reason !== 'probe_timeout') {
353
+ return null;
354
+ }
355
+ const recordSignature = buildControlHostSupervisionRestartSignature(record.diagnostic);
356
+ if (recordSignature === null || recordSignature !== currentSignature) {
357
+ return null;
358
+ }
359
+ return {
360
+ healthy: true,
361
+ reason: 'active_worker_probe_timeout_quarantine',
362
+ message: `co-status probe timed out for the same active provider worker series already restarted at ${record.requested_at}; ${diagnostic.running_workers.length} active provider worker(s) remain visible in local provider-intake state, so supervision is quarantining repeated probe timeout restart churn while retaining the prior fail-closed timeout record.`
363
+ };
364
+ }
365
+ return null;
366
+ }
367
+ function isProviderRefreshLifecycleRestartRequiredDiagnostic(polling) {
368
+ if (!polling || polling.restart_required !== true) {
369
+ return false;
370
+ }
371
+ return (polling.reason === 'provider_refresh_lifecycle_stuck' ||
372
+ polling.last_error === 'provider_refresh_lifecycle_stuck');
373
+ }
374
+ function isCurrentControlHostSupervisionPollingDiagnostic(polling, minPollingUpdatedAt) {
375
+ const minimumUpdatedAt = parseIsoTimestampToMs(minPollingUpdatedAt);
376
+ if (minimumUpdatedAt === null) {
377
+ return true;
378
+ }
379
+ const pollingUpdatedAt = parseIsoTimestampToMs(polling?.updated_at);
380
+ return pollingUpdatedAt !== null && pollingUpdatedAt >= minimumUpdatedAt;
381
+ }
382
+ function hasAvailableProviderWorkerCapacity(diagnostic) {
383
+ const running = diagnostic.counts.running;
384
+ const retrying = diagnostic.counts.retrying;
385
+ const maxAllowed = diagnostic.counts.max_allowed ?? null;
386
+ if (running === null || retrying === null || maxAllowed === null) {
387
+ return false;
388
+ }
389
+ return running + retrying < maxAllowed;
390
+ }
391
+ function buildControlHostSupervisionPollingDiagnostic(polling) {
392
+ return {
393
+ updated_at: readIsoString(polling.updated_at),
394
+ checking: polling.checking === true,
395
+ queued: polling.queued === true,
396
+ stuck: polling.stuck === true,
397
+ restart_required: polling.restart_required === true,
398
+ reason: readNonEmptyString(polling.reason),
399
+ last_error: readNonEmptyString(polling.last_error),
400
+ refresh_phase: readNonEmptyString(polling.refresh_phase),
401
+ refresh_request_class: readNonEmptyString(polling.refresh_request_class),
402
+ refresh_provider_keys: readStringArray(polling.refresh_provider_keys),
403
+ operation_elapsed_ms: readFiniteNumber(polling.operation_elapsed_ms),
404
+ stalled_after_ms: readFiniteNumber(polling.stalled_after_ms),
405
+ control_host_owner: isRecord(polling.control_host_owner) ? { ...polling.control_host_owner } : null
406
+ };
407
+ }
408
+ function buildControlHostSupervisionRunningWorkerSnapshot(value) {
409
+ if (!isRecord(value)) {
410
+ return null;
411
+ }
412
+ const issueIdentifier = readNonEmptyString(value.issue_identifier);
413
+ if (!issueIdentifier) {
414
+ return null;
415
+ }
416
+ return {
417
+ issue_id: readIsoOrPlainString(value.issue_id),
418
+ issue_identifier: issueIdentifier,
419
+ state: readNonEmptyString(value.state),
420
+ display_state: readNonEmptyString(value.display_state),
421
+ pid: readNonEmptyString(value.pid),
422
+ worker_host: readNonEmptyString(value.worker_host),
423
+ session_id: readNonEmptyString(value.session_id),
424
+ started_at: readIsoString(value.started_at),
425
+ last_event_at: readIsoString(value.last_event_at)
426
+ };
427
+ }
428
+ function normalizeControlHostSupervisionRestartHistory(value) {
429
+ if (!Array.isArray(value)) {
430
+ return [];
431
+ }
432
+ const normalized = value
433
+ .map((entry) => normalizeControlHostSupervisionRestartRecord(entry))
434
+ .filter((entry) => entry !== null);
435
+ return normalized.slice(-CONTROL_HOST_SUPERVISION_RESTART_HISTORY_LIMIT);
436
+ }
437
+ function normalizeControlHostSupervisionRestartRecord(value) {
438
+ if (!value || typeof value !== 'object') {
439
+ return null;
440
+ }
441
+ const requestedAt = readIsoString(value.requested_at);
442
+ const reason = readNonEmptyString(value.reason);
443
+ if (!requestedAt || !reason) {
444
+ return null;
445
+ }
446
+ return {
447
+ requested_at: requestedAt,
448
+ reason,
449
+ message: readNonEmptyString(value.message) ?? '',
450
+ consecutive_unhealthy_samples: readFiniteNumber(value.consecutive_unhealthy_samples) ?? 0,
451
+ child_pid: readFiniteNumber(value.child_pid),
452
+ probe_duration_ms: readFiniteNumber(value.probe_duration_ms),
453
+ diagnostic: normalizeStoredControlHostSupervisionHealthDiagnostic(value.diagnostic)
454
+ };
455
+ }
456
+ function buildControlHostSupervisionRestartSignature(diagnostic) {
457
+ if (!diagnostic?.polling) {
458
+ return null;
459
+ }
460
+ const workerSeries = diagnostic.running_workers
461
+ .map((worker) => buildControlHostSupervisionWorkerSeriesKey(worker))
462
+ .filter((value) => value !== null)
463
+ .sort();
464
+ if (workerSeries.length === 0) {
465
+ return null;
466
+ }
467
+ // Quarantine repeated restart churn on the stable active-worker series, not on transient
468
+ // refresh checkpoints that can legitimately drift within one stuck refresh cycle.
469
+ return JSON.stringify({
470
+ reason: diagnostic.polling.reason ?? diagnostic.polling.last_error ?? null,
471
+ worker_series: workerSeries
472
+ });
473
+ }
474
+ function buildControlHostSupervisionWorkerSeriesKey(worker) {
475
+ if (worker.issue_identifier.length === 0) {
476
+ return null;
477
+ }
478
+ return JSON.stringify({
479
+ issue_identifier: worker.issue_identifier,
480
+ session_id: worker.session_id ?? null,
481
+ started_at: worker.started_at ?? null,
482
+ pid: worker.pid ?? null
483
+ });
484
+ }
485
+ function isProviderRefreshLifecycleRestartRequired(polling) {
486
+ if (polling.restart_required !== true) {
487
+ return false;
488
+ }
489
+ return (polling.reason === 'provider_refresh_lifecycle_stuck' ||
490
+ polling.last_error === 'provider_refresh_lifecycle_stuck');
491
+ }
492
+ function parseIsoTimestampToMs(value) {
493
+ if (typeof value !== 'string' || value.trim().length === 0) {
494
+ return null;
495
+ }
496
+ const parsed = Date.parse(value);
497
+ return Number.isFinite(parsed) ? parsed : null;
498
+ }
499
+ export function parseControlHostSupervisionCsv(raw) {
500
+ if (typeof raw !== 'string') {
501
+ return null;
502
+ }
503
+ const trimmed = raw.trim();
504
+ if (trimmed.length === 0) {
505
+ return null;
506
+ }
507
+ if (trimmed === '-' || trimmed.toLowerCase() === 'none') {
508
+ return [];
509
+ }
510
+ return trimmed
511
+ .split(',')
512
+ .map((value) => value.trim())
513
+ .filter((value) => value.length > 0);
514
+ }
515
+ function readNonEmptyString(value) {
516
+ if (typeof value !== 'string') {
517
+ return null;
518
+ }
519
+ const trimmed = value.trim();
520
+ return trimmed.length > 0 ? trimmed : null;
521
+ }
522
+ function readIsoString(value) {
523
+ const candidate = readNonEmptyString(value);
524
+ return candidate && Number.isFinite(Date.parse(candidate)) ? candidate : null;
525
+ }
526
+ function readIsoOrPlainString(value) {
527
+ return readNonEmptyString(value);
528
+ }
529
+ function readFiniteNumber(value) {
530
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
531
+ }
532
+ function readStringArray(value) {
533
+ if (!Array.isArray(value)) {
534
+ return null;
535
+ }
536
+ const normalized = value
537
+ .map((entry) => readNonEmptyString(entry))
538
+ .filter((entry) => entry !== null);
539
+ return normalized.length > 0 ? normalized : null;
540
+ }
541
+ export function sanitizeControlHostSupervisionPathSegment(value) {
542
+ const trimmed = value.trim();
543
+ const sanitized = trimmed.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');
544
+ if (sanitized === '.' || sanitized === '..') {
545
+ throw new Error('control-host supervision label may not resolve to "." or "..".');
546
+ }
547
+ return sanitized.length > 0 ? sanitized : 'control-host';
548
+ }
549
+ function normalizeLabel(value) {
550
+ const normalized = normalizeNonEmptyValue(value, DEFAULT_CONTROL_HOST_SUPERVISION_LABEL);
551
+ if (!/^[A-Za-z0-9._-]+$/u.test(normalized)) {
552
+ throw new Error('control-host supervision label may only contain letters, numbers, dots, underscores, and hyphens.');
553
+ }
554
+ return normalized;
555
+ }
556
+ function normalizeNonEmptyValue(value, fallback) {
557
+ if (typeof value !== 'string') {
558
+ return fallback;
559
+ }
560
+ const trimmed = value.trim();
561
+ return trimmed.length > 0 ? trimmed : fallback;
562
+ }
563
+ function resolveRequiredPath(value, cwd, label) {
564
+ const trimmed = value.trim();
565
+ if (trimmed.length === 0) {
566
+ throw new Error(`${label} must be non-empty.`);
567
+ }
568
+ return resolveOptionalPath(trimmed, cwd);
569
+ }
570
+ function resolveOptionalPath(value, cwd) {
571
+ return isAbsolute(value) ? resolve(value) : resolve(cwd, value);
572
+ }
573
+ function coercePositiveInteger(value, fallback, label) {
574
+ if (value === undefined || value === null) {
575
+ return fallback;
576
+ }
577
+ if (!Number.isInteger(value) || value <= 0) {
578
+ throw new Error(`${label} must be a positive integer.`);
579
+ }
580
+ return value;
581
+ }
582
+ function coercePositiveTimerSeconds(value, fallback, label) {
583
+ const parsed = coercePositiveInteger(value, fallback, label);
584
+ if (parsed > CONTROL_HOST_SUPERVISION_MAX_NODE_TIMER_SECONDS) {
585
+ throw new Error(`${label} must be <= ${CONTROL_HOST_SUPERVISION_MAX_NODE_TIMER_SECONDS} seconds to stay within Node timer limits.`);
586
+ }
587
+ return parsed;
588
+ }
589
+ function coerceNonNegativeInteger(value, fallback, label) {
590
+ if (value === undefined || value === null) {
591
+ return fallback;
592
+ }
593
+ if (!Number.isInteger(value) || value < 0) {
594
+ throw new Error(`${label} must be a non-negative integer.`);
595
+ }
596
+ return value;
597
+ }
598
+ function escapeXml(value) {
599
+ return value
600
+ .replaceAll('&', '&amp;')
601
+ .replaceAll('<', '&lt;')
602
+ .replaceAll('>', '&gt;')
603
+ .replaceAll('"', '&quot;')
604
+ .replaceAll("'", '&apos;');
605
+ }
606
+ function isRecord(value) {
607
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
608
+ }
@@ -0,0 +1,8 @@
1
+ import { createControlOversightReadService } from './controlOversightReadService.js';
2
+ export function createControlOversightFacade(context) {
3
+ const readService = createControlOversightReadService(context);
4
+ return {
5
+ ...readService,
6
+ subscribe: (listener) => context.runtime.subscribe(listener)
7
+ };
8
+ }
@@ -0,0 +1,16 @@
1
+ import { readControlTelegramDispatch } from './controlTelegramDispatchRead.js';
2
+ import { readControlTelegramQuestions } from './controlTelegramQuestionRead.js';
3
+ export function createControlOversightReadService(context) {
4
+ return {
5
+ readSelectedRun: async () => context.runtime.snapshot().readSelectedRunSnapshot(),
6
+ readDispatch: async () => readControlTelegramDispatch({
7
+ ...context,
8
+ expiryLifecycle: context.expiryLifecycle,
9
+ emitDispatchPilotAuditEvents: context.emitDispatchPilotAuditEvents
10
+ }),
11
+ readQuestions: async () => readControlTelegramQuestions({
12
+ ...context,
13
+ expiryLifecycle: context.expiryLifecycle
14
+ })
15
+ };
16
+ }
@@ -0,0 +1,6 @@
1
+ export const LINEAR_ADVISORY_STATE_FILE = 'linear-advisory-state.json';
2
+ export const PROVIDER_INTAKE_STATE_FILE = 'provider-intake-state.json';
3
+ export const CONTROL_HOST_OWNER_FILE = 'control-host-owner.json';
4
+ export const CONTROL_HOST_OWNER_LOCK_DIR = 'control-host-owner.lock';
5
+ export const CONTROL_HOST_DUPLICATE_OWNER_FILE = 'control-host-duplicate-owner.json';
6
+ export const CONTROL_HOST_STALE_OWNER_FILE = 'control-host-stale-owner.json';
@@ -0,0 +1,18 @@
1
+ import { createQuestionChildResolutionAdapter } from './questionChildResolutionAdapter.js';
2
+ export function createControlQuestionChildResolutionAdapter(context) {
3
+ return createQuestionChildResolutionAdapter({
4
+ allowedRunRoots: context.config.ui.allowedRunRoots,
5
+ allowedBindHosts: context.config.ui.allowedBindHosts,
6
+ expiryFallback: context.config.delegate.expiryFallback,
7
+ readParentRunId: () => context.controlStore.snapshot().run_id,
8
+ validateDelegationToken: (token, parentRunId, childRunId) => Boolean(context.delegationTokens.validate(token, parentRunId, childRunId)),
9
+ emitResolutionFallback: (payload) => emitControlQuestionChildResolutionFallbackEvent(context, payload)
10
+ });
11
+ }
12
+ async function emitControlQuestionChildResolutionFallbackEvent(context, payload) {
13
+ await context.eventTransport.emitControlEvent({
14
+ event: 'question.resolve_child_fallback',
15
+ actor: 'control',
16
+ payload: payload
17
+ });
18
+ }