@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,476 @@
1
+ import { isoTimestamp } from '../utils/time.js';
2
+ const TRANSPORT_MUTATING_ACTIONS = new Set(['pause', 'resume', 'cancel']);
3
+ const TRANSPORT_IDENTITY_PATTERN = /^[A-Za-z0-9._:@-]{1,128}$/;
4
+ const TRANSPORT_SOURCE_PATTERN = /^[A-Za-z0-9._:-]{1,64}$/;
5
+ const TRANSPORT_PRINCIPAL_PATTERN = /^[A-Za-z0-9._:@/=-]{1,256}$/;
6
+ const TRANSPORT_NONCE_PATTERN = /^[A-Za-z0-9._~:/+=-]{8,256}$/;
7
+ const TRANSPORT_METADATA_KEYS = [
8
+ 'actor_id',
9
+ 'actorId',
10
+ 'actor_source',
11
+ 'actorSource',
12
+ 'transport_principal',
13
+ 'transportPrincipal',
14
+ 'principal',
15
+ 'transport_nonce',
16
+ 'transportNonce',
17
+ 'transport_nonce_expires_at',
18
+ 'transportNonceExpiresAt',
19
+ 'nonce',
20
+ 'nonce_expires_at',
21
+ 'nonceExpiresAt'
22
+ ];
23
+ const DEFAULT_TRANSPORT_IDEMPOTENCY_WINDOW_MS = 10 * 60 * 1000;
24
+ const DEFAULT_TRANSPORT_NONCE_MAX_TTL_MS = 10 * 60 * 1000;
25
+ const MAX_TRANSPORT_POLICY_WINDOW_MS = 24 * 60 * 60 * 1000;
26
+ export function normalizeControlActionRequest(input) {
27
+ const action = readStringValue(input.body, 'action');
28
+ if (!isControlAction(action)) {
29
+ return { ok: false, status: 400, error: 'invalid_action' };
30
+ }
31
+ if (input.authKind === 'session' && action !== 'pause' && action !== 'resume') {
32
+ return { ok: false, status: 403, error: 'ui_action_disallowed' };
33
+ }
34
+ if (input.authKind === 'session' && hasCoordinatorMetadata(input.body)) {
35
+ return { ok: false, status: 403, error: 'ui_control_metadata_disallowed' };
36
+ }
37
+ const requestId = readStringValue(input.body, 'request_id', 'requestId') ?? null;
38
+ const intentId = readStringValue(input.body, 'intent_id', 'intentId') ?? null;
39
+ const requestedBy = readStringValue(input.body, 'requested_by', 'requestedBy') ?? 'ui';
40
+ const reason = readStringValue(input.body, 'reason');
41
+ const confirmNonce = action === 'cancel' ? readStringValue(input.body, 'confirm_nonce', 'confirmNonce') : undefined;
42
+ const deferTransportResolutionToConfirmation = action === 'cancel' && Boolean(confirmNonce) && !hasAnyOwnProperty(input.body, ['transport']);
43
+ const transportMutationResult = deferTransportResolutionToConfirmation
44
+ ? { request: null }
45
+ : resolveTransportMutationRequest(input.body, action);
46
+ if (transportMutationResult.error) {
47
+ return {
48
+ ok: false,
49
+ status: transportMutationResult.status ?? 400,
50
+ error: transportMutationResult.error,
51
+ traceability: buildCanonicalTraceability({
52
+ action,
53
+ decision: 'rejected',
54
+ requestId,
55
+ intentId,
56
+ taskId: input.taskId,
57
+ runId: input.snapshot.run_id,
58
+ manifestPath: input.manifestPath,
59
+ transport: transportMutationResult.partial?.transport ?? null,
60
+ actorId: transportMutationResult.partial?.actorId ?? null,
61
+ actorSource: transportMutationResult.partial?.actorSource ?? null,
62
+ principal: transportMutationResult.partial?.principal ?? null
63
+ })
64
+ };
65
+ }
66
+ return {
67
+ ok: true,
68
+ value: {
69
+ action,
70
+ requestId,
71
+ intentId,
72
+ requestedBy,
73
+ reason,
74
+ confirmNonce,
75
+ deferTransportResolutionToConfirmation,
76
+ transportMutation: transportMutationResult.request
77
+ }
78
+ };
79
+ }
80
+ export function validateTransportMutationPreflight(input) {
81
+ if (!input.transportMutation) {
82
+ return { ok: true, idempotencyWindowMs: null };
83
+ }
84
+ const transportPolicy = resolveTransportMutatingPolicy(input.snapshot.feature_toggles);
85
+ const traceability = buildCanonicalTraceability({
86
+ action: input.action,
87
+ decision: 'rejected',
88
+ requestId: input.requestId,
89
+ intentId: input.intentId,
90
+ taskId: input.taskId,
91
+ runId: input.snapshot.run_id,
92
+ manifestPath: input.manifestPath,
93
+ transport: input.transportMutation.transport,
94
+ actorId: input.transportMutation.actorId,
95
+ actorSource: input.transportMutation.actorSource,
96
+ principal: input.transportMutation.principal
97
+ });
98
+ if (!transportPolicy.enabled) {
99
+ return {
100
+ ok: false,
101
+ status: 403,
102
+ error: 'transport_mutating_controls_disabled',
103
+ traceability
104
+ };
105
+ }
106
+ if (transportPolicy.allowedTransports &&
107
+ !transportPolicy.allowedTransports.has(input.transportMutation.transport)) {
108
+ return {
109
+ ok: false,
110
+ status: 403,
111
+ error: 'transport_mutating_transport_not_allowed',
112
+ traceability
113
+ };
114
+ }
115
+ if (!input.requestId && !input.intentId) {
116
+ return {
117
+ ok: false,
118
+ status: 400,
119
+ error: 'transport_idempotency_key_missing',
120
+ traceability
121
+ };
122
+ }
123
+ const nowMs = Date.now();
124
+ if (input.transportMutation.nonceExpiresAtMs <= nowMs) {
125
+ return {
126
+ ok: false,
127
+ status: 409,
128
+ error: 'transport_nonce_expired',
129
+ traceability
130
+ };
131
+ }
132
+ if (input.transportMutation.nonceExpiresAtMs - nowMs > transportPolicy.nonceMaxTtlMs) {
133
+ return {
134
+ ok: false,
135
+ status: 400,
136
+ error: 'transport_nonce_expiry_out_of_range',
137
+ traceability
138
+ };
139
+ }
140
+ if (input.isTransportNonceConsumed(input.transportMutation.nonce)) {
141
+ return {
142
+ ok: false,
143
+ status: 409,
144
+ error: 'transport_nonce_replayed',
145
+ traceability
146
+ };
147
+ }
148
+ return {
149
+ ok: true,
150
+ idempotencyWindowMs: transportPolicy.idempotencyWindowMs
151
+ };
152
+ }
153
+ export function resolveTransportMutationRequestFromConfirmationScope(input) {
154
+ const hasBodyTransportField = hasAnyOwnProperty(input.body, ['transport']);
155
+ const hasBodyTransportMetadata = hasAnyOwnProperty(input.body, TRANSPORT_METADATA_KEYS);
156
+ const hasConfirmedTransportField = hasAnyOwnProperty(input.params, ['transport']);
157
+ const hasConfirmedTransportMetadata = hasAnyOwnProperty(input.params, TRANSPORT_METADATA_KEYS);
158
+ const confirmedTransportRaw = readStringValue(input.params, 'transport');
159
+ const confirmedTransport = parseTransport(confirmedTransportRaw);
160
+ if (!confirmedTransport) {
161
+ if (hasConfirmedTransportField ||
162
+ hasConfirmedTransportMetadata ||
163
+ hasBodyTransportField ||
164
+ hasBodyTransportMetadata) {
165
+ return {
166
+ request: null,
167
+ status: 409,
168
+ error: 'confirmation_scope_mismatch',
169
+ partial: { transport: null }
170
+ };
171
+ }
172
+ return { request: null };
173
+ }
174
+ const confirmedActorId = readStringValue(input.params, 'actor_id', 'actorId');
175
+ const confirmedActorSource = readStringValue(input.params, 'actor_source', 'actorSource');
176
+ const confirmedPrincipal = readStringValue(input.params, 'transport_principal', 'transportPrincipal', 'principal');
177
+ const topLevelTransport = readStringValue(input.body, 'transport');
178
+ const topLevelActorId = readStringValue(input.body, 'actor_id', 'actorId');
179
+ const topLevelActorSource = readStringValue(input.body, 'actor_source', 'actorSource');
180
+ const topLevelPrincipal = readStringValue(input.body, 'transport_principal', 'transportPrincipal', 'principal');
181
+ const hasTopLevelActorId = hasAnyOwnProperty(input.body, ['actor_id', 'actorId']);
182
+ const hasTopLevelActorSource = hasAnyOwnProperty(input.body, ['actor_source', 'actorSource']);
183
+ const hasTopLevelPrincipal = hasAnyOwnProperty(input.body, [
184
+ 'transport_principal',
185
+ 'transportPrincipal',
186
+ 'principal'
187
+ ]);
188
+ if ((hasBodyTransportField && topLevelTransport !== confirmedTransport) ||
189
+ (hasTopLevelActorId && topLevelActorId !== confirmedActorId) ||
190
+ (hasTopLevelActorSource && topLevelActorSource !== confirmedActorSource) ||
191
+ (hasTopLevelPrincipal && topLevelPrincipal !== confirmedPrincipal)) {
192
+ return {
193
+ request: null,
194
+ status: 409,
195
+ error: 'confirmation_scope_mismatch',
196
+ partial: {
197
+ transport: confirmedTransport,
198
+ actorId: confirmedActorId ?? null,
199
+ actorSource: confirmedActorSource ?? null,
200
+ principal: confirmedPrincipal ?? null
201
+ }
202
+ };
203
+ }
204
+ return resolveTransportMutationRequest({
205
+ ...input.body,
206
+ transport: confirmedTransport,
207
+ actor_id: confirmedActorId,
208
+ actor_source: confirmedActorSource,
209
+ transport_principal: confirmedPrincipal
210
+ }, input.action);
211
+ }
212
+ export function resolveTransportMutationRequest(body, action) {
213
+ const mutatingAction = TRANSPORT_MUTATING_ACTIONS.has(action);
214
+ const hasTransportField = Object.prototype.hasOwnProperty.call(body, 'transport');
215
+ const hasTransportMetadata = TRANSPORT_METADATA_KEYS.some((key) => Object.prototype.hasOwnProperty.call(body, key));
216
+ if (mutatingAction && hasTransportMetadata && !hasTransportField) {
217
+ return { request: null, status: 400, error: 'transport_invalid', partial: { transport: null } };
218
+ }
219
+ const rawTransport = body.transport;
220
+ const normalizedTransport = typeof rawTransport === 'string' ? rawTransport.trim() : undefined;
221
+ if (hasTransportField && mutatingAction && !normalizedTransport) {
222
+ return { request: null, status: 400, error: 'transport_invalid', partial: { transport: null } };
223
+ }
224
+ const transport = parseTransport(normalizedTransport);
225
+ if (normalizedTransport && !transport) {
226
+ return { request: null, status: 400, error: 'transport_unsupported', partial: { transport: null } };
227
+ }
228
+ if (!transport || !mutatingAction) {
229
+ return { request: null };
230
+ }
231
+ const actorId = readStringValue(body, 'actor_id', 'actorId');
232
+ if (!actorId) {
233
+ return { request: null, status: 400, error: 'transport_actor_id_missing', partial: { transport } };
234
+ }
235
+ if (!TRANSPORT_IDENTITY_PATTERN.test(actorId)) {
236
+ return {
237
+ request: null,
238
+ status: 400,
239
+ error: 'transport_actor_id_invalid',
240
+ partial: { transport, actorId }
241
+ };
242
+ }
243
+ const actorSource = readStringValue(body, 'actor_source', 'actorSource');
244
+ if (!actorSource) {
245
+ return {
246
+ request: null,
247
+ status: 400,
248
+ error: 'transport_actor_source_missing',
249
+ partial: { transport, actorId }
250
+ };
251
+ }
252
+ if (!TRANSPORT_SOURCE_PATTERN.test(actorSource)) {
253
+ return {
254
+ request: null,
255
+ status: 400,
256
+ error: 'transport_actor_source_invalid',
257
+ partial: { transport, actorId, actorSource }
258
+ };
259
+ }
260
+ if (!actorSource.toLowerCase().startsWith(transport)) {
261
+ return {
262
+ request: null,
263
+ status: 400,
264
+ error: 'transport_actor_source_mismatch',
265
+ partial: { transport, actorId, actorSource }
266
+ };
267
+ }
268
+ const principal = readStringValue(body, 'transport_principal', 'transportPrincipal', 'principal');
269
+ if (!principal) {
270
+ return {
271
+ request: null,
272
+ status: 400,
273
+ error: 'transport_principal_missing',
274
+ partial: { transport, actorId, actorSource }
275
+ };
276
+ }
277
+ if (!TRANSPORT_PRINCIPAL_PATTERN.test(principal)) {
278
+ return {
279
+ request: null,
280
+ status: 400,
281
+ error: 'transport_principal_invalid',
282
+ partial: { transport, actorId, actorSource, principal }
283
+ };
284
+ }
285
+ const nonce = readStringValue(body, 'transport_nonce', 'transportNonce', 'nonce');
286
+ if (!nonce) {
287
+ return {
288
+ request: null,
289
+ status: 400,
290
+ error: 'transport_nonce_missing',
291
+ partial: { transport, actorId, actorSource, principal }
292
+ };
293
+ }
294
+ if (!TRANSPORT_NONCE_PATTERN.test(nonce)) {
295
+ return {
296
+ request: null,
297
+ status: 400,
298
+ error: 'transport_nonce_invalid',
299
+ partial: { transport, actorId, actorSource, principal }
300
+ };
301
+ }
302
+ const rawExpiry = readStringValue(body, 'transport_nonce_expires_at', 'transportNonceExpiresAt', 'nonce_expires_at', 'nonceExpiresAt');
303
+ if (!rawExpiry) {
304
+ return {
305
+ request: null,
306
+ status: 400,
307
+ error: 'transport_nonce_expiry_missing',
308
+ partial: { transport, actorId, actorSource, principal }
309
+ };
310
+ }
311
+ const nonceExpiresAtMs = Date.parse(rawExpiry);
312
+ if (!Number.isFinite(nonceExpiresAtMs)) {
313
+ return {
314
+ request: null,
315
+ status: 400,
316
+ error: 'transport_nonce_expiry_invalid',
317
+ partial: { transport, actorId, actorSource, principal }
318
+ };
319
+ }
320
+ return {
321
+ request: {
322
+ transport,
323
+ actorId,
324
+ actorSource,
325
+ principal,
326
+ nonce,
327
+ nonceExpiresAt: new Date(nonceExpiresAtMs).toISOString(),
328
+ nonceExpiresAtMs
329
+ }
330
+ };
331
+ }
332
+ export function buildCanonicalTraceability(input) {
333
+ const timestamp = input.timestamp ?? isoTimestamp();
334
+ return {
335
+ actor_id: input.actorId,
336
+ actor_source: input.actorSource,
337
+ transport: input.transport,
338
+ transport_principal: input.principal,
339
+ intent_id: input.intentId,
340
+ request_id: input.requestId,
341
+ task_id: input.taskId,
342
+ run_id: input.runId,
343
+ manifest_path: input.manifestPath,
344
+ action: input.action,
345
+ decision: input.decision,
346
+ timestamp
347
+ };
348
+ }
349
+ function isControlAction(action) {
350
+ return action === 'pause' || action === 'resume' || action === 'cancel' || action === 'fail';
351
+ }
352
+ function parseTransport(value) {
353
+ if (!value) {
354
+ return null;
355
+ }
356
+ if (value === 'discord' || value === 'telegram') {
357
+ return value;
358
+ }
359
+ return null;
360
+ }
361
+ function resolveTransportMutatingPolicy(featureToggles) {
362
+ const toggles = featureToggles ?? {};
363
+ const direct = readRecordValue(toggles, 'transport_mutating_controls');
364
+ const coordinator = readRecordValue(toggles, 'coordinator');
365
+ const nested = coordinator ? readRecordValue(coordinator, 'transport_mutating_controls') : undefined;
366
+ const policy = nested ?? direct ?? {};
367
+ const allowedTransportValues = readStringArrayValue(policy, 'allowed_transports', 'allowedTransports');
368
+ return {
369
+ enabled: readBooleanValue(policy, 'enabled') ?? false,
370
+ idempotencyWindowMs: clampPolicyWindow(readNumberValue(policy, 'idempotency_window_ms', 'idempotencyWindowMs'), DEFAULT_TRANSPORT_IDEMPOTENCY_WINDOW_MS),
371
+ nonceMaxTtlMs: clampPolicyWindow(readNumberValue(policy, 'nonce_max_ttl_ms', 'nonceMaxTtlMs'), DEFAULT_TRANSPORT_NONCE_MAX_TTL_MS),
372
+ allowedTransports: resolveAllowedTransportPolicy(allowedTransportValues)
373
+ };
374
+ }
375
+ function resolveAllowedTransportPolicy(values) {
376
+ if (!values) {
377
+ return null;
378
+ }
379
+ const allowed = new Set();
380
+ for (const value of values) {
381
+ const transport = parseTransport(value);
382
+ if (transport) {
383
+ allowed.add(transport);
384
+ }
385
+ }
386
+ return allowed;
387
+ }
388
+ function clampPolicyWindow(value, fallback) {
389
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
390
+ return fallback;
391
+ }
392
+ return Math.min(Math.max(Math.floor(value), 1), MAX_TRANSPORT_POLICY_WINDOW_MS);
393
+ }
394
+ function hasCoordinatorMetadata(body) {
395
+ const disallowedKeys = [
396
+ 'intent_id',
397
+ 'intentId',
398
+ 'request_id',
399
+ 'requestId',
400
+ 'task_id',
401
+ 'taskId',
402
+ 'run_id',
403
+ 'runId',
404
+ 'manifest_path',
405
+ 'manifestPath'
406
+ ];
407
+ return disallowedKeys.some((key) => Object.prototype.hasOwnProperty.call(body, key));
408
+ }
409
+ function readStringValue(record, ...keys) {
410
+ for (const key of keys) {
411
+ const value = record[key];
412
+ if (typeof value === 'string' && value.trim().length > 0) {
413
+ return value.trim();
414
+ }
415
+ }
416
+ return undefined;
417
+ }
418
+ function hasAnyOwnProperty(record, keys) {
419
+ for (const key of keys) {
420
+ if (Object.prototype.hasOwnProperty.call(record, key)) {
421
+ return true;
422
+ }
423
+ }
424
+ return false;
425
+ }
426
+ function readNumberValue(record, ...keys) {
427
+ for (const key of keys) {
428
+ const value = record[key];
429
+ if (typeof value === 'number' && Number.isFinite(value)) {
430
+ return value;
431
+ }
432
+ if (typeof value === 'string' && value.trim().length > 0) {
433
+ const parsed = Number(value);
434
+ if (Number.isFinite(parsed)) {
435
+ return parsed;
436
+ }
437
+ }
438
+ }
439
+ return undefined;
440
+ }
441
+ function readBooleanValue(record, ...keys) {
442
+ for (const key of keys) {
443
+ const value = record[key];
444
+ if (typeof value === 'boolean') {
445
+ return value;
446
+ }
447
+ }
448
+ return undefined;
449
+ }
450
+ function readRecordValue(record, key) {
451
+ const value = record[key];
452
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
453
+ return value;
454
+ }
455
+ return undefined;
456
+ }
457
+ function readStringArrayValue(record, ...keys) {
458
+ for (const key of keys) {
459
+ const value = record[key];
460
+ if (!Array.isArray(value)) {
461
+ continue;
462
+ }
463
+ const parsed = [];
464
+ for (const item of value) {
465
+ if (typeof item !== 'string') {
466
+ continue;
467
+ }
468
+ const trimmed = item.trim();
469
+ if (trimmed.length > 0) {
470
+ parsed.push(trimmed);
471
+ }
472
+ }
473
+ return parsed;
474
+ }
475
+ return undefined;
476
+ }
@@ -0,0 +1,57 @@
1
+ import { basename, dirname } from 'node:path';
2
+ import { createControlQuestionChildResolutionAdapter } from './controlQuestionChildResolution.js';
3
+ import { emitControlActionAuditEvent, emitDispatchPilotAuditEvents, writeControlError } from './controlServerAuditAndErrorHelpers.js';
4
+ import { runProviderIssueHandoffRefresh } from './controlServerPublicLifecycle.js';
5
+ import { readJsonBody } from './controlServerRequestBodyHelpers.js';
6
+ export function createControlAuthenticatedRouteContext(input) {
7
+ const questionChildResolutionAdapter = createControlQuestionChildResolutionAdapter(input.context);
8
+ return {
9
+ pathname: input.pathname,
10
+ method: input.req.method,
11
+ authKind: input.authKind,
12
+ req: input.req,
13
+ res: input.res,
14
+ clients: input.context.clients,
15
+ presenterContext: input.presenterContext,
16
+ confirmAutoPause: input.context.config.confirm.autoPause,
17
+ taskId: resolveTaskIdFromManifestPath(input.context.paths.manifestPath),
18
+ manifestPath: input.context.paths.manifestPath,
19
+ controlStore: input.context.controlStore,
20
+ confirmationStore: input.context.confirmationStore,
21
+ questionQueue: input.context.questionQueue,
22
+ delegationTokens: input.context.delegationTokens,
23
+ persist: input.context.persist,
24
+ runtime: input.context.runtime,
25
+ refreshProviderIssues: () => input.context.providerIssueHandoff
26
+ ? runProviderIssueHandoffRefresh(input.context.providerIssueHandoff, {
27
+ queueIfBusy: true,
28
+ acknowledgeAccepted: true,
29
+ allowIdleRestartRequiredRetry: true
30
+ })
31
+ : Promise.resolve(null),
32
+ readRequestBody: () => readJsonBody(input.req),
33
+ readDispatchEvaluation: () => input.runtimeSnapshot.readDispatchEvaluation(),
34
+ onDispatchEvaluated: (record) => emitDispatchPilotAuditEvents(input.context, record),
35
+ emitControlEvent: (eventInput) => input.context.eventTransport.emitControlEvent(eventInput),
36
+ emitControlActionAuditEvent: (auditInput) => emitControlActionAuditEvent(input.context, auditInput),
37
+ writeControlError: (status, error, traceability) => writeControlError(input.res, status, error, traceability),
38
+ expireConfirmations: () => input.context.expiryLifecycle?.expireConfirmations() ?? Promise.resolve(),
39
+ expireQuestions: () => input.context.expiryLifecycle?.expireQuestions(questionChildResolutionAdapter) ?? Promise.resolve(),
40
+ queueQuestionResolutions: (records) => questionChildResolutionAdapter.queueQuestionResolutions(records),
41
+ readDelegationHeaders: () => questionChildResolutionAdapter.readDelegationHeaders(input.req),
42
+ validateDelegation: (delegationAuth) => questionChildResolutionAdapter.validateDelegation(delegationAuth),
43
+ resolveManifestPath: (rawPath) => questionChildResolutionAdapter.resolveManifestPath(rawPath),
44
+ readManifest: (path) => questionChildResolutionAdapter.readManifest(path),
45
+ resolveChildQuestion: (record, outcome) => questionChildResolutionAdapter.resolveChildQuestion(record, outcome)
46
+ };
47
+ }
48
+ function resolveTaskIdFromManifestPath(manifestPath) {
49
+ const runDir = dirname(manifestPath);
50
+ const cliDir = dirname(runDir);
51
+ if (basename(cliDir) !== 'cli') {
52
+ return null;
53
+ }
54
+ const taskDir = dirname(cliDir);
55
+ const taskId = basename(taskDir);
56
+ return taskId || null;
57
+ }
@@ -0,0 +1,39 @@
1
+ import { createControlExpiryLifecycle } from './controlExpiryLifecycle.js';
2
+ import { buildControlInternalContext } from './controlRequestContext.js';
3
+ import { createControlQuestionChildResolutionAdapter } from './controlQuestionChildResolution.js';
4
+ import { createControlTelegramBridgeBootstrapLifecycle } from './controlTelegramBridgeBootstrapLifecycle.js';
5
+ export function createControlBootstrapAssembly(options) {
6
+ let expiryLifecycle = null;
7
+ const assembledExpiryLifecycle = createControlExpiryLifecycle({
8
+ intervalMs: options.intervalMs,
9
+ confirmationStore: options.requestContextShared.confirmationStore,
10
+ questionQueue: options.requestContextShared.questionQueue,
11
+ persist: {
12
+ confirmations: options.requestContextShared.persist.confirmations,
13
+ questions: options.requestContextShared.persist.questions
14
+ },
15
+ runtime: options.requestContextShared.runtime,
16
+ emitControlEvent: (input) => options.requestContextShared.eventTransport.emitControlEvent(input),
17
+ createQuestionChildResolutionAdapter: () => createControlQuestionChildResolutionAdapter(buildControlInternalContext({
18
+ ...options.requestContextShared,
19
+ expiryLifecycle
20
+ }))
21
+ });
22
+ expiryLifecycle = assembledExpiryLifecycle;
23
+ const bootstrapLifecycle = createControlTelegramBridgeBootstrapLifecycle({
24
+ paths: {
25
+ runDir: options.requestContextShared.paths.runDir,
26
+ controlAuthPath: options.requestContextShared.paths.controlAuthPath,
27
+ controlEndpointPath: options.requestContextShared.paths.controlEndpointPath
28
+ },
29
+ persistControl: options.requestContextShared.persist.control,
30
+ startExpiryLifecycle: () => expiryLifecycle?.start(),
31
+ requestContextShared: options.requestContextShared,
32
+ getExpiryLifecycle: () => expiryLifecycle,
33
+ emitDispatchPilotAuditEvents: options.emitDispatchPilotAuditEvents
34
+ });
35
+ return {
36
+ expiryLifecycle: assembledExpiryLifecycle,
37
+ bootstrapLifecycle
38
+ };
39
+ }
@@ -0,0 +1,16 @@
1
+ import { chmod } from 'node:fs/promises';
2
+ import { writeJsonAtomic } from '../utils/fs.js';
3
+ import { isoTimestamp } from '../utils/time.js';
4
+ export async function persistControlBootstrapMetadata(context, input) {
5
+ await writeJsonAtomic(context.paths.controlAuthPath, {
6
+ token: input.controlToken,
7
+ created_at: isoTimestamp()
8
+ });
9
+ await chmod(context.paths.controlAuthPath, 0o600).catch(() => undefined);
10
+ await writeJsonAtomic(context.paths.controlEndpointPath, {
11
+ base_url: input.baseUrl,
12
+ token_path: context.paths.controlAuthPath
13
+ });
14
+ await chmod(context.paths.controlEndpointPath, 0o600).catch(() => undefined);
15
+ await context.persistControl();
16
+ }
@@ -0,0 +1,49 @@
1
+ import { logger } from '../../logger.js';
2
+ export function createControlEventTransport(options) {
3
+ return new ControlEventTransportRuntime(options);
4
+ }
5
+ class ControlEventTransportRuntime {
6
+ eventStream;
7
+ clients;
8
+ runtime;
9
+ constructor(options) {
10
+ this.eventStream = options.eventStream;
11
+ this.clients = options.clients;
12
+ this.runtime = options.runtime;
13
+ }
14
+ async emitControlEvent(input) {
15
+ if (!this.eventStream) {
16
+ return;
17
+ }
18
+ let entry;
19
+ try {
20
+ entry = await this.eventStream.append({
21
+ event: input.event,
22
+ actor: input.actor,
23
+ payload: input.payload
24
+ });
25
+ }
26
+ catch (error) {
27
+ logger.warn(`Failed to append control event ${input.event}: ${error?.message ?? error}`);
28
+ return;
29
+ }
30
+ this.writeToClients(entry);
31
+ }
32
+ broadcast(entry) {
33
+ this.writeToClients(entry);
34
+ this.runtime.publish({
35
+ eventSeq: entry.seq,
36
+ source: entry.event
37
+ });
38
+ }
39
+ writeToClients(entry) {
40
+ const payload = `data: ${JSON.stringify(entry)}\n\n`;
41
+ for (const client of this.clients) {
42
+ client.write(payload, (error) => {
43
+ if (error) {
44
+ this.clients.delete(client);
45
+ }
46
+ });
47
+ }
48
+ }
49
+ }