@zq-silk/yui 0.15.7 → 0.15.8

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 (281) hide show
  1. package/ARCHITECTURE.md +192 -399
  2. package/README.md +127 -1149
  3. package/dist/agent/adapterCatalog.js +15 -2
  4. package/dist/agent/agent.js +23 -3
  5. package/dist/agent/argumentPolicy.js +7 -1
  6. package/dist/agent/connectionPlan.js +62 -0
  7. package/dist/agent/executionComponents.js +158 -0
  8. package/dist/agent/launchEnvironment.js +31 -3
  9. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  10. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  11. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  12. package/dist/brief/taskBrief.js +12 -0
  13. package/dist/cli/agentConfigurationPicker.js +13 -0
  14. package/dist/cli/commandCatalog.js +157 -70
  15. package/dist/cli/interactionCandidates.js +5 -5
  16. package/dist/cli/interactionPolicy.js +38 -8
  17. package/dist/cli/invocationRouter.js +1 -1
  18. package/dist/cli/managedDiagnostics.js +28 -0
  19. package/dist/cli/operatorWizard.js +1 -7
  20. package/dist/cli/roleOptionOrder.js +27 -0
  21. package/dist/cli/roleWizard.js +50 -14
  22. package/dist/cli/updateOrchestrator.js +1 -1
  23. package/dist/cli/updatePorts.js +3 -4
  24. package/dist/cli.js +178 -95
  25. package/dist/commands/agentCommands.js +72 -14
  26. package/dist/commands/capabilityCommands.js +9 -6
  27. package/dist/commands/configCommands.js +20 -20
  28. package/dist/commands/deliveryGuardPreflight.js +2 -2
  29. package/dist/commands/executionAuditCommands.js +24 -24
  30. package/dist/commands/globalRoleCommands.js +1 -1
  31. package/dist/commands/grantCommands.js +4 -4
  32. package/dist/commands/operatorCommands.js +1 -7
  33. package/dist/commands/projectCommands.js +4 -4
  34. package/dist/commands/resourcesCommands.js +2 -2
  35. package/dist/commands/roleConfiguration.js +25 -5
  36. package/dist/commands/roleRuntimeGuard.js +4 -5
  37. package/dist/commands/sessionCommands.js +3 -7
  38. package/dist/commands/taskActivationCommands.js +259 -0
  39. package/dist/commands/taskActor.js +28 -49
  40. package/dist/commands/taskCommands.js +1188 -710
  41. package/dist/commands/taskContextCommand.js +39 -583
  42. package/dist/commands/taskExecutionCommands.js +32 -32
  43. package/dist/commands/taskInputCommands.js +40 -104
  44. package/dist/commands/taskIntegrationCommands.js +3 -2
  45. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  46. package/dist/commands/taskNextActionCommand.js +8 -8
  47. package/dist/commands/taskOverviewCommand.js +33 -45
  48. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  49. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  50. package/dist/commands/telemetryCommands.js +36 -38
  51. package/dist/config/configCatalog.js +4 -4
  52. package/dist/config/yuiConfig.js +8 -8
  53. package/dist/context/contextSnapshot.js +10 -10
  54. package/dist/context/dispatchContext.js +11 -11
  55. package/dist/context/roleSessionContext.js +6 -3
  56. package/dist/context/{turnContextPack.js → runContextPack.js} +146 -81
  57. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  58. package/dist/context/sessionBootstrapManifest.js +21 -2
  59. package/dist/context/sourceRunContext.js +30 -0
  60. package/dist/context/taskContext.js +458 -0
  61. package/dist/context/wakeNotification.js +27 -27
  62. package/dist/controller/agentRuntimeObserver.js +21 -24
  63. package/dist/controller/capabilityBridge.js +17 -6
  64. package/dist/controller/clientRuntime.js +65 -92
  65. package/dist/controller/controller.js +114 -188
  66. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  67. package/dist/controller/jobControl.js +54 -85
  68. package/dist/controller/resourceInventory.js +8 -27
  69. package/dist/controller/resourceInventoryLinux.js +12 -13
  70. package/dist/controller/runtime.js +529 -479
  71. package/dist/controller/runtimeEventInbox.js +55 -25
  72. package/dist/controller/runtimeEventProcessor.js +22 -31
  73. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  74. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  75. package/dist/controller/runtimeObservationHook.js +14 -18
  76. package/dist/controller/sessionNotify.js +16 -24
  77. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  78. package/dist/controller/structuredProviderObservation.js +138 -99
  79. package/dist/coordination/workMailbox.js +3 -3
  80. package/dist/coordination/workMailboxQueue.js +36 -33
  81. package/dist/core/boundedRpc.js +8 -1
  82. package/dist/core/controllerClient.js +20 -1
  83. package/dist/core/controllerServer.js +4 -4
  84. package/dist/doctor/doctor.js +13 -2
  85. package/dist/domain/agentResultTransport.js +9 -9
  86. package/dist/execution/codexThreadNaming.js +2 -8
  87. package/dist/execution/executionHealth.js +51 -63
  88. package/dist/execution/reviewMainRun.js +137 -0
  89. package/dist/execution/workItemExecution.js +28 -29
  90. package/dist/execution/workItemExecutionProjection.js +99 -107
  91. package/dist/execution/workItemMainRun.js +141 -0
  92. package/dist/executor/agentAdapter.js +227 -20
  93. package/dist/executor/agentConfigurationCatalog.js +126 -4
  94. package/dist/executor/agentConfigurationProbe.js +162 -4
  95. package/dist/executor/agentExecutor.js +79 -78
  96. package/dist/executor/effectiveLaunch.js +105 -18
  97. package/dist/executor/executorRegistry.js +29 -44
  98. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  99. package/dist/executor/workspacePreflightClassification.js +16 -16
  100. package/dist/grant/capabilityGrant.js +6 -3
  101. package/dist/input/inputRequest.js +12 -10
  102. package/dist/integration/gitIntegrationService.js +4 -11
  103. package/dist/integration/integrationQueueService.js +4 -4
  104. package/dist/interaction/operatorPresentation.js +1 -1
  105. package/dist/kernel/builtinCapabilities.js +247 -12
  106. package/dist/kernel/capabilityRegistry.js +64 -18
  107. package/dist/kernel/instanceHost.js +12 -1
  108. package/dist/kernel/kernelPorts.js +2 -2
  109. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  110. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  111. package/dist/message/message.js +62 -6
  112. package/dist/message/messageContinuation.js +204 -0
  113. package/dist/observability/executionAudit.js +70 -72
  114. package/dist/observability/faultClassification.js +2 -2
  115. package/dist/observability/orchestrationMetrics.js +8 -8
  116. package/dist/operator/operatorSessionHistory.js +1 -7
  117. package/dist/output/agentConfigurationPresentation.js +8 -3
  118. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  119. package/dist/output/rolePresentation.js +54 -3
  120. package/dist/plugins/pluginChild.js +104 -0
  121. package/dist/plugins/pluginIntent.js +26 -0
  122. package/dist/plugins/pluginInterpreter.js +43 -0
  123. package/dist/plugins/pluginPackage.js +101 -0
  124. package/dist/plugins/pluginProcess.js +112 -0
  125. package/dist/plugins/pluginService.js +380 -0
  126. package/dist/profile/agentProfile.js +1 -1
  127. package/dist/repository/gitWorkspace.js +26 -4
  128. package/dist/repository/project.js +19 -4
  129. package/dist/repository/taskBaseFreshness.js +13 -13
  130. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  131. package/dist/repository/taskWorkspacePreparer.js +344 -83
  132. package/dist/resources/autoResourceGc.js +3 -3
  133. package/dist/resources/liveReferences.js +3 -3
  134. package/dist/resources/projectResource.js +123 -0
  135. package/dist/resources/projectResourceService.js +421 -0
  136. package/dist/resources/resourceDiscovery.js +6 -6
  137. package/dist/resources/resourceGc.js +1 -1
  138. package/dist/resources/resourceRegistrar.js +1 -1
  139. package/dist/resources/resourceTypes.js +1 -1
  140. package/dist/review/deltaRecheck.js +3 -3
  141. package/dist/review/reviewAcceptance.js +16 -16
  142. package/dist/review/reviewDecision.js +7 -7
  143. package/dist/review/reviewRound.js +21 -20
  144. package/dist/review/reviewerAvailability.js +2 -2
  145. package/dist/role/role.js +51 -7
  146. package/dist/role/taskRoleUpdate.js +30 -0
  147. package/dist/runtime/acpProtocol.js +425 -0
  148. package/dist/runtime/acpSession.js +731 -0
  149. package/dist/runtime/acpSessionConfiguration.js +260 -0
  150. package/dist/runtime/agentDriver.js +30 -11
  151. package/dist/runtime/agentEndpoint.js +278 -0
  152. package/dist/runtime/agentEndpointIdentity.js +86 -0
  153. package/dist/runtime/agentEndpointOwnership.js +239 -0
  154. package/dist/runtime/agentError.js +2 -10
  155. package/dist/runtime/agentHost.js +565 -314
  156. package/dist/runtime/agentRunConfiguration.js +258 -0
  157. package/dist/runtime/builtinAgentDrivers.js +134 -18
  158. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  159. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  160. package/dist/runtime/claude-process-owner +0 -0
  161. package/dist/runtime/codexAppServerRuntime.js +38 -30
  162. package/dist/runtime/codexInteractiveHost.js +41 -6
  163. package/dist/runtime/continuationManager.js +2 -6
  164. package/dist/runtime/executionEnvironment.js +30 -0
  165. package/dist/runtime/firstProgressAdvisory.js +11 -11
  166. package/dist/runtime/index.js +4 -3
  167. package/dist/runtime/jsonLineChannel.js +109 -0
  168. package/dist/runtime/launchBroker.js +91 -16
  169. package/dist/runtime/launchDiagnostics.js +2 -2
  170. package/dist/runtime/lifecycleReservation.js +10 -18
  171. package/dist/runtime/managedCaller.js +61 -17
  172. package/dist/runtime/nativeSessionControl.js +102 -0
  173. package/dist/runtime/ports.js +6 -21
  174. package/dist/runtime/processExitObservation.js +8 -7
  175. package/dist/runtime/promptEnvelope.js +17 -6
  176. package/dist/runtime/providerContinuation.js +3 -9
  177. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  178. package/dist/runtime/providerControl.js +2 -7
  179. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  180. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  181. package/dist/runtime/runtimeBinding.js +0 -1
  182. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  183. package/dist/runtime/runtimeDeadlines.js +9 -0
  184. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  185. package/dist/runtime/runtimeObservation.js +29 -65
  186. package/dist/runtime/runtimeProjection.js +43 -51
  187. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  188. package/dist/runtime/sessionLaunchRequest.js +3 -7
  189. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  190. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  191. package/dist/runtime/sessionReconciliation.js +4 -8
  192. package/dist/runtime/sessionTerminationGuard.js +70 -259
  193. package/dist/runtime/sessionTokenMetrics.js +5 -16
  194. package/dist/runtime/structuredProviderHost.js +237 -117
  195. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  196. package/dist/runtime/tmuxAdapters.js +39 -86
  197. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  198. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  199. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  200. package/dist/scheduler/ports.js +80 -9
  201. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  202. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  203. package/dist/scheduler/taskExecutionProjection.js +120 -124
  204. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  205. package/dist/scheduler/taskWake.js +11 -4
  206. package/dist/scheduler/wakeReason.js +9 -1
  207. package/dist/setup/setupCommand.js +1 -0
  208. package/dist/storage/migrations/agentRunContract.js +159 -0
  209. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  210. package/dist/storage/sqliteSchema.js +431 -5
  211. package/dist/storage/sqliteStore.js +375 -220
  212. package/dist/storage/storageVersions.js +1 -1
  213. package/dist/storage/storeRpc.js +10 -5
  214. package/dist/storage/taskStore.js +13 -11
  215. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  216. package/dist/surface/surfaceContributions.js +102 -0
  217. package/dist/task/completionReadiness.js +32 -6
  218. package/dist/task/deliveryGuard.js +16 -16
  219. package/dist/task/draftPlan.js +72 -12
  220. package/dist/task/nextAction.js +144 -128
  221. package/dist/task/remoteDelivery.js +6 -6
  222. package/dist/task/task.js +184 -18
  223. package/dist/task/taskActivation.js +301 -0
  224. package/dist/task/taskActivationService.js +392 -0
  225. package/dist/task/taskRecordReference.js +5 -4
  226. package/dist/task/taskRecordRetirement.js +1 -1
  227. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  228. package/dist/telemetry/telemetryConfig.js +14 -14
  229. package/dist/telemetry/telemetryWiring.js +2 -2
  230. package/dist/web/assets/assetManifest.js +2 -0
  231. package/dist/web/assets/client/app.js +120 -20
  232. package/dist/web/assets/client/components.js +87 -54
  233. package/dist/web/assets/client/i18n.js +83 -41
  234. package/dist/web/assets/client/markdown.js +1 -1
  235. package/dist/web/assets/client/taskSurface.js +353 -0
  236. package/dist/web/assets/client/view.js +49 -44
  237. package/dist/web/assets/shell.js +1 -1
  238. package/dist/web/assets/styles/cards.js +22 -4
  239. package/dist/web/controllerWeb.js +60 -0
  240. package/dist/web/webMutation.js +28 -0
  241. package/dist/web/webServer.js +118 -8
  242. package/dist/web/webSnapshot.js +81 -74
  243. package/dist/web/webTaskSurface.js +64 -0
  244. package/dist/workItem/dependencyGate.js +1 -1
  245. package/dist/workItem/workItem.js +80 -48
  246. package/dist/workspace/workItemChangeSetManager.js +16 -9
  247. package/docs/agent-result-consumption.md +94 -0
  248. package/docs/agent-runtime-drivers.md +91 -0
  249. package/docs/architecture/README.md +38 -0
  250. package/docs/architecture/capabilities-and-resources.md +79 -0
  251. package/docs/managed-turn-and-session-runtime.md +222 -0
  252. package/docs/observability/README.md +81 -0
  253. package/docs/plugin-sdk.md +290 -0
  254. package/docs/provider-runtime.md +163 -0
  255. package/docs/release-workflow.md +303 -0
  256. package/docs/roles-and-configuration.md +113 -0
  257. package/docs/sqlite-control-plane-design.md +76 -0
  258. package/docs/task-dag-semantics.md +57 -0
  259. package/docs/task-delivery.md +103 -0
  260. package/docs/task-local-identity.md +6 -6
  261. package/docs/testing/verification-levels.md +86 -0
  262. package/i18n/README.zh-CN.md +98 -739
  263. package/package.json +2 -2
  264. package/skills/yui-leader/SKILL.md +130 -103
  265. package/skills/yui-leader/references/integration.md +39 -0
  266. package/skills/yui-leader/references/replicated-execution.md +42 -0
  267. package/skills/yui-leader/references/task-plugins.md +33 -0
  268. package/skills/yui-operator/SKILL.md +30 -59
  269. package/skills/yui-reviewer/SKILL.md +35 -36
  270. package/skills/yui-runtime/SKILL.md +88 -24
  271. package/skills/yui-runtime/references/publication.md +22 -0
  272. package/skills/yui-runtime/references/recovery.md +64 -0
  273. package/skills/yui-worker/SKILL.md +37 -39
  274. package/dist/cli/roleOptionCatalog.js +0 -68
  275. package/dist/context/sourceTurnContext.js +0 -30
  276. package/dist/execution/reviewMainTurn.js +0 -161
  277. package/dist/execution/workItemMainTurn.js +0 -164
  278. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  279. package/dist/runtime/preallocatedNativeSession.js +0 -13
  280. package/dist/runtime/runtimeStopReceipt.js +0 -42
  281. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -2,21 +2,21 @@ import { selectedSchedulerRoles, selectedActiveSchedulerTasks } from "./ports.js
2
2
  import { nextPendingBatch } from "../coordination/workMailbox.js";
3
3
  import { RUNTIME_DIAGNOSTIC_AFTER_MS, SEMANTIC_STALL_WINDOW_MS } from "../runtime/runtimeHealthPolicy.js";
4
4
  /**
5
- * Default window of no durable progress before a live-but-idle Turn becomes a
6
- * traceable needs-attention signal. It is deliberately long: a healthy Turn that
5
+ * Default window of no durable progress before a live-but-idle AgentRun becomes a
6
+ * traceable needs-attention signal. It is deliberately long: a healthy AgentRun that
7
7
  * is simply slow keeps its structured checkpoint fresh and never crosses it.
8
8
  */
9
9
  export const DEFAULT_STALL_WINDOW_MS = SEMANTIC_STALL_WINDOW_MS;
10
10
  /** Cheap workflow-stall candidate filter; the real threshold remains 30m. */
11
11
  export const DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS = RUNTIME_DIAGNOSTIC_AFTER_MS;
12
- export const TURN_PROGRESS_EVENT = "turn.progress";
13
- export const TURN_STALLED_EVENT = "turn.stalled";
14
- export const TURN_RECOVERED_EVENT = "turn.recovered";
15
- export const TURN_DIAGNOSTIC_FINISHED_EVENT = "runtime.diagnostic-finished";
12
+ export const RUN_PROGRESS_EVENT = "run.progress";
13
+ export const RUN_STALLED_EVENT = "run.stalled";
14
+ export const RUN_RECOVERED_EVENT = "run.recovered";
15
+ export const RUN_DIAGNOSTIC_FINISHED_EVENT = "runtime.diagnostic-finished";
16
16
  /** Structured, non-Message recovery evidence written by an explicit Leader. */
17
17
  /** Workflow-semantic events that count for the durable progress clock. */
18
18
  const ACTIVITY_EVENT_TYPES = new Set([
19
- TURN_PROGRESS_EVENT,
19
+ RUN_PROGRESS_EVENT,
20
20
  "message.sent",
21
21
  "input.answered",
22
22
  "input.auto-answered",
@@ -31,17 +31,17 @@ const ACTIVITY_EVENT_TYPES = new Set([
31
31
  ]);
32
32
  /**
33
33
  * One pure projection used by every Role. Resource activity is retained only
34
- * as exact-generation diagnostic evidence; it never changes the durable
34
+ * as exact-Session diagnostic evidence; it never changes the durable
35
35
  * progress clock, suppresses workflow attention, or authorizes recovery.
36
36
  */
37
- export function projectRoleTurnHealth(input) {
37
+ export function projectRoleRunHealth(input) {
38
38
  const windowMs = input.windowMs ?? DEFAULT_STALL_WINDOW_MS;
39
39
  const diagnosticAfterMs = input.diagnosticAfterMs
40
40
  ?? DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS;
41
41
  if (!Number.isFinite(windowMs) || windowMs <= 0) {
42
- throw new Error("Role Turn stall window must be a positive number of milliseconds.");
42
+ throw new Error("Role AgentRun stall window must be a positive number of milliseconds.");
43
43
  }
44
- const evaluation = evaluateRoleTurnStall({
44
+ const evaluation = evaluateRoleRunStall({
45
45
  progressAt: input.progressAt,
46
46
  now: input.now,
47
47
  windowMs
@@ -58,7 +58,6 @@ export function projectRoleTurnHealth(input) {
58
58
  : session.status === "ended"
59
59
  ? session.endReason === "failed" ? "broken" : "stopped"
60
60
  : !hasResourceIdentityText(session.nativeSessionId)
61
- && !hasResourceIdentityText(session.runtimeGenerationId)
62
61
  ? "unknown"
63
62
  : "matching";
64
63
  const resourceActivity = hostLiveness === "present"
@@ -107,16 +106,16 @@ export function projectRoleTurnHealth(input) {
107
106
  /**
108
107
  * Pure stall decision. Given the last durable progress timestamp and whatever
109
108
  * progress point the previous attention (if any) recorded, decide whether the
110
- * Turn is stalled and whether this is new evidence worth surfacing again.
109
+ * AgentRun is stalled and whether this is new evidence worth surfacing again.
111
110
  */
112
- export function evaluateRoleTurnStall(input) {
111
+ export function evaluateRoleRunStall(input) {
113
112
  const windowMs = input.windowMs ?? DEFAULT_STALL_WINDOW_MS;
114
113
  if (!Number.isFinite(windowMs) || windowMs <= 0) {
115
- throw new Error("Role Turn stall window must be a positive number of milliseconds.");
114
+ throw new Error("Role AgentRun stall window must be a positive number of milliseconds.");
116
115
  }
117
116
  const progressMs = Date.parse(input.progressAt);
118
117
  if (!Number.isFinite(progressMs)) {
119
- throw new Error("Role Turn stall progress timestamp is invalid.");
118
+ throw new Error("Role AgentRun stall progress timestamp is invalid.");
120
119
  }
121
120
  const idleMs = input.now.getTime() - progressMs;
122
121
  const stalled = idleMs >= windowMs;
@@ -124,7 +123,7 @@ export function evaluateRoleTurnStall(input) {
124
123
  return { stalled, isNewEpisode, idleMs, progressAt: input.progressAt };
125
124
  }
126
125
  /**
127
- * Latest durable progress timestamp for an active Turn. Turn creation,
126
+ * Latest durable progress timestamp for an active AgentRun. AgentRun creation,
128
127
  * explicit workflow checkpoints, and semantic domain activity count as
129
128
  * progress. Provider operations, tokens, CPU/memory and bookkeeping are
130
129
  * intentionally excluded.
@@ -136,17 +135,17 @@ export function latestDurableProgressAt(input) {
136
135
  input.latestActivityAt
137
136
  ].filter((value) => (typeof value === "string" && Number.isFinite(Date.parse(value))));
138
137
  if (candidates.length === 0) {
139
- throw new Error("No durable progress timestamp is available for the Turn.");
138
+ throw new Error("No durable progress timestamp is available for the AgentRun.");
140
139
  }
141
140
  return candidates.reduce((latest, value) => (Date.parse(value) > Date.parse(latest) ? value : latest));
142
141
  }
143
- /** Most recent semantic timestamp carried by a Turn progress event. */
144
- export function latestTurnProgressAt(events, turnId) {
142
+ /** Most recent semantic timestamp carried by a AgentRun progress event. */
143
+ export function latestRunProgressAt(events, runId) {
145
144
  let latest;
146
145
  for (const event of events) {
147
- if (event.type !== TURN_PROGRESS_EVENT)
146
+ if (event.type !== RUN_PROGRESS_EVENT)
148
147
  continue;
149
- if (event.payload.turnId !== turnId)
148
+ if (event.payload.runId !== runId)
150
149
  continue;
151
150
  const progressAt = typeof event.payload.progressAt === "string"
152
151
  && Number.isFinite(Date.parse(event.payload.progressAt))
@@ -163,11 +162,11 @@ export function latestTurnProgressAt(events, turnId) {
163
162
  }
164
163
  /**
165
164
  * Resolve the exact semantic progress fence shared by resource production and
166
- * stall consumption for one active Turn. Resource evidence carries this value
165
+ * stall consumption for one active AgentRun. Resource evidence carries this value
167
166
  * as an exact fence, but never advances it.
168
167
  */
169
- export function currentRoleTurnProgressAt(store, taskId, roleName, run) {
170
- const progress = store.getTurnDurableProgress(taskId, roleName, run.id);
168
+ export function currentRoleRunProgressAt(store, taskId, roleName, run) {
169
+ const progress = store.getRunDurableProgress(taskId, roleName, run.id);
171
170
  if (progress !== null) {
172
171
  return {
173
172
  progressAt: progress.progressAt,
@@ -179,12 +178,12 @@ export function currentRoleTurnProgressAt(store, taskId, roleName, run) {
179
178
  return { progressAt: run.createdAt };
180
179
  }
181
180
  /**
182
- * Computes the current semantic progress fence for an exact Turn. The optional
183
- * related-record readers add Work/Review/Integration evidence to the Turn and
181
+ * Computes the current semantic progress fence for an exact AgentRun. The optional
182
+ * related-record readers add Work/Review/Integration evidence to the AgentRun and
184
183
  * event facts used by on-demand projections.
185
184
  */
186
- export function latestTurnDurableProgressAt(store, taskId, roleName, turnId, precomputed) {
187
- const run = store.getTurn(taskId, turnId);
185
+ export function latestRunDurableProgressAt(store, taskId, roleName, runId, precomputed) {
186
+ const run = store.getRun(taskId, runId);
188
187
  if (run === null || run.taskId !== taskId || run.roleName !== roleName)
189
188
  return null;
190
189
  // Scheduler reconciliation supplies its once-per-revision fold; on-demand
@@ -193,10 +192,10 @@ export function latestTurnDurableProgressAt(store, taskId, roleName, turnId, pre
193
192
  const events = folded ? undefined : store.listEvents(taskId);
194
193
  const latestCheckpointAt = folded
195
194
  ? precomputed.latestCheckpointAt
196
- : latestTurnProgressAt(events, run.id);
195
+ : latestRunProgressAt(events, run.id);
197
196
  const latestActivityAt = folded
198
197
  ? precomputed.latestActivityAt
199
- : latestTurnActivityAt(events, run.id);
198
+ : latestRunActivityAt(events, run.id);
200
199
  const baseline = latestDurableProgressAt({
201
200
  startedAt: run.createdAt,
202
201
  latestCheckpointAt,
@@ -216,8 +215,8 @@ export function latestTurnDurableProgressAt(store, taskId, roleName, turnId, pre
216
215
  .filter(({ source }) => (source.kind === "work-item" && source.workItemId === run.workItemId))
217
216
  ?? [];
218
217
  const inputProgress = store.listInputRequests?.(taskId)
219
- .filter((request) => (request.requester.turnId === run.id
220
- || request.blockedRefs.some((ref) => ref.type === "turn" && ref.id === run.id)))
218
+ .filter((request) => (request.requester.runId === run.id
219
+ || request.blockedRefs.some((ref) => ref.type === "run" && ref.id === run.id)))
221
220
  ?? [];
222
221
  const related = [
223
222
  workItem?.updatedAt,
@@ -238,11 +237,11 @@ export function latestTurnDurableProgressAt(store, taskId, roleName, turnId, pre
238
237
  ...(latestRelatedAt === undefined ? {} : { evidence: "work-review-integration" })
239
238
  };
240
239
  }
241
- /** Most recent createdAt of a Turn-scoped event of one type, if any. */
242
- export function latestTurnEventTime(events, type, turnId) {
240
+ /** Most recent createdAt of a AgentRun-scoped event of one type, if any. */
241
+ export function latestRunEventTime(events, type, runId) {
243
242
  let latest;
244
243
  for (const event of events) {
245
- if (event.type !== type || event.payload.turnId !== turnId)
244
+ if (event.type !== type || event.payload.runId !== runId)
246
245
  continue;
247
246
  if (latest === undefined || Date.parse(event.createdAt) > Date.parse(latest)) {
248
247
  latest = event.createdAt;
@@ -250,16 +249,16 @@ export function latestTurnEventTime(events, type, turnId) {
250
249
  }
251
250
  return latest;
252
251
  }
253
- /** Most recent non-control event carrying a Turn identity. */
254
- export function latestTurnActivityAt(events, turnId) {
252
+ /** Most recent non-control event carrying a AgentRun identity. */
253
+ export function latestRunActivityAt(events, runId) {
255
254
  let latest;
256
255
  for (const event of events) {
257
256
  if (!ACTIVITY_EVENT_TYPES.has(event.type)
258
- || event.payload.turnId !== turnId
259
- || event.type === TURN_STALLED_EVENT
260
- || event.type === TURN_RECOVERED_EVENT)
257
+ || event.payload.runId !== runId
258
+ || event.type === RUN_STALLED_EVENT
259
+ || event.type === RUN_RECOVERED_EVENT)
261
260
  continue;
262
- const activityAt = event.type === TURN_PROGRESS_EVENT
261
+ const activityAt = event.type === RUN_PROGRESS_EVENT
263
262
  && typeof event.payload.progressAt === "string"
264
263
  && Number.isFinite(Date.parse(event.payload.progressAt))
265
264
  ? event.payload.progressAt
@@ -270,11 +269,11 @@ export function latestTurnActivityAt(events, turnId) {
270
269
  }
271
270
  return latest;
272
271
  }
273
- /** The progress point recorded by the most recent stall attention for a Turn. */
274
- export function latestStallProgressAt(events, turnId) {
272
+ /** The progress point recorded by the most recent stall attention for a AgentRun. */
273
+ export function latestStallProgressAt(events, runId) {
275
274
  let latest;
276
275
  for (const event of events) {
277
- if (event.type !== TURN_STALLED_EVENT || event.payload.turnId !== turnId)
276
+ if (event.type !== RUN_STALLED_EVENT || event.payload.runId !== runId)
278
277
  continue;
279
278
  if (latest === undefined || Date.parse(event.createdAt) > Date.parse(latest.createdAt)) {
280
279
  latest = event;
@@ -283,10 +282,10 @@ export function latestStallProgressAt(events, turnId) {
283
282
  return latest?.payload.progressAt;
284
283
  }
285
284
  /** Latest stall episode identity used for source-idempotent attention. */
286
- export function latestStallEvidenceKey(events, turnId) {
285
+ export function latestStallEvidenceKey(events, runId) {
287
286
  let latest;
288
287
  for (const event of events) {
289
- if (event.type !== TURN_STALLED_EVENT || event.payload.turnId !== turnId)
288
+ if (event.type !== RUN_STALLED_EVENT || event.payload.runId !== runId)
290
289
  continue;
291
290
  if (latest === undefined || Date.parse(event.createdAt) > Date.parse(latest.createdAt)) {
292
291
  latest = event;
@@ -300,27 +299,27 @@ export function latestStallEvidenceKey(events, turnId) {
300
299
  };
301
300
  }
302
301
  /**
303
- * Folds a Task's event history into per-Turn progress facts in one O(events)
302
+ * Folds a Task's event history into per-AgentRun progress facts in one O(events)
304
303
  * pass. The adapter builds this once per durable revision and serves the
305
304
  * stall reconciliation from it, replacing the per-candidate full-history
306
305
  * clones and scans that turned one pass into an O(candidates x events) hot
307
306
  * read. The fold mirrors latestTurnProgressAt/latestTurnActivityAt/
308
307
  * latestStallProgressAt/latestStallEvidenceKey exactly.
309
308
  */
310
- export function foldTurnProgressFacts(events) {
311
- const byTurn = new Map();
309
+ export function foldRunProgressFacts(events) {
310
+ const byRun = new Map();
312
311
  const latestStallCreatedAt = new Map();
313
312
  for (const event of events) {
314
- const turnId = event.payload.turnId;
315
- if (typeof turnId !== "string")
313
+ const runId = event.payload.runId;
314
+ if (typeof runId !== "string")
316
315
  continue;
317
- let facts = byTurn.get(turnId);
316
+ let facts = byRun.get(runId);
318
317
  if (facts === undefined) {
319
318
  facts = {};
320
- byTurn.set(turnId, facts);
319
+ byRun.set(runId, facts);
321
320
  }
322
321
  const type = event.type;
323
- const isProgress = type === TURN_PROGRESS_EVENT;
322
+ const isProgress = type === RUN_PROGRESS_EVENT;
324
323
  if (isProgress) {
325
324
  const validProgress = typeof event.payload.progressAt === "string"
326
325
  && Number.isFinite(Date.parse(event.payload.progressAt));
@@ -337,11 +336,11 @@ export function foldTurnProgressFacts(events) {
337
336
  facts.latestActivityAt = progressAt;
338
337
  }
339
338
  }
340
- else if (type === TURN_STALLED_EVENT) {
341
- const previousCreatedAt = latestStallCreatedAt.get(turnId);
339
+ else if (type === RUN_STALLED_EVENT) {
340
+ const previousCreatedAt = latestStallCreatedAt.get(runId);
342
341
  if (previousCreatedAt === undefined
343
342
  || Date.parse(event.createdAt) > Date.parse(previousCreatedAt)) {
344
- latestStallCreatedAt.set(turnId, event.createdAt);
343
+ latestStallCreatedAt.set(runId, event.createdAt);
345
344
  facts.latestStall = typeof event.payload.progressAt === "string"
346
345
  ? {
347
346
  progressAt: event.payload.progressAt,
@@ -353,33 +352,33 @@ export function foldTurnProgressFacts(events) {
353
352
  }
354
353
  }
355
354
  else if (ACTIVITY_EVENT_TYPES.has(type)
356
- && type !== TURN_STALLED_EVENT
357
- && type !== TURN_RECOVERED_EVENT) {
355
+ && type !== RUN_STALLED_EVENT
356
+ && type !== RUN_RECOVERED_EVENT) {
358
357
  if (facts.latestActivityAt === undefined
359
358
  || Date.parse(event.createdAt) > Date.parse(facts.latestActivityAt)) {
360
359
  facts.latestActivityAt = event.createdAt;
361
360
  }
362
361
  }
363
362
  }
364
- return byTurn;
363
+ return byRun;
365
364
  }
366
365
  /** Yield the event loop so already-written control requests stay responsive. */
367
366
  function yieldEventLoop() {
368
367
  return new Promise((resolve) => setImmediate(resolve));
369
368
  }
370
369
  /**
371
- * True while a Turn remains in an unresolved stall episode: a stall was raised
370
+ * True while a AgentRun remains in an unresolved stall episode: a stall was raised
372
371
  * and no later checkpoint has advanced its durable progress since. This is the
373
372
  * projection the runtime-health view reads to surface needs-attention.
374
373
  */
375
- export function isRoleTurnStalled(events, turnId) {
374
+ export function isRoleRunStalled(events, runId) {
376
375
  let stalled;
377
376
  let recoveredAt;
378
377
  let progressAt;
379
378
  for (const event of events) {
380
- if (event.payload.turnId !== turnId)
379
+ if (event.payload.runId !== runId)
381
380
  continue;
382
- if (event.type === TURN_STALLED_EVENT) {
381
+ if (event.type === RUN_STALLED_EVENT) {
383
382
  if (event.payload.status === "diagnostic-only")
384
383
  continue;
385
384
  if (stalled === undefined
@@ -388,14 +387,14 @@ export function isRoleTurnStalled(events, turnId) {
388
387
  }
389
388
  continue;
390
389
  }
391
- if (event.type === TURN_RECOVERED_EVENT) {
390
+ if (event.type === RUN_RECOVERED_EVENT) {
392
391
  if (recoveredAt === undefined
393
392
  || Date.parse(event.createdAt) > Date.parse(recoveredAt)) {
394
393
  recoveredAt = event.createdAt;
395
394
  }
396
395
  continue;
397
396
  }
398
- if (event.type !== TURN_PROGRESS_EVENT)
397
+ if (event.type !== RUN_PROGRESS_EVENT)
399
398
  continue;
400
399
  const candidate = typeof event.payload.progressAt === "string"
401
400
  && Number.isFinite(Date.parse(event.payload.progressAt))
@@ -418,26 +417,30 @@ export function isRoleTurnStalled(events, turnId) {
418
417
  return progressAt === undefined || Date.parse(progressAt) <= Date.parse(stalledProgressAt);
419
418
  }
420
419
  /**
421
- * Low-frequency health pass for active Task Role Turns. An unaccepted Turn is
420
+ * Low-frequency health pass for active Task Role AgentRuns. An unaccepted AgentRun is
422
421
  * watched as delivery-stalled after the reasonable delivery window; an
423
- * accepted Turn is displayed as checkpoint-overdue after fifteen minutes, but
422
+ * accepted AgentRun is displayed as checkpoint-overdue after fifteen minutes, but
424
423
  * this scheduler performs no runtime inspection until the thirty-minute
425
424
  * diagnostic window is due.
426
- * Leader Turns are only persisted when classification reaches truly-stalled —
425
+ * Leader AgentRuns are only persisted when classification reaches truly-stalled —
427
426
  * healthy downstream work, open user input, and recent own progress remain
428
427
  * structured waiting/working facts. No branch sends terminal bytes, retries,
429
- * replaces a Session, or changes Turn status.
428
+ * replaces a Session, or changes AgentRun status.
430
429
  */
431
- export async function reconcileStalledRoleTurns(store, delivery, now, selection, windowMs = DEFAULT_STALL_WINDOW_MS, liveStatuses, resourceEvidence, diagnosticAfterMs = DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS) {
430
+ export async function reconcileStalledRoleRuns(store, delivery, now, selection, windowMs = DEFAULT_STALL_WINDOW_MS, liveStatuses, resourceEvidence, diagnosticAfterMs = DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS) {
432
431
  // Dirty mailbox passes are intentionally not a second scheduler. Full
433
- // reconcile owns the all-active-Turn scan; dirty passes may still route the
432
+ // reconcile owns the all-active-AgentRun scan; dirty passes may still route the
434
433
  // existing mailbox work without manufacturing another episode.
435
434
  if (selection !== undefined && !selection.full)
436
435
  return [];
437
- if (store.recordRoleTurnStall === undefined)
436
+ if (store.recordRoleRunStall === undefined)
438
437
  return [];
439
- const candidates = selectedActiveSchedulerTasks(store, selection).flatMap((task) => (selectedSchedulerRoles(store, task.id, selection).flatMap((role) => {
440
- const run = store.getActiveTurn(task.id, role.name);
438
+ // A Draft planning Turn can stall exactly like any other admitted Turn, so it
439
+ // is selected here too; the episode stays diagnostic-only either way.
440
+ const candidates = selectedActiveSchedulerTasks(store, selection, {
441
+ includePlanningDrafts: true
442
+ }).flatMap((task) => (selectedSchedulerRoles(store, task.id, selection).flatMap((role) => {
443
+ const run = store.getActiveRun(task.id, role.name);
441
444
  if (run === null || run.status !== "active")
442
445
  return [];
443
446
  return [{
@@ -456,20 +459,20 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
456
459
  eventsByTask.set(taskId, events);
457
460
  return events;
458
461
  };
459
- const cadenceCandidates = candidates.filter(({ task, run }) => isStallCandidate(run, now, windowMs, latestTurnEventTime(diagnosticEvents(task.id), TURN_DIAGNOSTIC_FINISHED_EVENT, run.id)));
462
+ const cadenceCandidates = candidates.filter(({ task, run }) => isStallCandidate(run, now, windowMs, latestRunEventTime(diagnosticEvents(task.id), RUN_DIAGNOSTIC_FINISHED_EVENT, run.id)));
460
463
  const stallCandidates = cadenceCandidates.filter(({ task, role, run }) => {
461
- const progressAt = currentRoleTurnProgressAt(store, task.id, role.name, run).progressAt;
462
- return isStallCandidate(run, now, windowMs, latestTurnEventTime(diagnosticEvents(task.id), TURN_DIAGNOSTIC_FINISHED_EVENT, run.id), progressAt);
464
+ const progressAt = currentRoleRunProgressAt(store, task.id, role.name, run).progressAt;
465
+ return isStallCandidate(run, now, windowMs, latestRunEventTime(diagnosticEvents(task.id), RUN_DIAGNOSTIC_FINISHED_EVENT, run.id), progressAt);
463
466
  });
464
467
  if (stallCandidates.length === 0)
465
468
  return [];
466
469
  const diagnosticStartedAt = now.toISOString();
467
470
  const finishDiagnostics = (outcome) => {
468
471
  for (const { task, role, run } of stallCandidates) {
469
- store.recordRoleTurnDiagnostic?.({
472
+ store.recordRoleRunDiagnostic?.({
470
473
  taskId: task.id,
471
474
  roleName: role.name,
472
- turnId: run.id,
475
+ runId: run.id,
473
476
  startedAt: diagnosticStartedAt,
474
477
  outcome,
475
478
  now
@@ -478,7 +481,7 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
478
481
  };
479
482
  const stallCandidateKeys = new Set(stallCandidates.map(({ task, role }) => (`${task.id}\0${role.name}`)));
480
483
  const observed = new Map();
481
- // Recent active Turns are known healthy enough for Leader classification from
484
+ // Recent active AgentRuns are known healthy enough for Leader classification from
482
485
  // their exact acceptance/creation boundary, but are deliberately not read
483
486
  // from tmux or Event history until the 30-minute diagnostic window.
484
487
  for (const candidate of candidates) {
@@ -504,22 +507,20 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
504
507
  statuses = await delivery.inspectRoles(stallCandidates.map(({ task, role, run, session }) => ({
505
508
  taskId: task.id,
506
509
  roleName: role.name,
507
- turnId: run.id,
510
+ runId: run.id,
508
511
  progressAt: run.createdAt,
509
512
  agentId: session?.agentId ?? run.effective.agentId,
510
513
  adapterId: session?.adapterId ?? run.effective.adapterId,
511
- ...(session?.runtimeGenerationId === undefined ? {} : { runtimeGenerationId: session.runtimeGenerationId }),
512
514
  ...(session?.nativeSessionId === undefined
513
515
  ? {}
514
516
  : { nativeSessionId: session.nativeSessionId })
515
517
  })), stallCandidates.map(({ task, role, run, session }) => ({
516
518
  taskId: task.id,
517
519
  roleName: role.name,
518
- turnId: run.id,
519
- progressAt: currentRoleTurnProgressAt(store, task.id, role.name, run).progressAt,
520
+ runId: run.id,
521
+ progressAt: currentRoleRunProgressAt(store, task.id, role.name, run).progressAt,
520
522
  agentId: session?.agentId ?? run.effective.agentId,
521
523
  adapterId: session?.adapterId ?? run.effective.adapterId,
522
- ...(session?.runtimeGenerationId === undefined ? {} : { runtimeGenerationId: session.runtimeGenerationId }),
523
524
  ...(session?.nativeSessionId === undefined
524
525
  ? {}
525
526
  : { nativeSessionId: session.nativeSessionId })
@@ -527,7 +528,7 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
527
528
  }
528
529
  catch {
529
530
  // Health inspection is advisory. Unknown host state must leave the exact
530
- // Turn/Session fence untouched. Closing this window schedules the next
531
+ // AgentRun/Session fence untouched. Closing this window schedules the next
531
532
  // bounded diagnostic thirty minutes later instead of hot-looping.
532
533
  finishDiagnostics("observation-error");
533
534
  return [];
@@ -574,7 +575,7 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
574
575
  : byRole.get(key);
575
576
  }
576
577
  catch {
577
- // Without a complete live snapshot, especially for downstream Turns,
578
+ // Without a complete live snapshot, especially for downstream AgentRuns,
578
579
  // Leader classification would be unsafe. Treat the whole advisory pass
579
580
  // as unknown instead of escalating a false stall.
580
581
  finishDiagnostics("observation-error");
@@ -594,12 +595,12 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
594
595
  });
595
596
  continue;
596
597
  }
597
- const progressFacts = store.getTurnProgressFacts(candidate.task.id, candidate.run.id);
598
- // The Turn creation boundary starts the execution clock; durable workflow
598
+ const progressFacts = store.getRunProgressFacts(candidate.task.id, candidate.run.id);
599
+ // The AgentRun creation boundary starts the execution clock; durable workflow
599
600
  // facts may advance it independently of Provider transport observations.
600
- const progress = currentRoleTurnProgressAt(store, candidate.task.id, candidate.role.name, candidate.run);
601
+ const progress = currentRoleRunProgressAt(store, candidate.task.id, candidate.role.name, candidate.run);
601
602
  const progressAt = progress.progressAt;
602
- const evaluation = evaluateRoleTurnStall({
603
+ const evaluation = evaluateRoleRunStall({
603
604
  progressAt,
604
605
  now,
605
606
  windowMs,
@@ -617,15 +618,12 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
617
618
  : {
618
619
  taskId: candidate.task.id,
619
620
  roleName: candidate.role.name,
620
- turnId: candidate.run.id,
621
+ runId: candidate.run.id,
621
622
  agentId: runAgentId,
622
623
  adapterId: runAdapterId,
623
624
  ...(candidate.session.nativeSessionId === undefined
624
625
  ? {}
625
626
  : { nativeSessionId: candidate.session.nativeSessionId }),
626
- ...(candidate.session.runtimeGenerationId === undefined
627
- ? {}
628
- : { runtimeGenerationId: candidate.session.runtimeGenerationId })
629
627
  };
630
628
  const resourceSnapshot = resourceForRun(resourceEvidence, candidate.task.id, candidate.role.name, candidate.run.id);
631
629
  const resourceIsCurrent = live === "present"
@@ -635,7 +633,7 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
635
633
  && resourceEvidenceMatchesCurrentRun(resourceSnapshot, expectedResourceIdentity, progressAt)
636
634
  && resourceEvidenceIsFresh(resourceSnapshot, now, windowMs, diagnosticAfterMs);
637
635
  const resource = resourceIsCurrent ? resourceSnapshot : undefined;
638
- const health = projectRoleTurnHealth({
636
+ const health = projectRoleRunHealth({
639
637
  progressAt,
640
638
  createdAt: candidate.run.createdAt,
641
639
  now,
@@ -647,8 +645,8 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
647
645
  resource,
648
646
  roleName: candidate.role.name
649
647
  });
650
- // Delivery-stalled Turns retain the existing delivery clock and immediate
651
- // Provider-uncertainty path. Accepted execution Turns use the shared
648
+ // Delivery-stalled AgentRuns retain the existing delivery clock and immediate
649
+ // Provider-uncertainty path. Accepted execution AgentRuns use the shared
652
650
  // projection. Exact Session/host resource evidence remains diagnostic.
653
651
  const resourceActivity = health.resourceActivity;
654
652
  const stalled = health.stalled && sessionMatchesRun && sessionUsable;
@@ -672,16 +670,16 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
672
670
  if (current.live !== "present" || !current.stalled || !current.stallCandidate)
673
671
  continue;
674
672
  const { candidate, progressAt } = current;
675
- const previous = store.getTurnProgressFacts(candidate.task.id, candidate.run.id)?.latestStall;
673
+ const previous = store.getRunProgressFacts(candidate.task.id, candidate.run.id)?.latestStall;
676
674
  if (previous !== undefined
677
675
  && Date.parse(progressAt) > Date.parse(previous.progressAt)) {
678
676
  // A new semantic progress point closes the previous episode first. It
679
677
  // may itself already be older than the window, in which case the same
680
- // pass records the next Turn+progressAt episode below.
681
- store.recordRoleTurnProgress?.({
678
+ // pass records the next AgentRun+progressAt episode below.
679
+ store.recordRoleRunProgress?.({
682
680
  taskId: candidate.task.id,
683
681
  roleName: candidate.role.name,
684
- turnId: candidate.run.id,
682
+ runId: candidate.run.id,
685
683
  progressAt,
686
684
  ...(current.evidence === undefined ? {} : { evidence: current.evidence }),
687
685
  now
@@ -706,15 +704,15 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
706
704
  : []),
707
705
  ...(current.evidence === undefined ? [] : [current.evidence])
708
706
  ].join(":");
709
- // The final contract is one episode per Turn + semantic progress point.
707
+ // The final contract is one episode per AgentRun + semantic progress point.
710
708
  // New role/session/provider evidence is retained in the Leader's next
711
709
  // diagnostic context, not duplicated as another Task-level alert.
712
710
  if (previous?.progressAt === progressAt)
713
711
  continue;
714
- const persisted = store.recordRoleTurnStall({
712
+ const persisted = store.recordRoleRunStall({
715
713
  taskId: candidate.task.id,
716
714
  roleName: candidate.role.name,
717
- turnId: candidate.run.id,
715
+ runId: candidate.run.id,
718
716
  agentId: candidate.run.effective.agentId,
719
717
  adapterId: candidate.run.effective.adapterId,
720
718
  session: candidate.session,
@@ -729,7 +727,7 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
729
727
  raised.push({
730
728
  taskId: candidate.task.id,
731
729
  roleName: candidate.role.name,
732
- turnId: candidate.run.id,
730
+ runId: candidate.run.id,
733
731
  status: persisted,
734
732
  kind,
735
733
  classification,
@@ -738,19 +736,19 @@ export async function reconcileStalledRoleTurns(store, delivery, now, selection,
738
736
  }
739
737
  }
740
738
  // A related WorkItem/Review/Integration fold may advance progress without
741
- // carrying the Turn id. Materialize it once so context/web can clear the
739
+ // carrying the AgentRun id. Materialize it once so context/web can clear the
742
740
  // attention projection and the event history records the recovery boundary.
743
741
  for (const current of observed.values()) {
744
742
  if (current.live !== "present" || current.stalled || !current.stallCandidate)
745
743
  continue;
746
744
  const { candidate, progressAt } = current;
747
- const previous = store.getTurnProgressFacts(candidate.task.id, candidate.run.id)?.latestStall;
745
+ const previous = store.getRunProgressFacts(candidate.task.id, candidate.run.id)?.latestStall;
748
746
  if (previous !== undefined
749
747
  && Date.parse(progressAt) > Date.parse(previous.progressAt)) {
750
- store.recordRoleTurnProgress?.({
748
+ store.recordRoleRunProgress?.({
751
749
  taskId: candidate.task.id,
752
750
  roleName: candidate.role.name,
753
- turnId: candidate.run.id,
751
+ runId: candidate.run.id,
754
752
  progressAt,
755
753
  ...(current.evidence === undefined ? {} : { evidence: current.evidence }),
756
754
  now
@@ -773,7 +771,7 @@ function classifyLeaderStall(store, taskId, observed, now, windowMs) {
773
771
  if (store.hasOpenInputRequest(taskId))
774
772
  return "waiting-user";
775
773
  const downstream = [...observed.values()].filter((entry) => (entry.candidate.task.id === taskId && entry.candidate.role.name !== "leader"));
776
- // A present downstream Turn keeps recovery Leader-owned. If that Turn is
774
+ // A present downstream AgentRun keeps recovery Leader-owned. If that AgentRun is
777
775
  // itself stalled, this pass has just routed its structured attention to the
778
776
  // Leader; escalating the Leader to the Operator in the same pass would skip
779
777
  // the intended recovery owner.
@@ -782,13 +780,13 @@ function classifyLeaderStall(store, taskId, observed, now, windowMs) {
782
780
  const mailbox = store.getWorkMailbox({ kind: "role", taskId, roleName: "leader" });
783
781
  const pending = mailbox === null || mailbox === undefined ? null : nextPendingBatch(mailbox);
784
782
  const processing = mailbox?.processing;
785
- const processingCurrent = processing?.executionRef?.type === "turn"
783
+ const processingCurrent = processing?.executionRef?.type === "run"
786
784
  && processing.executionRef.taskId === taskId
787
785
  && leader !== undefined
788
786
  && processing.executionRef.id === leader.candidate.run.id;
789
- const currentTurnId = leader?.candidate.run.id;
790
- if (processingCurrent && currentTurnId !== undefined && processing !== null) {
791
- const actionProgressAt = latestLeaderActionProgressAt(store, taskId, currentTurnId, processing.startedAt, processing.batch, now);
787
+ const currentRunId = leader?.candidate.run.id;
788
+ if (processingCurrent && currentRunId !== undefined && processing !== null) {
789
+ const actionProgressAt = latestLeaderActionProgressAt(store, taskId, currentRunId, processing.startedAt, processing.batch, now);
792
790
  const actionProgressMs = Date.parse(actionProgressAt);
793
791
  const actionStalled = Number.isFinite(actionProgressMs)
794
792
  && now.getTime() - actionProgressMs >= windowMs;
@@ -807,7 +805,7 @@ function classifyLeaderStall(store, taskId, observed, now, windowMs) {
807
805
  return "truly-stalled";
808
806
  }
809
807
  const LEADER_ACTION_PROGRESS_TYPES = new Set([
810
- TURN_PROGRESS_EVENT,
808
+ RUN_PROGRESS_EVENT,
811
809
  "input.answered",
812
810
  "input.auto-answered",
813
811
  "input.cancelled",
@@ -823,7 +821,7 @@ const LEADER_ACTION_PROGRESS_TYPES = new Set([
823
821
  "decision.superseded",
824
822
  "milestone.added"
825
823
  ]);
826
- function latestLeaderActionProgressAt(store, taskId, turnId, startedAt, batch, now) {
824
+ function latestLeaderActionProgressAt(store, taskId, runId, startedAt, batch, now) {
827
825
  const startedMs = Date.parse(startedAt);
828
826
  if (!Number.isFinite(startedMs))
829
827
  return "";
@@ -834,14 +832,14 @@ function latestLeaderActionProgressAt(store, taskId, turnId, startedAt, batch, n
834
832
  continue;
835
833
  if (event.payload.taskId !== undefined && event.payload.taskId !== taskId)
836
834
  continue;
837
- if (!leaderActionEventMatches(event, taskId, turnId, batch))
835
+ if (!leaderActionEventMatches(event, taskId, runId, batch))
838
836
  continue;
839
837
  const createdMs = Date.parse(event.createdAt);
840
838
  if (!Number.isFinite(createdMs)
841
839
  || createdMs < startedMs
842
840
  || createdMs > now.getTime())
843
841
  continue;
844
- const value = event.type === TURN_PROGRESS_EVENT
842
+ const value = event.type === RUN_PROGRESS_EVENT
845
843
  && typeof event.payload.progressAt === "string"
846
844
  && Number.isFinite(Date.parse(event.payload.progressAt))
847
845
  ? event.payload.progressAt
@@ -857,12 +855,12 @@ function latestLeaderActionProgressAt(store, taskId, turnId, startedAt, batch, n
857
855
  }
858
856
  return latest;
859
857
  }
860
- function leaderActionEventMatches(event, taskId, turnId, batch) {
858
+ function leaderActionEventMatches(event, taskId, runId, batch) {
861
859
  if (event.taskId !== taskId)
862
860
  return false;
863
- if (event.payload.leaderTurnId === turnId)
861
+ if (event.payload.leaderRunId === runId)
864
862
  return true;
865
- if (event.payload.turnId === turnId)
863
+ if (event.payload.runId === runId)
866
864
  return true;
867
865
  const refs = batch.refs ?? [];
868
866
  const refMatches = (type, payloadKey) => {
@@ -871,7 +869,7 @@ function leaderActionEventMatches(event, taskId, turnId, batch) {
871
869
  && ref.id === id
872
870
  && (ref.taskId === undefined || ref.taskId === taskId)));
873
871
  };
874
- if (refMatches("turn", "turnId"))
872
+ if (refMatches("run", "runId"))
875
873
  return true;
876
874
  if (refMatches("work-item", "workItemId"))
877
875
  return true;
@@ -897,7 +895,7 @@ function leaderStallEvidence(store, taskId, observed, now, windowMs) {
897
895
  : "recent";
898
896
  const processing = store.getWorkMailbox({ kind: "role", taskId, roleName: "leader" })?.processing;
899
897
  const leader = [...observed.values()].find((entry) => (entry.candidate.task.id === taskId && entry.candidate.role.name === "leader"));
900
- const processingCurrent = processing?.executionRef?.type === "turn"
898
+ const processingCurrent = processing?.executionRef?.type === "run"
901
899
  && processing.executionRef.taskId === taskId
902
900
  && leader !== undefined
903
901
  && processing.executionRef.id === leader.candidate.run.id;
@@ -928,27 +926,18 @@ function exactLiveStatuses(statuses, candidates) {
928
926
  throw new Error("Tmux Role stall snapshot is incomplete.");
929
927
  return result;
930
928
  }
931
- function resourceForRun(snapshot, taskId, roleName, turnId) {
929
+ function resourceForRun(snapshot, taskId, roleName, runId) {
932
930
  if (snapshot === undefined)
933
931
  return undefined;
934
- return snapshot.get(`${taskId}\0${roleName}\0${turnId}`);
932
+ return snapshot.get(`${taskId}\0${roleName}\0${runId}`);
935
933
  }
936
934
  function resourceEvidenceMatchesCurrentRun(resource, expected, progressAt) {
937
935
  if (resource === undefined || expected === undefined)
938
936
  return false;
939
937
  const identity = resource.identity;
940
- if (identity === undefined
941
- || resource.progressAt !== progressAt
942
- || identity.taskId !== expected.taskId
943
- || identity.roleName !== expected.roleName
944
- || identity.turnId !== expected.turnId
945
- || identity.agentId !== expected.agentId
946
- || identity.adapterId !== expected.adapterId
947
- || identity.nativeSessionId !== expected.nativeSessionId
948
- || identity.runtimeGenerationId !== expected.runtimeGenerationId)
938
+ if (identity === undefined || resource.progressAt !== progressAt || identity.taskId !== expected.taskId || identity.roleName !== expected.roleName || identity.runId !== expected.runId || identity.agentId !== expected.agentId || identity.adapterId !== expected.adapterId || identity.nativeSessionId !== expected.nativeSessionId)
949
939
  return false;
950
- return hasResourceIdentityText(identity.nativeSessionId)
951
- || hasResourceIdentityText(identity.runtimeGenerationId);
940
+ return hasResourceIdentityText(identity.nativeSessionId);
952
941
  }
953
942
  function hasResourceIdentityText(value) {
954
943
  return typeof value === "string" && value.trim().length > 0;