@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,1035 @@
1
+ import { buildProjectionSelectedPayload, resolveProviderWorkerHost, buildTrackedPayloadEnvelope, buildSelectedRunLatestEventPayload } from './observabilityReadModel.js';
2
+ import { classifyProviderLinearWorkflowState, normalizeProviderLinearWorkflowState } from './providerLinearWorkflowStates.js';
3
+ const PROVIDER_LINEAR_WORKER_PIPELINE_TITLE = 'Provider Linear Worker';
4
+ const PROVIDER_LINEAR_WORKER_PIPELINE_ID = 'provider-linear-worker';
5
+ const SYNTHETIC_LINEAR_TASK_ID_PATTERN = /^linear-[a-z0-9]+(?:-[a-z0-9]+)*$/i;
6
+ export function buildCompatibilityProjectionSnapshot(snapshot) {
7
+ const index = buildCompatibilityIssueIndex({
8
+ selected: snapshot.selected,
9
+ running: snapshot.running,
10
+ retrying: snapshot.retrying,
11
+ dispatchPilot: snapshot.dispatchPilot
12
+ });
13
+ const issuesByIdentifier = new Map(index.issues.map((issue) => [issue.issueIdentifier, issue]));
14
+ const pollingBudgetOwner = resolveCompatibilityPollingBudgetOwner(snapshot);
15
+ const running = index.runningOrder.flatMap((issueIdentifier) => {
16
+ const source = issuesByIdentifier.get(issueIdentifier)?.runningSource;
17
+ return source
18
+ ? [
19
+ buildCompatibilityRunningEntry(source, resolveCompatibilityRunningPolling(source, snapshot.polling ?? null, pollingBudgetOwner))
20
+ ]
21
+ : [];
22
+ });
23
+ const retrying = index.retryOrder.flatMap((issueIdentifier) => {
24
+ const source = issuesByIdentifier.get(issueIdentifier)?.retrySource;
25
+ return source ? [buildCompatibilityRetryEntry(source)] : [];
26
+ });
27
+ const runningByIssue = new Map(running.map((entry) => [entry.issue_identifier, entry]));
28
+ const retryingByIssue = new Map(retrying.map((entry) => [entry.issue_identifier, entry]));
29
+ const selectedIssue = snapshot.selected ? issuesByIdentifier.get(snapshot.selected.issueIdentifier) ?? null : null;
30
+ const selectedActiveSource = selectedIssue?.runningSource ?? selectedIssue?.retrySource ?? null;
31
+ const selectedSnapshotSuppressed = snapshot.selected !== null && shouldSuppressInactiveSelectedPayload(snapshot.selected);
32
+ const selectedSource = selectedSnapshotSuppressed
33
+ ? selectedActiveSource ?? selectedIssue?.selectedSource ?? snapshot.selected
34
+ : snapshot.selected ?? selectedActiveSource ?? selectedIssue?.selectedSource ?? null;
35
+ const selectedSourceIsPreferredActiveSource = selectedSource !== null && selectedSource === selectedActiveSource;
36
+ const selectedPayload = selectedSource &&
37
+ (selectedSourceIsPreferredActiveSource || !shouldSuppressInactiveSelectedPayload(selectedSource))
38
+ ? buildProjectionSelectedPayload(selectedSource, snapshot.providerIntake ?? null)
39
+ : null;
40
+ const issues = index.issues
41
+ .map((issue) => {
42
+ if (shouldPruneTerminalSelectedCompatibilityIssue(issue)) {
43
+ return null;
44
+ }
45
+ const preferredSource = issue.runningSource ?? issue.retrySource ?? issue.selectedSource;
46
+ if (!preferredSource) {
47
+ return null;
48
+ }
49
+ return {
50
+ issueIdentifier: preferredSource.issueIdentifier,
51
+ aliases: Array.from(issue.aliases),
52
+ payload: buildCompatibilityIssuePayload({
53
+ source: preferredSource,
54
+ running: runningByIssue.get(issue.issueIdentifier) ?? null,
55
+ retry: retryingByIssue.get(issue.issueIdentifier) ?? null,
56
+ dispatchPilotSummary: issue.dispatchPilotSummary,
57
+ providerIntake: snapshot.providerIntake ?? null
58
+ })
59
+ };
60
+ })
61
+ .filter((issue) => issue !== null);
62
+ return {
63
+ running,
64
+ retrying,
65
+ maxConcurrentAgents: snapshot.maxConcurrentAgents ?? null,
66
+ codexTotals: snapshot.codexTotals,
67
+ rateLimits: snapshot.rateLimits,
68
+ issues,
69
+ selected: selectedPayload,
70
+ dispatchPilot: snapshot.dispatchPilot,
71
+ tracked: snapshot.tracked,
72
+ providerIntake: snapshot.providerIntake,
73
+ providerWorkflow: snapshot.providerWorkflow,
74
+ polling: snapshot.polling
75
+ };
76
+ }
77
+ function shouldPruneTerminalSelectedCompatibilityIssue(issue) {
78
+ if (issue.runningSource || issue.retrySource || !issue.selectedSource) {
79
+ return false;
80
+ }
81
+ return (isTerminalReleasedCompletedProviderSource(issue.selectedSource) ||
82
+ isStaleInProgressTerminalReleasedProviderSource(issue.selectedSource));
83
+ }
84
+ function isTerminalReleasedCompletedProviderSource(source) {
85
+ const debugSnapshot = source.providerDebugSnapshot ?? null;
86
+ if (!isTerminalReleasedInactiveProviderSource(source)) {
87
+ return false;
88
+ }
89
+ if (!isCompletedCompatibilityRunStatus(source.rawStatus)) {
90
+ return false;
91
+ }
92
+ return hasCompletedMergeCloseout(debugSnapshot);
93
+ }
94
+ function shouldSuppressInactiveSelectedPayload(source) {
95
+ return isStaleInProgressTerminalReleasedProviderSource(source);
96
+ }
97
+ function isStaleInProgressTerminalReleasedProviderSource(source) {
98
+ const debugSnapshot = source.providerDebugSnapshot ?? null;
99
+ return (normalizeProviderLinearWorkflowState(source.rawStatus) === 'in_progress' &&
100
+ isTerminalReleasedInactiveProviderSource(source) &&
101
+ hasCompletedMergeCloseout(debugSnapshot));
102
+ }
103
+ function isTerminalReleasedInactiveProviderSource(source) {
104
+ const claim = source.providerDebugSnapshot?.claim ?? null;
105
+ if (normalizeProviderLinearWorkflowState(claim?.state) !== 'released') {
106
+ return false;
107
+ }
108
+ if (normalizeProviderLinearWorkflowState(claim?.reason) !== 'provider_issue_released:not_active') {
109
+ return false;
110
+ }
111
+ return isTerminalProviderIssueState(source);
112
+ }
113
+ function isCompletedCompatibilityRunStatus(status) {
114
+ const normalized = normalizeProviderLinearWorkflowState(status);
115
+ return (normalized === 'succeeded' ||
116
+ normalized === 'success' ||
117
+ normalized === 'completed' ||
118
+ normalized === 'done');
119
+ }
120
+ function isTerminalProviderIssueState(source) {
121
+ const trackedLinear = source.tracked?.linear ?? null;
122
+ const debugSnapshot = source.providerDebugSnapshot ?? null;
123
+ const claimEvidence = {
124
+ state: debugSnapshot?.claim?.issue_state ?? null,
125
+ state_type: debugSnapshot?.claim?.issue_state_type ?? null,
126
+ updated_at: debugSnapshot?.claim?.issue_updated_at ??
127
+ debugSnapshot?.claim?.updated_at ??
128
+ null
129
+ };
130
+ const claimState = classifyProviderLinearWorkflowState(claimEvidence);
131
+ if (claimState.isTerminal) {
132
+ return !hasNewerActiveProviderIssueState(source, claimEvidence.updated_at);
133
+ }
134
+ return [
135
+ {
136
+ state: trackedLinear?.state ?? null,
137
+ state_type: trackedLinear?.state_type ?? null,
138
+ updated_at: trackedLinear?.updated_at ?? null
139
+ },
140
+ {
141
+ state: debugSnapshot?.live_linear_state.state ?? null,
142
+ state_type: debugSnapshot?.live_linear_state.state_type ?? null,
143
+ updated_at: debugSnapshot?.live_linear_state.updated_at ?? null
144
+ },
145
+ {
146
+ state: source.compatibilityState ?? null,
147
+ state_type: null,
148
+ updated_at: source.updatedAt ?? null
149
+ }
150
+ ].some((evidence) => {
151
+ const workflowState = classifyProviderLinearWorkflowState(evidence);
152
+ return (workflowState.isTerminal && !hasNewerActiveProviderIssueState(source, evidence.updated_at));
153
+ });
154
+ }
155
+ function hasNewerActiveProviderIssueState(source, claimUpdatedAt) {
156
+ const trackedLinear = source.tracked?.linear ?? null;
157
+ const debugSnapshot = source.providerDebugSnapshot ?? null;
158
+ return [
159
+ {
160
+ state: debugSnapshot?.claim?.issue_state ?? null,
161
+ state_type: debugSnapshot?.claim?.issue_state_type ?? null,
162
+ updated_at: debugSnapshot?.claim?.issue_updated_at ??
163
+ debugSnapshot?.claim?.updated_at ??
164
+ null
165
+ },
166
+ {
167
+ state: trackedLinear?.state ?? null,
168
+ state_type: trackedLinear?.state_type ?? null,
169
+ updated_at: trackedLinear?.updated_at ?? null
170
+ },
171
+ {
172
+ state: debugSnapshot?.live_linear_state.state ?? null,
173
+ state_type: debugSnapshot?.live_linear_state.state_type ?? null,
174
+ updated_at: debugSnapshot?.live_linear_state.updated_at ?? null
175
+ }
176
+ ].some((evidence) => {
177
+ const workflowState = classifyProviderLinearWorkflowState(evidence);
178
+ return workflowState.isActive && compareIsoTimestamp(evidence.updated_at, claimUpdatedAt) > 0;
179
+ });
180
+ }
181
+ function hasCompletedMergeCloseout(debugSnapshot) {
182
+ const progress = debugSnapshot?.progress ?? null;
183
+ if (progress?.kind === 'merge_closeout' && progress.status === 'completed') {
184
+ return true;
185
+ }
186
+ const pullRequest = debugSnapshot?.pull_request ?? null;
187
+ const mergeCloseoutStatus = normalizeProviderLinearWorkflowState(pullRequest?.merge_closeout_status);
188
+ if (mergeCloseoutStatus !== 'merged') {
189
+ return false;
190
+ }
191
+ return Boolean(pullRequest?.merged_at);
192
+ }
193
+ export function findCompatibilityProjectionIssueRecord(projection, issueIdentifier) {
194
+ return findCompatibilityIssueLike(projection.issues, issueIdentifier);
195
+ }
196
+ export function buildCompatibilityIssueIndex(snapshot) {
197
+ const issuesByIdentifier = new Map();
198
+ const issueOrder = [];
199
+ const runningOrder = [];
200
+ const retryOrder = [];
201
+ const registerIssue = (source, input = {}) => {
202
+ if (!source) {
203
+ return;
204
+ }
205
+ const existing = issuesByIdentifier.get(source.issueIdentifier) ??
206
+ {
207
+ issueIdentifier: source.issueIdentifier,
208
+ selectedSource: null,
209
+ runningSource: null,
210
+ retrySource: null,
211
+ aliases: new Set(),
212
+ dispatchPilotSummary: null
213
+ };
214
+ if (!issuesByIdentifier.has(source.issueIdentifier)) {
215
+ issueOrder.push(source.issueIdentifier);
216
+ }
217
+ if (input.kind === 'selected') {
218
+ existing.selectedSource ??= source;
219
+ }
220
+ if (input.kind === 'running') {
221
+ const shouldAppend = !existing.runningSource;
222
+ existing.runningSource = pickPreferredCompatibilitySource(existing.runningSource, source);
223
+ if (shouldAppend) {
224
+ runningOrder.push(source.issueIdentifier);
225
+ }
226
+ }
227
+ if (input.kind === 'retry') {
228
+ const shouldAppend = !existing.retrySource;
229
+ existing.retrySource = pickPreferredCompatibilitySource(existing.retrySource, source);
230
+ if (shouldAppend) {
231
+ retryOrder.push(source.issueIdentifier);
232
+ }
233
+ }
234
+ existing.dispatchPilotSummary ??= input.dispatchPilotSummary ?? null;
235
+ for (const alias of buildCompatibilityIssueAliases(source)) {
236
+ existing.aliases.add(alias);
237
+ }
238
+ issuesByIdentifier.set(source.issueIdentifier, existing);
239
+ };
240
+ if (!isSyntheticLinearFallbackOnlyIssueSource(snapshot.selected)) {
241
+ registerIssue(snapshot.selected, {
242
+ kind: 'selected',
243
+ dispatchPilotSummary: snapshot.dispatchPilot
244
+ });
245
+ }
246
+ snapshot.running.forEach((entry) => {
247
+ if (!isSyntheticLinearFallbackOnlyIssueSource(entry)) {
248
+ registerIssue(entry, { kind: 'running' });
249
+ }
250
+ });
251
+ snapshot.retrying.forEach((entry) => {
252
+ if (!isSyntheticLinearFallbackOnlyIssueSource(entry)) {
253
+ registerIssue(entry, { kind: 'retry' });
254
+ }
255
+ });
256
+ return {
257
+ issues: issueOrder.flatMap((issueIdentifier) => {
258
+ const issue = issuesByIdentifier.get(issueIdentifier);
259
+ return issue
260
+ ? [
261
+ {
262
+ issueIdentifier: issue.issueIdentifier,
263
+ selectedSource: issue.selectedSource,
264
+ runningSource: issue.runningSource,
265
+ retrySource: issue.retrySource,
266
+ aliases: Array.from(issue.aliases),
267
+ dispatchPilotSummary: issue.dispatchPilotSummary
268
+ }
269
+ ]
270
+ : [];
271
+ }),
272
+ runningOrder,
273
+ retryOrder
274
+ };
275
+ }
276
+ function resolveCompatibilityPollingBudgetOwner(snapshot) {
277
+ const trackedLinear = snapshot.tracked?.linear ?? snapshot.selected?.tracked?.linear ?? null;
278
+ if (!trackedLinear) {
279
+ return null;
280
+ }
281
+ const issueId = trackedLinear.id ?? null;
282
+ const issueIdentifier = trackedLinear.identifier ?? null;
283
+ if (!issueId && !issueIdentifier) {
284
+ return null;
285
+ }
286
+ return {
287
+ issueId,
288
+ issueIdentifier
289
+ };
290
+ }
291
+ function resolveCompatibilityRunningPolling(source, polling, owner) {
292
+ if (!polling || !owner) {
293
+ return null;
294
+ }
295
+ if (owner.issueId && source.issueId) {
296
+ return owner.issueId === source.issueId ? polling : null;
297
+ }
298
+ if (owner.issueIdentifier && owner.issueIdentifier === source.issueIdentifier) {
299
+ return polling;
300
+ }
301
+ return null;
302
+ }
303
+ export function findCompatibilityIssueLike(issues, issueIdentifier) {
304
+ for (const issue of issues) {
305
+ if (issue.issueIdentifier === issueIdentifier) {
306
+ return issue;
307
+ }
308
+ }
309
+ for (const issue of issues) {
310
+ if (issue.aliases.includes(issueIdentifier)) {
311
+ return issue;
312
+ }
313
+ }
314
+ return null;
315
+ }
316
+ export function buildCompatibilityRunningEntry(selected, polling = null) {
317
+ const proof = selected.providerLinearWorkerProof ?? null;
318
+ const workerHost = resolveProviderWorkerHost({
319
+ providerLinearWorkerProof: proof,
320
+ providerDebugSnapshot: selected.providerDebugSnapshot,
321
+ stageStartedAt: selected.startedAt
322
+ });
323
+ const proofCurrentTurnActivity = proof?.current_turn_activity ?? null;
324
+ const proofCanonicalEvent = normalizeCompatibilityMessage(proofCurrentTurnActivity?.event);
325
+ const proofCanonicalMessage = normalizeCompatibilityMessage(proofCurrentTurnActivity?.message_or_payload);
326
+ const proofCanonicalRecordedAt = normalizeCompatibilityMessage(proofCurrentTurnActivity?.recorded_at);
327
+ const proofCanonicalSessionId = normalizeCompatibilityMessage(proofCurrentTurnActivity?.session_id);
328
+ const useLegacyProofFallback = proofCurrentTurnActivity === null;
329
+ const hasCanonicalProofTelemetry = Boolean(proofCanonicalEvent || proofCanonicalMessage);
330
+ const proofEvent = useLegacyProofFallback
331
+ ? normalizeCompatibilityMessage(proof?.last_event)
332
+ : proofCanonicalEvent;
333
+ const proofMessage = useLegacyProofFallback
334
+ ? normalizeCompatibilityMessage(proof?.last_message)
335
+ : proofCanonicalMessage;
336
+ const proofEventAt = useLegacyProofFallback
337
+ ? normalizeCompatibilityMessage(proof?.last_event_at)
338
+ : proofCanonicalRecordedAt;
339
+ const runningEvent = selectRunningEvent({
340
+ latestEvent: selected.latestEvent?.event ?? null,
341
+ latestEventAt: selected.latestEvent?.at ?? null,
342
+ latestMessage: selected.latestEvent?.message ?? null,
343
+ latestAction: selected.latestAction ?? null,
344
+ rawStatus: selected.rawStatus,
345
+ proofEvent,
346
+ proofMessage,
347
+ proofEventAt
348
+ });
349
+ const preferProofTelemetry = runningEvent.source === 'proof';
350
+ const latestEventKey = normalizeCompatibilityEventKey(selected.latestEvent?.event ?? null);
351
+ const preserveLatestControlActionContext = runningEvent.source === 'latest' && isExplicitControlActionEventKey(latestEventKey);
352
+ const runningMessage = preferProofTelemetry
353
+ ? proofMessage ?? selected.latestEvent?.message ?? selected.summary
354
+ : preserveLatestControlActionContext
355
+ ? selected.latestEvent?.message ?? selected.summary
356
+ : selected.latestEvent?.message ?? proofMessage ?? selected.summary;
357
+ const runningMessageSource = preferProofTelemetry
358
+ ? proofMessage
359
+ ? 'proof'
360
+ : selected.latestEvent?.message
361
+ ? 'latest'
362
+ : 'fallback'
363
+ : preserveLatestControlActionContext
364
+ ? selected.latestEvent?.message
365
+ ? 'latest'
366
+ : 'fallback'
367
+ : selected.latestEvent?.message
368
+ ? 'latest'
369
+ : proofMessage
370
+ ? 'proof'
371
+ : 'fallback';
372
+ const runningEventAt = preferProofTelemetry
373
+ ? proofEventAt ?? selected.latestEvent?.at ?? selected.updatedAt
374
+ : preserveLatestControlActionContext
375
+ ? selected.latestEvent?.at ?? selected.updatedAt
376
+ : selected.latestEvent?.at ?? proofEventAt ?? selected.updatedAt;
377
+ const displayEvent = resolveCompatibilityRunningDisplayEvent({
378
+ selected,
379
+ runningEvent: runningEvent.event,
380
+ runningMessage,
381
+ polling
382
+ });
383
+ const proofEventSource = normalizeCompatibilityMessage(proofCurrentTurnActivity?.source) === 'session_log_hydration'
384
+ ? 'canonical_session_log_hydration'
385
+ : hasCanonicalProofTelemetry
386
+ ? 'canonical_stdout_jsonl'
387
+ : 'legacy_proof_fields';
388
+ const eventSource = runningEvent.source === 'latest'
389
+ ? selected.latestEvent?.source ?? 'latest_event'
390
+ : runningEvent.source === 'proof'
391
+ ? proofEventSource
392
+ : 'fallback';
393
+ const messageRecordedAt = runningMessageSource === 'latest'
394
+ ? selected.latestEvent?.messageRecordedAt ?? null
395
+ : runningMessageSource === 'proof'
396
+ ? useLegacyProofFallback
397
+ ? null
398
+ : proofMessage
399
+ ? proofCanonicalRecordedAt ?? null
400
+ : null
401
+ : null;
402
+ const sourceUpdatedAt = runningEvent.source === 'latest'
403
+ ? selected.latestEvent?.sourceUpdatedAt ?? selected.latestEvent?.at ?? selected.updatedAt
404
+ : runningEvent.source === 'proof'
405
+ ? useLegacyProofFallback
406
+ ? normalizeCompatibilityMessage(proof?.updated_at) ?? proofEventAt ?? null
407
+ : proofCanonicalRecordedAt ?? normalizeCompatibilityMessage(proof?.updated_at) ?? null
408
+ : selected.updatedAt;
409
+ const eventCandidates = runningEvent.source === 'latest'
410
+ ? selected.latestEvent?.candidates ?? []
411
+ : runningEvent.source === 'proof'
412
+ ? [
413
+ {
414
+ source: eventSource,
415
+ event: proofEvent,
416
+ summary: proofMessage,
417
+ message_recorded_at: proofMessage ? messageRecordedAt : null,
418
+ source_updated_at: sourceUpdatedAt,
419
+ derived: false,
420
+ accepted: true,
421
+ rejection_reason: null
422
+ }
423
+ ]
424
+ : [];
425
+ return {
426
+ issue_id: selected.issueId,
427
+ issue_identifier: selected.issueIdentifier,
428
+ state: resolveCompatibilityRunningState(selected),
429
+ display_state: selected.displayStatus,
430
+ status_reason: selected.statusReason,
431
+ pid: selected.providerLinearWorkerProof?.pid ?? null,
432
+ ...(workerHost !== null ? { worker_host: workerHost } : {}),
433
+ session_id: useLegacyProofFallback
434
+ ? normalizeCompatibilityMessage(proof?.latest_session_id)
435
+ : proofCanonicalSessionId,
436
+ turn_count: proof?.turn_count ?? null,
437
+ last_event: runningEvent.event,
438
+ last_message: runningMessage,
439
+ display_event: displayEvent,
440
+ event_source: eventSource,
441
+ message_recorded_at: messageRecordedAt,
442
+ source_updated_at: sourceUpdatedAt,
443
+ event_candidates: eventCandidates,
444
+ started_at: selected.startedAt,
445
+ last_event_at: runningEventAt,
446
+ tokens: proof?.tokens ?? buildEmptyTokenUsage()
447
+ };
448
+ }
449
+ export function buildCompatibilityRetryEntry(selected) {
450
+ const retryState = selected.providerRetryState ?? null;
451
+ const proof = selected.providerLinearWorkerProof ?? null;
452
+ const workerHost = resolveProviderWorkerHost({
453
+ providerLinearWorkerProof: proof,
454
+ providerDebugSnapshot: selected.providerDebugSnapshot,
455
+ stageStartedAt: selected.startedAt
456
+ });
457
+ return {
458
+ issue_id: selected.issueId,
459
+ issue_identifier: selected.issueIdentifier,
460
+ task_id: selected.taskId,
461
+ run_id: selected.runId,
462
+ state: selected.rawStatus,
463
+ display_state: selected.displayStatus,
464
+ status_reason: selected.statusReason,
465
+ session_id: proof?.latest_session_id ?? null,
466
+ ...(workerHost !== null ? { worker_host: workerHost } : {}),
467
+ thread_id: proof?.thread_id ?? null,
468
+ turn_count: proof?.turn_count ?? null,
469
+ workspace_path: selected.workspacePath,
470
+ attempt: retryState?.attempt ?? null,
471
+ due_at: retryState?.due_at ?? null,
472
+ error: retryState?.error ?? selected.lastError,
473
+ last_event: selected.latestEvent?.event ?? selected.latestAction ?? selected.rawStatus,
474
+ last_message: selected.latestEvent?.message ?? selected.summary,
475
+ started_at: selected.startedAt,
476
+ last_event_at: selected.latestEvent?.at ?? selected.updatedAt
477
+ };
478
+ }
479
+ export function buildCompatibilityIssuePayload(input) {
480
+ const retryPayload = input.retry ??
481
+ (input.source.providerRetryState ? buildCompatibilityRetryEntry(input.source) : null);
482
+ const selectedPayload = buildProjectionSelectedPayload(input.source, input.providerIntake ?? null);
483
+ const latestEvent = buildSelectedRunLatestEventPayload(input.source.latestEvent);
484
+ const recentEvents = latestEvent ? [latestEvent] : [];
485
+ const workerHost = resolveProviderWorkerHost({
486
+ providerLinearWorkerProof: input.source.providerLinearWorkerProof,
487
+ providerDebugSnapshot: input.source.providerDebugSnapshot,
488
+ providerIntake: input.providerIntake ?? null,
489
+ issueIdentifier: input.source.issueIdentifier,
490
+ issueId: input.source.issueId,
491
+ stageStartedAt: input.source.startedAt
492
+ });
493
+ return {
494
+ issue_identifier: input.source.issueIdentifier,
495
+ issue_id: input.source.issueId,
496
+ task_id: input.source.taskId,
497
+ run_id: input.source.runId,
498
+ status: resolveCompatibilityIssueStatus(input.running, input.retry, input.source),
499
+ raw_status: input.source.rawStatus,
500
+ display_status: input.source.displayStatus,
501
+ status_reason: input.source.statusReason,
502
+ workspace: {
503
+ path: input.source.workspacePath ?? input.source.providerLinearWorkerProof?.workspace_path ?? null
504
+ },
505
+ ...(workerHost !== null ? { worker_host: workerHost } : {}),
506
+ attempts: buildCompatibilityIssueAttempts(input.source, retryPayload),
507
+ running: input.running,
508
+ retry: retryPayload,
509
+ logs: {
510
+ codex_session_logs: []
511
+ },
512
+ summary: input.source.summary,
513
+ latest_event: latestEvent,
514
+ question_summary: selectedPayload.question_summary,
515
+ recent_events: recentEvents,
516
+ last_error: input.source.lastError,
517
+ tracked: buildTrackedPayloadEnvelope(input.source.tracked),
518
+ ...(input.source.providerLinearWorkerProof
519
+ ? { provider_linear_worker_proof: input.source.providerLinearWorkerProof }
520
+ : {}),
521
+ ...(input.source.providerDebugSnapshot
522
+ ? { provider_debug_snapshot: input.source.providerDebugSnapshot }
523
+ : {}),
524
+ ...(input.dispatchPilotSummary ? { dispatch_pilot: input.dispatchPilotSummary } : {})
525
+ };
526
+ }
527
+ function buildCompatibilityIssueAttempts(source, retry) {
528
+ const attempt = retry?.attempt ?? source.providerRetryState?.attempt ?? null;
529
+ if (attempt === null || attempt === undefined) {
530
+ return {
531
+ restart_count: null,
532
+ current_retry_attempt: null
533
+ };
534
+ }
535
+ return {
536
+ restart_count: Math.max(attempt - 1, 0),
537
+ current_retry_attempt: attempt
538
+ };
539
+ }
540
+ function buildEmptyTokenUsage() {
541
+ return {
542
+ input_tokens: null,
543
+ output_tokens: null,
544
+ total_tokens: null
545
+ };
546
+ }
547
+ function resolveCompatibilityRunningDisplayEvent(input) {
548
+ const proof = input.selected.providerLinearWorkerProof ?? null;
549
+ const codexBudgetEvent = resolveCodexBudgetExhaustionEvent(proof?.rate_limits ?? null);
550
+ if (codexBudgetEvent) {
551
+ return codexBudgetEvent;
552
+ }
553
+ const nextRefreshInMs = resolveCompatibilityNextRefreshCountdownMs(input.polling);
554
+ const hasProjectedNextRefreshState = input.polling?.next_refresh_state !== undefined &&
555
+ input.polling?.next_refresh_state !== null;
556
+ const pollingLinearBudgetEvent = resolveCompatibilityPollingLinearBudgetExhaustionEvent(input.selected, input.polling, nextRefreshInMs);
557
+ if (pollingLinearBudgetEvent) {
558
+ return pollingLinearBudgetEvent;
559
+ }
560
+ const authoritativeLinearBudget = resolveAuthoritativeLinearBudget({
561
+ selected: input.selected,
562
+ polling: input.polling
563
+ });
564
+ const authoritativeLinearBudgetForEvent = authoritativeLinearBudget === input.polling?.linear_budget &&
565
+ !shouldUseCompatibilityPollingCooldownState(input.polling)
566
+ ? null
567
+ : authoritativeLinearBudget;
568
+ const authoritativeNextRefreshInMs = authoritativeLinearBudgetForEvent === input.polling?.linear_budget ? nextRefreshInMs : null;
569
+ const linearBudgetEvent = resolveLinearBudgetExhaustionEvent(authoritativeLinearBudgetForEvent, {
570
+ nextRefreshInMs: authoritativeNextRefreshInMs,
571
+ preferProjectedCountdown: authoritativeLinearBudgetForEvent === input.polling?.linear_budget &&
572
+ hasProjectedNextRefreshState
573
+ });
574
+ if (linearBudgetEvent) {
575
+ return linearBudgetEvent;
576
+ }
577
+ const displayState = input.selected.displayStatus;
578
+ const progressSummary = normalizeCompatibilityMessage(input.selected.providerDebugSnapshot?.progress?.summary) ??
579
+ normalizeCompatibilityMessage(proof?.progress?.summary) ??
580
+ null;
581
+ const candidates = [
582
+ normalizeCompatibilityMessage(input.runningMessage),
583
+ progressSummary,
584
+ normalizeCompatibilityMessage(input.selected.latestEvent?.message),
585
+ normalizeCompatibilityMessage(input.selected.summary)
586
+ ];
587
+ for (const candidate of candidates) {
588
+ if (isHighSignalCompatibilityText(candidate, displayState)) {
589
+ return candidate;
590
+ }
591
+ }
592
+ const humanizedEvent = humanizeCompatibilityRunningEvent(input.runningEvent);
593
+ if (isHighSignalCompatibilityText(humanizedEvent, displayState)) {
594
+ return humanizedEvent;
595
+ }
596
+ const humanizedStatusReason = humanizeCompatibilityRunningEvent(input.selected.statusReason);
597
+ if (isHighSignalCompatibilityText(humanizedStatusReason, displayState)) {
598
+ return humanizedStatusReason;
599
+ }
600
+ return null;
601
+ }
602
+ function resolveCompatibilityNextRefreshCountdownMs(polling) {
603
+ if (typeof polling?.next_refresh_in_ms === 'number' &&
604
+ Number.isFinite(polling.next_refresh_in_ms) &&
605
+ polling.next_refresh_in_ms >= 0) {
606
+ return polling.next_refresh_in_ms;
607
+ }
608
+ const hasProjectedState = polling?.next_refresh_state !== undefined && polling?.next_refresh_state !== null;
609
+ if (hasProjectedState) {
610
+ return null;
611
+ }
612
+ return typeof polling?.next_poll_in_ms === 'number' &&
613
+ Number.isFinite(polling.next_poll_in_ms) &&
614
+ polling.next_poll_in_ms >= 0
615
+ ? polling.next_poll_in_ms
616
+ : null;
617
+ }
618
+ function resolveCompatibilityPollingLinearBudgetExhaustionEvent(selected, polling, nextRefreshInMs) {
619
+ const pollingBudget = polling?.linear_budget ?? null;
620
+ if (!shouldUseCompatibilityPollingCooldownState(polling) ||
621
+ !isCompatibilityLinearBudgetSharedExhausted(pollingBudget)) {
622
+ return null;
623
+ }
624
+ const proofBudget = selected.providerLinearWorkerProof?.linear_budget ?? null;
625
+ if (isCompatibilityLinearBudgetSharedExhausted(proofBudget)) {
626
+ return null;
627
+ }
628
+ return resolveLinearBudgetExhaustionEvent(pollingBudget, {
629
+ nextRefreshInMs,
630
+ preferProjectedCountdown: polling?.next_refresh_state !== undefined && polling?.next_refresh_state !== null
631
+ });
632
+ }
633
+ function shouldUseCompatibilityPollingCooldownState(polling) {
634
+ return (polling?.next_refresh_state === undefined ||
635
+ polling?.next_refresh_state === null ||
636
+ polling.next_refresh_state === 'cooldown');
637
+ }
638
+ function resolveAuthoritativeLinearBudget(input) {
639
+ const proof = input.selected.providerLinearWorkerProof ?? null;
640
+ const proofBudget = proof?.linear_budget ?? null;
641
+ const pollingBudget = input.polling?.linear_budget ?? null;
642
+ if (!proofBudget) {
643
+ return pollingBudget;
644
+ }
645
+ if (!pollingBudget) {
646
+ return proofBudget;
647
+ }
648
+ const proofTimestamp = Date.parse(proofBudget.observed_at ?? proof?.updated_at ?? input.selected.updatedAt ?? '') ||
649
+ Number.NEGATIVE_INFINITY;
650
+ const pollingTimestamp = Date.parse(pollingBudget.observed_at ?? input.polling?.updated_at ?? '') ||
651
+ Number.NEGATIVE_INFINITY;
652
+ return pollingTimestamp >= proofTimestamp ? pollingBudget : proofBudget;
653
+ }
654
+ function resolveCodexBudgetExhaustionEvent(rateLimits) {
655
+ const codex = asCompatibilityRecord(rateLimits?.codex) ?? asCompatibilityRecord(rateLimits);
656
+ if (!codex) {
657
+ return null;
658
+ }
659
+ const buckets = [
660
+ [resolveCodexRateLimitBucketLabel(asCompatibilityRecord(codex.primary)) ?? 'primary', asCompatibilityRecord(codex.primary)],
661
+ [resolveCodexRateLimitBucketLabel(asCompatibilityRecord(codex.secondary)) ?? 'secondary', asCompatibilityRecord(codex.secondary)],
662
+ ['requests', asCompatibilityRecord(codex.requests)],
663
+ ['requests', asCompatibilityRecord(codex.endpoint_requests)]
664
+ ];
665
+ for (const [label, bucket] of buckets) {
666
+ if (bucket && isCompatibilityBucketExhausted(bucket)) {
667
+ return `codex ${label} bucket exhausted; worker paused until reset`;
668
+ }
669
+ }
670
+ return null;
671
+ }
672
+ function resolveLinearBudgetExhaustionEvent(budget, options = {}) {
673
+ if (isCompatibilityLinearBudgetBucketFamilyExhausted(budget, 'requests')) {
674
+ const nextRefresh = formatCompatibilityCountdownMs(resolveCompatibilityLinearBudgetCountdownMs(budget, options.nextRefreshInMs ?? null, options.preferProjectedCountdown === true));
675
+ return nextRefresh
676
+ ? `linear requests exhausted; next tracked-issue refresh at ${nextRefresh}`
677
+ : 'linear requests exhausted; polling deferred until reset';
678
+ }
679
+ if (isCompatibilityLinearBudgetBucketFamilyExhausted(budget, 'complexity')) {
680
+ const nextRefresh = formatCompatibilityCountdownMs(resolveCompatibilityLinearBudgetCountdownMs(budget, options.nextRefreshInMs ?? null, options.preferProjectedCountdown === true));
681
+ return nextRefresh
682
+ ? `linear complexity budget exhausted; next tracked-issue refresh at ${nextRefresh}`
683
+ : 'linear complexity budget exhausted; polling deferred until reset';
684
+ }
685
+ return null;
686
+ }
687
+ function isCompatibilityLinearBudgetBucketFamilyExhausted(budget, family) {
688
+ const primaryBucket = family === 'requests' ? budget?.requests : budget?.complexity;
689
+ const endpointBucket = family === 'requests' ? budget?.endpoint_requests : budget?.endpoint_complexity;
690
+ return (isCompatibilityLinearBudgetBucketExhausted(primaryBucket) ||
691
+ isCompatibilityLinearBudgetBucketExhausted(endpointBucket));
692
+ }
693
+ function isCompatibilityLinearBudgetSharedExhausted(budget) {
694
+ return (isCompatibilityLinearBudgetBucketExhausted(budget?.requests) ||
695
+ isCompatibilityLinearBudgetBucketExhausted(budget?.complexity));
696
+ }
697
+ function isCompatibilityLinearBudgetBucketExhausted(bucket) {
698
+ const remaining = normalizeCompatibilityRemaining(bucket?.remaining);
699
+ return remaining !== null && remaining <= 0;
700
+ }
701
+ function resolveCompatibilityLinearBudgetCountdownMs(budget, projectedMs, preferProjectedCountdown) {
702
+ const normalizedProjectedMs = typeof projectedMs === 'number' && Number.isFinite(projectedMs) && projectedMs >= 0
703
+ ? projectedMs
704
+ : null;
705
+ const retryAfterSeconds = normalizeCompatibilityRemaining(budget?.retry_after_seconds);
706
+ if (preferProjectedCountdown && normalizedProjectedMs !== null) {
707
+ return normalizedProjectedMs;
708
+ }
709
+ if (retryAfterSeconds !== null) {
710
+ return Math.max(0, Math.ceil(retryAfterSeconds * 1000));
711
+ }
712
+ return normalizedProjectedMs;
713
+ }
714
+ function normalizeCompatibilityRemaining(value) {
715
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
716
+ }
717
+ function isCompatibilityBucketExhausted(bucket) {
718
+ const remaining = readCompatibilityRecordNumber(bucket, ['remaining']);
719
+ if (remaining !== null) {
720
+ return remaining <= 0;
721
+ }
722
+ const usedPercent = readCompatibilityRecordNumber(bucket, ['usedPercent', 'used_percent']);
723
+ if (usedPercent !== null) {
724
+ return usedPercent >= 100;
725
+ }
726
+ return false;
727
+ }
728
+ function resolveCodexRateLimitBucketLabel(bucket) {
729
+ if (!bucket) {
730
+ return null;
731
+ }
732
+ const windowDurationMins = readCompatibilityRecordNumber(bucket, [
733
+ 'windowDurationMins',
734
+ 'window_duration_mins',
735
+ 'window_minutes'
736
+ ]);
737
+ const normalizedWindowMinutes = windowDurationMins !== null && Number.isFinite(windowDurationMins)
738
+ ? Math.max(0, Math.trunc(windowDurationMins))
739
+ : null;
740
+ if (normalizedWindowMinutes === 300) {
741
+ return '5-hour';
742
+ }
743
+ if (normalizedWindowMinutes === 10_080) {
744
+ return 'weekly';
745
+ }
746
+ return null;
747
+ }
748
+ function formatCompatibilityCountdownMs(valueMs) {
749
+ if (typeof valueMs !== 'number' || !Number.isFinite(valueMs) || valueMs < 0) {
750
+ return null;
751
+ }
752
+ return formatCompatibilityDurationSeconds(Math.ceil(valueMs / 1000));
753
+ }
754
+ function formatCompatibilityDurationSeconds(valueSeconds) {
755
+ const totalSeconds = Math.max(0, Math.floor(valueSeconds));
756
+ if (totalSeconds < 60) {
757
+ return `${totalSeconds}s`;
758
+ }
759
+ const minutes = Math.floor(totalSeconds / 60);
760
+ const seconds = totalSeconds % 60;
761
+ if (minutes < 60) {
762
+ return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`;
763
+ }
764
+ const hours = Math.floor(minutes / 60);
765
+ const remainingMinutes = minutes % 60;
766
+ if (hours < 24) {
767
+ return remainingMinutes === 0 ? `${hours}h` : `${hours}h ${remainingMinutes}m`;
768
+ }
769
+ const days = Math.floor(hours / 24);
770
+ const remainingHours = hours % 24;
771
+ return remainingHours === 0 ? `${days}d` : `${days}d ${remainingHours}h`;
772
+ }
773
+ function humanizeCompatibilityRunningEvent(value) {
774
+ const normalized = normalizeCompatibilityEventKey(value);
775
+ if (!normalized) {
776
+ return null;
777
+ }
778
+ switch (normalized) {
779
+ case 'task_started':
780
+ return 'session started';
781
+ case 'task_complete':
782
+ case 'turn_completed':
783
+ return 'turn completed';
784
+ case 'turn_started':
785
+ return 'turn started';
786
+ case 'turn_failed':
787
+ return 'turn failed';
788
+ case 'turn_cancelled':
789
+ return 'turn cancelled';
790
+ case 'thread_tokenusage_updated':
791
+ return 'token usage updated';
792
+ case 'account_ratelimits_updated':
793
+ return 'rate limits updated';
794
+ case 'queued_questions':
795
+ return 'queued questions';
796
+ case 'review_handoff':
797
+ return 'review handoff ready';
798
+ default:
799
+ return normalized.replace(/_/g, ' ');
800
+ }
801
+ }
802
+ function isHighSignalCompatibilityText(value, displayState) {
803
+ if (!value) {
804
+ return false;
805
+ }
806
+ const normalized = value.trim().toLowerCase();
807
+ const normalizedDisplayState = normalizeCompatibilityMessage(displayState)?.toLowerCase() ?? '';
808
+ if (normalized.length === 0 || normalized === normalizedDisplayState || normalized === 'n/a') {
809
+ return false;
810
+ }
811
+ return !GENERIC_COMPATIBILITY_RUNNING_TEXT.has(normalized);
812
+ }
813
+ const GENERIC_COMPATIBILITY_RUNNING_TEXT = new Set([
814
+ 'retry queued',
815
+ 'turn running',
816
+ 'worker turn active',
817
+ 'provider worker turn is active.',
818
+ 'provider worker turn is active',
819
+ 'turn active',
820
+ 'provider run active',
821
+ 'issue is active but worker progress has not been observed yet.'
822
+ ]);
823
+ function asCompatibilityRecord(value) {
824
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
825
+ }
826
+ function readCompatibilityRecordNumber(record, keys) {
827
+ for (const key of keys) {
828
+ const value = record[key];
829
+ if (typeof value === 'number' && Number.isFinite(value)) {
830
+ return value;
831
+ }
832
+ }
833
+ return null;
834
+ }
835
+ function selectRunningEvent(input) {
836
+ const latestEventKey = normalizeCompatibilityEventKey(input.latestEvent);
837
+ const genericFallbacks = new Set([
838
+ input.rawStatus,
839
+ input.latestAction === 'pause' ? null : input.latestAction,
840
+ 'in_progress',
841
+ 'running',
842
+ 'resuming',
843
+ 'started',
844
+ 'message',
845
+ 'notification',
846
+ 'item.started',
847
+ 'item.completed',
848
+ 'item.updated'
849
+ ]
850
+ .map((value) => normalizeCompatibilityEventKey(value))
851
+ .filter((value) => Boolean(value)));
852
+ const proofTelemetryIsNewerThanLatest = compareCompatibilityTimestamps(input.proofEventAt, input.latestEventAt) > 0;
853
+ const proofMayOverrideLatestControlAction = !isExplicitControlActionEventKey(latestEventKey) || proofTelemetryIsNewerThanLatest;
854
+ const preferProofTelemetry = Boolean(input.proofEvent || input.proofMessage) &&
855
+ proofMayOverrideLatestControlAction &&
856
+ (!latestEventKey ||
857
+ genericFallbacks.has(latestEventKey) ||
858
+ (!normalizeCompatibilityMessage(input.latestMessage) && normalizeCompatibilityMessage(input.proofMessage)));
859
+ if (preferProofTelemetry) {
860
+ return {
861
+ event: input.proofEvent ?? input.latestEvent ?? input.latestAction ?? input.rawStatus,
862
+ source: 'proof'
863
+ };
864
+ }
865
+ if (input.latestEvent) {
866
+ return {
867
+ event: input.latestEvent,
868
+ source: 'latest'
869
+ };
870
+ }
871
+ return {
872
+ event: input.latestAction ?? input.rawStatus,
873
+ source: 'fallback'
874
+ };
875
+ }
876
+ function normalizeCompatibilityEventKey(value) {
877
+ if (!value) {
878
+ return null;
879
+ }
880
+ const trimmed = value.trim();
881
+ if (trimmed.length === 0) {
882
+ return null;
883
+ }
884
+ return trimmed
885
+ .toLowerCase()
886
+ .replace(/^codex\/event\//u, '')
887
+ .replace(/[./]+/gu, '_')
888
+ .replace(/[^a-z0-9_]+/gu, '_')
889
+ .replace(/_+/gu, '_')
890
+ .replace(/^_|_$/gu, '');
891
+ }
892
+ function normalizeCompatibilityMessage(value) {
893
+ if (!value) {
894
+ return null;
895
+ }
896
+ const trimmed = value.trim();
897
+ return trimmed.length > 0 ? trimmed : null;
898
+ }
899
+ function isExplicitControlActionEventKey(value) {
900
+ return value === 'pause' || value === 'resume';
901
+ }
902
+ function compareCompatibilityTimestamps(left, right) {
903
+ const leftTime = parseCompatibilityTimestamp(left);
904
+ const rightTime = parseCompatibilityTimestamp(right);
905
+ if (leftTime === null || rightTime === null) {
906
+ return 0;
907
+ }
908
+ return leftTime - rightTime;
909
+ }
910
+ function parseCompatibilityTimestamp(value) {
911
+ if (!value) {
912
+ return null;
913
+ }
914
+ const parsed = Date.parse(value);
915
+ return Number.isFinite(parsed) ? parsed : null;
916
+ }
917
+ function resolveCompatibilityRunningState(selected) {
918
+ return selected.compatibilityState ?? selected.rawStatus;
919
+ }
920
+ function resolveCompatibilityIssueStatus(running, retry, source) {
921
+ if (running) {
922
+ return 'running';
923
+ }
924
+ if (retry) {
925
+ return 'retrying';
926
+ }
927
+ if (source.rawStatus === 'succeeded' &&
928
+ (source.displayStatus === 'pending_shared_root_reconciliation' || source.displayStatus === 'failed')) {
929
+ return source.displayStatus;
930
+ }
931
+ return source.rawStatus;
932
+ }
933
+ function buildCompatibilityIssueAliases(selected) {
934
+ const aliases = new Set();
935
+ const candidates = selected.lookupAliases.length > 0
936
+ ? selected.lookupAliases
937
+ : [selected.issueIdentifier, selected.issueId, selected.taskId, selected.runId];
938
+ for (const candidate of candidates) {
939
+ if (candidate) {
940
+ aliases.add(candidate);
941
+ }
942
+ }
943
+ return Array.from(aliases);
944
+ }
945
+ function hasExplicitCompatibilityIssueIdentity(source) {
946
+ if (source.issueIdentifier &&
947
+ !isFallbackCompatibilityIdentityValue(source.issueIdentifier, source)) {
948
+ return true;
949
+ }
950
+ if (source.issueId && !isFallbackCompatibilityIdentityValue(source.issueId, source)) {
951
+ return true;
952
+ }
953
+ return false;
954
+ }
955
+ function isFallbackCompatibilityIdentityValue(value, source) {
956
+ return (isFallbackCompatibilityIdentityAlias(value, source.taskId) ||
957
+ isFallbackCompatibilityIdentityAlias(value, source.runId));
958
+ }
959
+ function isFallbackCompatibilityIdentityAlias(value, candidate) {
960
+ if (!candidate) {
961
+ return false;
962
+ }
963
+ if (value === candidate) {
964
+ return true;
965
+ }
966
+ return SYNTHETIC_LINEAR_TASK_ID_PATTERN.test(value) && candidate.startsWith(`${value}-`);
967
+ }
968
+ function isSyntheticLinearFallbackOnlyIssueSource(source) {
969
+ return (source !== null &&
970
+ hasSyntheticLinearFallbackProvenance(source) &&
971
+ source.taskId !== null &&
972
+ SYNTHETIC_LINEAR_TASK_ID_PATTERN.test(source.taskId) &&
973
+ !hasExplicitCompatibilityIssueIdentity(source));
974
+ }
975
+ function hasSyntheticLinearFallbackProvenance(source) {
976
+ if (source.issueProvider !== null && source.issueProvider !== 'linear') {
977
+ return false;
978
+ }
979
+ return (source.pipelineId === PROVIDER_LINEAR_WORKER_PIPELINE_ID ||
980
+ source.pipelineTitle === PROVIDER_LINEAR_WORKER_PIPELINE_TITLE ||
981
+ source.providerLinearWorkerProof != null ||
982
+ (source.issueProvider === 'linear' &&
983
+ (source.pipelineId === 'docs-review' ||
984
+ source.pipelineId === 'implementation-gate' ||
985
+ source.pipelineId === 'docs-relevance-advisory' ||
986
+ source.pipelineId === 'provider-linear-child-lane')));
987
+ }
988
+ function pickPreferredCompatibilitySource(current, candidate) {
989
+ if (!current) {
990
+ return candidate;
991
+ }
992
+ return compareCompatibilitySourcePriority(candidate, current) > 0 ? candidate : current;
993
+ }
994
+ function compareCompatibilitySourcePriority(left, right) {
995
+ const timestampComparison = compareIsoTimestamp(resolveCompatibilitySourcePriorityTimestamp(left), resolveCompatibilitySourcePriorityTimestamp(right)) ||
996
+ compareIsoTimestamp(left.updatedAt, right.updatedAt) ||
997
+ compareIsoTimestamp(left.startedAt, right.startedAt) ||
998
+ compareIsoTimestamp(left.completedAt, right.completedAt);
999
+ if (timestampComparison !== 0) {
1000
+ return timestampComparison;
1001
+ }
1002
+ return (compareLexical(left.runId, right.runId) ||
1003
+ compareLexical(left.taskId, right.taskId) ||
1004
+ compareLexical(left.issueIdentifier, right.issueIdentifier));
1005
+ }
1006
+ function resolveCompatibilitySourcePriorityTimestamp(source) {
1007
+ const sourceRecord = source;
1008
+ return (sourceRecord.providerDebugSnapshot?.progress?.last_semantic_progress_at ??
1009
+ sourceRecord.providerDebugSnapshot?.last_semantic_progress_at ??
1010
+ source.latestEvent?.at ??
1011
+ null);
1012
+ }
1013
+ function compareIsoTimestamp(left, right) {
1014
+ const leftValue = parseTimestamp(left);
1015
+ const rightValue = parseTimestamp(right);
1016
+ if (leftValue === rightValue) {
1017
+ return 0;
1018
+ }
1019
+ return leftValue > rightValue ? 1 : -1;
1020
+ }
1021
+ function parseTimestamp(value) {
1022
+ if (!value) {
1023
+ return Number.NEGATIVE_INFINITY;
1024
+ }
1025
+ const parsed = Date.parse(value);
1026
+ return Number.isFinite(parsed) ? parsed : Number.NEGATIVE_INFINITY;
1027
+ }
1028
+ function compareLexical(left, right) {
1029
+ const normalizedLeft = left ?? '';
1030
+ const normalizedRight = right ?? '';
1031
+ if (normalizedLeft === normalizedRight) {
1032
+ return 0;
1033
+ }
1034
+ return normalizedLeft.localeCompare(normalizedRight);
1035
+ }