@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
@@ -3,7 +3,7 @@ import { updateExecutionLane } from "../execution/workItemExecution.js";
3
3
  import { usageError } from "../errors/cliError.js";
4
4
  import { requestDurableJobCancel } from "../job/durableJob.js";
5
5
  import { finishReviewRound, updateReviewExecutionGroup } from "../review/reviewRound.js";
6
- import { failTurn } from "../turn/turn.js";
6
+ import { failRun } from "../agentRun/agentRun.js";
7
7
  import { queueLeaderWakeup } from "../scheduler/wakeupQueue.js";
8
8
  import { startTaskExecution, stopTaskExecution } from "../task/task.js";
9
9
  import { taskActor } from "./taskActor.js";
@@ -54,34 +54,34 @@ export function stopTaskExecutionCommand(request, store, options = {}) {
54
54
  const task = tx.getTask(request.taskId);
55
55
  if (task === null)
56
56
  throw usageError(`Task not found: ${request.taskId}.`);
57
- if (task.status !== "active") {
58
- throw usageError(`Only an active Task can be stopped: ${task.id}.`);
57
+ if (task.status !== "active" && task.status !== "draft") {
58
+ throw usageError(`Only an open Task can be stopped: ${task.id}.`);
59
59
  }
60
60
  const changed = task.executionGate.state !== "stopped";
61
61
  tx.saveTask(stopTaskExecution(task, now));
62
- const activeTurns = tx.listTurns(task.id).filter((run) => run.status === "active");
62
+ const activeRuns = tx.listRuns(task.id).filter((run) => run.status === "active");
63
63
  const activeJobs = tx.listDurableJobs(task.id)
64
64
  .filter((job) => job.status === "queued" || job.status === "running");
65
65
  for (const job of activeJobs) {
66
66
  tx.saveDurableJob(task.id, requestDurableJobCancel(job, now));
67
67
  }
68
- failExecutionAttempts(tx, task.id, activeTurns, request.reason, now);
69
- for (const run of activeTurns) {
70
- tx.saveTurn(failTurn(run, "cancelled", `Task execution stopped: ${request.reason}`, now));
68
+ failExecutionAttempts(tx, task.id, activeRuns, request.reason, now);
69
+ for (const run of activeRuns) {
70
+ tx.saveRun(failRun(run, "cancelled", `Task execution stopped: ${request.reason}`, now));
71
71
  if (run.executionGroupId !== undefined && run.executionLaneId !== undefined) {
72
- tx.clearActiveExecutionLaneTurn(task.id, run.executionGroupId, run.executionLaneId);
72
+ tx.clearActiveExecutionLaneRun(task.id, run.executionGroupId, run.executionLaneId);
73
73
  }
74
- tx.clearActiveTurn(task.id, run.roleName);
74
+ tx.clearActiveRun(task.id, run.roleName);
75
75
  }
76
- const roleNames = taskRuntimeRoleNames(tx, task.id, activeTurns);
76
+ const roleNames = taskRuntimeRoleNames(tx, task.id, activeRuns);
77
77
  for (const roleName of roleNames) {
78
- tx.clearActiveTurn(task.id, roleName);
78
+ tx.clearActiveRun(task.id, roleName);
79
79
  }
80
80
  // A stop is allowed to discard stale pointer projections even when their
81
- // historical Turns are already terminal.
82
- for (const run of tx.listTurns(task.id)) {
81
+ // historical AgentRuns are already terminal.
82
+ for (const run of tx.listRuns(task.id)) {
83
83
  if (run.executionGroupId !== undefined && run.executionLaneId !== undefined) {
84
- tx.clearActiveExecutionLaneTurn(task.id, run.executionGroupId, run.executionLaneId);
84
+ tx.clearActiveExecutionLaneRun(task.id, run.executionGroupId, run.executionLaneId);
85
85
  }
86
86
  }
87
87
  for (const mailbox of tx.listWorkMailboxes()) {
@@ -93,17 +93,17 @@ export function stopTaskExecutionCommand(request, store, options = {}) {
93
93
  tx.saveEvent(task.id, createTaskEvent(tx.nextEventId(task.id), task.id, "task.execution-stopped", {
94
94
  by: actor,
95
95
  reason: request.reason,
96
- terminatedRuns: String(activeTurns.length)
96
+ terminatedRuns: String(activeRuns.length)
97
97
  }, now));
98
98
  return {
99
99
  taskId: task.id,
100
100
  changed,
101
101
  roleNames,
102
- terminatedTurnIds: activeTurns.map(({ id }) => id),
102
+ terminatedRunIds: activeRuns.map(({ id }) => id),
103
103
  cancelledJobIds: activeJobs.map(({ id }) => id),
104
104
  output: changed
105
105
  ? `Stopped Task execution: ${task.id}. Progress was preserved; `
106
- + `${activeTurns.length} active attempt(s) were terminated and `
106
+ + `${activeRuns.length} AgentRun record(s) were cancelled and `
107
107
  + `${activeJobs.length} DurableJob(s) were cancelled.`
108
108
  : `Task execution is already stopped: ${task.id}. Runtime cleanup will be verified.`
109
109
  };
@@ -117,13 +117,13 @@ export function startTaskExecutionCommand(taskId, store, options = {}) {
117
117
  const task = tx.getTask(taskId);
118
118
  if (task === null)
119
119
  throw usageError(`Task not found: ${taskId}.`);
120
- if (task.status !== "active") {
121
- throw usageError(`Only an active Task can be started: ${task.id}.`);
120
+ if (task.status !== "active" && task.status !== "draft") {
121
+ throw usageError(`Only an open Task can be started: ${task.id}.`);
122
122
  }
123
123
  if (task.executionGate.state === "enabled") {
124
124
  return { taskId: task.id, changed: false, output: `Task execution is already enabled: ${task.id}.` };
125
125
  }
126
- if (tx.listTurns(task.id).some((run) => run.status === "active")
126
+ if (tx.listRuns(task.id).some((run) => run.status === "active")
127
127
  || tx.listDurableJobs(task.id).some((job) => job.status === "queued" || job.status === "running")) {
128
128
  throw usageError(`Task still has an active execution attempt: ${task.id}.`);
129
129
  }
@@ -167,12 +167,12 @@ function requireOperatorOrUser(environment, taskId) {
167
167
  }
168
168
  return actor;
169
169
  }
170
- function taskRuntimeRoleNames(store, taskId, turns) {
170
+ function taskRuntimeRoleNames(store, taskId, runs) {
171
171
  const names = new Set(store.listRoles(taskId).map(({ name }) => name));
172
172
  for (const sessions of store.listRoleSessionSets(taskId))
173
173
  names.add(sessions.owner.roleName);
174
- for (const turn of turns)
175
- names.add(turn.roleName);
174
+ for (const run of runs)
175
+ names.add(run.roleName);
176
176
  for (const owner of store.listSessionOwners()) {
177
177
  if (owner.owner.scope === "task" && owner.owner.taskId === taskId) {
178
178
  names.add(owner.owner.roleName);
@@ -180,24 +180,24 @@ function taskRuntimeRoleNames(store, taskId, turns) {
180
180
  }
181
181
  return [...names].sort();
182
182
  }
183
- function failExecutionAttempts(store, taskId, turns, reason, now) {
183
+ function failExecutionAttempts(store, taskId, runs, reason, now) {
184
184
  const summary = `Task execution stopped: ${reason}`;
185
185
  const reviewRounds = new Map(store.listReviewRounds(taskId).map((round) => [round.id, round]));
186
186
  const affectedReviewRoundIds = new Set();
187
- for (const turn of turns) {
188
- if (turn.reviewRoundId !== undefined) {
189
- affectedReviewRoundIds.add(turn.reviewRoundId);
190
- if (turn.executionGroupId === undefined || turn.executionLaneId === undefined)
187
+ for (const run of runs) {
188
+ if (run.reviewRoundId !== undefined) {
189
+ affectedReviewRoundIds.add(run.reviewRoundId);
190
+ if (run.executionGroupId === undefined || run.executionLaneId === undefined)
191
191
  continue;
192
- const round = reviewRounds.get(turn.reviewRoundId);
193
- const group = round?.executionGroup?.id === turn.executionGroupId
192
+ const round = reviewRounds.get(run.reviewRoundId);
193
+ const group = round?.executionGroup?.id === run.executionGroupId
194
194
  ? round.executionGroup
195
195
  : undefined;
196
- const lane = group?.lanes.find(({ id }) => id === turn.executionLaneId);
196
+ const lane = group?.lanes.find(({ id }) => id === run.executionLaneId);
197
197
  if (round !== undefined && group !== undefined && lane !== undefined
198
198
  && lane.disposition === "open") {
199
199
  reviewRounds.set(round.id, updateReviewExecutionGroup(round, updateExecutionLane(group, lane.id, {
200
- currentTurnId: turn.id,
200
+ currentRunId: run.id,
201
201
  disposition: "failed"
202
202
  }, now)));
203
203
  }
@@ -5,9 +5,8 @@ import { answerInputRequest, cancelInputRequest, createInputRequest } from "../i
5
5
  import { defaultTableWidth, renderTable } from "../output/table.js";
6
6
  import { formatTimestamp } from "../output/timePresentation.js";
7
7
  import { enqueueWork } from "../coordination/workMailboxQueue.js";
8
- import { isRoleTurnStalled, TURN_RECOVERED_EVENT } from "../scheduler/roleTurnStall.js";
9
- import { hasRuntimeCleanupObligation, isRuntimeLaunchReservation, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
10
- import { isLinuxProcessLive, listOwnedProcessTree } from "../runtime/sessionOwnerIdentity.js";
8
+ import { isRoleRunStalled, RUN_RECOVERED_EVENT } from "../scheduler/roleRunStall.js";
9
+ import { requireManagedTaskCaller } from "../runtime/managedCaller.js";
11
10
  import { resolveTaskRecordReference } from "../task/taskRecordReference.js";
12
11
  const LEADER_ROLE = "leader";
13
12
  export function runTaskInputCommand(args, store, options) {
@@ -55,13 +54,13 @@ function createRequest(args, store, options) {
55
54
  };
56
55
  const request = store.transaction((tx) => {
57
56
  const task = requireTask(tx, parsed.positionals[0]);
58
- if (task.status !== "active")
57
+ if (task.status !== "active" && task.status !== "draft")
59
58
  throw usageError(inactiveTaskMessage(task, "requesting input"));
60
59
  const blockedRefs = blockedValues.map((value) => parseInputBlockedRef(value, task.id));
61
60
  validateBlockedInputOwnership(tx, task.id, blockedRefs);
62
61
  const origin = requireLeaderInputOrigin(tx, task.id, options.environment);
63
62
  const created = createInputRequest(tx.nextInputRequestId(task.id), task.id, origin.requester, { question, choices, blockedRefs, policy }, now);
64
- const wasStalled = isRoleTurnStalled(tx.listEvents(task.id), origin.turn.id);
63
+ const wasStalled = origin.run !== null && isRoleRunStalled(tx.listEvents(task.id), origin.run.id);
65
64
  tx.saveInputRequest(task.id, created);
66
65
  enqueueWork(tx, { kind: "operator" }, "input-requested", now, [
67
66
  { type: "input", taskId: task.id, id: created.id }
@@ -69,9 +68,9 @@ function createRequest(args, store, options) {
69
68
  source: "input-request",
70
69
  dedupeKey: `operator-input:${task.id}:${created.id}`
71
70
  });
72
- if (wasStalled) {
73
- recordTaskEvent(tx, task.id, TURN_RECOVERED_EVENT, {
74
- turnId: origin.turn.id,
71
+ if (wasStalled && origin.run !== null) {
72
+ recordTaskEvent(tx, task.id, RUN_RECOVERED_EVENT, {
73
+ runId: origin.run.id,
75
74
  roleName: LEADER_ROLE,
76
75
  progressAt: now.toISOString(),
77
76
  kind: "input-request"
@@ -79,7 +78,8 @@ function createRequest(args, store, options) {
79
78
  }
80
79
  recordTaskEvent(tx, task.id, "input.requested", {
81
80
  requestId: created.id,
82
- requesterTurnId: created.requester.turnId,
81
+ ...(created.requester.runId === undefined ? {} : { requesterRunId: created.requester.runId }),
82
+ ...(created.requester.nativeSessionId === undefined ? {} : { requesterNativeSessionId: created.requester.nativeSessionId }),
83
83
  policy: created.policy.kind
84
84
  }, now);
85
85
  return created;
@@ -154,7 +154,7 @@ function answerRequest(args, store, options) {
154
154
  if (current === null)
155
155
  throw dataError(`Input request not found: ${located.id}.`);
156
156
  const task = requireTask(tx, current.taskId);
157
- if (task.status !== "active")
157
+ if (task.status !== "active" && task.status !== "draft")
158
158
  throw usageError(inactiveTaskMessage(task, "answering input"));
159
159
  const answered = answerInputRequest(current, answer, inputAnswerer(options.environment), now);
160
160
  tx.saveInputRequest(task.id, answered);
@@ -176,7 +176,7 @@ function cancelRequest(args, store, options) {
176
176
  const now = clock(options);
177
177
  const request = store.transaction((tx) => {
178
178
  const task = requireTask(tx, parsed.positionals[0]);
179
- if (task.status !== "active")
179
+ if (task.status !== "active" && task.status !== "draft")
180
180
  throw usageError(inactiveTaskMessage(task, "cancelling input"));
181
181
  const current = tx.getInputRequest(task.id, parsed.positionals[1]);
182
182
  if (current === null)
@@ -200,33 +200,24 @@ function cancelRequest(args, store, options) {
200
200
  }
201
201
  function requireLeaderInputOrigin(store, taskId, environment) {
202
202
  const env = environment ?? {};
203
- const role = requireRole(store, taskId, LEADER_ROLE);
204
- const turn = store.getActiveTurn(taskId, LEADER_ROLE);
205
- if (env.YUI_SESSION_SCOPE !== "task"
206
- || env.YUI_TASK_ID !== taskId
207
- || env.YUI_ROLE !== LEADER_ROLE
208
- || turn === null
209
- || env.YUI_AGENT_ID !== turn.effective.agentId
210
- || turn.status !== "active"
211
- || turn.workItemId !== undefined) {
212
- throw usageError("Task input request requires the active Leader Turn environment.");
203
+ const caller = requireManagedTaskCaller(store, env);
204
+ if (caller.taskId !== taskId || caller.roleName !== LEADER_ROLE) {
205
+ throw usageError("Only the current Task Leader may request user input.");
213
206
  }
207
+ const role = requireRole(store, taskId, LEADER_ROLE);
208
+ const run = store.getActiveRun(taskId, LEADER_ROLE);
214
209
  const sessions = store.getTaskRoleSessionSet(taskId, LEADER_ROLE);
215
- const nativeSessionId = trimmed(env.YUI_NATIVE_SESSION_ID);
216
- if (nativeSessionId !== undefined
217
- && sessions?.sessions[turn.effective.agentId]?.nativeSessionId !== nativeSessionId) {
218
- throw usageError("Task input request native session does not match the active Leader session.");
219
- }
210
+ const nativeSessionId = caller.nativeSessionId;
220
211
  return {
221
212
  requester: {
222
213
  taskId,
223
214
  roleName: "leader",
224
- agentId: turn.effective.agentId,
225
- turnId: turn.id,
226
- ...(nativeSessionId === undefined ? {} : { nativeSessionId })
215
+ agentId: caller.agentId,
216
+ ...(run === null ? {} : { runId: run.id }),
217
+ nativeSessionId
227
218
  },
228
219
  role,
229
- turn,
220
+ run,
230
221
  sessions
231
222
  };
232
223
  }
@@ -235,93 +226,38 @@ function assertInputCancelOrigin(store, request, environment) {
235
226
  if (isCurrentGlobalOperator(store, env)) {
236
227
  return "operator";
237
228
  }
238
- if (env.YUI_SESSION_SCOPE !== "task"
239
- || env.YUI_TASK_ID !== request.taskId
240
- || env.YUI_ROLE !== request.requester.roleName
241
- || env.YUI_AGENT_ID !== request.requester.agentId
242
- || (request.requester.nativeSessionId !== undefined
243
- && env.YUI_NATIVE_SESSION_ID !== request.requester.nativeSessionId)) {
244
- throw usageError("Only the originating Leader may cancel this input request.");
229
+ const caller = requireManagedTaskCaller(store, env);
230
+ if (caller.taskId !== request.taskId || caller.roleName !== LEADER_ROLE) {
231
+ throw usageError("Only the current Task Leader or Operator may cancel this input request.");
245
232
  }
246
233
  return "leader";
247
234
  }
248
235
  export function isCurrentGlobalOperator(store, environment) {
249
- if (environment.YUI_SESSION_SCOPE !== "global"
250
- || environment.YUI_ROLE !== "operator"
236
+ if ((environment.YUI_SESSION_SCOPE !== undefined && environment.YUI_SESSION_SCOPE !== "global")
237
+ || (environment.YUI_ROLE !== undefined && environment.YUI_ROLE !== "operator")
251
238
  || environment.YUI_TASK_ID !== undefined)
252
239
  return false;
253
240
  const role = store.getGlobalRole("operator");
254
241
  if (role === null)
255
242
  return false;
256
- const agentId = exactIdentity(environment.YUI_AGENT_ID);
257
- const adapterId = exactIdentity(environment.YUI_ADAPTER_ID);
258
- const runtimeGenerationId = exactIdentity(environment.YUI_RUNTIME_GENERATION_ID);
259
- const nativeSessionId = exactIdentity(environment.YUI_NATIVE_SESSION_ID);
260
243
  const binding = role.agentBindings[role.activeAgentId];
261
- if (agentId === undefined
262
- || adapterId === undefined
263
- || runtimeGenerationId === undefined
264
- || binding === undefined
265
- || binding.agentId !== agentId
266
- || binding.adapterId !== adapterId)
244
+ if (binding === undefined)
267
245
  return false;
268
246
  const sessions = store.getGlobalRoleSessionSet(role.name);
269
247
  const session = activeLiveRoleAgentSession(sessions);
270
248
  if (sessions === null || session === null || sessions.activeAgentId !== role.activeAgentId) {
271
- // Codex learns its native Session ID only after the first Turn. During
272
- // that narrow bootstrap window, authenticate against the durable launch
273
- // reservation and its strongly attributed live process owner instead.
274
- return nativeSessionId === undefined
275
- && binding.adapterId === "codex"
276
- && currentProcessBelongsToReservedGlobalLaunch(store, {
277
- roleName: role.name,
278
- agentId,
279
- adapterId,
280
- runtimeGenerationId
281
- });
249
+ return false;
282
250
  }
283
- // A fresh Codex launch discovers its native Session asynchronously. Its
284
- // launch envelope therefore cannot carry YUI_NATIVE_SESSION_ID, but the
285
- // durable Session still binds that provider identity to the exact launch
286
- // generation. Accept that one transport shape only when the current
287
- // launch, Agent, and adapter all match; Claude and stale/unknown launches
288
- // remain fail-closed on the native identity fence.
289
- const nativeSessionMatches = binding !== undefined && (nativeSessionId === session.nativeSessionId
290
- || (nativeSessionId === undefined
291
- && binding.adapterId === "codex"
292
- && session.adapterId === "codex"
293
- && session.runtimeGenerationId !== undefined
294
- && session.runtimeGenerationId === runtimeGenerationId));
251
+ // The provider's conversation survives Host restarts and entry-point changes.
252
+ // Prefer its command-time identity over a launch-time environment snapshot.
253
+ // A launch reservation alone is not a registered Operator conversation.
254
+ const nativeSessionId = exactIdentity(binding.adapterId === "codex"
255
+ ? environment.CODEX_THREAD_ID ?? environment.YUI_NATIVE_SESSION_ID
256
+ : environment.YUI_NATIVE_SESSION_ID);
295
257
  return binding.agentId === session.agentId
296
258
  && binding.adapterId === session.adapterId
297
- && session.agentId === agentId
298
- && session.adapterId === adapterId
299
- && session.runtimeGenerationId !== undefined
300
- && session.runtimeGenerationId === runtimeGenerationId
301
- && nativeSessionMatches;
302
- }
303
- function currentProcessBelongsToReservedGlobalLaunch(store, input) {
304
- if (store.getSessionOwner === undefined || store.getWorkMailbox === undefined)
305
- return false;
306
- const mailbox = store.getWorkMailbox(runtimeLifecycleTarget({
307
- scope: "global",
308
- roleName: input.roleName
309
- }));
310
- if (!isRuntimeLaunchReservation(mailbox?.processing, input.runtimeGenerationId)
311
- || hasRuntimeCleanupObligation(mailbox))
312
- return false;
313
- const owner = store.getSessionOwner(input.runtimeGenerationId);
314
- if (owner === null
315
- || owner.owner.scope !== "global"
316
- || owner.owner.roleName !== input.roleName
317
- || owner.agentId !== input.agentId
318
- || owner.adapterId !== input.adapterId
319
- || owner.runtimeGenerationId !== input.runtimeGenerationId
320
- || owner.providerRoot.attribution !== "launch-env"
321
- || !isLinuxProcessLive(owner.providerRoot.pid, owner.providerRoot.startIdentity)) {
322
- return false;
323
- }
324
- return listOwnedProcessTree(owner.providerRoot.pid, owner.providerRoot.processGroupId).some(({ pid }) => pid === process.pid);
259
+ && nativeSessionId !== undefined
260
+ && nativeSessionId === session.nativeSessionId;
325
261
  }
326
262
  function inputAnswerer(environment) {
327
263
  const env = environment ?? {};
@@ -342,7 +278,7 @@ function parseInputBlockedRef(value, taskId) {
342
278
  const separator = value.indexOf(":");
343
279
  const type = value.slice(0, separator);
344
280
  const id = value.slice(separator + 1).trim();
345
- if ((type !== "work-item" && type !== "turn") || separator <= 0 || id.length === 0) {
281
+ if ((type !== "work-item" && type !== "run") || separator <= 0 || id.length === 0) {
346
282
  throw usageError("--blocks must use work-item:<id> or turn:<id>.");
347
283
  }
348
284
  return { type, taskId, id };
@@ -351,7 +287,7 @@ function validateBlockedInputOwnership(store, taskId, references) {
351
287
  for (const reference of references) {
352
288
  const record = reference.type === "work-item"
353
289
  ? store.getWorkItem(taskId, reference.id)
354
- : store.getTurn(taskId, reference.id);
290
+ : store.getRun(taskId, reference.id);
355
291
  if (record === null)
356
292
  throw dataError(`Blocked ${reference.type} not found: ${reference.id}.`);
357
293
  }
@@ -386,7 +322,7 @@ function renderInputRequest(request, timeZone) {
386
322
  `Task: ${request.taskId}`,
387
323
  `Status: ${request.status}`,
388
324
  `Question: ${request.question}`,
389
- `Requested by: ${request.requester.agentId}/${request.requester.turnId}`,
325
+ `Requested by: ${request.requester.agentId}/${request.requester.runId ?? request.requester.nativeSessionId}`,
390
326
  ...(request.choices.length === 0
391
327
  ? ["Answer type: text"]
392
328
  : ["Choices:", ...request.choices.map((choice) => ` ${choice.key}: ${choice.label}`)]),
@@ -435,7 +371,7 @@ function inactiveTaskMessage(task, action) {
435
371
  if (task.status === "completed") {
436
372
  return `Task ${task.id} is completed; reopen it before ${action}.`;
437
373
  }
438
- if (task.status === "retired")
374
+ if (task.status === "cancelled")
439
375
  return `Task ${task.id} is retired; it cannot resume ${action}.`;
440
376
  return `Task is archived: ${task.id}.`;
441
377
  }
@@ -7,8 +7,9 @@ import { createIntegrationAttempt, recordResolutionDecision, supersedeIntegratio
7
7
  import { GitIntegrationService } from "../integration/gitIntegrationService.js";
8
8
  import { FileTaskWorkspacePreparer } from "../repository/taskWorkspacePreparer.js";
9
9
  import { runTaskIntegrationQueueCommand } from "./taskIntegrationQueueCommands.js";
10
- import { taskLocalActor } from "./taskActor.js";
10
+ import { assertTaskDeliveryAuthority as taskLocalActor } from "./taskActor.js";
11
11
  import { resolveTaskRecordReference } from "../task/taskRecordReference.js";
12
+ import { governingWorkItemCandidate } from "../workItem/workItem.js";
12
13
  export async function runTaskIntegrationCommand(args, store, home, options = {}) {
13
14
  const now = options.now ?? (() => new Date());
14
15
  const [command, ...rest] = args;
@@ -101,7 +102,7 @@ async function start(args, store, home, now, options) {
101
102
  const workItem = store.getWorkItem(task.id, workItemId);
102
103
  if (workItem === null)
103
104
  throw usageError(`WorkItem not found: ${workItemId}.`);
104
- const candidate = workItem.candidates.at(-1);
105
+ const candidate = governingWorkItemCandidate(workItem);
105
106
  if (candidate?.gitSnapshot === undefined || candidate.workspace === undefined) {
106
107
  throw usageError(`WorkItem has no committed result snapshot: ${workItem.id}.`);
107
108
  }
@@ -3,7 +3,7 @@ import { defaultTableWidth, renderTable } from "../output/table.js";
3
3
  import { resolveProject } from "../repository/project.js";
4
4
  import { NodeGitWorkspace } from "../repository/gitWorkspace.js";
5
5
  import { enqueueIntegrationQueueEntry, processIntegrationQueue, reconcileIntegrationQueueEntry, requeueIntegrationQueueEntry, supersedeIntegrationQueueEntry } from "../integration/integrationQueueService.js";
6
- import { taskLocalActor } from "./taskActor.js";
6
+ import { assertTaskDeliveryAuthority as taskLocalActor } from "./taskActor.js";
7
7
  import { parseRepeatable } from "./taskIntegrationCommands.js";
8
8
  import { resolveTaskRecordReference } from "../task/taskRecordReference.js";
9
9
  /**
@@ -69,20 +69,20 @@ export function runTaskNextActionCommand(args, store, currentTaskReviewCandidate
69
69
  const events = reader.listEvents(taskId);
70
70
  const task = reader.getTask(taskId);
71
71
  const remoteDelivery = projectTaskRemoteDeliveryFromStore(reader, task, currentTaskReviewCandidate);
72
- const operationalTurns = operationalTaskRecords(reader.listTurns(taskId), events, "turn");
72
+ const operationalRuns = operationalTaskRecords(reader.listRuns(taskId), events, "run");
73
73
  const reviewRounds = reader.listReviewRounds(taskId);
74
74
  const reviewDecision = projectReviewDecision({
75
75
  store: reader,
76
76
  task,
77
77
  roles: reader.listRoles(taskId),
78
- turns: operationalTurns,
78
+ runs: operationalRuns,
79
79
  rounds: reviewRounds,
80
80
  reviewConfig: reader.getReviewConfig(),
81
81
  currentCandidate: currentTaskReviewCandidate
82
82
  });
83
83
  const orchestration = projectTaskOrchestration({
84
84
  task,
85
- turns: operationalTurns,
85
+ runs: operationalRuns,
86
86
  roleSessionSets: reader.listRoleSessionSets(taskId),
87
87
  workItems: reader.listWorkItems(taskId),
88
88
  changeSets: reader.listChangeSets(taskId),
@@ -125,10 +125,10 @@ function renderNextAction(action, taskType, completionReadiness, knowledgePropos
125
125
  `Next action: ${action.kind}`,
126
126
  `Reason: ${action.reason}`,
127
127
  `Execution view: ${execution.status}; owner/action=${execution.owner}/${execution.action}; reason=${execution.reason}; ${execution.summary}`,
128
- `Active Turns (${execution.activeTurns.length}):`,
129
- ...(execution.activeTurns.length === 0
128
+ `Active AgentRuns (${execution.activeRuns.length}):`,
129
+ ...(execution.activeRuns.length === 0
130
130
  ? [" none"]
131
- : execution.activeTurns.map((run) => ` ${renderActiveTurn(run)}`)),
131
+ : execution.activeRuns.map((run) => ` ${renderActiveRun(run)}`)),
132
132
  ...(action.refs.length === 0
133
133
  ? ["Refs: none"]
134
134
  : ["Refs:", ...action.refs.map((ref) => ` ${ref.kind}: ${ref.id}`)]),
@@ -196,7 +196,7 @@ function renderNextAction(action, taskType, completionReadiness, knowledgePropos
196
196
  }
197
197
  return `${lines.join("\n")}\n`;
198
198
  }
199
- function renderActiveTurn(run) {
199
+ function renderActiveRun(run) {
200
200
  const subject = run.reviewRoundId === undefined
201
201
  ? run.workItemId === undefined ? "task" : `work-item=${run.workItemId}`
202
202
  : `review-round=${run.reviewRoundId}`;
@@ -212,6 +212,6 @@ function nextActionExecutionView(execution) {
212
212
  action: execution.action,
213
213
  reason: execution.reason,
214
214
  summary: execution.summary,
215
- activeTurns: execution.activeTurns
215
+ activeRuns: execution.activeRuns
216
216
  };
217
217
  }