@zq-silk/yui 0.13.9 → 0.14.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 (229) hide show
  1. package/ARCHITECTURE.md +69 -428
  2. package/README.md +108 -298
  3. package/dist/agent/managedRuntimeEnvironment.js +2 -2
  4. package/dist/cli/commandCatalog.js +39 -77
  5. package/dist/cli/interactionCandidates.js +4 -4
  6. package/dist/cli/interactionPolicy.js +7 -10
  7. package/dist/cli/invocationRouter.js +1 -1
  8. package/dist/cli/updateCommand.js +6 -27
  9. package/dist/cli/updateOrchestrator.js +63 -484
  10. package/dist/cli/updatePorts.js +15 -333
  11. package/dist/cli/upgradeCommand.js +8 -65
  12. package/dist/cli.js +57 -242
  13. package/dist/commands/configCommands.js +11 -62
  14. package/dist/commands/executionAuditCommands.js +23 -23
  15. package/dist/commands/globalRoleCommands.js +2 -7
  16. package/dist/commands/jobCommands.js +1 -4
  17. package/dist/commands/projectCommands.js +5 -5
  18. package/dist/commands/releaseCommands.js +3 -10
  19. package/dist/commands/resourcesCommands.js +2 -2
  20. package/dist/commands/sessionCommands.js +2 -2
  21. package/dist/commands/taskActor.js +31 -39
  22. package/dist/commands/taskChangeSetCommands.js +5 -12
  23. package/dist/commands/taskCommands.js +464 -1249
  24. package/dist/commands/taskContextCommand.js +35 -36
  25. package/dist/commands/taskExecutionCommands.js +33 -46
  26. package/dist/commands/taskInputCommands.js +20 -42
  27. package/dist/commands/taskNextActionCommand.js +9 -9
  28. package/dist/commands/taskOverviewCommand.js +56 -95
  29. package/dist/commands/taskRoleRuntimeStatus.js +77 -107
  30. package/dist/commands/taskUpstreamCommands.js +3 -3
  31. package/dist/commands/taskWorkspaceCommands.js +7 -79
  32. package/dist/commands/telemetryCommands.js +32 -124
  33. package/dist/commands/workflowCommands.js +3 -3
  34. package/dist/completion/fileCompletionManager.js +1 -1
  35. package/dist/config/configCatalog.js +4 -6
  36. package/dist/config/yuiConfig.js +6 -43
  37. package/dist/context/dispatchContext.js +14 -30
  38. package/dist/context/roleSessionContext.js +2 -2
  39. package/dist/context/sessionBootstrapManifest.js +2 -2
  40. package/dist/context/{runContextPack.js → turnContextPack.js} +58 -73
  41. package/dist/context/turnInputContract.js +204 -0
  42. package/dist/context/wakeNotification.js +2 -2
  43. package/dist/controller/agentRuntimeObserver.js +18 -18
  44. package/dist/controller/clientRuntime.js +13 -20
  45. package/dist/controller/controller.js +89 -116
  46. package/dist/controller/fileSchedulerStoreAdapter.js +511 -742
  47. package/dist/controller/jobControl.js +17 -17
  48. package/dist/controller/resourceInventory.js +6 -6
  49. package/dist/controller/resourceInventoryLinux.js +38 -59
  50. package/dist/controller/resourceInventoryRpc.js +3 -3
  51. package/dist/controller/resourceInventoryWorker.js +1 -1
  52. package/dist/controller/runtime.js +46 -53
  53. package/dist/controller/runtimeEventInbox.js +23 -31
  54. package/dist/controller/runtimeEventProcessor.js +15 -15
  55. package/dist/controller/{runtimeHookRunFence.js → runtimeHookTurnFence.js} +87 -81
  56. package/dist/controller/runtimeLaunchCoordinator.js +3 -3
  57. package/dist/controller/runtimeObservationHook.js +11 -8
  58. package/dist/controller/sessionNotify.js +11 -11
  59. package/dist/controller/structuredProviderObservation.js +89 -16
  60. package/dist/coordination/workMailbox.js +309 -579
  61. package/dist/coordination/workMailboxQueue.js +5 -6
  62. package/dist/core/controllerClient.js +1 -91
  63. package/dist/core/controllerServer.js +3 -6
  64. package/dist/doctor/doctor.js +51 -314
  65. package/dist/execution/candidateConvergence.js +3 -3
  66. package/dist/execution/executionGroup.js +32 -33
  67. package/dist/execution/executionHealth.js +36 -38
  68. package/dist/execution/resourceBroker.js +12 -12
  69. package/dist/executor/agentExecutor.js +30 -265
  70. package/dist/executor/effectiveLaunch.js +9 -19
  71. package/dist/executor/executorRegistry.js +43 -17
  72. package/dist/executor/fileRoleLaunchPlanner.js +56 -56
  73. package/dist/executor/launchPlan.js +3 -3
  74. package/dist/executor/workspacePreflightClassification.js +16 -16
  75. package/dist/grant/capabilityGrant.js +20 -25
  76. package/dist/input/inputRequest.js +12 -12
  77. package/dist/integration/changeSet.js +9 -13
  78. package/dist/integration/changeSetManifest.js +1 -1
  79. package/dist/integration/gitIntegrationService.js +2 -2
  80. package/dist/integration/integrationQueueService.js +5 -21
  81. package/dist/integration/overlapDiagnostics.js +2 -2
  82. package/dist/interaction/operatorPresentation.js +1 -1
  83. package/dist/job/jobRunner.js +1 -1
  84. package/dist/lifecycle/canonicalLifecycleEvent.js +25 -25
  85. package/dist/lifecycle/{exactRunTerminalization.js → exactTurnTerminalization.js} +116 -232
  86. package/dist/message/message.js +6 -6
  87. package/dist/observability/executionAudit.js +74 -86
  88. package/dist/observability/faultClassification.js +7 -24
  89. package/dist/observability/orchestrationMetrics.js +5 -5
  90. package/dist/observability/runtimeIdentity.js +34 -101
  91. package/dist/profile/agentProfile.js +1 -1
  92. package/dist/release/cliHomeReleaseFence.js +3 -3
  93. package/dist/release/releaseWorkflowEngine.js +6 -10
  94. package/dist/release/releaseWorkflowPorts.js +2 -2
  95. package/dist/release/workflowFileLock.js +1 -1
  96. package/dist/repository/checkoutSwap.js +1 -1
  97. package/dist/repository/gitWorkspace.js +0 -13
  98. package/dist/repository/project.js +1 -1
  99. package/dist/repository/projectMaintenanceLock.js +1 -2
  100. package/dist/repository/taskBaseFreshness.js +13 -13
  101. package/dist/repository/taskWorkspaceCoordinator.js +21 -25
  102. package/dist/repository/taskWorkspaceIdentity.js +8 -21
  103. package/dist/repository/taskWorkspacePreparer.js +63 -620
  104. package/dist/resources/autoResourceGc.js +3 -3
  105. package/dist/resources/liveReferences.js +1 -1
  106. package/dist/resources/resourceGc.js +1 -1
  107. package/dist/resources/sqliteResourceRegistry.js +1 -1
  108. package/dist/review/reviewDecision.js +7 -7
  109. package/dist/review/reviewFindingLedger.js +1 -1
  110. package/dist/review/reviewOutcomeClassifier.js +35 -50
  111. package/dist/review/reviewRound.js +14 -25
  112. package/dist/review/reviewerAvailability.js +4 -4
  113. package/dist/review/taskFinalReviewContractResolution.js +41 -0
  114. package/dist/role/role.js +6 -3
  115. package/dist/runtime/agentDriver.js +4 -0
  116. package/dist/runtime/agentHost.js +151 -36
  117. package/dist/runtime/builtinAgentDrivers.js +79 -2
  118. package/dist/runtime/codexAppServerRuntime.js +122 -0
  119. package/dist/runtime/continuationManager.js +3 -5
  120. package/dist/runtime/exactControlPlane.js +17 -42
  121. package/dist/runtime/firstProgressAdvisory.js +1 -1
  122. package/dist/runtime/index.js +2 -2
  123. package/dist/runtime/launchDiagnostics.js +2 -2
  124. package/dist/runtime/lifecycleReservation.js +4 -4
  125. package/dist/runtime/processExitObservation.js +1 -1
  126. package/dist/runtime/processExitOutbox.js +0 -32
  127. package/dist/runtime/promptEnvelope.js +9 -9
  128. package/dist/runtime/providerContinuation.js +2 -2
  129. package/dist/runtime/providerContinuationReconciliationService.js +2 -2
  130. package/dist/runtime/providerRuntimeIdentity.js +76 -24
  131. package/dist/runtime/recentTurnIds.js +38 -0
  132. package/dist/runtime/runtimeContinuationProjection.js +2 -2
  133. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  134. package/dist/runtime/runtimeObservation.js +58 -21
  135. package/dist/runtime/runtimeProjection.js +19 -27
  136. package/dist/runtime/sessionLaunchRequest.js +2 -2
  137. package/dist/runtime/structuredProviderHost.js +177 -12
  138. package/dist/runtime/tmuxAdapters.js +46 -11
  139. package/dist/scheduler/activeRoleTurnDelivery.js +245 -0
  140. package/dist/scheduler/leaderWakeupProcessor.js +147 -445
  141. package/dist/scheduler/operatorEvent.js +4 -6
  142. package/dist/scheduler/resourceQueueProjection.js +71 -0
  143. package/dist/scheduler/{roleRunLiveness.js → roleTurnLiveness.js} +24 -28
  144. package/dist/scheduler/{roleRunStall.js → roleTurnStall.js} +162 -247
  145. package/dist/scheduler/taskExecutionProjection.js +99 -99
  146. package/dist/scheduler/taskObservabilityProjection.js +10 -10
  147. package/dist/scheduler/taskWake.js +4 -4
  148. package/dist/scheduler/wakeReason.js +6 -10
  149. package/dist/scheduler/wakeupQueue.js +0 -9
  150. package/dist/setup/setupCommand.js +2 -2
  151. package/dist/storage/currentTaskStore.js +46 -0
  152. package/dist/storage/persistenceWorker.js +1 -1
  153. package/dist/storage/sqliteSchema.js +81 -485
  154. package/dist/storage/sqliteStore.js +206 -365
  155. package/dist/storage/storageSchema.js +1 -15
  156. package/dist/storage/storageVersions.js +8 -9
  157. package/dist/storage/storeRpc.js +10 -34
  158. package/dist/storage/taskStore.js +63 -3415
  159. package/dist/storage/upgrade/recordVersions.js +55 -149
  160. package/dist/storage/upgrade/upgradeOrchestrator.js +89 -1752
  161. package/dist/task/completionReadiness.js +5 -5
  162. package/dist/task/deliveryGuard.js +10 -10
  163. package/dist/task/nextAction.js +74 -77
  164. package/dist/task/task.js +2 -4
  165. package/dist/task/taskRecordReference.js +3 -3
  166. package/dist/task/taskRecordRetirement.js +1 -1
  167. package/dist/telemetry/sqliteTelemetryStore.js +53 -53
  168. package/dist/telemetry/telemetryConfig.js +14 -14
  169. package/dist/telemetry/telemetryWiring.js +8 -14
  170. package/dist/turn/turn.js +356 -0
  171. package/dist/{run/runIdentity.js → turn/turnIdentity.js} +4 -4
  172. package/dist/verification/gateArtifactStore.js +2 -2
  173. package/dist/web/assets/client/app.js +1 -1
  174. package/dist/web/assets/client/components.js +29 -54
  175. package/dist/web/assets/client/i18n.js +17 -37
  176. package/dist/web/assets/client/view.js +37 -37
  177. package/dist/web/assets/shell.js +1 -1
  178. package/dist/web/assets/styles/cards.js +5 -5
  179. package/dist/web/assets/styles/widgets.js +1 -2
  180. package/dist/web/webSnapshot.js +65 -60
  181. package/dist/workItem/workItem.js +11 -11
  182. package/dist/workspace/workItemChangeSetManager.js +1 -1
  183. package/docs/task-local-identity.md +5 -5
  184. package/i18n/README.zh-CN.md +41 -54
  185. package/package.json +1 -1
  186. package/skills/yui-leader/SKILL.md +85 -83
  187. package/skills/yui-operator/SKILL.md +16 -16
  188. package/skills/yui-reviewer/SKILL.md +10 -10
  189. package/skills/yui-runtime/SKILL.md +17 -18
  190. package/skills/yui-worker/SKILL.md +16 -18
  191. package/dist/context/runContextContract.js +0 -162
  192. package/dist/executor/turnCompletion.js +0 -126
  193. package/dist/review/taskFinalReviewContractEvent.js +0 -1
  194. package/dist/review/taskFinalReviewContractRebind.js +0 -367
  195. package/dist/run/agentRun.js +0 -356
  196. package/dist/run/rejectedYieldAttempt.js +0 -221
  197. package/dist/run/runControlRequest.js +0 -50
  198. package/dist/run/yieldReceipt.js +0 -65
  199. package/dist/runtime/turnCompletion.js +0 -3
  200. package/dist/scheduler/actionability.js +0 -323
  201. package/dist/scheduler/activeRoleRunDelivery.js +0 -868
  202. package/dist/scheduler/activeTaskProgress.js +0 -126
  203. package/dist/storage/compatibleTaskStore.js +0 -248
  204. package/dist/storage/migration/baseline.js +0 -78
  205. package/dist/storage/migration/classifier.js +0 -51
  206. package/dist/storage/migration/compatibleCodec.js +0 -53
  207. package/dist/storage/migration/engine.js +0 -147
  208. package/dist/storage/migration/index.js +0 -33
  209. package/dist/storage/migration/planner.js +0 -154
  210. package/dist/storage/migration/productionRegistry.js +0 -3931
  211. package/dist/storage/migration/registry.js +0 -169
  212. package/dist/storage/migration/report.js +0 -54
  213. package/dist/storage/migration/types.js +0 -31
  214. package/dist/storage/upgrade/homeClassification.js +0 -353
  215. package/dist/storage/upgrade/homeMigrationTarget.js +0 -595
  216. package/dist/storage/upgrade/migrationReceipt.js +0 -67
  217. package/dist/storage/upgrade/offlineUpgradeInventory.js +0 -453
  218. package/dist/storage/upgrade/productionMigrationRegistry.js +0 -6
  219. package/dist/storage/upgrade/pseudoLayoutRepair.js +0 -241
  220. package/dist/storage/upgrade/recordVersionScan.js +0 -176
  221. package/dist/storage/upgrade/sqliteFileSet.js +0 -50
  222. package/dist/storage/upgrade/sqliteMigrationTarget.js +0 -375
  223. package/dist/storage/upgrade/sqliteRecordMigrationTarget.js +0 -305
  224. package/dist/storage/upgrade/sqliteStateMigration.js +0 -918
  225. package/dist/storage/upgrade/switchProgress.js +0 -80
  226. package/dist/storage/upgrade/upgradeReceipt.js +0 -161
  227. package/dist/storage/upgradeCoordination.js +0 -187
  228. package/dist/storage/upgradeFence.js +0 -366
  229. package/dist/telemetry/telemetryCompaction.js +0 -252
@@ -1,5 +1,6 @@
1
1
  import { enqueueWork } from "../coordination/workMailboxQueue.js";
2
2
  import { createTaskEvent } from "../event/taskEvent.js";
3
+ import { queueLeaderWakeup } from "./wakeupQueue.js";
3
4
  export const LEADER_ATTENTION_REQUIRED_EVENT = "leader.attention-required";
4
5
  /** The sole Task-event boundary into the global Operator mailbox. */
5
6
  export function enqueueOperatorEvent(store, event, reason, now) {
@@ -7,9 +8,7 @@ export function enqueueOperatorEvent(store, event, reason, now) {
7
8
  { type: "event", taskId: event.taskId, id: event.id }
8
9
  ], {
9
10
  source: "task-event",
10
- dedupeKey: `operator-event:${event.taskId}:${event.id}`,
11
- deliveryMode: "followup",
12
- lane: "normal"
11
+ dedupeKey: `operator-event:${event.taskId}:${event.id}`
13
12
  });
14
13
  }
15
14
  /** Routes one Role fact to its supervisor without exposing Provider details to Operator code. */
@@ -20,10 +19,9 @@ export function routeRoleEvent(store, event, roleName, reason, now) {
20
19
  }
21
20
  enqueueWork(store, { kind: "role", taskId: event.taskId, roleName: "leader" }, reason, now, [{ type: "event", taskId: event.taskId, id: event.id }], {
22
21
  source: "task-event",
23
- dedupeKey: `leader-event:${event.taskId}:${event.id}`,
24
- deliveryMode: "followup",
25
- lane: "normal"
22
+ dedupeKey: `leader-event:${event.taskId}:${event.id}`
26
23
  });
24
+ queueLeaderWakeup(store, event.taskId, reason, now);
27
25
  }
28
26
  /** Records the semantic boundary used when a Leader can no longer continue. */
29
27
  export function recordLeaderAttentionRequired(store, input) {
@@ -0,0 +1,71 @@
1
+ import { currentWorkItemExecutionGroup } from "../workItem/workItem.js";
2
+ import { executionStageSpendClosed, observedExecutionResourceUsage, projectExecutionStageResources } from "../execution/resourceBroker.js";
3
+ /** Exact durable Broker queue used by resource admission. */
4
+ export function projectQueuedResourceLaneIdentities(store, now) {
5
+ return store.listActiveTaskIds().flatMap((taskId) => {
6
+ const taskTurns = store.listTurns(taskId);
7
+ const taskEvents = store.listEvents(taskId);
8
+ const workItemLanes = store.listWorkItems(taskId).flatMap((item) => {
9
+ if (item.status !== "running")
10
+ return [];
11
+ const group = currentWorkItemExecutionGroup(item);
12
+ if (group === undefined || group.resolution !== undefined)
13
+ return [];
14
+ if (group.stage !== undefined) {
15
+ const resources = projectExecutionStageResources({
16
+ group,
17
+ stageGroups: item.executionGroups,
18
+ usage: observedExecutionResourceUsage({
19
+ group,
20
+ stageGroups: item.executionGroups,
21
+ turns: taskTurns,
22
+ events: taskEvents
23
+ }),
24
+ now
25
+ });
26
+ if (executionStageSpendClosed(resources))
27
+ return [];
28
+ }
29
+ return group.lanes.flatMap((lane) => {
30
+ if (lane.status !== "pending"
31
+ || lane.effective === undefined
32
+ || lane.turnId !== undefined)
33
+ return [];
34
+ return [{
35
+ taskId,
36
+ workItemId: item.id,
37
+ executionGroupId: group.id,
38
+ executionLaneId: lane.id,
39
+ providerId: lane.effective.adapterId,
40
+ agentId: lane.effective.agentId,
41
+ ...(lane.effective.model === undefined ? {} : { model: lane.effective.model }),
42
+ requestedAt: lane.updatedAt
43
+ }];
44
+ });
45
+ });
46
+ const reviewLanes = store.listReviewRounds(taskId).flatMap((round) => {
47
+ if (round.status !== "pending" && round.status !== "running")
48
+ return [];
49
+ const group = round.executionGroup;
50
+ if (group === undefined || group.resolution !== undefined)
51
+ return [];
52
+ return group.lanes.flatMap((lane) => {
53
+ if (lane.status !== "pending"
54
+ || lane.effective === undefined
55
+ || lane.turnId !== undefined)
56
+ return [];
57
+ return [{
58
+ taskId,
59
+ ...(round.workItemId === undefined ? {} : { workItemId: round.workItemId }),
60
+ executionGroupId: group.id,
61
+ executionLaneId: lane.id,
62
+ providerId: lane.effective.adapterId,
63
+ agentId: lane.effective.agentId,
64
+ ...(lane.effective.model === undefined ? {} : { model: lane.effective.model }),
65
+ requestedAt: lane.updatedAt
66
+ }];
67
+ });
68
+ });
69
+ return [...workItemLanes, ...reviewLanes];
70
+ });
71
+ }
@@ -1,21 +1,19 @@
1
1
  import { selectedSchedulerRoles, selectedActiveSchedulerTasks } from "./ports.js";
2
2
  import { formatTaskRecordReference } from "../task/taskRecordReference.js";
3
- import { currentRoleRunProgressAt, DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS } from "./roleRunStall.js";
3
+ import { currentRoleTurnProgressAt, DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS } from "./roleTurnStall.js";
4
4
  /**
5
- * Lightweight liveness only. Host absence may fail a Run only before any
6
- * prompt bytes were pushed. After push, acceptance may be unknown even when
7
- * deliveredAt is absent; pane/process loss is therefore runtime-health
8
- * evidence, not an application-level outcome. The Run stays active so native
5
+ * Lightweight liveness only. Pane/process loss is runtime-health evidence,
6
+ * not an application-level outcome. The Turn stays active so native
9
7
  * child work or another observer can still contribute facts, while the stall
10
8
  * path raises bounded attention independently.
11
9
  * Process liveness is only a recovery signal. An absent pane/Host never proves
12
- * that the native Session or AgentRun ended; recover the same generation and
13
- * native identity when possible, otherwise preserve the active Run.
10
+ * that the native Session or Turn ended; recover the same generation and
11
+ * native identity when possible, otherwise preserve the active Turn.
14
12
  */
15
- export async function reconcileExitedRoleRuns(store, delivery, now, selection, excludedRunRefs = new Set(), liveStatuses, resourceEvidence, targetedInventory = selection !== undefined && !selection.full) {
13
+ export async function reconcileExitedRoleTurns(store, delivery, now, selection, excludedTurnRefs = new Set(), liveStatuses, resourceEvidence, targetedInventory = selection !== undefined && !selection.full) {
16
14
  const failed = [];
17
15
  const candidates = selectedActiveSchedulerTasks(store, selection).flatMap((task) => (selectedSchedulerRoles(store, task.id, selection).flatMap((role) => {
18
- const run = store.getActiveAgentRun(task.id, role.name);
16
+ const run = store.getActiveTurn(task.id, role.name);
19
17
  if (run === null)
20
18
  return [];
21
19
  const session = store.getRoleSession(task.id, role.name, run.effective.agentId);
@@ -29,8 +27,8 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
29
27
  roleName: role.name,
30
28
  agentId: run.effective.agentId,
31
29
  adapterId: run.effective.adapterId,
32
- runId: run.id,
33
- progressAt: run.deliveredAt ?? run.createdAt,
30
+ turnId: run.id,
31
+ progressAt: run.createdAt,
34
32
  ...(session?.launchId === undefined ? {} : { launchId: session.launchId }),
35
33
  ...(session?.nativeSessionId === undefined
36
34
  ? {}
@@ -40,10 +38,9 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
40
38
  })));
41
39
  if (candidates.length === 0)
42
40
  return failed;
43
- const eligible = candidates.filter(({ task, run }) => (!excludedRunRefs.has(formatTaskRecordReference(task.id, run.id, "agentRun"))
44
- && run.pushedAt === undefined));
41
+ const eligible = candidates.filter(({ task, run }) => (!excludedTurnRefs.has(formatTaskRecordReference(task.id, run.id, "turn"))));
45
42
  // Full reconciliation builds one complete provider inventory for every
46
- // active Run, including delivery-uncertain and completion-pending Runs.
43
+ // active Turn, including delivery-uncertain and completion-pending Turns.
47
44
  // The stall phase reuses that snapshot so one full pass never probes the
48
45
  // same pane twice. When targetedInventory is true, a dirty pass instead
49
46
  // uses exact probes below; stall reconciliation intentionally does not run
@@ -60,10 +57,10 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
60
57
  ? [{
61
58
  taskId: task.id,
62
59
  roleName: role.name,
63
- runId: run.id,
60
+ turnId: run.id,
64
61
  agentId: run.effective.agentId,
65
62
  adapterId: run.effective.adapterId,
66
- progressAt: currentRoleRunProgressAt(store, task.id, role.name, run).progressAt,
63
+ progressAt: currentRoleTurnProgressAt(store, task.id, role.name, run).progressAt,
67
64
  ...(session?.nativeSessionId === undefined
68
65
  ? {}
69
66
  : { nativeSessionId: session.nativeSessionId }),
@@ -79,7 +76,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
79
76
  for (const [key, resource] of batchSnapshot.resources) {
80
77
  const candidate = candidates.find(({ task, role }) => (`${task.id}\0${role.name}` === key));
81
78
  if (candidate !== undefined) {
82
- // Keep only the exact Run key. A task/role or bare-Run fallback can
79
+ // Keep only the exact Turn key. A task/role or bare-Turn fallback can
83
80
  // bridge an asynchronous sample from a prior generation.
84
81
  resourceEvidence.set(`${key}\0${candidate.run.id}`, resource);
85
82
  }
@@ -96,7 +93,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
96
93
  store.saveRoleHostExitObservation?.({
97
94
  taskId: task.id,
98
95
  roleName: role.name,
99
- runId: run.id,
96
+ turnId: run.id,
100
97
  ...(session?.launchId === undefined ? {} : { launchId: session.launchId }),
101
98
  ...(session?.nativeSessionId === undefined
102
99
  ? {}
@@ -113,7 +110,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
113
110
  delivery.forgetPrepared?.({
114
111
  taskId: task.id,
115
112
  roleName: role.name,
116
- runId: run.id
113
+ turnId: run.id
117
114
  });
118
115
  const recovered = await delivery.prepareRoleSession({
119
116
  taskId: task.id,
@@ -124,16 +121,16 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
124
121
  workspace: run.effective.workspace.root,
125
122
  ...(run.workspace === undefined ? {} : { managedWorkspace: run.workspace }),
126
123
  mode: "resume",
127
- runId: run.id,
124
+ turnId: run.id,
128
125
  nativeSessionId: session.nativeSessionId,
129
126
  ...(session.launchId === undefined
130
127
  ? {}
131
128
  : { hostActivationId: session.launchId })
132
129
  });
133
- store.saveRoleRunPrepared({
130
+ store.saveRoleTurnPrepared({
134
131
  task,
135
132
  role,
136
- run,
133
+ turn: run,
137
134
  session: recovered.session ?? session,
138
135
  ...(recovered.launchId === undefined ? {} : { launchId: recovered.launchId }),
139
136
  now
@@ -142,7 +139,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
142
139
  }
143
140
  catch {
144
141
  // Absence plus an inconclusive local recovery attempt is still not a
145
- // native Session death proof. Keep the exact Run active for the next
142
+ // native Session death proof. Keep the exact Turn active for the next
146
143
  // bounded recovery pass and expose the blocked axis separately.
147
144
  store.queueTaskProgress(task.id, "host-missing-native-resume-pending", now);
148
145
  }
@@ -201,11 +198,10 @@ function exactBatchInventory(batch, candidates) {
201
198
  function isResourceCandidate(task, run, now) {
202
199
  if (task.status !== "active"
203
200
  || task.executionGate.state !== "enabled"
204
- || run.status !== "active"
205
- || run.deliveredAt === undefined) {
201
+ || run.status !== "active") {
206
202
  return false;
207
203
  }
208
- const deliveredAt = Date.parse(run.deliveredAt);
209
- return Number.isFinite(deliveredAt)
210
- && now.getTime() - deliveredAt >= DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS;
204
+ const createdAt = Date.parse(run.createdAt);
205
+ return Number.isFinite(createdAt)
206
+ && now.getTime() - createdAt >= DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS;
211
207
  }