@kbediako/codex-orchestrator 0.1.38 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/README.md +70 -301
  3. package/bin/codex-orchestrator.js +161 -0
  4. package/codex.orchestrator.json +149 -13
  5. package/dist/bin/codex-orchestrator.js +795 -1154
  6. package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
  7. package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
  8. package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
  9. package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +183 -11
  10. package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
  11. package/dist/orchestrator/src/cli/coStatusCliShell.js +429 -0
  12. package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
  13. package/dist/orchestrator/src/cli/codexCliShell.js +72 -0
  14. package/dist/orchestrator/src/cli/codexDefaultsSetup.js +49 -11
  15. package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
  16. package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
  17. package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
  18. package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
  19. package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
  20. package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
  21. package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
  22. package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
  23. package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
  24. package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
  25. package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
  26. package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
  27. package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
  28. package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
  29. package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
  30. package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
  31. package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
  32. package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
  33. package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
  34. package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
  35. package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
  36. package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
  37. package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
  38. package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
  39. package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
  40. package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
  41. package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
  42. package/dist/orchestrator/src/cli/control/controlHostSupervision.js +608 -0
  43. package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
  44. package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
  45. package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
  46. package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
  47. package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
  48. package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
  49. package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
  50. package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
  51. package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
  52. package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
  53. package/dist/orchestrator/src/cli/control/controlRuntime.js +992 -0
  54. package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
  55. package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
  56. package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
  57. package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
  58. package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
  59. package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
  60. package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
  61. package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
  62. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
  63. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
  64. package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
  65. package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
  66. package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
  67. package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
  68. package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
  69. package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
  70. package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
  71. package/dist/orchestrator/src/cli/control/controlState.js +233 -2
  72. package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1899 -0
  73. package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
  74. package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
  75. package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
  76. package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
  77. package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
  78. package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
  79. package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
  80. package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
  81. package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
  82. package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
  83. package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
  84. package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
  85. package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
  86. package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
  87. package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
  88. package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
  89. package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
  90. package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
  91. package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
  92. package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
  93. package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
  94. package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
  95. package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
  96. package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
  97. package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
  98. package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
  99. package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
  100. package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
  101. package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
  102. package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
  103. package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
  104. package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
  105. package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
  106. package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
  107. package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
  108. package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
  109. package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
  110. package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
  111. package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
  112. package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
  113. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
  114. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
  115. package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
  116. package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
  117. package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
  118. package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
  119. package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
  120. package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
  121. package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
  122. package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
  123. package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
  124. package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1838 -0
  125. package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
  126. package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
  127. package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
  128. package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
  129. package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
  130. package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
  131. package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
  132. package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
  133. package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
  134. package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
  135. package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
  136. package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
  137. package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
  138. package/dist/orchestrator/src/cli/delegationServer.js +567 -678
  139. package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
  140. package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
  141. package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
  142. package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
  143. package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
  144. package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
  145. package/dist/orchestrator/src/cli/doctor.js +542 -122
  146. package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
  147. package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
  148. package/dist/orchestrator/src/cli/doctorUsage.js +119 -15
  149. package/dist/orchestrator/src/cli/exec/experience.js +16 -2
  150. package/dist/orchestrator/src/cli/exec/summary.js +3 -0
  151. package/dist/orchestrator/src/cli/execCliShell.js +51 -0
  152. package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
  153. package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
  154. package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
  155. package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
  156. package/dist/orchestrator/src/cli/init.js +1 -0
  157. package/dist/orchestrator/src/cli/initCliShell.js +50 -0
  158. package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
  159. package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
  160. package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
  161. package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
  162. package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
  163. package/dist/orchestrator/src/cli/planCliShell.js +19 -0
  164. package/dist/orchestrator/src/cli/prCliShell.js +41 -0
  165. package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
  166. package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1772 -0
  167. package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
  168. package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
  169. package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +5738 -0
  170. package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
  171. package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
  172. package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
  173. package/dist/orchestrator/src/cli/rlm/context.js +94 -7
  174. package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
  175. package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
  176. package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
  177. package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
  178. package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
  179. package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
  180. package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
  181. package/dist/orchestrator/src/cli/run/manifest.js +410 -73
  182. package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
  183. package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
  184. package/dist/orchestrator/src/cli/run/source0.js +690 -0
  185. package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
  186. package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
  187. package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
  188. package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
  189. package/dist/orchestrator/src/cli/services/commandRunner.js +667 -18
  190. package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
  191. package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
  192. package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
  193. package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
  194. package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
  195. package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
  196. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
  197. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
  198. package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
  199. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
  200. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
  201. package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
  202. package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
  203. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
  204. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
  205. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
  206. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
  207. package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
  208. package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
  209. package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
  210. package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
  211. package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
  212. package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
  213. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
  214. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
  215. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
  216. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
  217. package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
  218. package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
  219. package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
  220. package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
  221. package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
  222. package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
  223. package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
  224. package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
  225. package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
  226. package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
  227. package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
  228. package/dist/orchestrator/src/cli/startCliShell.js +68 -0
  229. package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
  230. package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
  231. package/dist/orchestrator/src/cli/utils/cloudPreflight.js +83 -1
  232. package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
  233. package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
  234. package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
  235. package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
  236. package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
  237. package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
  238. package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
  239. package/dist/orchestrator/src/learning/crystalizer.js +2 -2
  240. package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
  241. package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
  242. package/dist/orchestrator/src/persistence/lockFile.js +70 -4
  243. package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
  244. package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
  245. package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
  246. package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
  247. package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
  248. package/dist/packages/sdk-node/src/orchestrator.js +137 -13
  249. package/dist/packages/shared/config/designConfig.js +8 -1
  250. package/dist/packages/shared/streams/stdio.js +1 -1
  251. package/dist/scripts/design/pipeline/permit.js +15 -0
  252. package/dist/scripts/lib/docs-catalog.js +365 -0
  253. package/dist/scripts/lib/docs-helpers.js +87 -5
  254. package/dist/scripts/lib/pr-watch-merge.js +1088 -80
  255. package/dist/scripts/lib/provider-run-contract.js +26 -0
  256. package/dist/scripts/lib/review-command-intent-classification.js +532 -0
  257. package/dist/scripts/lib/review-command-probe-classification.js +385 -0
  258. package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
  259. package/dist/scripts/lib/review-execution-runtime.js +753 -0
  260. package/dist/scripts/lib/review-execution-state.js +1144 -0
  261. package/dist/scripts/lib/review-execution-telemetry.js +215 -0
  262. package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
  263. package/dist/scripts/lib/review-launch-attempt.js +601 -0
  264. package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
  265. package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
  266. package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
  267. package/dist/scripts/lib/review-prompt-context.js +376 -0
  268. package/dist/scripts/lib/review-scope-advisory.js +286 -0
  269. package/dist/scripts/lib/review-scope-paths.js +123 -0
  270. package/dist/scripts/lib/review-shell-command-parser.js +389 -0
  271. package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
  272. package/dist/scripts/lib/run-manifests.js +192 -36
  273. package/dist/scripts/lib/spark-policy-classifier.js +593 -0
  274. package/dist/scripts/run-review.js +507 -1777
  275. package/docs/public/downstream-setup.md +106 -0
  276. package/docs/public/provider-onboarding.md +173 -0
  277. package/package.json +20 -10
  278. package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
  279. package/plugins/codex-orchestrator/.mcp.json +13 -0
  280. package/plugins/codex-orchestrator/launcher.mjs +359 -0
  281. package/schemas/manifest.json +394 -0
  282. package/skills/collab-subagents-first/SKILL.md +1 -1
  283. package/skills/delegation-usage/DELEGATION_GUIDE.md +24 -11
  284. package/skills/delegation-usage/SKILL.md +19 -13
  285. package/skills/land/SKILL.md +77 -0
  286. package/skills/linear/SKILL.md +255 -0
  287. package/skills/release/SKILL.md +47 -3
  288. package/skills/standalone-review/SKILL.md +6 -1
  289. package/templates/README.md +4 -2
  290. package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
  291. package/templates/codex/.codex/agents/worker-complex.toml +1 -1
  292. package/templates/codex/.codex/config.toml +3 -4
  293. package/templates/codex/.codex/providers/README.md +13 -0
  294. package/templates/codex/.codex/providers/control.example.json +18 -0
  295. package/templates/codex/.codex/providers/provider.env.example +15 -0
  296. package/templates/codex/AGENTS.md +12 -7
  297. package/templates/codex/mcp-client.json +5 -1
  298. package/docs/README.md +0 -310
  299. package/docs/assets/setup.gif +0 -0
@@ -0,0 +1,1144 @@
1
+ import { ARCHITECTURE_CONTEXT_META_SURFACE_KIND, isTouchedScopePath, normalizeActiveCloseoutBundleRoot, normalizeAuditMetaSurfaceEnvVarPathMap, normalizeAuditStartupAnchorPath, normalizeScopePath, normalizeScopeRoot } from './review-meta-surface-normalization.js';
2
+ import { classifyShellProbeCommandLine, detectHeavyReviewCommand, isLikelyReviewCommandLine } from './review-command-probe-classification.js';
3
+ import { classifyCommandIntentCommandLine, classifyCommandIntentToolLine, formatCommandIntentViolationLabel } from './review-command-intent-classification.js';
4
+ import { extractInspectionTargets } from './review-inspection-target-parsing.js';
5
+ import { REVIEW_ACTIVE_CLOSEOUT_BUNDLE_KIND, analyzeStartupAnchorBoundaryProgress, classifyMetaSurfaceCommandLine, classifyMetaSurfaceOutputLine, classifyMetaSurfaceToolLine } from './review-meta-surface-boundary-analysis.js';
6
+ import { buildReviewTelemetryPayload, inferTerminationBoundaryKindsFromErrorMessage, } from './review-execution-telemetry.js';
7
+ const REVIEW_DELEGATION_STARTUP_LINE_RE = /\bmcp:\s*delegation\s+(starting|ready)\b/i;
8
+ const REVIEW_PROGRESS_SIGNAL_LINE_RE = /^(thinking|exec|codex)\b/i;
9
+ const DEFAULT_REVIEW_OUTPUT_PREVIEW_LIMIT = 32_768;
10
+ const DEFAULT_REVIEW_OUTPUT_SUMMARY_TAIL_LINE_LIMIT = 20;
11
+ const DEFAULT_REVIEW_OUTPUT_SUMMARY_HEAVY_COMMAND_LIMIT = 8;
12
+ const DEFAULT_REVIEW_OUTPUT_SUMMARY_COMMAND_LIMIT = 64;
13
+ const DEFAULT_LOW_SIGNAL_TIMEOUT_MS = 180_000;
14
+ const DEFAULT_VERDICT_STABILITY_TIMEOUT_MS = 180_000;
15
+ const DEFAULT_META_SURFACE_TIMEOUT_MS = 180_000;
16
+ const RELEVANT_REINSPECTION_MIN_COMMAND_STARTS = 8;
17
+ const RELEVANT_REINSPECTION_BASE_MAX_DISTINCT_TARGETS = 4;
18
+ const RELEVANT_REINSPECTION_MIN_REPEAT_TARGET_HITS = 3;
19
+ const STARTUP_ANCHOR_META_SURFACE_SIGNAL_BUDGET = 1;
20
+ const STARTUP_ANCHOR_ALLOWED_META_SURFACE_KINDS = new Set(['review-support']);
21
+ export const ARCHITECTURE_ALLOWED_META_SURFACE_KINDS = [
22
+ ARCHITECTURE_CONTEXT_META_SURFACE_KIND,
23
+ 'review-support',
24
+ 'review-docs'
25
+ ];
26
+ export const AUDIT_ALLOWED_META_SURFACE_KINDS = ['run-manifest', 'run-runner-log'];
27
+ const ALLOWED_META_SURFACE_KIND_SET = new Set([
28
+ ...AUDIT_ALLOWED_META_SURFACE_KINDS,
29
+ ...ARCHITECTURE_ALLOWED_META_SURFACE_KINDS
30
+ ]);
31
+ const COMMAND_LEVEL_ALLOWED_META_SURFACE_KIND_SET = new Set(ARCHITECTURE_ALLOWED_META_SURFACE_KINDS);
32
+ const LOW_SIGNAL_MIN_THINKING_BLOCKS = 10;
33
+ const LOW_SIGNAL_MIN_COMMAND_STARTS = 10;
34
+ const LOW_SIGNAL_MAX_DISTINCT_TARGETS = 4;
35
+ const LOW_SIGNAL_MIN_REPEAT_TARGET_HITS = 3;
36
+ const LOW_SIGNAL_MIN_REPEAT_SIGNATURE_HITS = 4;
37
+ const LOW_SIGNAL_RECENT_COMMAND_WINDOW = LOW_SIGNAL_MIN_COMMAND_STARTS;
38
+ const VERDICT_STABILITY_MIN_THINKING_BLOCKS = 4;
39
+ const VERDICT_STABILITY_MIN_COMMAND_STARTS = 4;
40
+ const VERDICT_STABILITY_MIN_OUTPUT_TARGET_SIGNALS = 4;
41
+ const VERDICT_STABILITY_MIN_OUTPUT_NARRATIVE_SIGNALS = 4;
42
+ const VERDICT_STABILITY_MAX_DISTINCT_OUTPUT_TARGETS = 4;
43
+ const VERDICT_STABILITY_MAX_DISTINCT_OUTPUT_SIGNATURES = 8;
44
+ const VERDICT_STABILITY_MIN_REPEAT_OUTPUT_TARGET_HITS = 2;
45
+ const VERDICT_STABILITY_MIN_REPEAT_OUTPUT_SIGNATURE_HITS = 2;
46
+ const VERDICT_STABILITY_RECENT_OUTPUT_WINDOW = 16;
47
+ const META_SURFACE_MIN_COMMAND_STARTS = 6;
48
+ const META_SURFACE_MIN_SIGNALS = 4;
49
+ const META_SURFACE_MIN_DISTINCT_SURFACES = 3;
50
+ const META_SURFACE_MIN_REPEAT_HITS = 2;
51
+ const META_SURFACE_RECENT_SIGNAL_WINDOW = 8;
52
+ const REVIEW_NARRATIVE_INSPECTION_MIN_LINE_LENGTH = 32;
53
+ const REVIEW_SPECULATIVE_NARRATIVE_LINE_RE = /^(?:I\b|I['’]m\b|It\s+(?:might|may|seems|feels)\b|Maybe\b|Perhaps\b)/iu;
54
+ const REVIEW_COMMAND_INTENT_VIOLATION_SAMPLE_LIMIT = 8;
55
+ export class ReviewExecutionState {
56
+ startedAtMs;
57
+ blockHeavyCommands;
58
+ allowValidationCommandIntents;
59
+ activeCloseoutBundleRoots;
60
+ previewLimit;
61
+ tailLineLimit;
62
+ heavyCommandLimit;
63
+ commandLimit;
64
+ lowSignalTimeoutMs;
65
+ verdictStabilityTimeoutMs;
66
+ metaSurfaceTimeoutMs;
67
+ allowedMetaSurfaceKinds;
68
+ touchedPaths;
69
+ enforceStartupAnchorBoundary;
70
+ enforceActiveCloseoutBundleRereadBoundary;
71
+ enforceRelevantReinspectionDwellBoundary;
72
+ startupAnchorScopeMode;
73
+ startupAnchorMode;
74
+ repoRoot;
75
+ auditStartupAnchorPaths;
76
+ auditStartupAnchorEnvVarPaths;
77
+ allowedMetaSurfacePaths;
78
+ allowedMetaSurfaceEnvVarPaths;
79
+ lastOutputAtMs;
80
+ preview = '';
81
+ lineCount = 0;
82
+ completionCount = 0;
83
+ startupEvents = 0;
84
+ reviewProgressSignals = 0;
85
+ thinkingBlocks = 0;
86
+ reviewProgressObserved = false;
87
+ startupAnchorObserved = false;
88
+ awaitingCommandLine = false;
89
+ blockedHeavyCommand = null;
90
+ lowSignalCandidateSinceMs = null;
91
+ verdictStabilityCandidateSinceMs = null;
92
+ metaSurfaceCandidateSinceMs = null;
93
+ relevantReinspectionDwellCandidateSinceMs = null;
94
+ startupAnchorViolationAtMs = null;
95
+ preAnchorCommandStarts = 0;
96
+ commandStarts = [];
97
+ heavyCommandStarts = [];
98
+ recentInspectionTargetSamples = [];
99
+ recentInspectionSignatures = [];
100
+ recentOutputInspectionTargetSamples = [];
101
+ recentOutputNarrativeSignatures = [];
102
+ recentConcreteOutputTargetSamples = [];
103
+ recentMetaSurfaceSamples = [];
104
+ preAnchorMetaSurfaceSamples = [];
105
+ commandIntentViolationSamples = [];
106
+ shellProbeSamples = [];
107
+ lastLines = [];
108
+ pendingFragmentsByStream = {
109
+ stdout: '',
110
+ stderr: ''
111
+ };
112
+ commandIntentViolation = null;
113
+ shellProbeViolation = null;
114
+ activeCloseoutBundleRereadViolation = null;
115
+ relevantReinspectionDwellViolation = null;
116
+ activeCloseoutBundleRereadCount = 0;
117
+ shellProbeCount = 0;
118
+ lastInspectionCommandLine = null;
119
+ constructor(options = {}) {
120
+ this.startedAtMs = options.startedAtMs ?? Date.now();
121
+ this.lastOutputAtMs = this.startedAtMs;
122
+ this.blockHeavyCommands = options.blockHeavyCommands ?? false;
123
+ this.allowValidationCommandIntents = options.allowValidationCommandIntents ?? false;
124
+ this.previewLimit = options.previewLimit ?? DEFAULT_REVIEW_OUTPUT_PREVIEW_LIMIT;
125
+ this.tailLineLimit = options.tailLineLimit ?? DEFAULT_REVIEW_OUTPUT_SUMMARY_TAIL_LINE_LIMIT;
126
+ this.heavyCommandLimit =
127
+ options.heavyCommandLimit ?? DEFAULT_REVIEW_OUTPUT_SUMMARY_HEAVY_COMMAND_LIMIT;
128
+ this.commandLimit = options.commandLimit ?? DEFAULT_REVIEW_OUTPUT_SUMMARY_COMMAND_LIMIT;
129
+ const configuredLowSignalTimeoutMs = options.lowSignalTimeoutMs;
130
+ this.lowSignalTimeoutMs =
131
+ configuredLowSignalTimeoutMs === undefined
132
+ ? DEFAULT_LOW_SIGNAL_TIMEOUT_MS
133
+ : configuredLowSignalTimeoutMs === null || configuredLowSignalTimeoutMs <= 0
134
+ ? null
135
+ : configuredLowSignalTimeoutMs;
136
+ const configuredVerdictStabilityTimeoutMs = options.verdictStabilityTimeoutMs;
137
+ this.verdictStabilityTimeoutMs =
138
+ configuredVerdictStabilityTimeoutMs === undefined
139
+ ? DEFAULT_VERDICT_STABILITY_TIMEOUT_MS
140
+ : configuredVerdictStabilityTimeoutMs === null || configuredVerdictStabilityTimeoutMs <= 0
141
+ ? null
142
+ : configuredVerdictStabilityTimeoutMs;
143
+ const configuredMetaSurfaceTimeoutMs = options.metaSurfaceTimeoutMs;
144
+ this.metaSurfaceTimeoutMs =
145
+ configuredMetaSurfaceTimeoutMs === undefined
146
+ ? DEFAULT_META_SURFACE_TIMEOUT_MS
147
+ : configuredMetaSurfaceTimeoutMs === null || configuredMetaSurfaceTimeoutMs <= 0
148
+ ? null
149
+ : configuredMetaSurfaceTimeoutMs;
150
+ this.allowedMetaSurfaceKinds = new Set((options.allowedMetaSurfaceKinds ?? []).filter((kind) => ALLOWED_META_SURFACE_KIND_SET.has(kind)));
151
+ this.repoRoot = normalizeScopeRoot(options.repoRoot);
152
+ this.touchedPaths = new Set((options.touchedPaths ?? []).map((entry) => normalizeScopePath(entry)).filter(Boolean));
153
+ this.activeCloseoutBundleRoots = new Set((options.activeCloseoutBundleRoots ?? [])
154
+ .map((entry) => normalizeActiveCloseoutBundleRoot(entry, this.repoRoot))
155
+ .filter((entry) => Boolean(entry)));
156
+ this.startupAnchorMode = options.startupAnchorMode ?? null;
157
+ this.auditStartupAnchorPaths = new Set((options.auditStartupAnchorPaths ?? [])
158
+ .map((entry) => normalizeAuditStartupAnchorPath(entry, this.repoRoot))
159
+ .filter((entry) => Boolean(entry)));
160
+ this.auditStartupAnchorEnvVarPaths = normalizeAuditMetaSurfaceEnvVarPathMap(options.auditStartupAnchorEnvVarPaths, this.repoRoot);
161
+ this.allowedMetaSurfacePaths = new Set((options.allowedMetaSurfacePaths ?? [])
162
+ .map((entry) => normalizeAuditStartupAnchorPath(entry, this.repoRoot))
163
+ .filter((entry) => Boolean(entry)));
164
+ this.allowedMetaSurfaceEnvVarPaths = normalizeAuditMetaSurfaceEnvVarPathMap(options.allowedMetaSurfaceEnvVarPaths, this.repoRoot);
165
+ this.enforceStartupAnchorBoundary =
166
+ (options.enforceStartupAnchorBoundary ?? false) &&
167
+ (this.startupAnchorMode === 'audit' || this.touchedPaths.size > 0);
168
+ this.enforceActiveCloseoutBundleRereadBoundary =
169
+ (options.enforceActiveCloseoutBundleRereadBoundary ?? this.enforceStartupAnchorBoundary) &&
170
+ this.activeCloseoutBundleRoots.size > 0;
171
+ this.enforceRelevantReinspectionDwellBoundary =
172
+ (options.enforceRelevantReinspectionDwellBoundary ?? this.enforceStartupAnchorBoundary) &&
173
+ this.touchedPaths.size > 0;
174
+ this.startupAnchorScopeMode = options.scopeMode ?? 'uncommitted';
175
+ }
176
+ observeChunk(chunk, stream, nowMs = Date.now()) {
177
+ const next = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : chunk;
178
+ this.lastOutputAtMs = nowMs;
179
+ if (this.preview.length < this.previewLimit) {
180
+ this.preview = `${this.preview}${next}`.slice(0, this.previewLimit);
181
+ }
182
+ const combined = `${this.pendingFragmentsByStream[stream]}${next}`;
183
+ const lines = combined.split(/\r?\n/u);
184
+ this.pendingFragmentsByStream[stream] = lines.pop() ?? '';
185
+ for (const line of lines) {
186
+ this.processLine(line, nowMs);
187
+ }
188
+ }
189
+ getPreview() {
190
+ return this.preview;
191
+ }
192
+ getBlockedHeavyCommand() {
193
+ return this.blockedHeavyCommand;
194
+ }
195
+ getLastOutputAtMs() {
196
+ return this.lastOutputAtMs;
197
+ }
198
+ getStartupLoopState() {
199
+ return {
200
+ startupEvents: this.startupEvents,
201
+ reviewProgressObserved: this.reviewProgressObserved
202
+ };
203
+ }
204
+ buildOutputSummary() {
205
+ const inspectionTargetSummary = this.buildInspectionTargetSummary();
206
+ const outputNarrativeSummary = this.buildOutputNarrativeSummary();
207
+ const preAnchorMetaSurfaceSummary = this.buildPreAnchorMetaSurfaceSummary();
208
+ return {
209
+ lineCount: this.lineCount,
210
+ commandStarts: [...this.commandStarts],
211
+ completionCount: this.completionCount,
212
+ startupEvents: this.startupEvents,
213
+ reviewProgressSignals: this.reviewProgressSignals,
214
+ thinkingBlocks: this.thinkingBlocks,
215
+ heavyCommandStarts: [...this.heavyCommandStarts],
216
+ distinctInspectionTargets: inspectionTargetSummary.distinctTargets,
217
+ maxInspectionTargetHits: inspectionTargetSummary.maxHits,
218
+ distinctInspectionSignatures: inspectionTargetSummary.distinctSignatures,
219
+ maxInspectionSignatureHits: inspectionTargetSummary.maxSignatureHits,
220
+ outputInspectionSignals: outputNarrativeSummary.outputInspectionSignals,
221
+ outputNarrativeSignals: outputNarrativeSummary.outputNarrativeSignals,
222
+ concreteOutputSignals: outputNarrativeSummary.concreteOutputSignals,
223
+ distinctOutputInspectionTargets: outputNarrativeSummary.distinctOutputTargets,
224
+ maxOutputInspectionTargetHits: outputNarrativeSummary.maxOutputTargetHits,
225
+ distinctOutputNarrativeSignatures: outputNarrativeSummary.distinctNarrativeSignatures,
226
+ maxOutputNarrativeSignatureHits: outputNarrativeSummary.maxNarrativeSignatureHits,
227
+ metaSurfaceSignals: inspectionTargetSummary.metaSurfaceSignals,
228
+ distinctMetaSurfaces: inspectionTargetSummary.distinctMetaSurfaces,
229
+ maxMetaSurfaceHits: inspectionTargetSummary.maxMetaSurfaceHits,
230
+ metaSurfaceKinds: inspectionTargetSummary.metaSurfaceKinds,
231
+ startupAnchorObserved: this.startupAnchorObserved,
232
+ preAnchorCommandStarts: this.preAnchorCommandStarts,
233
+ preAnchorMetaSurfaceSignals: preAnchorMetaSurfaceSummary.signals,
234
+ preAnchorDistinctMetaSurfaces: preAnchorMetaSurfaceSummary.distinctSurfaces,
235
+ preAnchorMetaSurfaceKinds: preAnchorMetaSurfaceSummary.kinds,
236
+ commandIntentViolationCount: this.commandIntentViolationSamples.length,
237
+ commandIntentViolationKinds: [
238
+ ...new Set(this.commandIntentViolationSamples.map((sample) => sample.kind))
239
+ ].sort(),
240
+ commandIntentViolationSamples: this.commandIntentViolationSamples.map((sample) => `[${sample.kind}] ${sample.sample}`),
241
+ shellProbeCount: this.shellProbeCount,
242
+ lastLines: [...this.lastLines]
243
+ };
244
+ }
245
+ getLowSignalDriftState(nowMs = Date.now()) {
246
+ const summary = this.buildOutputSummary();
247
+ const triggered = this.lowSignalTimeoutMs !== null &&
248
+ this.lowSignalCandidateSinceMs !== null &&
249
+ Math.max(0, nowMs - this.lowSignalCandidateSinceMs) >= this.lowSignalTimeoutMs;
250
+ return {
251
+ triggered,
252
+ reason: triggered
253
+ ? `low-signal review drift detected after ${formatDurationMs(Math.max(0, nowMs - this.startedAtMs))}: ${this.thinkingBlocks} thinking blocks, ${this.commandStarts.length} command starts, ${summary.distinctInspectionTargets} repeated inspection targets (max hit count ${summary.maxInspectionTargetHits}), ${summary.distinctInspectionSignatures} repeated inspection signatures (max hit count ${summary.maxInspectionSignatureHits}), sustained for ${formatDurationMs(Math.max(0, nowMs - this.lowSignalCandidateSinceMs))}.`
254
+ : null,
255
+ thinkingBlocks: this.thinkingBlocks,
256
+ commandStarts: this.commandStarts.length,
257
+ distinctInspectionTargets: summary.distinctInspectionTargets,
258
+ maxInspectionTargetHits: summary.maxInspectionTargetHits,
259
+ distinctInspectionSignatures: summary.distinctInspectionSignatures,
260
+ maxInspectionSignatureHits: summary.maxInspectionSignatureHits,
261
+ timeoutMs: this.lowSignalTimeoutMs
262
+ };
263
+ }
264
+ getVerdictStabilityState(nowMs = Date.now()) {
265
+ const summary = this.buildOutputSummary();
266
+ const triggered = this.verdictStabilityTimeoutMs !== null &&
267
+ this.verdictStabilityCandidateSinceMs !== null &&
268
+ Math.max(0, nowMs - this.verdictStabilityCandidateSinceMs) >=
269
+ this.verdictStabilityTimeoutMs;
270
+ return {
271
+ triggered,
272
+ reason: triggered
273
+ ? summary.distinctOutputInspectionTargets > 0
274
+ ? `bounded review verdict-stability drift detected after ${formatDurationMs(Math.max(0, nowMs - this.startedAtMs))}: ${this.thinkingBlocks} thinking blocks, ${this.commandStarts.length} command starts, ${summary.outputInspectionSignals} repeated output inspection signals across ${summary.distinctOutputInspectionTargets} target(s) (max hit count ${summary.maxOutputInspectionTargetHits}), ${summary.distinctOutputNarrativeSignatures} repeated narrative signature(s) (max hit count ${summary.maxOutputNarrativeSignatureHits}), sustained for ${formatDurationMs(Math.max(0, nowMs - this.verdictStabilityCandidateSinceMs))}.`
275
+ : `bounded review verdict-stability drift detected after ${formatDurationMs(Math.max(0, nowMs - this.startedAtMs))}: ${this.thinkingBlocks} thinking blocks, ${this.commandStarts.length} command starts, ${summary.outputNarrativeSignals} repeated speculative narrative signal(s) with no concrete output targets, ${summary.distinctOutputNarrativeSignatures} repeated narrative signature(s) (max hit count ${summary.maxOutputNarrativeSignatureHits}), sustained for ${formatDurationMs(Math.max(0, nowMs - this.verdictStabilityCandidateSinceMs))}.`
276
+ : null,
277
+ thinkingBlocks: this.thinkingBlocks,
278
+ commandStarts: this.commandStarts.length,
279
+ outputInspectionSignals: summary.outputInspectionSignals,
280
+ outputNarrativeSignals: summary.outputNarrativeSignals,
281
+ concreteOutputSignals: summary.concreteOutputSignals,
282
+ distinctOutputInspectionTargets: summary.distinctOutputInspectionTargets,
283
+ maxOutputInspectionTargetHits: summary.maxOutputInspectionTargetHits,
284
+ distinctOutputNarrativeSignatures: summary.distinctOutputNarrativeSignatures,
285
+ maxOutputNarrativeSignatureHits: summary.maxOutputNarrativeSignatureHits,
286
+ timeoutMs: this.verdictStabilityTimeoutMs
287
+ };
288
+ }
289
+ getMetaSurfaceExpansionState(nowMs = Date.now()) {
290
+ const summary = this.buildOutputSummary();
291
+ const activeCloseoutBundleRereadTriggered = this.enforceActiveCloseoutBundleRereadBoundary &&
292
+ this.activeCloseoutBundleRereadViolation !== null;
293
+ const triggered = !activeCloseoutBundleRereadTriggered &&
294
+ this.metaSurfaceTimeoutMs !== null &&
295
+ this.metaSurfaceCandidateSinceMs !== null &&
296
+ Math.max(0, nowMs - this.metaSurfaceCandidateSinceMs) >= this.metaSurfaceTimeoutMs;
297
+ return {
298
+ triggered,
299
+ reason: triggered
300
+ ? `bounded review meta-surface expansion detected after ${formatDurationMs(Math.max(0, nowMs - this.startedAtMs))}: ${this.commandStarts.length} command starts, ${summary.metaSurfaceSignals} meta-surface signals, ${summary.distinctMetaSurfaces} distinct meta-surfaces [${summary.metaSurfaceKinds.join(', ')}] (max hit count ${summary.maxMetaSurfaceHits}), sustained for ${formatDurationMs(Math.max(0, nowMs - this.metaSurfaceCandidateSinceMs))}.`
301
+ : null,
302
+ commandStarts: this.commandStarts.length,
303
+ metaSurfaceSignals: summary.metaSurfaceSignals,
304
+ distinctMetaSurfaces: summary.distinctMetaSurfaces,
305
+ maxMetaSurfaceHits: summary.maxMetaSurfaceHits,
306
+ timeoutMs: this.metaSurfaceTimeoutMs
307
+ };
308
+ }
309
+ getStartupAnchorBoundaryState(nowMs = Date.now()) {
310
+ const summary = this.buildOutputSummary();
311
+ const triggered = this.startupAnchorViolationAtMs !== null;
312
+ return {
313
+ triggered,
314
+ reason: triggered
315
+ ? `bounded review startup-anchor boundary violated after ${formatDurationMs(Math.max(0, this.startupAnchorViolationAtMs - this.startedAtMs))}: ${summary.preAnchorCommandStarts} pre-anchor command starts, ${summary.preAnchorMetaSurfaceSignals} pre-anchor meta-surface signals across ${summary.preAnchorDistinctMetaSurfaces} surface kind(s) [${summary.preAnchorMetaSurfaceKinds.join(', ')}] before the first startup anchor.`
316
+ : null,
317
+ anchorObserved: this.startupAnchorObserved,
318
+ preAnchorCommandStarts: summary.preAnchorCommandStarts,
319
+ preAnchorMetaSurfaceSignals: summary.preAnchorMetaSurfaceSignals,
320
+ preAnchorDistinctMetaSurfaces: summary.preAnchorDistinctMetaSurfaces,
321
+ preAnchorMetaSurfaceKinds: summary.preAnchorMetaSurfaceKinds
322
+ };
323
+ }
324
+ getCommandIntentBoundaryState(nowMs = Date.now()) {
325
+ const summary = this.buildOutputSummary();
326
+ const violation = this.commandIntentViolation;
327
+ return {
328
+ triggered: violation !== null,
329
+ reason: violation
330
+ ? `bounded review command-intent boundary violated after ${formatDurationMs(Math.max(0, nowMs - this.startedAtMs))}: ${formatCommandIntentViolationLabel(violation.kind)} via ${violation.sample}.`
331
+ : null,
332
+ violationKind: violation?.kind ?? null,
333
+ violationSample: violation?.sample ?? null,
334
+ violationCount: summary.commandIntentViolationCount,
335
+ violationKinds: summary.commandIntentViolationKinds
336
+ };
337
+ }
338
+ getShellProbeBoundaryState(nowMs = Date.now()) {
339
+ return {
340
+ triggered: this.shellProbeViolation !== null,
341
+ reason: this.shellProbeViolation
342
+ ? `bounded review shell-probe boundary violated after ${formatDurationMs(Math.max(0, this.shellProbeViolation.detectedAtMs - this.startedAtMs))}: repeated direct shell verification via ${this.shellProbeViolation.sample}.`
343
+ : null,
344
+ probeCount: this.shellProbeCount,
345
+ violationSample: this.shellProbeViolation?.sample ?? null
346
+ };
347
+ }
348
+ getActiveCloseoutBundleRereadBoundaryState(nowMs = Date.now()) {
349
+ return {
350
+ triggered: this.activeCloseoutBundleRereadViolation !== null,
351
+ reason: this.activeCloseoutBundleRereadViolation
352
+ ? `bounded review active-closeout-bundle reread boundary violated after ${formatDurationMs(Math.max(0, this.activeCloseoutBundleRereadViolation.detectedAtMs - this.startedAtMs))}: ${this.activeCloseoutBundleRereadViolation.rereadCount} repeated direct reread command(s) into the active closeout bundle after earlier bounded inspection via ${this.activeCloseoutBundleRereadViolation.sample}.`
353
+ : null,
354
+ rereadCount: this.activeCloseoutBundleRereadCount,
355
+ violationSample: this.activeCloseoutBundleRereadViolation?.sample ?? null,
356
+ anchorObserved: this.startupAnchorObserved
357
+ };
358
+ }
359
+ getRelevantReinspectionDwellBoundaryState(nowMs = Date.now()) {
360
+ const summary = this.buildOutputSummary();
361
+ const relevantInspectionSummary = this.buildInspectionTargetSummary(this.getRelevantReinspectionWindowSize());
362
+ const derivedTriggered = this.relevantReinspectionDwellViolation !== null ||
363
+ (this.enforceRelevantReinspectionDwellBoundary &&
364
+ this.lowSignalTimeoutMs !== null &&
365
+ this.relevantReinspectionDwellCandidateSinceMs !== null &&
366
+ Math.max(0, nowMs - this.relevantReinspectionDwellCandidateSinceMs) >=
367
+ this.lowSignalTimeoutMs);
368
+ const detectedAtMs = this.relevantReinspectionDwellViolation?.detectedAtMs ??
369
+ (derivedTriggered && this.relevantReinspectionDwellCandidateSinceMs !== null && this.lowSignalTimeoutMs !== null
370
+ ? this.relevantReinspectionDwellCandidateSinceMs + this.lowSignalTimeoutMs
371
+ : null);
372
+ const violationSample = this.relevantReinspectionDwellViolation?.sample ?? this.lastInspectionCommandLine;
373
+ const commandStarts = this.relevantReinspectionDwellViolation?.commandStarts ?? this.commandStarts.length;
374
+ const distinctTargets = this.relevantReinspectionDwellViolation?.distinctTargets ??
375
+ relevantInspectionSummary.distinctTargets;
376
+ const maxTargetHits = this.relevantReinspectionDwellViolation?.maxTargetHits ?? relevantInspectionSummary.maxHits;
377
+ return {
378
+ triggered: derivedTriggered,
379
+ reason: derivedTriggered && detectedAtMs !== null
380
+ ? `bounded review relevant-reinspection dwell boundary violated after ${formatDurationMs(Math.max(0, detectedAtMs - this.startedAtMs))}: ${commandStarts} command start(s) repeatedly revisited ${distinctTargets} bounded relevant target(s) (max target hit count ${maxTargetHits}) ${this.enforceStartupAnchorBoundary
381
+ ? 'after startup-anchor success'
382
+ : 'within the current bounded review surface'} without concrete findings or meta-surface drift${violationSample
383
+ ? ` via ${violationSample}`
384
+ : ''}.`
385
+ : null,
386
+ anchorObserved: this.startupAnchorObserved,
387
+ commandStarts: this.commandStarts.length,
388
+ distinctTargets: relevantInspectionSummary.distinctTargets,
389
+ maxTargetHits: relevantInspectionSummary.maxHits,
390
+ metaSurfaceSignals: summary.metaSurfaceSignals,
391
+ concreteOutputSignals: summary.concreteOutputSignals,
392
+ violationSample
393
+ };
394
+ }
395
+ snapshot(nowMs = Date.now()) {
396
+ return {
397
+ startedAtMs: this.startedAtMs,
398
+ lastOutputAtMs: this.lastOutputAtMs,
399
+ elapsedMs: Math.max(0, nowMs - this.startedAtMs),
400
+ idleMs: Math.max(0, nowMs - this.lastOutputAtMs),
401
+ awaitingCommandLine: this.awaitingCommandLine,
402
+ blockedHeavyCommand: this.blockedHeavyCommand,
403
+ startupEvents: this.startupEvents,
404
+ reviewProgressObserved: this.reviewProgressObserved,
405
+ summary: this.buildOutputSummary()
406
+ };
407
+ }
408
+ formatCheckpoint(nowMs = Date.now()) {
409
+ const snapshot = this.snapshot(nowMs);
410
+ const startupStatus = snapshot.reviewProgressObserved
411
+ ? 'review progress observed'
412
+ : `${snapshot.startupEvents} delegation startup events, no review progress yet`;
413
+ return `[run-review] waiting on codex review (${formatDurationMs(snapshot.elapsedMs)} elapsed, ${formatDurationMs(snapshot.idleMs)} idle; ${startupStatus}).`;
414
+ }
415
+ buildTelemetryPayload(options) {
416
+ const explicitTerminationBoundaryProvided = Object.prototype.hasOwnProperty.call(options, 'terminationBoundary');
417
+ return buildReviewTelemetryPayload({
418
+ status: options.status,
419
+ error: options.error ?? null,
420
+ terminationBoundary: explicitTerminationBoundaryProvided
421
+ ? options.terminationBoundary ?? null
422
+ : options.status === 'failed'
423
+ ? this.getTerminationBoundaryRecord(options.error ?? null)
424
+ : null,
425
+ outputLogPath: options.outputLogPath,
426
+ repoRoot: options.repoRoot,
427
+ includeRawTelemetry: options.includeRawTelemetry,
428
+ telemetryDebugEnvKey: options.telemetryDebugEnvKey,
429
+ launchContext: options.launchContext ?? null,
430
+ summary: this.buildOutputSummary()
431
+ });
432
+ }
433
+ recordCommandIntentViolationsFrom(other) {
434
+ for (const violation of other.commandIntentViolationSamples) {
435
+ this.recordCommandIntentViolation(violation);
436
+ }
437
+ }
438
+ getTerminationBoundaryRecordForKind(kind, nowMs = Date.now()) {
439
+ return this.buildTerminationBoundaryRecord(kind, nowMs);
440
+ }
441
+ getTerminationBoundaryRecord(errorMessage = null, nowMs = Date.now()) {
442
+ const matchedKinds = inferTerminationBoundaryKindsFromErrorMessage(errorMessage);
443
+ for (const kind of matchedKinds) {
444
+ if (kind === 'timeout' && errorMessage) {
445
+ return {
446
+ kind: 'timeout',
447
+ provenance: 'review-timeout',
448
+ reason: errorMessage,
449
+ sample: null
450
+ };
451
+ }
452
+ if (kind === 'stall' && errorMessage) {
453
+ return {
454
+ kind: 'stall',
455
+ provenance: 'output-stall',
456
+ reason: errorMessage,
457
+ sample: null
458
+ };
459
+ }
460
+ if (kind === 'startup-loop' && errorMessage) {
461
+ return {
462
+ kind: 'startup-loop',
463
+ provenance: 'delegation-startup-loop',
464
+ reason: errorMessage,
465
+ sample: null
466
+ };
467
+ }
468
+ const record = this.buildTerminationBoundaryRecord(kind, nowMs);
469
+ if (record) {
470
+ return record;
471
+ }
472
+ }
473
+ return null;
474
+ }
475
+ buildTerminationBoundaryRecord(kind, nowMs) {
476
+ if (kind === 'command-intent') {
477
+ const boundary = this.getCommandIntentBoundaryState(nowMs);
478
+ if (!boundary.triggered || !boundary.reason || !boundary.violationKind) {
479
+ return null;
480
+ }
481
+ return {
482
+ kind,
483
+ provenance: boundary.violationKind,
484
+ reason: boundary.reason,
485
+ sample: normalizeTerminationBoundarySample(boundary.violationSample)
486
+ };
487
+ }
488
+ if (kind === 'shell-probe') {
489
+ const boundary = this.getShellProbeBoundaryState(nowMs);
490
+ if (!boundary.triggered || !boundary.reason) {
491
+ return null;
492
+ }
493
+ return {
494
+ kind,
495
+ provenance: 'direct-shell-verification',
496
+ reason: boundary.reason,
497
+ sample: normalizeTerminationBoundarySample(boundary.violationSample)
498
+ };
499
+ }
500
+ if (kind === 'active-closeout-bundle-reread') {
501
+ const boundary = this.getActiveCloseoutBundleRereadBoundaryState(nowMs);
502
+ if (!boundary.triggered || !boundary.reason) {
503
+ return null;
504
+ }
505
+ return {
506
+ kind,
507
+ provenance: boundary.anchorObserved ? 'post-startup-anchor' : 'bounded-surface',
508
+ reason: boundary.reason,
509
+ sample: normalizeTerminationBoundarySample(boundary.violationSample)
510
+ };
511
+ }
512
+ if (kind === 'startup-anchor') {
513
+ const boundary = this.getStartupAnchorBoundaryState(nowMs);
514
+ if (!boundary.triggered || !boundary.reason) {
515
+ return null;
516
+ }
517
+ return {
518
+ kind,
519
+ provenance: 'pre-anchor-meta-surface',
520
+ reason: boundary.reason,
521
+ sample: boundary.preAnchorMetaSurfaceKinds[0] ?? null
522
+ };
523
+ }
524
+ if (kind === 'meta-surface-expansion') {
525
+ const boundary = this.getMetaSurfaceExpansionState(nowMs);
526
+ if (!boundary.triggered || !boundary.reason) {
527
+ return null;
528
+ }
529
+ const summary = this.buildOutputSummary();
530
+ const isPureActiveCloseoutSearch = summary.metaSurfaceKinds.length === 1 &&
531
+ summary.metaSurfaceKinds[0] === REVIEW_ACTIVE_CLOSEOUT_BUNDLE_KIND;
532
+ return {
533
+ kind,
534
+ provenance: isPureActiveCloseoutSearch
535
+ ? 'active-closeout-self-reference-search'
536
+ : 'meta-surface-kinds',
537
+ reason: boundary.reason,
538
+ sample: summary.metaSurfaceKinds[0] ?? null
539
+ };
540
+ }
541
+ if (kind === 'verdict-stability') {
542
+ const boundary = this.getVerdictStabilityState(nowMs);
543
+ if (!boundary.triggered || !boundary.reason) {
544
+ return null;
545
+ }
546
+ return {
547
+ kind,
548
+ provenance: boundary.distinctOutputInspectionTargets > 0
549
+ ? 'repeated-output-inspection'
550
+ : 'targetless-speculative-narrative',
551
+ reason: boundary.reason,
552
+ sample: null
553
+ };
554
+ }
555
+ const boundary = this.getRelevantReinspectionDwellBoundaryState(nowMs);
556
+ if (!boundary.triggered || !boundary.reason) {
557
+ return null;
558
+ }
559
+ return {
560
+ kind,
561
+ provenance: boundary.anchorObserved ? 'post-startup-anchor' : 'bounded-surface',
562
+ reason: boundary.reason,
563
+ sample: normalizeTerminationBoundarySample(boundary.violationSample)
564
+ };
565
+ }
566
+ processLine(line, nowMs) {
567
+ this.lineCount += 1;
568
+ const trimmed = line.trim();
569
+ let handledAsCommandLine = false;
570
+ if (trimmed.length > 0) {
571
+ this.lastLines.push(trimmed);
572
+ if (this.lastLines.length > this.tailLineLimit) {
573
+ this.lastLines.shift();
574
+ }
575
+ }
576
+ if (REVIEW_DELEGATION_STARTUP_LINE_RE.test(trimmed)) {
577
+ this.startupEvents += 1;
578
+ }
579
+ if (trimmed === 'thinking') {
580
+ this.thinkingBlocks += 1;
581
+ }
582
+ if (REVIEW_PROGRESS_SIGNAL_LINE_RE.test(trimmed)) {
583
+ this.reviewProgressSignals += 1;
584
+ this.reviewProgressObserved = true;
585
+ }
586
+ const metaSurfaceToolSample = classifyMetaSurfaceToolLine(trimmed);
587
+ if (metaSurfaceToolSample) {
588
+ this.recordMetaSurfaceToolSample(metaSurfaceToolSample, nowMs);
589
+ }
590
+ const commandIntentToolViolation = classifyCommandIntentToolLine(trimmed);
591
+ if (commandIntentToolViolation) {
592
+ this.recordCommandIntentViolation(commandIntentToolViolation);
593
+ }
594
+ if (trimmed === 'exec') {
595
+ this.awaitingCommandLine = true;
596
+ return;
597
+ }
598
+ if (this.awaitingCommandLine && trimmed.length > 0) {
599
+ const commandLine = normalizeReviewCommandLine(trimmed);
600
+ if (isLikelyReviewCommandLine(commandLine)) {
601
+ if (this.commandStarts.length >= this.commandLimit) {
602
+ this.commandStarts.shift();
603
+ }
604
+ this.commandStarts.push(commandLine);
605
+ const metaSurfaceSample = classifyMetaSurfaceCommandLine(commandLine, this.touchedPaths, this.repoRoot, this.activeCloseoutBundleRoots, {
606
+ allowedMetaSurfacePaths: this.allowedMetaSurfacePaths,
607
+ allowedMetaSurfaceEnvVarPaths: this.allowedMetaSurfaceEnvVarPaths
608
+ });
609
+ this.recordMetaSurfaceCommandSample(metaSurfaceSample, commandLine, nowMs);
610
+ this.recordInspectionTargets(commandLine);
611
+ this.recordStartupAnchorProgress(commandLine, nowMs);
612
+ const shellProbeSample = classifyShellProbeCommandLine(commandLine);
613
+ if (shellProbeSample) {
614
+ this.recordShellProbe(shellProbeSample, nowMs);
615
+ }
616
+ const commandIntentViolation = classifyCommandIntentCommandLine(commandLine, {
617
+ allowValidationCommandIntents: this.allowValidationCommandIntents
618
+ });
619
+ if (commandIntentViolation) {
620
+ this.recordCommandIntentViolation(commandIntentViolation);
621
+ }
622
+ const heavyCommand = detectHeavyReviewCommand(commandLine);
623
+ if (heavyCommand) {
624
+ if (this.heavyCommandStarts.length < this.heavyCommandLimit) {
625
+ this.heavyCommandStarts.push(commandLine);
626
+ }
627
+ if (this.blockHeavyCommands && !this.blockedHeavyCommand) {
628
+ this.blockedHeavyCommand = commandLine;
629
+ }
630
+ }
631
+ handledAsCommandLine = true;
632
+ this.awaitingCommandLine = false;
633
+ }
634
+ else if (REVIEW_PROGRESS_SIGNAL_LINE_RE.test(trimmed) ||
635
+ /\bsucceeded in\b|\bexited\b/i.test(trimmed)) {
636
+ this.awaitingCommandLine = false;
637
+ }
638
+ }
639
+ if (!handledAsCommandLine) {
640
+ const outputMetaSurfaceSample = classifyMetaSurfaceOutputLine(trimmed, this.activeCloseoutBundleRoots, this.repoRoot);
641
+ if (outputMetaSurfaceSample) {
642
+ this.recordMetaSurfaceSample(outputMetaSurfaceSample, nowMs);
643
+ }
644
+ this.recordConcreteOutputSignals(trimmed);
645
+ this.recordNarrativeInspectionSignals(trimmed);
646
+ }
647
+ if (/\bsucceeded in\b|\bexited\b/i.test(trimmed)) {
648
+ this.completionCount += 1;
649
+ }
650
+ this.updateLowSignalCandidate(nowMs);
651
+ this.updateVerdictStabilityCandidate(nowMs);
652
+ this.updateMetaSurfaceCandidate(nowMs);
653
+ this.updateRelevantReinspectionDwellCandidate(nowMs);
654
+ }
655
+ recordInspectionTargets(commandLine) {
656
+ const targets = extractInspectionTargets(commandLine, {
657
+ touchedPaths: this.touchedPaths,
658
+ repoRoot: this.repoRoot
659
+ });
660
+ if (targets.length === 0) {
661
+ return targets;
662
+ }
663
+ this.lastInspectionCommandLine = commandLine;
664
+ this.recentInspectionTargetSamples.push(targets);
665
+ while (this.recentInspectionTargetSamples.length > this.getRecordedInspectionSignalWindowSize()) {
666
+ this.recentInspectionTargetSamples.shift();
667
+ }
668
+ const signature = extractInspectionCommandSignature(commandLine, targets);
669
+ if (!signature) {
670
+ return targets;
671
+ }
672
+ this.recentInspectionSignatures.push(signature);
673
+ while (this.recentInspectionSignatures.length > this.getRecordedInspectionSignalWindowSize()) {
674
+ this.recentInspectionSignatures.shift();
675
+ }
676
+ return targets;
677
+ }
678
+ recordStartupAnchorProgress(commandLine, nowMs) {
679
+ if (!this.enforceStartupAnchorBoundary || this.startupAnchorObserved) {
680
+ return;
681
+ }
682
+ const startupBoundaryProgress = analyzeStartupAnchorBoundaryProgress(commandLine, {
683
+ repoRoot: this.repoRoot,
684
+ activeCloseoutBundleRoots: this.activeCloseoutBundleRoots,
685
+ touchedPaths: this.touchedPaths,
686
+ scopeMode: this.startupAnchorScopeMode,
687
+ startupAnchorMode: this.startupAnchorMode,
688
+ auditStartupAnchorPaths: this.auditStartupAnchorPaths,
689
+ auditStartupAnchorEnvVarPaths: this.auditStartupAnchorEnvVarPaths
690
+ });
691
+ for (const preAnchorMetaSurfaceSample of startupBoundaryProgress.preAnchorMetaSurfaceSamples) {
692
+ this.recordPreAnchorMetaSurfaceSample(preAnchorMetaSurfaceSample, nowMs);
693
+ }
694
+ if (startupBoundaryProgress.anchorObserved) {
695
+ this.startupAnchorObserved = true;
696
+ }
697
+ else {
698
+ this.preAnchorCommandStarts += 1;
699
+ }
700
+ }
701
+ updateLowSignalCandidate(nowMs) {
702
+ if (this.lowSignalTimeoutMs === null) {
703
+ this.lowSignalCandidateSinceMs = null;
704
+ return;
705
+ }
706
+ const summary = this.buildOutputSummary();
707
+ const driftShaped = this.reviewProgressObserved &&
708
+ this.thinkingBlocks >= LOW_SIGNAL_MIN_THINKING_BLOCKS &&
709
+ this.commandStarts.length >= LOW_SIGNAL_MIN_COMMAND_STARTS &&
710
+ summary.distinctInspectionTargets > 0 &&
711
+ summary.distinctInspectionTargets <= LOW_SIGNAL_MAX_DISTINCT_TARGETS &&
712
+ summary.maxInspectionTargetHits >= LOW_SIGNAL_MIN_REPEAT_TARGET_HITS &&
713
+ summary.distinctInspectionSignatures > 0 &&
714
+ summary.distinctInspectionSignatures <= LOW_SIGNAL_MAX_DISTINCT_TARGETS &&
715
+ summary.maxInspectionSignatureHits >= LOW_SIGNAL_MIN_REPEAT_SIGNATURE_HITS;
716
+ if (!driftShaped) {
717
+ this.lowSignalCandidateSinceMs = null;
718
+ return;
719
+ }
720
+ if (this.lowSignalCandidateSinceMs === null) {
721
+ this.lowSignalCandidateSinceMs = nowMs;
722
+ }
723
+ }
724
+ updateRelevantReinspectionDwellCandidate(nowMs) {
725
+ if (!this.enforceRelevantReinspectionDwellBoundary ||
726
+ this.lowSignalTimeoutMs === null ||
727
+ this.relevantReinspectionDwellViolation) {
728
+ this.relevantReinspectionDwellCandidateSinceMs = null;
729
+ return;
730
+ }
731
+ const summary = this.buildOutputSummary();
732
+ const relevantInspectionSummary = this.buildInspectionTargetSummary(this.getRelevantReinspectionWindowSize());
733
+ const anchorSatisfied = !this.enforceStartupAnchorBoundary || this.startupAnchorObserved;
734
+ const dwellShaped = anchorSatisfied &&
735
+ this.reviewProgressObserved &&
736
+ this.commandStarts.length >= RELEVANT_REINSPECTION_MIN_COMMAND_STARTS &&
737
+ relevantInspectionSummary.distinctTargets > 0 &&
738
+ relevantInspectionSummary.distinctTargets <= this.getRelevantReinspectionMaxDistinctTargets() &&
739
+ relevantInspectionSummary.maxHits >= RELEVANT_REINSPECTION_MIN_REPEAT_TARGET_HITS &&
740
+ relevantInspectionSummary.metaSurfaceSignals === 0 &&
741
+ summary.concreteOutputSignals === 0;
742
+ if (!dwellShaped) {
743
+ this.relevantReinspectionDwellCandidateSinceMs = null;
744
+ return;
745
+ }
746
+ if (this.relevantReinspectionDwellCandidateSinceMs === null) {
747
+ this.relevantReinspectionDwellCandidateSinceMs = nowMs;
748
+ return;
749
+ }
750
+ if (nowMs - this.relevantReinspectionDwellCandidateSinceMs >= this.lowSignalTimeoutMs &&
751
+ this.relevantReinspectionDwellViolation === null) {
752
+ this.relevantReinspectionDwellViolation = {
753
+ sample: this.lastInspectionCommandLine,
754
+ detectedAtMs: nowMs,
755
+ commandStarts: this.commandStarts.length,
756
+ distinctTargets: relevantInspectionSummary.distinctTargets,
757
+ maxTargetHits: relevantInspectionSummary.maxHits
758
+ };
759
+ }
760
+ }
761
+ recordNarrativeInspectionSignals(line) {
762
+ const signature = normalizeNarrativeInspectionSignature(line);
763
+ if (!signature) {
764
+ this.recordOutputNarrativeMiss();
765
+ return;
766
+ }
767
+ this.recentOutputNarrativeSignatures.push(signature);
768
+ while (this.recentOutputNarrativeSignatures.length > VERDICT_STABILITY_RECENT_OUTPUT_WINDOW) {
769
+ this.recentOutputNarrativeSignatures.shift();
770
+ }
771
+ const targets = extractInspectionTargets(signature);
772
+ if (targets.length === 0) {
773
+ this.recentOutputInspectionTargetSamples.push(null);
774
+ while (this.recentOutputInspectionTargetSamples.length > VERDICT_STABILITY_RECENT_OUTPUT_WINDOW) {
775
+ this.recentOutputInspectionTargetSamples.shift();
776
+ }
777
+ return;
778
+ }
779
+ this.recentOutputInspectionTargetSamples.push(targets);
780
+ while (this.recentOutputInspectionTargetSamples.length > VERDICT_STABILITY_RECENT_OUTPUT_WINDOW) {
781
+ this.recentOutputInspectionTargetSamples.shift();
782
+ }
783
+ }
784
+ recordOutputNarrativeMiss() {
785
+ this.recentOutputInspectionTargetSamples.push(null);
786
+ while (this.recentOutputInspectionTargetSamples.length > VERDICT_STABILITY_RECENT_OUTPUT_WINDOW) {
787
+ this.recentOutputInspectionTargetSamples.shift();
788
+ }
789
+ this.recentOutputNarrativeSignatures.push(null);
790
+ while (this.recentOutputNarrativeSignatures.length > VERDICT_STABILITY_RECENT_OUTPUT_WINDOW) {
791
+ this.recentOutputNarrativeSignatures.shift();
792
+ }
793
+ }
794
+ recordConcreteOutputSignals(line) {
795
+ if (this.touchedPaths.size === 0) {
796
+ this.recentConcreteOutputTargetSamples.push(null);
797
+ while (this.recentConcreteOutputTargetSamples.length > VERDICT_STABILITY_RECENT_OUTPUT_WINDOW) {
798
+ this.recentConcreteOutputTargetSamples.shift();
799
+ }
800
+ return;
801
+ }
802
+ const targets = extractConcreteOutputTargets(line, this.touchedPaths, this.repoRoot);
803
+ this.recentConcreteOutputTargetSamples.push(targets.length > 0 ? targets : null);
804
+ while (this.recentConcreteOutputTargetSamples.length > VERDICT_STABILITY_RECENT_OUTPUT_WINDOW) {
805
+ this.recentConcreteOutputTargetSamples.shift();
806
+ }
807
+ }
808
+ recordMetaSurfaceCommandSample(sample, commandLine, nowMs) {
809
+ const nextSample = sample &&
810
+ COMMAND_LEVEL_ALLOWED_META_SURFACE_KIND_SET.has(sample) &&
811
+ this.allowedMetaSurfaceKinds.has(sample)
812
+ ? null
813
+ : sample;
814
+ this.recentMetaSurfaceSamples.push(nextSample);
815
+ while (this.recentMetaSurfaceSamples.length > META_SURFACE_RECENT_SIGNAL_WINDOW) {
816
+ this.recentMetaSurfaceSamples.shift();
817
+ }
818
+ if (this.enforceActiveCloseoutBundleRereadBoundary &&
819
+ nextSample === REVIEW_ACTIVE_CLOSEOUT_BUNDLE_KIND &&
820
+ this.commandStarts.length > 1) {
821
+ this.activeCloseoutBundleRereadCount += 1;
822
+ if (!this.activeCloseoutBundleRereadViolation && this.activeCloseoutBundleRereadCount > 1) {
823
+ this.activeCloseoutBundleRereadViolation = {
824
+ sample: commandLine,
825
+ detectedAtMs: nowMs,
826
+ rereadCount: this.activeCloseoutBundleRereadCount
827
+ };
828
+ }
829
+ }
830
+ }
831
+ recordMetaSurfaceToolSample(sample, nowMs) {
832
+ this.recordMetaSurfaceSample(sample, nowMs);
833
+ }
834
+ recordCommandIntentViolation(violation) {
835
+ if (this.commandIntentViolationSamples.some((sample) => sample.kind === violation.kind && sample.sample === violation.sample)) {
836
+ return;
837
+ }
838
+ if (!this.commandIntentViolation) {
839
+ this.commandIntentViolation = violation;
840
+ }
841
+ this.commandIntentViolationSamples.push(violation);
842
+ while (this.commandIntentViolationSamples.length > REVIEW_COMMAND_INTENT_VIOLATION_SAMPLE_LIMIT) {
843
+ this.commandIntentViolationSamples.shift();
844
+ }
845
+ }
846
+ recordShellProbe(sample, nowMs) {
847
+ this.shellProbeCount += 1;
848
+ this.shellProbeSamples.push(sample);
849
+ while (this.shellProbeSamples.length > REVIEW_COMMAND_INTENT_VIOLATION_SAMPLE_LIMIT) {
850
+ this.shellProbeSamples.shift();
851
+ }
852
+ if (!this.shellProbeViolation && this.shellProbeCount > 1) {
853
+ this.shellProbeViolation = {
854
+ sample,
855
+ detectedAtMs: nowMs
856
+ };
857
+ }
858
+ }
859
+ recordMetaSurfaceSample(sample, _nowMs) {
860
+ const nextSample = sample && this.allowedMetaSurfaceKinds.has(sample) ? null : sample;
861
+ this.recentMetaSurfaceSamples.push(nextSample);
862
+ while (this.recentMetaSurfaceSamples.length > META_SURFACE_RECENT_SIGNAL_WINDOW) {
863
+ this.recentMetaSurfaceSamples.shift();
864
+ }
865
+ }
866
+ recordPreAnchorMetaSurfaceSample(sample, nowMs) {
867
+ if (STARTUP_ANCHOR_ALLOWED_META_SURFACE_KINDS.has(sample)) {
868
+ return;
869
+ }
870
+ this.preAnchorMetaSurfaceSamples.push(sample);
871
+ if (this.startupAnchorViolationAtMs === null &&
872
+ this.preAnchorMetaSurfaceSamples.length > STARTUP_ANCHOR_META_SURFACE_SIGNAL_BUDGET) {
873
+ this.startupAnchorViolationAtMs = nowMs;
874
+ }
875
+ }
876
+ updateMetaSurfaceCandidate(nowMs) {
877
+ if (this.metaSurfaceTimeoutMs === null) {
878
+ this.metaSurfaceCandidateSinceMs = null;
879
+ return;
880
+ }
881
+ const summary = this.buildOutputSummary();
882
+ const expansionShaped = this.reviewProgressObserved &&
883
+ this.commandStarts.length >= META_SURFACE_MIN_COMMAND_STARTS &&
884
+ summary.metaSurfaceSignals >= META_SURFACE_MIN_SIGNALS &&
885
+ (summary.distinctMetaSurfaces >= META_SURFACE_MIN_DISTINCT_SURFACES ||
886
+ summary.maxMetaSurfaceHits >= META_SURFACE_MIN_REPEAT_HITS);
887
+ if (!expansionShaped) {
888
+ this.metaSurfaceCandidateSinceMs = null;
889
+ return;
890
+ }
891
+ if (this.metaSurfaceCandidateSinceMs === null) {
892
+ this.metaSurfaceCandidateSinceMs = nowMs;
893
+ }
894
+ }
895
+ updateVerdictStabilityCandidate(nowMs) {
896
+ if (this.verdictStabilityTimeoutMs === null) {
897
+ this.verdictStabilityCandidateSinceMs = null;
898
+ return;
899
+ }
900
+ const summary = this.buildOutputSummary();
901
+ const fileTargetDriftShaped = this.reviewProgressObserved &&
902
+ this.thinkingBlocks >= VERDICT_STABILITY_MIN_THINKING_BLOCKS &&
903
+ this.commandStarts.length >= VERDICT_STABILITY_MIN_COMMAND_STARTS &&
904
+ summary.outputInspectionSignals >= VERDICT_STABILITY_MIN_OUTPUT_TARGET_SIGNALS &&
905
+ summary.distinctOutputInspectionTargets > 0 &&
906
+ summary.distinctOutputInspectionTargets <= VERDICT_STABILITY_MAX_DISTINCT_OUTPUT_TARGETS &&
907
+ summary.maxOutputInspectionTargetHits >= VERDICT_STABILITY_MIN_REPEAT_OUTPUT_TARGET_HITS &&
908
+ summary.distinctOutputNarrativeSignatures > 0 &&
909
+ summary.distinctOutputNarrativeSignatures <=
910
+ VERDICT_STABILITY_MAX_DISTINCT_OUTPUT_SIGNATURES &&
911
+ summary.maxOutputNarrativeSignatureHits >=
912
+ VERDICT_STABILITY_MIN_REPEAT_OUTPUT_SIGNATURE_HITS;
913
+ const genericNarrativeDriftShaped = this.reviewProgressObserved &&
914
+ this.thinkingBlocks >= VERDICT_STABILITY_MIN_THINKING_BLOCKS &&
915
+ this.commandStarts.length >= VERDICT_STABILITY_MIN_COMMAND_STARTS &&
916
+ summary.outputNarrativeSignals >= VERDICT_STABILITY_MIN_OUTPUT_NARRATIVE_SIGNALS &&
917
+ summary.distinctOutputInspectionTargets === 0 &&
918
+ summary.concreteOutputSignals === 0 &&
919
+ summary.distinctOutputNarrativeSignatures > 0 &&
920
+ summary.distinctOutputNarrativeSignatures <=
921
+ VERDICT_STABILITY_MAX_DISTINCT_OUTPUT_SIGNATURES &&
922
+ summary.maxOutputNarrativeSignatureHits >=
923
+ VERDICT_STABILITY_MIN_REPEAT_OUTPUT_SIGNATURE_HITS;
924
+ const driftShaped = fileTargetDriftShaped || genericNarrativeDriftShaped;
925
+ if (!driftShaped) {
926
+ this.verdictStabilityCandidateSinceMs = null;
927
+ return;
928
+ }
929
+ if (this.verdictStabilityCandidateSinceMs === null) {
930
+ this.verdictStabilityCandidateSinceMs = nowMs;
931
+ }
932
+ }
933
+ buildInspectionTargetSummary(windowSize = LOW_SIGNAL_RECENT_COMMAND_WINDOW) {
934
+ const recentTargetHits = new Map();
935
+ const relevantTargetSamples = this.recentInspectionTargetSamples.slice(-windowSize);
936
+ for (const targets of relevantTargetSamples) {
937
+ for (const target of targets) {
938
+ recentTargetHits.set(target, (recentTargetHits.get(target) ?? 0) + 1);
939
+ }
940
+ }
941
+ let maxHits = 0;
942
+ for (const hits of recentTargetHits.values()) {
943
+ if (hits > maxHits) {
944
+ maxHits = hits;
945
+ }
946
+ }
947
+ const recentSignatureHits = new Map();
948
+ const relevantSignatures = this.recentInspectionSignatures.slice(-windowSize);
949
+ for (const signature of relevantSignatures) {
950
+ recentSignatureHits.set(signature, (recentSignatureHits.get(signature) ?? 0) + 1);
951
+ }
952
+ let maxSignatureHits = 0;
953
+ for (const hits of recentSignatureHits.values()) {
954
+ if (hits > maxSignatureHits) {
955
+ maxSignatureHits = hits;
956
+ }
957
+ }
958
+ const recentMetaSurfaceHits = new Map();
959
+ for (const sample of this.recentMetaSurfaceSamples) {
960
+ if (!sample) {
961
+ continue;
962
+ }
963
+ recentMetaSurfaceHits.set(sample, (recentMetaSurfaceHits.get(sample) ?? 0) + 1);
964
+ }
965
+ let maxMetaSurfaceHits = 0;
966
+ for (const hits of recentMetaSurfaceHits.values()) {
967
+ if (hits > maxMetaSurfaceHits) {
968
+ maxMetaSurfaceHits = hits;
969
+ }
970
+ }
971
+ return {
972
+ distinctTargets: recentTargetHits.size,
973
+ maxHits,
974
+ distinctSignatures: recentSignatureHits.size,
975
+ maxSignatureHits,
976
+ metaSurfaceSignals: [...recentMetaSurfaceHits.values()].reduce((sum, hits) => sum + hits, 0),
977
+ distinctMetaSurfaces: recentMetaSurfaceHits.size,
978
+ maxMetaSurfaceHits,
979
+ metaSurfaceKinds: [...recentMetaSurfaceHits.keys()].sort()
980
+ };
981
+ }
982
+ getRelevantReinspectionMaxDistinctTargets() {
983
+ return Math.max(RELEVANT_REINSPECTION_BASE_MAX_DISTINCT_TARGETS, this.touchedPaths.size);
984
+ }
985
+ getRelevantReinspectionWindowSize() {
986
+ return Math.max(LOW_SIGNAL_RECENT_COMMAND_WINDOW, this.getRelevantReinspectionMaxDistinctTargets() * RELEVANT_REINSPECTION_MIN_REPEAT_TARGET_HITS);
987
+ }
988
+ getRecordedInspectionSignalWindowSize() {
989
+ return this.getRelevantReinspectionWindowSize();
990
+ }
991
+ buildOutputNarrativeSummary() {
992
+ const outputTargetHits = new Map();
993
+ for (const targets of this.recentOutputInspectionTargetSamples) {
994
+ if (!targets) {
995
+ continue;
996
+ }
997
+ for (const target of targets) {
998
+ outputTargetHits.set(target, (outputTargetHits.get(target) ?? 0) + 1);
999
+ }
1000
+ }
1001
+ let maxOutputTargetHits = 0;
1002
+ for (const hits of outputTargetHits.values()) {
1003
+ if (hits > maxOutputTargetHits) {
1004
+ maxOutputTargetHits = hits;
1005
+ }
1006
+ }
1007
+ const outputNarrativeSignatureHits = new Map();
1008
+ for (const signature of this.recentOutputNarrativeSignatures) {
1009
+ if (!signature) {
1010
+ continue;
1011
+ }
1012
+ outputNarrativeSignatureHits.set(signature, (outputNarrativeSignatureHits.get(signature) ?? 0) + 1);
1013
+ }
1014
+ let maxNarrativeSignatureHits = 0;
1015
+ for (const hits of outputNarrativeSignatureHits.values()) {
1016
+ if (hits > maxNarrativeSignatureHits) {
1017
+ maxNarrativeSignatureHits = hits;
1018
+ }
1019
+ }
1020
+ let concreteOutputSignals = 0;
1021
+ for (const targets of this.recentConcreteOutputTargetSamples) {
1022
+ if (!targets) {
1023
+ continue;
1024
+ }
1025
+ concreteOutputSignals += targets.length;
1026
+ }
1027
+ return {
1028
+ outputInspectionSignals: [...outputTargetHits.values()].reduce((sum, hits) => sum + hits, 0),
1029
+ outputNarrativeSignals: [...outputNarrativeSignatureHits.values()].reduce((sum, hits) => sum + hits, 0),
1030
+ concreteOutputSignals,
1031
+ distinctOutputTargets: outputTargetHits.size,
1032
+ maxOutputTargetHits,
1033
+ distinctNarrativeSignatures: outputNarrativeSignatureHits.size,
1034
+ maxNarrativeSignatureHits
1035
+ };
1036
+ }
1037
+ buildPreAnchorMetaSurfaceSummary() {
1038
+ const preAnchorMetaSurfaceHits = new Map();
1039
+ for (const sample of this.preAnchorMetaSurfaceSamples) {
1040
+ preAnchorMetaSurfaceHits.set(sample, (preAnchorMetaSurfaceHits.get(sample) ?? 0) + 1);
1041
+ }
1042
+ return {
1043
+ signals: [...preAnchorMetaSurfaceHits.values()].reduce((sum, hits) => sum + hits, 0),
1044
+ distinctSurfaces: preAnchorMetaSurfaceHits.size,
1045
+ kinds: [...preAnchorMetaSurfaceHits.keys()].sort()
1046
+ };
1047
+ }
1048
+ }
1049
+ function normalizeTerminationBoundarySample(sample) {
1050
+ if (!sample) {
1051
+ return null;
1052
+ }
1053
+ const trimmed = sample.trim();
1054
+ return trimmed.length > 0 ? trimmed : null;
1055
+ }
1056
+ export function formatDurationMs(durationMs) {
1057
+ const roundedMs = Math.max(0, Math.round(durationMs));
1058
+ if (roundedMs < 1000) {
1059
+ return `${roundedMs}ms`;
1060
+ }
1061
+ const totalSeconds = Math.max(0, Math.floor(durationMs / 1000));
1062
+ if (totalSeconds < 60) {
1063
+ return `${totalSeconds}s`;
1064
+ }
1065
+ const minutes = Math.floor(totalSeconds / 60);
1066
+ const seconds = totalSeconds % 60;
1067
+ if (minutes < 60) {
1068
+ return `${minutes}m ${seconds}s`;
1069
+ }
1070
+ const hours = Math.floor(minutes / 60);
1071
+ const remainingMinutes = minutes % 60;
1072
+ return `${hours}h ${remainingMinutes}m ${seconds}s`;
1073
+ }
1074
+ function normalizeReviewCommandLine(line) {
1075
+ const trimmed = line.trim();
1076
+ if (!trimmed) {
1077
+ return '';
1078
+ }
1079
+ const succeededIndex = trimmed.indexOf(' succeeded in ');
1080
+ if (succeededIndex >= 0) {
1081
+ return trimmed.slice(0, succeededIndex).trimEnd();
1082
+ }
1083
+ const exitedIndex = trimmed.indexOf(' exited ');
1084
+ if (exitedIndex >= 0) {
1085
+ return trimmed.slice(0, exitedIndex).trimEnd();
1086
+ }
1087
+ return trimmed;
1088
+ }
1089
+ function normalizeNarrativeInspectionSignature(line) {
1090
+ const normalized = line.trim().replace(/\s+/gu, ' ');
1091
+ if (normalized.length < REVIEW_NARRATIVE_INSPECTION_MIN_LINE_LENGTH) {
1092
+ return null;
1093
+ }
1094
+ if (normalized === 'thinking' ||
1095
+ normalized === 'exec' ||
1096
+ REVIEW_PROGRESS_SIGNAL_LINE_RE.test(normalized) ||
1097
+ isLikelyReviewCommandLine(normalized) ||
1098
+ /^mcp:/iu.test(normalized) ||
1099
+ /^(?:diff --git|index |--- |\+\+\+ |@@|```)/u.test(normalized) ||
1100
+ /\bsucceeded in\b|\bexited\b/iu.test(normalized)) {
1101
+ return null;
1102
+ }
1103
+ if (!REVIEW_SPECULATIVE_NARRATIVE_LINE_RE.test(normalized)) {
1104
+ return null;
1105
+ }
1106
+ return normalized;
1107
+ }
1108
+ function extractConcreteOutputTargets(line, touchedPaths, repoRoot) {
1109
+ const normalized = line.trim().replace(/\s+/gu, ' ');
1110
+ if (normalized.length === 0 ||
1111
+ normalized === 'thinking' ||
1112
+ normalized === 'exec' ||
1113
+ REVIEW_PROGRESS_SIGNAL_LINE_RE.test(normalized) ||
1114
+ isLikelyReviewCommandLine(normalized) ||
1115
+ /^mcp:/iu.test(normalized) ||
1116
+ /^(?:diff --git|index |--- |\+\+\+ |@@|```)/u.test(normalized) ||
1117
+ /^[`"']/u.test(normalized) ||
1118
+ /\bsucceeded in\b|\bexited\b/iu.test(normalized) ||
1119
+ normalizeNarrativeInspectionSignature(normalized)) {
1120
+ return [];
1121
+ }
1122
+ const concreteTargets = new Set();
1123
+ for (const touchedPath of touchedPaths) {
1124
+ const normalizedTouchedPath = normalizeScopePath(touchedPath);
1125
+ if (normalizedTouchedPath.length === 0) {
1126
+ continue;
1127
+ }
1128
+ const escapedTouchedPath = escapeRegex(normalizedTouchedPath);
1129
+ const lineMarkerRe = new RegExp(`${escapedTouchedPath}(?::\\d+(?::\\d+)?)\\b|${escapedTouchedPath}#L\\d+(?:C\\d+)?\\b`, 'iu');
1130
+ if (lineMarkerRe.test(normalized) && isTouchedScopePath(normalizedTouchedPath, touchedPaths, repoRoot)) {
1131
+ concreteTargets.add(normalizedTouchedPath);
1132
+ }
1133
+ }
1134
+ return [...concreteTargets];
1135
+ }
1136
+ function escapeRegex(value) {
1137
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
1138
+ }
1139
+ function extractInspectionCommandSignature(commandLine, targets) {
1140
+ if (targets.length === 0) {
1141
+ return null;
1142
+ }
1143
+ return normalizeReviewCommandLine(commandLine);
1144
+ }