@zq-silk/yui 0.15.7 → 0.15.9

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 (308) hide show
  1. package/ARCHITECTURE.md +194 -399
  2. package/ARCHITECTURE.zh-CN.md +151 -0
  3. package/README.md +306 -1131
  4. package/dist/agent/adapterCatalog.js +15 -2
  5. package/dist/agent/agent.js +23 -3
  6. package/dist/agent/argumentPolicy.js +7 -1
  7. package/dist/agent/connectionPlan.js +62 -0
  8. package/dist/agent/executionComponents.js +158 -0
  9. package/dist/agent/launchEnvironment.js +31 -3
  10. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  11. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  12. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  13. package/dist/artifacts/artifactCapability.js +74 -0
  14. package/dist/artifacts/artifactCommitLock.js +249 -0
  15. package/dist/artifacts/artifactPaths.js +151 -0
  16. package/dist/artifacts/gitArtifactRef.js +146 -0
  17. package/dist/artifacts/managedGit.js +332 -0
  18. package/dist/artifacts/taskArtifactRepository.js +277 -0
  19. package/dist/brief/taskBrief.js +12 -0
  20. package/dist/cli/agentConfigurationPicker.js +13 -0
  21. package/dist/cli/commandCatalog.js +165 -74
  22. package/dist/cli/interactionCandidates.js +5 -5
  23. package/dist/cli/interactionPolicy.js +38 -8
  24. package/dist/cli/invocationRouter.js +1 -1
  25. package/dist/cli/managedDiagnostics.js +28 -0
  26. package/dist/cli/operatorWizard.js +1 -7
  27. package/dist/cli/roleOptionOrder.js +27 -0
  28. package/dist/cli/roleWizard.js +50 -14
  29. package/dist/cli/updateOrchestrator.js +1 -1
  30. package/dist/cli/updatePorts.js +3 -4
  31. package/dist/cli.js +245 -95
  32. package/dist/commands/agentCommands.js +72 -14
  33. package/dist/commands/capabilityCommands.js +9 -6
  34. package/dist/commands/configCommands.js +20 -20
  35. package/dist/commands/deliveryGuardPreflight.js +2 -2
  36. package/dist/commands/executionAuditCommands.js +24 -24
  37. package/dist/commands/globalRoleCommands.js +1 -1
  38. package/dist/commands/grantCommands.js +4 -4
  39. package/dist/commands/operatorCommands.js +34 -9
  40. package/dist/commands/projectCommands.js +4 -4
  41. package/dist/commands/resourcesCommands.js +2 -2
  42. package/dist/commands/roleConfiguration.js +25 -5
  43. package/dist/commands/roleRuntimeGuard.js +4 -5
  44. package/dist/commands/sessionCommands.js +3 -7
  45. package/dist/commands/taskActivationCommands.js +281 -0
  46. package/dist/commands/taskActor.js +28 -49
  47. package/dist/commands/taskCommands.js +1461 -720
  48. package/dist/commands/taskContextCommand.js +39 -583
  49. package/dist/commands/taskExecutionCommands.js +32 -32
  50. package/dist/commands/taskInputCommands.js +40 -104
  51. package/dist/commands/taskIntegrationCommands.js +3 -2
  52. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  53. package/dist/commands/taskNextActionCommand.js +8 -8
  54. package/dist/commands/taskOverviewCommand.js +33 -45
  55. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  56. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  57. package/dist/commands/telemetryCommands.js +36 -38
  58. package/dist/config/configCatalog.js +4 -4
  59. package/dist/config/yuiConfig.js +8 -8
  60. package/dist/context/contextSnapshot.js +10 -10
  61. package/dist/context/dispatchContext.js +11 -11
  62. package/dist/context/roleSessionContext.js +6 -3
  63. package/dist/context/{turnContextPack.js → runContextPack.js} +158 -81
  64. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  65. package/dist/context/sessionBootstrapManifest.js +21 -2
  66. package/dist/context/sourceRunContext.js +30 -0
  67. package/dist/context/taskContext.js +481 -0
  68. package/dist/context/wakeNotification.js +27 -27
  69. package/dist/controller/agentRuntimeObserver.js +21 -24
  70. package/dist/controller/capabilityBridge.js +17 -6
  71. package/dist/controller/clientRuntime.js +65 -92
  72. package/dist/controller/controller.js +120 -188
  73. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  74. package/dist/controller/jobControl.js +54 -85
  75. package/dist/controller/resourceInventory.js +8 -27
  76. package/dist/controller/resourceInventoryLinux.js +12 -13
  77. package/dist/controller/runtime.js +529 -479
  78. package/dist/controller/runtimeEventInbox.js +55 -25
  79. package/dist/controller/runtimeEventProcessor.js +22 -31
  80. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  81. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  82. package/dist/controller/runtimeObservationHook.js +14 -18
  83. package/dist/controller/sessionNotify.js +16 -24
  84. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  85. package/dist/controller/structuredProviderObservation.js +138 -99
  86. package/dist/coordination/workMailbox.js +3 -3
  87. package/dist/coordination/workMailboxQueue.js +36 -33
  88. package/dist/core/boundedRpc.js +8 -1
  89. package/dist/core/controllerClient.js +20 -1
  90. package/dist/core/controllerServer.js +4 -4
  91. package/dist/doctor/doctor.js +13 -2
  92. package/dist/domain/agentResultTransport.js +9 -9
  93. package/dist/execution/codexThreadNaming.js +2 -8
  94. package/dist/execution/executionHealth.js +51 -63
  95. package/dist/execution/reviewMainRun.js +137 -0
  96. package/dist/execution/workItemExecution.js +28 -29
  97. package/dist/execution/workItemExecutionProjection.js +99 -107
  98. package/dist/execution/workItemMainRun.js +141 -0
  99. package/dist/executor/agentAdapter.js +227 -20
  100. package/dist/executor/agentConfigurationCatalog.js +126 -4
  101. package/dist/executor/agentConfigurationProbe.js +162 -4
  102. package/dist/executor/agentExecutor.js +79 -78
  103. package/dist/executor/effectiveLaunch.js +105 -18
  104. package/dist/executor/executorRegistry.js +29 -44
  105. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  106. package/dist/executor/workspacePreflightClassification.js +16 -16
  107. package/dist/grant/capabilityGrant.js +6 -3
  108. package/dist/input/inputRequest.js +12 -10
  109. package/dist/integration/gitIntegrationService.js +4 -11
  110. package/dist/integration/integrationQueueService.js +4 -4
  111. package/dist/interaction/operatorPresentation.js +1 -1
  112. package/dist/kernel/builtinCapabilities.js +255 -12
  113. package/dist/kernel/capabilityRegistry.js +64 -18
  114. package/dist/kernel/instanceHost.js +12 -1
  115. package/dist/kernel/kernelPorts.js +2 -2
  116. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  117. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  118. package/dist/message/message.js +118 -6
  119. package/dist/message/messageContinuation.js +204 -0
  120. package/dist/observability/executionAudit.js +70 -72
  121. package/dist/observability/faultClassification.js +2 -2
  122. package/dist/observability/orchestrationMetrics.js +8 -8
  123. package/dist/operator/operatorSessionHistory.js +1 -7
  124. package/dist/output/agentConfigurationPresentation.js +8 -3
  125. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  126. package/dist/output/rolePresentation.js +54 -3
  127. package/dist/plugins/pluginChild.js +104 -0
  128. package/dist/plugins/pluginIntent.js +26 -0
  129. package/dist/plugins/pluginInterpreter.js +43 -0
  130. package/dist/plugins/pluginPackage.js +101 -0
  131. package/dist/plugins/pluginProcess.js +112 -0
  132. package/dist/plugins/pluginService.js +388 -0
  133. package/dist/profile/agentProfile.js +1 -1
  134. package/dist/repository/gitWorkspace.js +26 -4
  135. package/dist/repository/project.js +19 -4
  136. package/dist/repository/taskBaseFreshness.js +13 -13
  137. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  138. package/dist/repository/taskWorkspacePreparer.js +344 -83
  139. package/dist/resources/autoResourceGc.js +3 -3
  140. package/dist/resources/liveReferences.js +3 -3
  141. package/dist/resources/projectResource.js +75 -0
  142. package/dist/resources/projectResourceService.js +343 -0
  143. package/dist/resources/resourceDiscovery.js +6 -6
  144. package/dist/resources/resourceGc.js +1 -1
  145. package/dist/resources/resourceRegistrar.js +1 -1
  146. package/dist/resources/resourceTypes.js +1 -1
  147. package/dist/review/deltaRecheck.js +3 -3
  148. package/dist/review/reviewAcceptance.js +16 -16
  149. package/dist/review/reviewDecision.js +7 -7
  150. package/dist/review/reviewRound.js +21 -20
  151. package/dist/review/reviewerAvailability.js +2 -2
  152. package/dist/role/role.js +51 -7
  153. package/dist/role/taskRoleUpdate.js +30 -0
  154. package/dist/runtime/acpProtocol.js +425 -0
  155. package/dist/runtime/acpSession.js +731 -0
  156. package/dist/runtime/acpSessionConfiguration.js +260 -0
  157. package/dist/runtime/agentDriver.js +30 -11
  158. package/dist/runtime/agentEndpoint.js +278 -0
  159. package/dist/runtime/agentEndpointIdentity.js +86 -0
  160. package/dist/runtime/agentEndpointOwnership.js +239 -0
  161. package/dist/runtime/agentError.js +2 -10
  162. package/dist/runtime/agentHost.js +565 -314
  163. package/dist/runtime/agentRunConfiguration.js +258 -0
  164. package/dist/runtime/builtinAgentDrivers.js +134 -18
  165. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  166. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  167. package/dist/runtime/claude-process-owner +0 -0
  168. package/dist/runtime/codexAppServerRuntime.js +38 -30
  169. package/dist/runtime/codexInteractiveHost.js +41 -6
  170. package/dist/runtime/continuationManager.js +2 -6
  171. package/dist/runtime/executionEnvironment.js +30 -0
  172. package/dist/runtime/firstProgressAdvisory.js +11 -11
  173. package/dist/runtime/index.js +4 -3
  174. package/dist/runtime/jsonLineChannel.js +109 -0
  175. package/dist/runtime/launchBroker.js +91 -16
  176. package/dist/runtime/launchDiagnostics.js +2 -2
  177. package/dist/runtime/lifecycleReservation.js +10 -18
  178. package/dist/runtime/managedCaller.js +61 -17
  179. package/dist/runtime/nativeSessionControl.js +102 -0
  180. package/dist/runtime/ports.js +6 -21
  181. package/dist/runtime/processExitObservation.js +8 -7
  182. package/dist/runtime/promptEnvelope.js +17 -6
  183. package/dist/runtime/providerContinuation.js +3 -9
  184. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  185. package/dist/runtime/providerControl.js +2 -7
  186. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  187. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  188. package/dist/runtime/runtimeBinding.js +0 -1
  189. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  190. package/dist/runtime/runtimeDeadlines.js +9 -0
  191. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  192. package/dist/runtime/runtimeObservation.js +29 -65
  193. package/dist/runtime/runtimeProjection.js +43 -51
  194. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  195. package/dist/runtime/sessionLaunchRequest.js +3 -7
  196. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  197. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  198. package/dist/runtime/sessionReconciliation.js +4 -8
  199. package/dist/runtime/sessionTerminationGuard.js +70 -259
  200. package/dist/runtime/sessionTokenMetrics.js +5 -16
  201. package/dist/runtime/structuredProviderHost.js +237 -117
  202. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  203. package/dist/runtime/tmuxAdapters.js +39 -86
  204. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  205. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  206. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  207. package/dist/scheduler/ports.js +80 -9
  208. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  209. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  210. package/dist/scheduler/taskExecutionProjection.js +120 -124
  211. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  212. package/dist/scheduler/taskWake.js +11 -4
  213. package/dist/scheduler/wakeReason.js +9 -1
  214. package/dist/setup/setupCommand.js +3 -7
  215. package/dist/storage/migrations/agentRunContract.js +159 -0
  216. package/dist/storage/migrations/artifactsToGit.js +338 -0
  217. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  218. package/dist/storage/migrations/submitIntent.js +126 -0
  219. package/dist/storage/sqliteSchema.js +467 -7
  220. package/dist/storage/sqliteStore.js +355 -220
  221. package/dist/storage/storageVersions.js +1 -1
  222. package/dist/storage/storeRpc.js +10 -5
  223. package/dist/storage/taskStore.js +13 -11
  224. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  225. package/dist/surface/surfaceContributions.js +102 -0
  226. package/dist/task/completionReadiness.js +32 -6
  227. package/dist/task/deliveryGuard.js +16 -16
  228. package/dist/task/draftPlan.js +72 -12
  229. package/dist/task/nextAction.js +144 -128
  230. package/dist/task/remoteDelivery.js +6 -6
  231. package/dist/task/task.js +184 -18
  232. package/dist/task/taskActivation.js +327 -0
  233. package/dist/task/taskActivationService.js +408 -0
  234. package/dist/task/taskRecordReference.js +5 -4
  235. package/dist/task/taskRecordRetirement.js +1 -1
  236. package/dist/task/taskSubmission.js +236 -0
  237. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  238. package/dist/telemetry/telemetryConfig.js +14 -14
  239. package/dist/telemetry/telemetryWiring.js +2 -2
  240. package/dist/web/assets/assetManifest.js +2 -0
  241. package/dist/web/assets/client/app.js +121 -20
  242. package/dist/web/assets/client/components.js +87 -54
  243. package/dist/web/assets/client/i18n.js +83 -41
  244. package/dist/web/assets/client/markdown.js +1 -1
  245. package/dist/web/assets/client/taskSurface.js +442 -0
  246. package/dist/web/assets/client/view.js +49 -44
  247. package/dist/web/assets/shell.js +1 -1
  248. package/dist/web/assets/styles/cards.js +22 -4
  249. package/dist/web/controllerWeb.js +60 -0
  250. package/dist/web/webMutation.js +28 -0
  251. package/dist/web/webServer.js +133 -8
  252. package/dist/web/webSnapshot.js +81 -74
  253. package/dist/web/webTaskSurface.js +64 -0
  254. package/dist/workItem/dependencyGate.js +1 -1
  255. package/dist/workItem/workItem.js +84 -48
  256. package/dist/workspace/workItemChangeSetManager.js +16 -9
  257. package/docs/agent-result-consumption.md +96 -0
  258. package/docs/agent-result-consumption.zh-CN.md +81 -0
  259. package/docs/agent-runtime-drivers.md +93 -0
  260. package/docs/agent-runtime-drivers.zh-CN.md +77 -0
  261. package/docs/architecture/README.md +50 -0
  262. package/docs/architecture/README.zh-CN.md +43 -0
  263. package/docs/architecture/capabilities-and-resources.md +118 -0
  264. package/docs/architecture/capabilities-and-resources.zh-CN.md +83 -0
  265. package/docs/managed-turn-and-session-runtime.md +224 -0
  266. package/docs/managed-turn-and-session-runtime.zh-CN.md +180 -0
  267. package/docs/observability/README.md +83 -0
  268. package/docs/observability/README.zh-CN.md +71 -0
  269. package/docs/plugin-sdk.md +393 -0
  270. package/docs/plugin-sdk.zh-CN.md +293 -0
  271. package/docs/provider-runtime.md +165 -0
  272. package/docs/provider-runtime.zh-CN.md +132 -0
  273. package/docs/release-workflow.md +305 -0
  274. package/docs/release-workflow.zh-CN.md +237 -0
  275. package/docs/roles-and-configuration.md +115 -0
  276. package/docs/roles-and-configuration.zh-CN.md +96 -0
  277. package/docs/sqlite-control-plane-design.md +78 -0
  278. package/docs/sqlite-control-plane-design.zh-CN.md +62 -0
  279. package/docs/task-dag-semantics.md +80 -0
  280. package/docs/task-dag-semantics.zh-CN.md +59 -0
  281. package/docs/task-delivery.md +105 -0
  282. package/docs/task-delivery.zh-CN.md +82 -0
  283. package/docs/task-local-identity.md +8 -6
  284. package/docs/task-local-identity.zh-CN.md +58 -0
  285. package/docs/testing/verification-levels.md +88 -0
  286. package/docs/testing/verification-levels.zh-CN.md +69 -0
  287. package/i18n/README.zh-CN.md +270 -722
  288. package/package.json +3 -2
  289. package/skills/yui-leader/SKILL.md +88 -304
  290. package/skills/yui-leader/references/execution.md +303 -0
  291. package/skills/yui-leader/references/integration.md +39 -0
  292. package/skills/yui-leader/references/planning.md +109 -0
  293. package/skills/yui-leader/references/replicated-execution.md +42 -0
  294. package/skills/yui-leader/references/task-plugins.md +37 -0
  295. package/skills/yui-operator/SKILL.md +46 -62
  296. package/skills/yui-reviewer/SKILL.md +35 -36
  297. package/skills/yui-runtime/SKILL.md +88 -24
  298. package/skills/yui-runtime/references/publication.md +22 -0
  299. package/skills/yui-runtime/references/recovery.md +64 -0
  300. package/skills/yui-worker/SKILL.md +37 -39
  301. package/dist/cli/roleOptionCatalog.js +0 -68
  302. package/dist/context/sourceTurnContext.js +0 -30
  303. package/dist/execution/reviewMainTurn.js +0 -161
  304. package/dist/execution/workItemMainTurn.js +0 -164
  305. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  306. package/dist/runtime/preallocatedNativeSession.js +0 -13
  307. package/dist/runtime/runtimeStopReceipt.js +0 -42
  308. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -2,16 +2,15 @@ import { isDeepStrictEqual } from "node:util";
2
2
  import { normalizedUniqueIdentities, normalizedUniqueText, requireIdentity, requirePositiveInteger, requireText, requireTimestamp } from "../domain/validation.js";
3
3
  import { validateContextSnapshotRef } from "../context/contextSnapshot.js";
4
4
  import { validateEffectiveLaunchSnapshot } from "../executor/effectiveLaunch.js";
5
- import { MAX_SYNTHESIS_SOURCE_TURNS } from "../context/sourceTurnContext.js";
5
+ import { MAX_SYNTHESIS_SOURCE_RUNS } from "../context/sourceRunContext.js";
6
6
  export const WORK_ITEM_EXECUTION_GROUP_SCHEMA_VERSION = 2;
7
7
  export const WORK_ITEM_EXECUTION_LANE_SCHEMA_VERSION = 2;
8
8
  export const WORK_ITEM_EXECUTION_ASSIGNMENT_SCHEMA_VERSION = 1;
9
- export const MINIMUM_WORK_ITEM_SYNTHESIS_RESULTS = 2;
9
+ export const MINIMUM_EXECUTION_GROUP_LANES = 2;
10
10
  export const EXECUTION_GROUP_SCHEMA_VERSION = WORK_ITEM_EXECUTION_GROUP_SCHEMA_VERSION;
11
11
  export const EXECUTION_LANE_SCHEMA_VERSION = WORK_ITEM_EXECUTION_LANE_SCHEMA_VERSION;
12
12
  export const EXECUTION_ASSIGNMENT_SCHEMA_VERSION = WORK_ITEM_EXECUTION_ASSIGNMENT_SCHEMA_VERSION;
13
- export const MINIMUM_SYNTHESIS_RESULTS = MINIMUM_WORK_ITEM_SYNTHESIS_RESULTS;
14
- export const MAXIMUM_SYNTHESIS_RESULTS = MAX_SYNTHESIS_SOURCE_TURNS;
13
+ export const MAXIMUM_SYNTHESIS_RESULTS = MAX_SYNTHESIS_SOURCE_RUNS;
15
14
  export function createWorkItemExecutionAssignment(input) {
16
15
  return validateWorkItemExecutionAssignment({
17
16
  schemaVersion: WORK_ITEM_EXECUTION_ASSIGNMENT_SCHEMA_VERSION,
@@ -25,7 +24,7 @@ export function createReviewExecutionAssignment(input) {
25
24
  });
26
25
  }
27
26
  export function createExecutionGroup(id, taskId, assignment, laneInputs, now) {
28
- if (laneInputs.length < MINIMUM_SYNTHESIS_RESULTS) {
27
+ if (laneInputs.length < MINIMUM_EXECUTION_GROUP_LANES) {
29
28
  throw new Error("A replicated ExecutionGroup requires at least two Lanes.");
30
29
  }
31
30
  if (laneInputs.length > MAXIMUM_SYNTHESIS_RESULTS) {
@@ -51,7 +50,7 @@ export function createExecutionGroup(id, taskId, assignment, laneInputs, now) {
51
50
  roleName: lane.roleName,
52
51
  ...(lane.effective === undefined ? {} : { effective: lane.effective }),
53
52
  ...(lane.workspace === undefined ? {} : { workspace: lane.workspace }),
54
- ...(lane.currentTurnId === undefined ? {} : { currentTurnId: lane.currentTurnId }),
53
+ ...(lane.currentRunId === undefined ? {} : { currentRunId: lane.currentRunId }),
55
54
  disposition: "open",
56
55
  createdAt: timestamp,
57
56
  updatedAt: timestamp
@@ -74,28 +73,28 @@ export function updateExecutionLane(group, laneId, patch, now) {
74
73
  throw new Error(`Terminal ExecutionLane is immutable: ${laneId}.`);
75
74
  }
76
75
  const disposition = patch.disposition ?? current.disposition;
77
- const currentTurnId = patch.currentTurnId ?? current.currentTurnId;
78
- const successfulTurnId = patch.successfulTurnId ?? current.successfulTurnId;
76
+ const currentRunId = patch.currentRunId ?? current.currentRunId;
77
+ const successfulRunId = patch.successfulRunId ?? current.successfulRunId;
79
78
  const effective = patch.effective ?? current.effective;
80
79
  const workspace = patch.workspace ?? current.workspace;
81
80
  if ((effective === undefined) !== (workspace === undefined)) {
82
81
  throw new Error("ExecutionLane launch facts are incomplete.");
83
82
  }
84
83
  if (disposition === "succeeded") {
85
- if (successfulTurnId === undefined || successfulTurnId !== currentTurnId) {
86
- throw new Error("A succeeded Lane must identify its current successful Turn.");
84
+ if (successfulRunId === undefined || successfulRunId !== currentRunId) {
85
+ throw new Error("A succeeded Lane must identify its current successful AgentRun.");
87
86
  }
88
87
  }
89
- else if (successfulTurnId !== undefined) {
90
- throw new Error("Only a succeeded Lane may identify a successful Turn.");
88
+ else if (successfulRunId !== undefined) {
89
+ throw new Error("Only a succeeded Lane may identify a successful AgentRun.");
91
90
  }
92
91
  const timestamp = now.toISOString();
93
92
  const updated = {
94
93
  ...current,
95
94
  ...(effective === undefined ? {} : { effective }),
96
95
  ...(workspace === undefined ? {} : { workspace }),
97
- ...(currentTurnId === undefined ? {} : { currentTurnId }),
98
- ...(successfulTurnId === undefined ? {} : { successfulTurnId }),
96
+ ...(currentRunId === undefined ? {} : { currentRunId }),
97
+ ...(successfulRunId === undefined ? {} : { successfulRunId }),
99
98
  disposition,
100
99
  updatedAt: timestamp,
101
100
  ...(disposition === "open" ? {} : { endedAt: timestamp })
@@ -114,7 +113,7 @@ export function updateWorkItemExecutionLane(group, laneId, patch, now) {
114
113
  /**
115
114
  * Reopen only failed Lanes for an explicit retry of the same semantic
116
115
  * execution. Successful results remain settled, while each failed Lane
117
- * returns to the same state produced by a naturally failed Turn: open and
116
+ * returns to the same state produced by a naturally failed AgentRun: open and
118
117
  * still pointing at the failed attempt that dispatch must replace.
119
118
  *
120
119
  * This is the sole terminal-to-open Lane transition. Normal Lane updates keep
@@ -255,7 +254,7 @@ export function validateExecutionGroup(group) {
255
254
  if (assignment.taskId !== group.taskId) {
256
255
  throw new Error("ExecutionGroup Assignment Task does not match its Group.");
257
256
  }
258
- if (!Array.isArray(group.lanes) || group.lanes.length < MINIMUM_SYNTHESIS_RESULTS) {
257
+ if (!Array.isArray(group.lanes) || group.lanes.length < MINIMUM_EXECUTION_GROUP_LANES) {
259
258
  throw new Error("A replicated ExecutionGroup requires at least two Lanes.");
260
259
  }
261
260
  if (group.lanes.length > MAXIMUM_SYNTHESIS_RESULTS) {
@@ -353,8 +352,8 @@ export function summarizeExecutionGroup(group) {
353
352
  roleName: lane.roleName,
354
353
  ordinal: lane.ordinal,
355
354
  disposition: lane.disposition,
356
- ...(lane.currentTurnId === undefined ? {} : { currentTurnId: lane.currentTurnId }),
357
- ...(lane.successfulTurnId === undefined ? {} : { successfulTurnId: lane.successfulTurnId }),
355
+ ...(lane.currentRunId === undefined ? {} : { currentRunId: lane.currentRunId }),
356
+ ...(lane.successfulRunId === undefined ? {} : { successfulRunId: lane.successfulRunId }),
358
357
  ...(lane.effective === undefined ? {} : { effective: lane.effective })
359
358
  }))
360
359
  };
@@ -385,8 +384,8 @@ function validateWorkItemExecutionLane(lane, groupId, ordinal) {
385
384
  "roleName",
386
385
  "effective",
387
386
  "workspace",
388
- "currentTurnId",
389
- "successfulTurnId",
387
+ "currentRunId",
388
+ "successfulRunId",
390
389
  "disposition",
391
390
  "createdAt",
392
391
  "updatedAt",
@@ -413,23 +412,23 @@ function validateWorkItemExecutionLane(lane, groupId, ordinal) {
413
412
  requireText(lane.workspace.root, "ExecutionLane workspace root");
414
413
  normalizedUniqueIdentities(lane.workspace.writableProjectIds, "ExecutionLane writable Project");
415
414
  }
416
- if (lane.currentTurnId !== undefined && lane.effective === undefined) {
415
+ if (lane.currentRunId !== undefined && lane.effective === undefined) {
417
416
  throw new Error("A dispatched ExecutionLane requires launch facts.");
418
417
  }
419
- if (lane.currentTurnId !== undefined)
420
- requireIdentity(lane.currentTurnId, "ExecutionLane current Turn id");
421
- if (lane.successfulTurnId !== undefined)
422
- requireIdentity(lane.successfulTurnId, "ExecutionLane successful Turn id");
418
+ if (lane.currentRunId !== undefined)
419
+ requireIdentity(lane.currentRunId, "ExecutionLane current AgentRun id");
420
+ if (lane.successfulRunId !== undefined)
421
+ requireIdentity(lane.successfulRunId, "ExecutionLane successful AgentRun id");
423
422
  if (!["open", "succeeded", "failed"].includes(lane.disposition)) {
424
423
  throw new Error(`ExecutionLane disposition is invalid: ${String(lane.disposition)}.`);
425
424
  }
426
425
  if (lane.disposition === "succeeded") {
427
- if (lane.currentTurnId === undefined || lane.successfulTurnId !== lane.currentTurnId) {
428
- throw new Error("A succeeded Lane must identify its current successful Turn.");
426
+ if (lane.currentRunId === undefined || lane.successfulRunId !== lane.currentRunId) {
427
+ throw new Error("A succeeded Lane must identify its current successful AgentRun.");
429
428
  }
430
429
  }
431
- else if (lane.successfulTurnId !== undefined) {
432
- throw new Error("Only a succeeded Lane may identify a successful Turn.");
430
+ else if (lane.successfulRunId !== undefined) {
431
+ throw new Error("Only a succeeded Lane may identify a successful AgentRun.");
433
432
  }
434
433
  requireTimestamp(lane.createdAt, "ExecutionLane createdAt");
435
434
  requireTimestamp(lane.updatedAt, "ExecutionLane updatedAt");
@@ -1,14 +1,14 @@
1
1
  import { governingWorkItemCandidate, currentWorkItemExecutionGroup } from "../workItem/workItem.js";
2
- import { MINIMUM_WORK_ITEM_SYNTHESIS_RESULTS } from "./workItemExecution.js";
3
- export function projectWorkItemExecution(item, turns, sessionSets = []) {
2
+ import { synthesisSourceRunIds } from "../context/runContextPack.js";
3
+ export function projectWorkItemExecution(item, runs, sessionSets = [], sourceStore) {
4
4
  const group = currentWorkItemExecutionGroup(item);
5
- const relevantTurns = turns.filter((turn) => turn.workItemId === item.id);
5
+ const relevantRuns = runs.filter((run) => run.workItemId === item.id);
6
6
  const sessionsByRole = new Map(sessionSets.map((set) => [set.owner.roleName, set]));
7
7
  const lanes = group === undefined
8
8
  ? []
9
9
  : [...group.lanes]
10
10
  .sort((left, right) => left.ordinal - right.ordinal || left.id.localeCompare(right.id))
11
- .map((lane) => projectLane(item, group, lane, relevantTurns, sessionsByRole));
11
+ .map((lane) => projectLane(item, group, lane, relevantRuns, sessionsByRole));
12
12
  const laneCounts = Object.freeze({
13
13
  running: lanes.filter(({ status }) => status === "running").length,
14
14
  succeeded: lanes.filter(({ status }) => status === "succeeded").length,
@@ -16,9 +16,9 @@ export function projectWorkItemExecution(item, turns, sessionSets = []) {
16
16
  failed: lanes.filter(({ status }) => status === "failed").length,
17
17
  unknown: lanes.filter(({ status }) => status === "unknown").length
18
18
  });
19
- const mainTurn = projectMainTurn(item, group, relevantTurns, sessionsByRole);
20
- const synthesis = projectSynthesis(group, lanes, mainTurn);
21
- const candidate = projectCandidate(item, group, relevantTurns, lanes, mainTurn);
19
+ const mainRun = projectMainRun(item, group, relevantRuns, sessionsByRole);
20
+ const synthesis = projectSynthesis(group, lanes, mainRun);
21
+ const candidate = projectCandidate(item, group, relevantRuns, mainRun, sourceStore);
22
22
  return Object.freeze({
23
23
  schemaVersion: 1,
24
24
  shape: group === undefined ? "direct" : "replicated",
@@ -26,15 +26,15 @@ export function projectWorkItemExecution(item, turns, sessionSets = []) {
26
26
  lanes: Object.freeze(lanes),
27
27
  laneCounts,
28
28
  synthesis,
29
- mainTurn,
29
+ mainRun,
30
30
  candidate,
31
- nextAction: projectNextAction(item, lanes, synthesis, mainTurn, candidate)
31
+ nextAction: projectNextAction(item, lanes, synthesis, mainRun, candidate)
32
32
  });
33
33
  }
34
- function projectLane(item, group, lane, turns, sessionsByRole) {
35
- const current = lane.currentTurnId === undefined
34
+ function projectLane(item, group, lane, runs, sessionsByRole) {
35
+ const current = lane.currentRunId === undefined
36
36
  ? undefined
37
- : turns.find(({ id }) => id === lane.currentTurnId);
37
+ : runs.find(({ id }) => id === lane.currentRunId);
38
38
  const exact = current !== undefined
39
39
  && current.taskId === item.taskId
40
40
  && current.workItemId === item.id
@@ -42,7 +42,7 @@ function projectLane(item, group, lane, turns, sessionsByRole) {
42
42
  && current.executionLaneId === lane.id
43
43
  && current.roleName === lane.roleName;
44
44
  const session = exact
45
- ? turnSessionStatus(current, sessionsByRole.get(lane.roleName))
45
+ ? runSessionStatus(current, sessionsByRole.get(lane.roleName))
46
46
  : "unobserved";
47
47
  if (lane.disposition === "failed") {
48
48
  return Object.freeze({
@@ -50,14 +50,14 @@ function projectLane(item, group, lane, turns, sessionsByRole) {
50
50
  ordinal: lane.ordinal,
51
51
  roleName: lane.roleName,
52
52
  status: "failed",
53
- ...(lane.currentTurnId === undefined ? {} : { currentTurnId: lane.currentTurnId }),
53
+ ...(lane.currentRunId === undefined ? {} : { currentRunId: lane.currentRunId }),
54
54
  session,
55
55
  observation: exact ? "observed" : "unobserved"
56
56
  });
57
57
  }
58
58
  if (lane.disposition === "succeeded") {
59
59
  const producerObserved = exact
60
- && lane.successfulTurnId === current.id
60
+ && lane.successfulRunId === current.id
61
61
  && current.status === "completed"
62
62
  && current.result !== undefined;
63
63
  return Object.freeze({
@@ -65,8 +65,8 @@ function projectLane(item, group, lane, turns, sessionsByRole) {
65
65
  ordinal: lane.ordinal,
66
66
  roleName: lane.roleName,
67
67
  status: producerObserved ? "succeeded" : "unknown",
68
- ...(lane.currentTurnId === undefined ? {} : { currentTurnId: lane.currentTurnId }),
69
- ...(lane.successfulTurnId === undefined ? {} : { successfulTurnId: lane.successfulTurnId }),
68
+ ...(lane.currentRunId === undefined ? {} : { currentRunId: lane.currentRunId }),
69
+ ...(lane.successfulRunId === undefined ? {} : { successfulRunId: lane.successfulRunId }),
70
70
  session,
71
71
  observation: producerObserved ? "observed" : "unobserved"
72
72
  });
@@ -77,7 +77,7 @@ function projectLane(item, group, lane, turns, sessionsByRole) {
77
77
  ordinal: lane.ordinal,
78
78
  roleName: lane.roleName,
79
79
  status: "unknown",
80
- ...(lane.currentTurnId === undefined ? {} : { currentTurnId: lane.currentTurnId }),
80
+ ...(lane.currentRunId === undefined ? {} : { currentRunId: lane.currentRunId }),
81
81
  session: "unobserved",
82
82
  observation: "unobserved"
83
83
  });
@@ -88,10 +88,10 @@ function projectLane(item, group, lane, turns, sessionsByRole) {
88
88
  ordinal: lane.ordinal,
89
89
  roleName: lane.roleName,
90
90
  status: "needs-attention",
91
- currentTurnId: current.id,
91
+ currentRunId: current.id,
92
92
  session,
93
- retryTurnId: current.id,
94
- settleTurnId: current.id,
93
+ retryRunId: current.id,
94
+ settleRunId: current.id,
95
95
  observation: "observed"
96
96
  });
97
97
  }
@@ -101,7 +101,8 @@ function projectLane(item, group, lane, turns, sessionsByRole) {
101
101
  ordinal: lane.ordinal,
102
102
  roleName: lane.roleName,
103
103
  status: session === "ended" ? "needs-attention" : "running",
104
- currentTurnId: current.id,
104
+ currentRunId: current.id,
105
+ delivery: observedAdmission(current, sessionsByRole.get(lane.roleName)),
105
106
  session,
106
107
  observation: "observed"
107
108
  });
@@ -111,19 +112,19 @@ function projectLane(item, group, lane, turns, sessionsByRole) {
111
112
  ordinal: lane.ordinal,
112
113
  roleName: lane.roleName,
113
114
  status: "unknown",
114
- currentTurnId: current.id,
115
+ currentRunId: current.id,
115
116
  session,
116
117
  observation: "unobserved"
117
118
  });
118
119
  }
119
- function projectMainTurn(item, group, turns, sessionsByRole) {
120
- const candidates = turns.filter((turn) => (turn.purpose === "execution"
121
- && turn.roleName === item.assignee
122
- && turn.executionGroupId === undefined
123
- && turn.executionLaneId === undefined
124
- && turn.sourceExecutionGroupId === group?.id)).sort(compareTurns);
125
- const turn = candidates.at(-1);
126
- if (turn === undefined) {
120
+ function projectMainRun(item, group, runs, sessionsByRole) {
121
+ const candidates = runs.filter((run) => (run.purpose === "execution"
122
+ && run.roleName === item.assignee
123
+ && run.executionGroupId === undefined
124
+ && run.executionLaneId === undefined
125
+ && run.sourceExecutionGroupId === group?.id)).sort(compareRuns);
126
+ const run = candidates.at(-1);
127
+ if (run === undefined) {
127
128
  return Object.freeze({
128
129
  status: "not-started",
129
130
  ...(item.assignee === undefined ? {} : { roleName: item.assignee }),
@@ -132,65 +133,56 @@ function projectMainTurn(item, group, turns, sessionsByRole) {
132
133
  observation: "unobserved"
133
134
  });
134
135
  }
135
- const session = turnSessionStatus(turn, sessionsByRole.get(turn.roleName));
136
+ const session = runSessionStatus(run, sessionsByRole.get(run.roleName));
136
137
  const base = {
137
- roleName: turn.roleName,
138
- turnId: turn.id,
139
- ...(turn.sourceExecutionGroupId === undefined
138
+ roleName: run.roleName,
139
+ runId: run.id,
140
+ ...(run.sourceExecutionGroupId === undefined
140
141
  ? {}
141
- : { sourceExecutionGroupId: turn.sourceExecutionGroupId }),
142
+ : { sourceExecutionGroupId: run.sourceExecutionGroupId }),
142
143
  session
143
144
  };
144
- if (turn.status === "failed") {
145
+ if (run.status === "failed") {
145
146
  return Object.freeze({
146
147
  ...base,
147
148
  status: "needs-attention",
148
- retryTurnId: turn.id,
149
+ retryRunId: run.id,
149
150
  observation: "observed"
150
151
  });
151
152
  }
152
- if (turn.status === "active") {
153
+ if (run.status === "active") {
153
154
  return Object.freeze({
154
155
  ...base,
156
+ delivery: observedAdmission(run, sessionsByRole.get(run.roleName)),
155
157
  status: session === "ended" ? "needs-attention" : "running",
156
158
  observation: "observed"
157
159
  });
158
160
  }
159
161
  return Object.freeze({
160
162
  ...base,
161
- status: turn.result === undefined ? "unknown" : "succeeded",
162
- observation: turn.result === undefined ? "unobserved" : "observed"
163
+ status: run.result === undefined ? "unknown" : "succeeded",
164
+ observation: run.result === undefined ? "unobserved" : "observed"
163
165
  });
164
166
  }
165
- function projectSynthesis(group, lanes, mainTurn) {
167
+ function projectSynthesis(group, lanes, mainRun) {
166
168
  if (group === undefined) {
167
169
  return Object.freeze({
168
170
  status: "not-applicable",
169
- successfulLaneCount: 0,
170
- requiredSuccessfulLaneCount: MINIMUM_WORK_ITEM_SYNTHESIS_RESULTS
171
+ successfulLaneCount: 0
171
172
  });
172
173
  }
173
174
  const successfulLaneCount = group.lanes.filter(({ disposition }) => disposition === "succeeded").length;
174
175
  let status;
175
- if (group.lanes.some(({ disposition }) => disposition === "open")) {
176
- status = "blocked-by-open-lanes";
176
+ if (mainRun.status === "not-started") {
177
+ status = "awaiting-selection";
177
178
  }
178
- else if (lanes.some((lane) => (lane.status === "unknown" && group.lanes.some(({ id, disposition }) => (id === lane.laneId && disposition === "succeeded"))))) {
179
- status = "unknown";
180
- }
181
- else if (successfulLaneCount < MINIMUM_WORK_ITEM_SYNTHESIS_RESULTS) {
182
- status = "insufficient-results";
183
- }
184
- else if (mainTurn.status === "not-started") {
185
- status = "eligible";
186
- }
187
- else if (mainTurn.status === "running") {
179
+ else if (mainRun.status === "running") {
188
180
  status = "main-running";
189
181
  }
190
- else if (mainTurn.status === "needs-attention") {
182
+ else if (mainRun.status === "needs-attention") {
191
183
  status = "main-needs-attention";
192
184
  }
193
- else if (mainTurn.status === "succeeded") {
185
+ else if (mainRun.status === "succeeded") {
194
186
  status = "complete";
195
187
  }
196
188
  else {
@@ -198,16 +190,15 @@ function projectSynthesis(group, lanes, mainTurn) {
198
190
  }
199
191
  return Object.freeze({
200
192
  status,
201
- successfulLaneCount,
202
- requiredSuccessfulLaneCount: MINIMUM_WORK_ITEM_SYNTHESIS_RESULTS
193
+ successfulLaneCount
203
194
  });
204
195
  }
205
- function projectCandidate(item, group, turns, lanes, mainTurn) {
196
+ function projectCandidate(item, group, runs, mainRun, sourceStore) {
206
197
  const candidate = governingWorkItemCandidate(item);
207
198
  if (candidate === undefined) {
208
199
  return Object.freeze({
209
200
  status: "none",
210
- successfulLaneTurns: Object.freeze([]),
201
+ successfulLaneRuns: Object.freeze([]),
211
202
  observation: "observed"
212
203
  });
213
204
  }
@@ -215,43 +206,43 @@ function projectCandidate(item, group, turns, lanes, mainTurn) {
215
206
  const valid = group === undefined && item.assignee === undefined;
216
207
  return candidateProjection(candidate, valid ? "observed" : "unknown", [], valid);
217
208
  }
218
- const sourceTurnId = candidate.source.turnId;
219
- const sourceTurn = turns.find(({ id }) => id === sourceTurnId);
220
- const laneTurns = group === undefined
209
+ const sourceRunId = candidate.source.runId;
210
+ const sourceRun = runs.find(({ id }) => id === sourceRunId);
211
+ const laneRuns = group === undefined || sourceStore === undefined || sourceRun === undefined
221
212
  ? []
222
- : [...group.lanes]
223
- .filter(({ disposition, successfulTurnId }) => (disposition === "succeeded" && successfulTurnId !== undefined))
224
- .sort((left, right) => left.ordinal - right.ordinal || left.id.localeCompare(right.id))
225
- .map((lane) => ({ laneId: lane.id, successfulTurnId: lane.successfulTurnId }));
226
- const valid = sourceTurn !== undefined
227
- && sourceTurn.id === mainTurn.turnId
228
- && sourceTurn.status === "completed"
229
- && sourceTurn.result !== undefined
230
- && sourceTurn.executionGroupId === undefined
231
- && sourceTurn.executionLaneId === undefined
232
- && sourceTurn.sourceExecutionGroupId === group?.id
213
+ : synthesisSourceRunIds(sourceStore, sourceRun).flatMap((id) => {
214
+ const selected = runs.find((run) => run.id === id);
215
+ return selected?.executionLaneId === undefined ? [] : [{
216
+ laneId: selected.executionLaneId, successfulRunId: selected.id
217
+ }];
218
+ });
219
+ const valid = sourceRun !== undefined
220
+ && sourceRun.id === mainRun.runId
221
+ && sourceRun.status === "completed"
222
+ && sourceRun.result !== undefined
223
+ && sourceRun.executionGroupId === undefined
224
+ && sourceRun.executionLaneId === undefined
225
+ && sourceRun.sourceExecutionGroupId === group?.id
233
226
  && candidate.executionLaneId === undefined
234
227
  && candidate.executionGroupId === undefined
235
- && (group === undefined || (laneTurns.length >= MINIMUM_WORK_ITEM_SYNTHESIS_RESULTS
236
- && lanes.filter(({ successfulTurnId }) => successfulTurnId !== undefined)
237
- .every(({ status }) => status === "succeeded")));
238
- return candidateProjection(candidate, valid ? "observed" : "unknown", laneTurns, valid, group?.id);
228
+ && (group === undefined || laneRuns.length > 0);
229
+ return candidateProjection(candidate, valid ? "observed" : "unknown", laneRuns, valid, group?.id);
239
230
  }
240
- function candidateProjection(candidate, status, successfulLaneTurns, observed, sourceExecutionGroupId) {
231
+ function candidateProjection(candidate, status, successfulLaneRuns, observed, sourceExecutionGroupId) {
241
232
  return Object.freeze({
242
233
  status,
243
234
  candidateId: candidate.id,
244
235
  sourceType: candidate.source.type,
245
- ...(candidate.source.type === "turn" ? { mainTurnId: candidate.source.turnId } : {}),
236
+ ...(candidate.source.type === "run" ? { mainRunId: candidate.source.runId } : {}),
246
237
  ...(sourceExecutionGroupId === undefined ? {} : { sourceExecutionGroupId }),
247
- successfulLaneTurns: Object.freeze(successfulLaneTurns),
238
+ successfulLaneRuns: Object.freeze(successfulLaneRuns),
248
239
  observation: observed ? "observed" : "unobserved"
249
240
  });
250
241
  }
251
- function projectNextAction(item, lanes, synthesis, mainTurn, candidate) {
252
- if (["completed", "retired"].includes(item.status))
242
+ function projectNextAction(item, lanes, synthesis, mainRun, candidate) {
243
+ if (["accepted", "retired"].includes(item.status))
253
244
  return action("none", [], []);
254
- if (item.status === "awaiting_acceptance") {
245
+ if ((item.status === "open" && item.currentCandidateId !== undefined)) {
255
246
  return candidate.status === "observed"
256
247
  ? action("decide-candidate", ["leader"], [candidate.candidateId])
257
248
  : action("inspect-unknown", ["leader"], candidate.candidateId === undefined ? [] : [candidate.candidateId]);
@@ -261,35 +252,32 @@ function projectNextAction(item, lanes, synthesis, mainTurn, candidate) {
261
252
  .filter(({ status }) => status === "unknown")
262
253
  .map(({ laneId }) => laneId));
263
254
  }
264
- const recoveries = lanes.filter(({ retryTurnId }) => retryTurnId !== undefined);
255
+ const recoveries = lanes.filter(({ retryRunId }) => retryRunId !== undefined);
265
256
  if (recoveries.length > 0) {
266
- return action("retry-or-settle-lanes", ["leader"], recoveries.map(({ retryTurnId }) => retryTurnId));
257
+ return action("retry-or-settle-lanes", ["leader"], recoveries.map(({ retryRunId }) => retryRunId));
267
258
  }
268
259
  const activeLanes = lanes.filter(({ status }) => status === "running");
269
260
  if (activeLanes.length > 0) {
270
261
  return action("wait-for-lanes", activeLanes.map(({ roleName }) => roleName), activeLanes.map(({ laneId }) => laneId));
271
262
  }
272
- if (synthesis.status === "insufficient-results") {
273
- return action("redispatch-work", ["leader"], [item.id]);
263
+ if (synthesis.status === "awaiting-selection") {
264
+ return action("select-synthesis-sources", ["leader"], [item.id]);
274
265
  }
275
- if (synthesis.status === "eligible") {
276
- return action("await-main-dispatch", ["controller", ...(item.assignee === undefined ? [] : [item.assignee])], [item.id]);
266
+ if (mainRun.status === "running") {
267
+ return action("wait-for-main", mainRun.roleName === undefined ? [] : [mainRun.roleName], mainRun.runId === undefined ? [] : [mainRun.runId]);
277
268
  }
278
- if (mainTurn.status === "running") {
279
- return action("wait-for-main", mainTurn.roleName === undefined ? [] : [mainTurn.roleName], mainTurn.turnId === undefined ? [] : [mainTurn.turnId]);
269
+ if (mainRun.status === "needs-attention") {
270
+ return mainRun.retryRunId === undefined
271
+ ? action("inspect-unknown", ["leader"], mainRun.runId === undefined ? [] : [mainRun.runId])
272
+ : action("retry-main", ["leader"], [mainRun.retryRunId]);
280
273
  }
281
- if (mainTurn.status === "needs-attention") {
282
- return mainTurn.retryTurnId === undefined
283
- ? action("inspect-unknown", ["leader"], mainTurn.turnId === undefined ? [] : [mainTurn.turnId])
284
- : action("retry-main", ["leader"], [mainTurn.retryTurnId]);
274
+ if (mainRun.status === "succeeded" && item.status === "open") {
275
+ return action("submit-candidate", ["leader"], [mainRun.runId]);
285
276
  }
286
- if (mainTurn.status === "succeeded" && item.status === "running") {
287
- return action("submit-candidate", ["leader"], [mainTurn.turnId]);
277
+ if (mainRun.status === "unknown" || synthesis.status === "unknown") {
278
+ return action("inspect-unknown", ["leader"], mainRun.runId === undefined ? [item.id] : [mainRun.runId]);
288
279
  }
289
- if (mainTurn.status === "unknown" || synthesis.status === "unknown") {
290
- return action("inspect-unknown", ["leader"], mainTurn.turnId === undefined ? [item.id] : [mainTurn.turnId]);
291
- }
292
- if (item.status === "pending" || item.status === "failed") {
280
+ if (item.status === "open") {
293
281
  return action("dispatch-work", ["leader"], [item.id]);
294
282
  }
295
283
  return action("inspect-unknown", ["leader"], [item.id]);
@@ -301,9 +289,13 @@ function action(kind, owners, targetIds) {
301
289
  targetIds: Object.freeze([...new Set(targetIds)])
302
290
  });
303
291
  }
304
- function turnSessionStatus(turn, set) {
305
- return set?.sessions[turn.effective.agentId]?.status ?? "unobserved";
292
+ function runSessionStatus(run, set) {
293
+ return set?.sessions[run.effective.agentId]?.status ?? "unobserved";
294
+ }
295
+ function observedAdmission(run, sessions) {
296
+ const native = sessions?.providerBinding?.run;
297
+ return native?.runId === run.id ? native.status : "unobserved";
306
298
  }
307
- function compareTurns(left, right) {
299
+ function compareRuns(left, right) {
308
300
  return left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id);
309
301
  }