@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,102 @@
1
+ class DefaultControlExpiryLifecycle {
2
+ intervalMs;
3
+ confirmationStore;
4
+ questionQueue;
5
+ runtime;
6
+ persist;
7
+ emitControlEvent;
8
+ createQuestionChildResolutionAdapter;
9
+ timer = null;
10
+ closed = false;
11
+ constructor(options) {
12
+ this.intervalMs = options.intervalMs;
13
+ this.confirmationStore = options.confirmationStore;
14
+ this.questionQueue = options.questionQueue;
15
+ this.runtime = options.runtime;
16
+ this.persist = options.persist;
17
+ this.emitControlEvent = options.emitControlEvent;
18
+ this.createQuestionChildResolutionAdapter = options.createQuestionChildResolutionAdapter;
19
+ }
20
+ start() {
21
+ if (this.closed || this.timer) {
22
+ return;
23
+ }
24
+ this.scheduleNext();
25
+ }
26
+ close() {
27
+ this.closed = true;
28
+ if (this.timer) {
29
+ clearTimeout(this.timer);
30
+ this.timer = null;
31
+ }
32
+ }
33
+ async expireConfirmations() {
34
+ const expired = this.confirmationStore.expire();
35
+ if (expired.length === 0) {
36
+ return;
37
+ }
38
+ await this.persist.confirmations();
39
+ for (const entry of expired) {
40
+ await this.emitControlEvent({
41
+ event: 'confirmation_resolved',
42
+ actor: 'runner',
43
+ payload: {
44
+ request_id: entry.request.request_id,
45
+ nonce_id: entry.nonce_id,
46
+ outcome: 'expired'
47
+ }
48
+ });
49
+ }
50
+ }
51
+ async expireQuestions(questionChildResolutionAdapter = this.createQuestionChildResolutionAdapter()) {
52
+ const expired = this.questionQueue.expire();
53
+ if (expired.length === 0) {
54
+ return;
55
+ }
56
+ await this.persist.questions();
57
+ for (const record of expired) {
58
+ await this.emitControlEvent({
59
+ event: 'question_closed',
60
+ actor: 'runner',
61
+ payload: {
62
+ question_id: record.question_id,
63
+ parent_run_id: record.parent_run_id,
64
+ outcome: 'expired',
65
+ closed_at: record.closed_at ?? null,
66
+ expires_at: record.expires_at ?? null
67
+ }
68
+ });
69
+ await questionChildResolutionAdapter.resolveChildQuestion(record, 'expired');
70
+ }
71
+ this.runtime.publish({ source: 'questions.expire' });
72
+ }
73
+ scheduleNext() {
74
+ this.timer = setTimeout(() => {
75
+ void this.runScheduledSweep();
76
+ }, this.intervalMs);
77
+ }
78
+ async runScheduledSweep() {
79
+ this.timer = null;
80
+ if (this.closed) {
81
+ return;
82
+ }
83
+ try {
84
+ await this.expireConfirmations();
85
+ }
86
+ catch {
87
+ // Preserve prior best-effort background expiry behavior.
88
+ }
89
+ try {
90
+ await this.expireQuestions();
91
+ }
92
+ catch {
93
+ // Preserve prior best-effort background expiry behavior.
94
+ }
95
+ if (!this.closed) {
96
+ this.scheduleNext();
97
+ }
98
+ }
99
+ }
100
+ export function createControlExpiryLifecycle(options) {
101
+ return new DefaultControlExpiryLifecycle(options);
102
+ }
@@ -0,0 +1,480 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, rm } from 'node:fs/promises';
3
+ import { hostname } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import process from 'node:process';
6
+ import { writeJsonAtomic } from '../utils/fs.js';
7
+ import { isoTimestamp } from '../utils/time.js';
8
+ import { CONTROL_HOST_DUPLICATE_OWNER_FILE, CONTROL_HOST_OWNER_FILE, CONTROL_HOST_OWNER_LOCK_DIR, CONTROL_HOST_STALE_OWNER_FILE } from './controlPersistenceFiles.js';
9
+ export class DuplicateControlHostOwnerError extends Error {
10
+ code = 'duplicate_control_host_owner';
11
+ reason;
12
+ existingOwner;
13
+ attemptedOwner;
14
+ diagnosticPath;
15
+ constructor(input) {
16
+ super(formatDuplicateControlHostOwnerMessage(input.reason, input.existingOwner, input.attemptedOwner, input.diagnosticPath));
17
+ this.name = 'DuplicateControlHostOwnerError';
18
+ this.reason = input.reason;
19
+ this.existingOwner = input.existingOwner;
20
+ this.attemptedOwner = input.attemptedOwner;
21
+ this.diagnosticPath = input.diagnosticPath;
22
+ }
23
+ }
24
+ export async function acquireControlHostOwnership(options) {
25
+ const paths = resolveControlHostOwnershipPaths(options.paths.runDir);
26
+ const now = options.now ?? isoTimestamp;
27
+ const isProcessAlive = options.isProcessAlive ?? isLocalProcessAlive;
28
+ const attemptedOwner = buildControlHostOwnerMetadata(options, paths, now());
29
+ await mkdir(paths.runDir, { recursive: true });
30
+ await removePriorOwnershipDiagnostics(paths).catch(() => undefined);
31
+ for (let attempt = 0; attempt < 2; attempt += 1) {
32
+ try {
33
+ await mkdir(paths.lockDir);
34
+ try {
35
+ await writeJsonAtomic(paths.lockOwnerPath, attemptedOwner);
36
+ await writeJsonAtomic(paths.ownerPath, attemptedOwner);
37
+ }
38
+ catch (error) {
39
+ await rm(paths.lockDir, { recursive: true, force: true }).catch(() => undefined);
40
+ throw error;
41
+ }
42
+ return createControlHostOwnershipHandle(attemptedOwner, paths, now);
43
+ }
44
+ catch (error) {
45
+ if (!isAlreadyExistsError(error)) {
46
+ throw error;
47
+ }
48
+ const existingOwner = await readControlHostOwnerMetadataFromPath(paths.lockOwnerPath);
49
+ const existingState = classifyExistingOwner(existingOwner, {
50
+ host: attemptedOwner.hostname,
51
+ isProcessAlive
52
+ });
53
+ if (existingState.kind === 'stale') {
54
+ await reclaimStaleControlHostOwner({
55
+ paths,
56
+ attemptedOwner,
57
+ staleOwner: existingState.owner,
58
+ observedAt: now,
59
+ isProcessAlive
60
+ });
61
+ continue;
62
+ }
63
+ const reason = existingState.kind === 'active'
64
+ ? 'duplicate_control_host_owner'
65
+ : 'ambiguous_control_host_owner';
66
+ await writeControlHostOwnershipDiagnostic({
67
+ paths,
68
+ reason,
69
+ action: reason === 'duplicate_control_host_owner'
70
+ ? 'duplicate_rejected'
71
+ : 'ambiguous_rejected',
72
+ existingOwner: existingState.owner,
73
+ attemptedOwner,
74
+ observedAt: now(),
75
+ diagnosticPath: paths.duplicateDiagnosticPath
76
+ });
77
+ throw new DuplicateControlHostOwnerError({
78
+ reason,
79
+ existingOwner: existingState.owner,
80
+ attemptedOwner,
81
+ diagnosticPath: paths.duplicateDiagnosticPath
82
+ });
83
+ }
84
+ }
85
+ throw new DuplicateControlHostOwnerError({
86
+ reason: 'ambiguous_control_host_owner',
87
+ existingOwner: await readControlHostOwnerMetadataFromPath(paths.lockOwnerPath),
88
+ attemptedOwner,
89
+ diagnosticPath: paths.duplicateDiagnosticPath
90
+ });
91
+ }
92
+ export async function readControlHostOwnerMetadata(runDir) {
93
+ return await readControlHostOwnerMetadataFromPath(join(runDir, CONTROL_HOST_OWNER_FILE));
94
+ }
95
+ export function buildControlHostOwnershipPollingPayload(metadata) {
96
+ return {
97
+ status: 'owned',
98
+ reason: null,
99
+ updated_at: metadata.updated_at,
100
+ owner: summarizeControlHostOwner(metadata),
101
+ diagnostic_path: null,
102
+ lock_dir: metadata.lock_dir,
103
+ owner_path: metadata.owner_path
104
+ };
105
+ }
106
+ export async function readControlHostOwnershipDiagnosticSummary(runDir) {
107
+ const duplicate = await readControlHostOwnershipDiagnosticFromPath(join(runDir, CONTROL_HOST_DUPLICATE_OWNER_FILE));
108
+ if (duplicate) {
109
+ return buildControlHostOwnershipPollingPayloadFromDiagnostic(duplicate);
110
+ }
111
+ const stale = await readControlHostOwnershipDiagnosticFromPath(join(runDir, CONTROL_HOST_STALE_OWNER_FILE));
112
+ if (stale) {
113
+ return buildControlHostOwnershipPollingPayloadFromDiagnostic(stale);
114
+ }
115
+ return null;
116
+ }
117
+ export async function readControlHostOwnershipOperatorHint(runDir) {
118
+ const diagnostic = await readControlHostOwnershipDiagnosticSummary(runDir);
119
+ if (!diagnostic || diagnostic.status === 'owned') {
120
+ return null;
121
+ }
122
+ const owner = diagnostic.owner;
123
+ const attempted = diagnostic.attempted_owner ?? null;
124
+ const ownerText = owner
125
+ ? `owner pid=${owner.pid} host=${owner.hostname} task=${owner.task_id ?? 'unknown'} run=${owner.run_id} pipeline=${owner.pipeline_id ?? 'unknown'}`
126
+ : 'owner metadata unavailable';
127
+ const attemptedText = attempted
128
+ ? `attempted pid=${attempted.pid} host=${attempted.hostname}`
129
+ : 'attempted owner unavailable';
130
+ return `control-host ownership diagnostic: ${diagnostic.reason ?? diagnostic.status}; ${ownerText}; ${attemptedText}; artifact=${diagnostic.diagnostic_path ?? 'unknown'}`;
131
+ }
132
+ export function normalizeControlHostOwnershipPollingPayload(value) {
133
+ if (!isRecordLike(value)) {
134
+ return null;
135
+ }
136
+ const status = normalizePollingStatus(value.status);
137
+ if (!status) {
138
+ return null;
139
+ }
140
+ return {
141
+ status,
142
+ reason: normalizeDiagnosticReason(value.reason),
143
+ updated_at: typeof value.updated_at === 'string' ? value.updated_at : '',
144
+ owner: normalizeControlHostOwnerSummary(value.owner),
145
+ attempted_owner: normalizeControlHostOwnerSummary(value.attempted_owner),
146
+ diagnostic_path: typeof value.diagnostic_path === 'string' ? value.diagnostic_path : null,
147
+ lock_dir: typeof value.lock_dir === 'string' ? value.lock_dir : null,
148
+ owner_path: typeof value.owner_path === 'string' ? value.owner_path : null
149
+ };
150
+ }
151
+ function createControlHostOwnershipHandle(metadata, paths, now) {
152
+ return {
153
+ metadata,
154
+ polling: buildControlHostOwnershipPollingPayload(metadata),
155
+ async release() {
156
+ const currentOwner = await readControlHostOwnerMetadataFromPath(paths.lockOwnerPath);
157
+ if (!currentOwner || currentOwner.owner_token !== metadata.owner_token) {
158
+ return;
159
+ }
160
+ const releasedAt = now();
161
+ const releasedOwner = {
162
+ ...metadata,
163
+ status: 'released',
164
+ updated_at: releasedAt,
165
+ released_at: releasedAt
166
+ };
167
+ await writeJsonAtomic(paths.ownerPath, releasedOwner);
168
+ await rm(paths.lockDir, { recursive: true, force: true });
169
+ }
170
+ };
171
+ }
172
+ function buildControlHostOwnerMetadata(options, paths, timestamp) {
173
+ return {
174
+ schema_version: 1,
175
+ status: 'owned',
176
+ owner_token: randomUUID(),
177
+ acquired_at: timestamp,
178
+ updated_at: timestamp,
179
+ released_at: null,
180
+ repo_root: normalizeNullableString(options.repoRoot),
181
+ task_id: normalizeNullableString(options.taskId),
182
+ run_id: options.runId,
183
+ run_dir: paths.runDir,
184
+ pipeline_id: normalizeNullableString(options.pipelineId),
185
+ pid: options.processId ?? process.pid,
186
+ ppid: options.parentProcessId === undefined ? process.ppid : options.parentProcessId,
187
+ hostname: options.host ?? hostname(),
188
+ cwd: options.cwd === undefined ? process.cwd() : options.cwd,
189
+ argv: options.argv ?? process.argv.slice(),
190
+ lock_dir: paths.lockDir,
191
+ lock_owner_path: paths.lockOwnerPath,
192
+ owner_path: paths.ownerPath
193
+ };
194
+ }
195
+ function resolveControlHostOwnershipPaths(runDir) {
196
+ return {
197
+ runDir,
198
+ lockDir: join(runDir, CONTROL_HOST_OWNER_LOCK_DIR),
199
+ reclaimLockDir: join(runDir, `${CONTROL_HOST_OWNER_LOCK_DIR}.reclaim`),
200
+ lockOwnerPath: join(runDir, CONTROL_HOST_OWNER_LOCK_DIR, 'owner.json'),
201
+ ownerPath: join(runDir, CONTROL_HOST_OWNER_FILE),
202
+ duplicateDiagnosticPath: join(runDir, CONTROL_HOST_DUPLICATE_OWNER_FILE),
203
+ staleDiagnosticPath: join(runDir, CONTROL_HOST_STALE_OWNER_FILE)
204
+ };
205
+ }
206
+ async function reclaimStaleControlHostOwner(input) {
207
+ try {
208
+ await mkdir(input.paths.reclaimLockDir);
209
+ }
210
+ catch (error) {
211
+ if (isAlreadyExistsError(error)) {
212
+ return false;
213
+ }
214
+ throw error;
215
+ }
216
+ try {
217
+ const currentOwner = await readControlHostOwnerMetadataFromPath(input.paths.lockOwnerPath);
218
+ if (!currentOwner || currentOwner.owner_token !== input.staleOwner.owner_token) {
219
+ return false;
220
+ }
221
+ const currentState = classifyExistingOwner(currentOwner, {
222
+ host: input.attemptedOwner.hostname,
223
+ isProcessAlive: input.isProcessAlive
224
+ });
225
+ if (currentState.kind !== 'stale') {
226
+ return false;
227
+ }
228
+ await writeControlHostOwnershipDiagnostic({
229
+ paths: input.paths,
230
+ reason: 'stale_control_host_owner',
231
+ action: 'stale_reclaimed',
232
+ existingOwner: currentOwner,
233
+ attemptedOwner: input.attemptedOwner,
234
+ observedAt: input.observedAt(),
235
+ diagnosticPath: input.paths.staleDiagnosticPath
236
+ });
237
+ await rm(input.paths.lockDir, { recursive: true, force: true });
238
+ return true;
239
+ }
240
+ finally {
241
+ await rm(input.paths.reclaimLockDir, { recursive: true, force: true }).catch(() => undefined);
242
+ }
243
+ }
244
+ async function writeControlHostOwnershipDiagnostic(input) {
245
+ const diagnostic = {
246
+ schema_version: 1,
247
+ reason: input.reason,
248
+ observed_at: input.observedAt,
249
+ run_dir: input.paths.runDir,
250
+ lock_dir: input.paths.lockDir,
251
+ diagnostic_path: input.diagnosticPath,
252
+ existing_owner: input.existingOwner,
253
+ attempted_owner: input.attemptedOwner,
254
+ action: input.action
255
+ };
256
+ await writeJsonAtomic(input.diagnosticPath, diagnostic);
257
+ return diagnostic;
258
+ }
259
+ async function removePriorOwnershipDiagnostics(paths) {
260
+ await Promise.all([
261
+ rm(paths.duplicateDiagnosticPath, { force: true }),
262
+ rm(paths.staleDiagnosticPath, { force: true })
263
+ ]);
264
+ }
265
+ function classifyExistingOwner(owner, input) {
266
+ if (!owner) {
267
+ return { kind: 'ambiguous', owner: null };
268
+ }
269
+ if (!Number.isInteger(owner.pid) || owner.pid <= 0) {
270
+ return { kind: 'ambiguous', owner };
271
+ }
272
+ if (owner.hostname && owner.hostname !== input.host) {
273
+ return { kind: 'active', owner };
274
+ }
275
+ return input.isProcessAlive(owner.pid)
276
+ ? { kind: 'active', owner }
277
+ : { kind: 'stale', owner };
278
+ }
279
+ function isLocalProcessAlive(pid) {
280
+ try {
281
+ process.kill(pid, 0);
282
+ return true;
283
+ }
284
+ catch (error) {
285
+ return error?.code !== 'ESRCH';
286
+ }
287
+ }
288
+ async function readControlHostOwnerMetadataFromPath(path) {
289
+ try {
290
+ return normalizeControlHostOwnerMetadata(JSON.parse(await readFile(path, 'utf8')));
291
+ }
292
+ catch {
293
+ return null;
294
+ }
295
+ }
296
+ async function readControlHostOwnershipDiagnosticFromPath(path) {
297
+ try {
298
+ return normalizeControlHostOwnershipDiagnostic(JSON.parse(await readFile(path, 'utf8')));
299
+ }
300
+ catch {
301
+ return null;
302
+ }
303
+ }
304
+ function normalizeControlHostOwnerMetadata(value) {
305
+ if (!isRecordLike(value)) {
306
+ return null;
307
+ }
308
+ if (value.schema_version !== 1 || (value.status !== 'owned' && value.status !== 'released')) {
309
+ return null;
310
+ }
311
+ if (typeof value.owner_token !== 'string' ||
312
+ typeof value.acquired_at !== 'string' ||
313
+ typeof value.updated_at !== 'string' ||
314
+ typeof value.run_id !== 'string' ||
315
+ typeof value.run_dir !== 'string' ||
316
+ typeof value.pid !== 'number' ||
317
+ typeof value.hostname !== 'string' ||
318
+ typeof value.lock_dir !== 'string' ||
319
+ typeof value.lock_owner_path !== 'string' ||
320
+ typeof value.owner_path !== 'string') {
321
+ return null;
322
+ }
323
+ return {
324
+ schema_version: 1,
325
+ status: value.status,
326
+ owner_token: value.owner_token,
327
+ acquired_at: value.acquired_at,
328
+ updated_at: value.updated_at,
329
+ released_at: typeof value.released_at === 'string' ? value.released_at : null,
330
+ repo_root: typeof value.repo_root === 'string' ? value.repo_root : null,
331
+ task_id: typeof value.task_id === 'string' ? value.task_id : null,
332
+ run_id: value.run_id,
333
+ run_dir: value.run_dir,
334
+ pipeline_id: typeof value.pipeline_id === 'string' ? value.pipeline_id : null,
335
+ pid: value.pid,
336
+ ppid: typeof value.ppid === 'number' ? value.ppid : null,
337
+ hostname: value.hostname,
338
+ cwd: typeof value.cwd === 'string' ? value.cwd : null,
339
+ argv: Array.isArray(value.argv)
340
+ ? value.argv.filter((entry) => typeof entry === 'string')
341
+ : [],
342
+ lock_dir: value.lock_dir,
343
+ lock_owner_path: value.lock_owner_path,
344
+ owner_path: value.owner_path
345
+ };
346
+ }
347
+ function normalizeControlHostOwnershipDiagnostic(value) {
348
+ if (!isRecordLike(value) || value.schema_version !== 1) {
349
+ return null;
350
+ }
351
+ const reason = normalizeDiagnosticReason(value.reason);
352
+ if (!reason) {
353
+ return null;
354
+ }
355
+ const attemptedOwner = normalizeControlHostOwnerMetadata(value.attempted_owner);
356
+ if (!attemptedOwner) {
357
+ return null;
358
+ }
359
+ const action = value.action === 'duplicate_rejected' ||
360
+ value.action === 'ambiguous_rejected' ||
361
+ value.action === 'stale_reclaimed'
362
+ ? value.action
363
+ : reason === 'stale_control_host_owner'
364
+ ? 'stale_reclaimed'
365
+ : reason === 'duplicate_control_host_owner'
366
+ ? 'duplicate_rejected'
367
+ : 'ambiguous_rejected';
368
+ return {
369
+ schema_version: 1,
370
+ reason,
371
+ observed_at: typeof value.observed_at === 'string' ? value.observed_at : '',
372
+ run_dir: typeof value.run_dir === 'string' ? value.run_dir : attemptedOwner.run_dir,
373
+ lock_dir: typeof value.lock_dir === 'string' ? value.lock_dir : attemptedOwner.lock_dir,
374
+ diagnostic_path: typeof value.diagnostic_path === 'string' ? value.diagnostic_path : '',
375
+ existing_owner: normalizeControlHostOwnerMetadata(value.existing_owner),
376
+ attempted_owner: attemptedOwner,
377
+ action
378
+ };
379
+ }
380
+ function buildControlHostOwnershipPollingPayloadFromDiagnostic(diagnostic) {
381
+ const status = diagnostic.action === 'stale_reclaimed'
382
+ ? 'stale_reclaimed'
383
+ : diagnostic.action === 'ambiguous_rejected'
384
+ ? 'ambiguous_rejected'
385
+ : 'duplicate_rejected';
386
+ return {
387
+ status,
388
+ reason: diagnostic.reason,
389
+ updated_at: diagnostic.observed_at,
390
+ owner: diagnostic.existing_owner ? summarizeControlHostOwner(diagnostic.existing_owner) : null,
391
+ attempted_owner: summarizeControlHostOwner(diagnostic.attempted_owner),
392
+ diagnostic_path: diagnostic.diagnostic_path,
393
+ lock_dir: diagnostic.lock_dir,
394
+ owner_path: diagnostic.existing_owner?.owner_path ?? diagnostic.attempted_owner.owner_path
395
+ };
396
+ }
397
+ function summarizeControlHostOwner(metadata) {
398
+ return {
399
+ owner_token: metadata.owner_token,
400
+ status: metadata.status,
401
+ pid: metadata.pid,
402
+ ppid: metadata.ppid,
403
+ hostname: metadata.hostname,
404
+ acquired_at: metadata.acquired_at,
405
+ updated_at: metadata.updated_at,
406
+ released_at: metadata.released_at,
407
+ repo_root: metadata.repo_root,
408
+ task_id: metadata.task_id,
409
+ run_id: metadata.run_id,
410
+ run_dir: metadata.run_dir,
411
+ pipeline_id: metadata.pipeline_id,
412
+ lock_dir: metadata.lock_dir,
413
+ owner_path: metadata.owner_path
414
+ };
415
+ }
416
+ function normalizeControlHostOwnerSummary(value) {
417
+ if (!isRecordLike(value)) {
418
+ return null;
419
+ }
420
+ if (typeof value.owner_token !== 'string' ||
421
+ typeof value.status !== 'string' ||
422
+ typeof value.pid !== 'number' ||
423
+ typeof value.hostname !== 'string' ||
424
+ typeof value.acquired_at !== 'string' ||
425
+ typeof value.updated_at !== 'string' ||
426
+ typeof value.run_id !== 'string' ||
427
+ typeof value.run_dir !== 'string' ||
428
+ typeof value.lock_dir !== 'string' ||
429
+ typeof value.owner_path !== 'string') {
430
+ return null;
431
+ }
432
+ const status = value.status === 'released' ? 'released' : 'owned';
433
+ return {
434
+ owner_token: value.owner_token,
435
+ status,
436
+ pid: value.pid,
437
+ ppid: typeof value.ppid === 'number' ? value.ppid : null,
438
+ hostname: value.hostname,
439
+ acquired_at: value.acquired_at,
440
+ updated_at: value.updated_at,
441
+ released_at: typeof value.released_at === 'string' ? value.released_at : null,
442
+ repo_root: typeof value.repo_root === 'string' ? value.repo_root : null,
443
+ task_id: typeof value.task_id === 'string' ? value.task_id : null,
444
+ run_id: value.run_id,
445
+ run_dir: value.run_dir,
446
+ pipeline_id: typeof value.pipeline_id === 'string' ? value.pipeline_id : null,
447
+ lock_dir: value.lock_dir,
448
+ owner_path: value.owner_path
449
+ };
450
+ }
451
+ function normalizeDiagnosticReason(value) {
452
+ return value === 'duplicate_control_host_owner' ||
453
+ value === 'ambiguous_control_host_owner' ||
454
+ value === 'stale_control_host_owner'
455
+ ? value
456
+ : null;
457
+ }
458
+ function normalizePollingStatus(value) {
459
+ return value === 'owned' ||
460
+ value === 'duplicate_rejected' ||
461
+ value === 'ambiguous_rejected' ||
462
+ value === 'stale_reclaimed'
463
+ ? value
464
+ : null;
465
+ }
466
+ function normalizeNullableString(value) {
467
+ return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;
468
+ }
469
+ function isRecordLike(value) {
470
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
471
+ }
472
+ function isAlreadyExistsError(error) {
473
+ return error?.code === 'EEXIST';
474
+ }
475
+ function formatDuplicateControlHostOwnerMessage(reason, existingOwner, attemptedOwner, diagnosticPath) {
476
+ const ownerText = existingOwner
477
+ ? `existing pid=${existingOwner.pid} host=${existingOwner.hostname} task=${existingOwner.task_id ?? 'unknown'} run=${existingOwner.run_id} pipeline=${existingOwner.pipeline_id ?? 'unknown'}`
478
+ : 'existing owner metadata unavailable';
479
+ return `control-host ownership rejected (${reason}): ${ownerText}; attempted pid=${attemptedOwner.pid} host=${attemptedOwner.hostname}; diagnostic=${diagnosticPath}`;
480
+ }