@zq-silk/yui 0.15.7 → 0.15.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/ARCHITECTURE.md +194 -399
  2. package/ARCHITECTURE.zh-CN.md +151 -0
  3. package/README.md +306 -1131
  4. package/dist/agent/adapterCatalog.js +15 -2
  5. package/dist/agent/agent.js +23 -3
  6. package/dist/agent/argumentPolicy.js +7 -1
  7. package/dist/agent/connectionPlan.js +62 -0
  8. package/dist/agent/executionComponents.js +158 -0
  9. package/dist/agent/launchEnvironment.js +31 -3
  10. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  11. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  12. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  13. package/dist/artifacts/artifactCapability.js +74 -0
  14. package/dist/artifacts/artifactCommitLock.js +249 -0
  15. package/dist/artifacts/artifactPaths.js +151 -0
  16. package/dist/artifacts/gitArtifactRef.js +146 -0
  17. package/dist/artifacts/managedGit.js +332 -0
  18. package/dist/artifacts/taskArtifactRepository.js +277 -0
  19. package/dist/brief/taskBrief.js +12 -0
  20. package/dist/cli/agentConfigurationPicker.js +13 -0
  21. package/dist/cli/commandCatalog.js +165 -74
  22. package/dist/cli/interactionCandidates.js +5 -5
  23. package/dist/cli/interactionPolicy.js +38 -8
  24. package/dist/cli/invocationRouter.js +1 -1
  25. package/dist/cli/managedDiagnostics.js +28 -0
  26. package/dist/cli/operatorWizard.js +1 -7
  27. package/dist/cli/roleOptionOrder.js +27 -0
  28. package/dist/cli/roleWizard.js +50 -14
  29. package/dist/cli/updateOrchestrator.js +1 -1
  30. package/dist/cli/updatePorts.js +3 -4
  31. package/dist/cli.js +245 -95
  32. package/dist/commands/agentCommands.js +72 -14
  33. package/dist/commands/capabilityCommands.js +9 -6
  34. package/dist/commands/configCommands.js +20 -20
  35. package/dist/commands/deliveryGuardPreflight.js +2 -2
  36. package/dist/commands/executionAuditCommands.js +24 -24
  37. package/dist/commands/globalRoleCommands.js +1 -1
  38. package/dist/commands/grantCommands.js +4 -4
  39. package/dist/commands/operatorCommands.js +34 -9
  40. package/dist/commands/projectCommands.js +4 -4
  41. package/dist/commands/resourcesCommands.js +2 -2
  42. package/dist/commands/roleConfiguration.js +25 -5
  43. package/dist/commands/roleRuntimeGuard.js +4 -5
  44. package/dist/commands/sessionCommands.js +3 -7
  45. package/dist/commands/taskActivationCommands.js +281 -0
  46. package/dist/commands/taskActor.js +28 -49
  47. package/dist/commands/taskCommands.js +1461 -720
  48. package/dist/commands/taskContextCommand.js +39 -583
  49. package/dist/commands/taskExecutionCommands.js +32 -32
  50. package/dist/commands/taskInputCommands.js +40 -104
  51. package/dist/commands/taskIntegrationCommands.js +3 -2
  52. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  53. package/dist/commands/taskNextActionCommand.js +8 -8
  54. package/dist/commands/taskOverviewCommand.js +33 -45
  55. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  56. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  57. package/dist/commands/telemetryCommands.js +36 -38
  58. package/dist/config/configCatalog.js +4 -4
  59. package/dist/config/yuiConfig.js +8 -8
  60. package/dist/context/contextSnapshot.js +10 -10
  61. package/dist/context/dispatchContext.js +11 -11
  62. package/dist/context/roleSessionContext.js +6 -3
  63. package/dist/context/{turnContextPack.js → runContextPack.js} +158 -81
  64. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  65. package/dist/context/sessionBootstrapManifest.js +21 -2
  66. package/dist/context/sourceRunContext.js +30 -0
  67. package/dist/context/taskContext.js +481 -0
  68. package/dist/context/wakeNotification.js +27 -27
  69. package/dist/controller/agentRuntimeObserver.js +21 -24
  70. package/dist/controller/capabilityBridge.js +17 -6
  71. package/dist/controller/clientRuntime.js +65 -92
  72. package/dist/controller/controller.js +120 -188
  73. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  74. package/dist/controller/jobControl.js +54 -85
  75. package/dist/controller/resourceInventory.js +8 -27
  76. package/dist/controller/resourceInventoryLinux.js +12 -13
  77. package/dist/controller/runtime.js +529 -479
  78. package/dist/controller/runtimeEventInbox.js +55 -25
  79. package/dist/controller/runtimeEventProcessor.js +22 -31
  80. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  81. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  82. package/dist/controller/runtimeObservationHook.js +14 -18
  83. package/dist/controller/sessionNotify.js +16 -24
  84. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  85. package/dist/controller/structuredProviderObservation.js +138 -99
  86. package/dist/coordination/workMailbox.js +3 -3
  87. package/dist/coordination/workMailboxQueue.js +36 -33
  88. package/dist/core/boundedRpc.js +8 -1
  89. package/dist/core/controllerClient.js +20 -1
  90. package/dist/core/controllerServer.js +4 -4
  91. package/dist/doctor/doctor.js +13 -2
  92. package/dist/domain/agentResultTransport.js +9 -9
  93. package/dist/execution/codexThreadNaming.js +2 -8
  94. package/dist/execution/executionHealth.js +51 -63
  95. package/dist/execution/reviewMainRun.js +137 -0
  96. package/dist/execution/workItemExecution.js +28 -29
  97. package/dist/execution/workItemExecutionProjection.js +99 -107
  98. package/dist/execution/workItemMainRun.js +141 -0
  99. package/dist/executor/agentAdapter.js +227 -20
  100. package/dist/executor/agentConfigurationCatalog.js +126 -4
  101. package/dist/executor/agentConfigurationProbe.js +162 -4
  102. package/dist/executor/agentExecutor.js +79 -78
  103. package/dist/executor/effectiveLaunch.js +105 -18
  104. package/dist/executor/executorRegistry.js +29 -44
  105. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  106. package/dist/executor/workspacePreflightClassification.js +16 -16
  107. package/dist/grant/capabilityGrant.js +6 -3
  108. package/dist/input/inputRequest.js +12 -10
  109. package/dist/integration/gitIntegrationService.js +4 -11
  110. package/dist/integration/integrationQueueService.js +4 -4
  111. package/dist/interaction/operatorPresentation.js +1 -1
  112. package/dist/kernel/builtinCapabilities.js +255 -12
  113. package/dist/kernel/capabilityRegistry.js +64 -18
  114. package/dist/kernel/instanceHost.js +12 -1
  115. package/dist/kernel/kernelPorts.js +2 -2
  116. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  117. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  118. package/dist/message/message.js +118 -6
  119. package/dist/message/messageContinuation.js +204 -0
  120. package/dist/observability/executionAudit.js +70 -72
  121. package/dist/observability/faultClassification.js +2 -2
  122. package/dist/observability/orchestrationMetrics.js +8 -8
  123. package/dist/operator/operatorSessionHistory.js +1 -7
  124. package/dist/output/agentConfigurationPresentation.js +8 -3
  125. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  126. package/dist/output/rolePresentation.js +54 -3
  127. package/dist/plugins/pluginChild.js +104 -0
  128. package/dist/plugins/pluginIntent.js +26 -0
  129. package/dist/plugins/pluginInterpreter.js +43 -0
  130. package/dist/plugins/pluginPackage.js +101 -0
  131. package/dist/plugins/pluginProcess.js +112 -0
  132. package/dist/plugins/pluginService.js +388 -0
  133. package/dist/profile/agentProfile.js +1 -1
  134. package/dist/repository/gitWorkspace.js +26 -4
  135. package/dist/repository/project.js +19 -4
  136. package/dist/repository/taskBaseFreshness.js +13 -13
  137. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  138. package/dist/repository/taskWorkspacePreparer.js +344 -83
  139. package/dist/resources/autoResourceGc.js +3 -3
  140. package/dist/resources/liveReferences.js +3 -3
  141. package/dist/resources/projectResource.js +75 -0
  142. package/dist/resources/projectResourceService.js +343 -0
  143. package/dist/resources/resourceDiscovery.js +6 -6
  144. package/dist/resources/resourceGc.js +1 -1
  145. package/dist/resources/resourceRegistrar.js +1 -1
  146. package/dist/resources/resourceTypes.js +1 -1
  147. package/dist/review/deltaRecheck.js +3 -3
  148. package/dist/review/reviewAcceptance.js +16 -16
  149. package/dist/review/reviewDecision.js +7 -7
  150. package/dist/review/reviewRound.js +21 -20
  151. package/dist/review/reviewerAvailability.js +2 -2
  152. package/dist/role/role.js +51 -7
  153. package/dist/role/taskRoleUpdate.js +30 -0
  154. package/dist/runtime/acpProtocol.js +425 -0
  155. package/dist/runtime/acpSession.js +731 -0
  156. package/dist/runtime/acpSessionConfiguration.js +260 -0
  157. package/dist/runtime/agentDriver.js +30 -11
  158. package/dist/runtime/agentEndpoint.js +278 -0
  159. package/dist/runtime/agentEndpointIdentity.js +86 -0
  160. package/dist/runtime/agentEndpointOwnership.js +239 -0
  161. package/dist/runtime/agentError.js +2 -10
  162. package/dist/runtime/agentHost.js +565 -314
  163. package/dist/runtime/agentRunConfiguration.js +258 -0
  164. package/dist/runtime/builtinAgentDrivers.js +134 -18
  165. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  166. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  167. package/dist/runtime/claude-process-owner +0 -0
  168. package/dist/runtime/codexAppServerRuntime.js +38 -30
  169. package/dist/runtime/codexInteractiveHost.js +41 -6
  170. package/dist/runtime/continuationManager.js +2 -6
  171. package/dist/runtime/executionEnvironment.js +30 -0
  172. package/dist/runtime/firstProgressAdvisory.js +11 -11
  173. package/dist/runtime/index.js +4 -3
  174. package/dist/runtime/jsonLineChannel.js +109 -0
  175. package/dist/runtime/launchBroker.js +91 -16
  176. package/dist/runtime/launchDiagnostics.js +2 -2
  177. package/dist/runtime/lifecycleReservation.js +10 -18
  178. package/dist/runtime/managedCaller.js +61 -17
  179. package/dist/runtime/nativeSessionControl.js +102 -0
  180. package/dist/runtime/ports.js +6 -21
  181. package/dist/runtime/processExitObservation.js +8 -7
  182. package/dist/runtime/promptEnvelope.js +17 -6
  183. package/dist/runtime/providerContinuation.js +3 -9
  184. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  185. package/dist/runtime/providerControl.js +2 -7
  186. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  187. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  188. package/dist/runtime/runtimeBinding.js +0 -1
  189. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  190. package/dist/runtime/runtimeDeadlines.js +9 -0
  191. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  192. package/dist/runtime/runtimeObservation.js +29 -65
  193. package/dist/runtime/runtimeProjection.js +43 -51
  194. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  195. package/dist/runtime/sessionLaunchRequest.js +3 -7
  196. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  197. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  198. package/dist/runtime/sessionReconciliation.js +4 -8
  199. package/dist/runtime/sessionTerminationGuard.js +70 -259
  200. package/dist/runtime/sessionTokenMetrics.js +5 -16
  201. package/dist/runtime/structuredProviderHost.js +237 -117
  202. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  203. package/dist/runtime/tmuxAdapters.js +39 -86
  204. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  205. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  206. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  207. package/dist/scheduler/ports.js +80 -9
  208. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  209. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  210. package/dist/scheduler/taskExecutionProjection.js +120 -124
  211. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  212. package/dist/scheduler/taskWake.js +11 -4
  213. package/dist/scheduler/wakeReason.js +9 -1
  214. package/dist/setup/setupCommand.js +3 -7
  215. package/dist/storage/migrations/agentRunContract.js +159 -0
  216. package/dist/storage/migrations/artifactsToGit.js +338 -0
  217. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  218. package/dist/storage/migrations/submitIntent.js +126 -0
  219. package/dist/storage/sqliteSchema.js +467 -7
  220. package/dist/storage/sqliteStore.js +355 -220
  221. package/dist/storage/storageVersions.js +1 -1
  222. package/dist/storage/storeRpc.js +10 -5
  223. package/dist/storage/taskStore.js +13 -11
  224. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  225. package/dist/surface/surfaceContributions.js +102 -0
  226. package/dist/task/completionReadiness.js +32 -6
  227. package/dist/task/deliveryGuard.js +16 -16
  228. package/dist/task/draftPlan.js +72 -12
  229. package/dist/task/nextAction.js +144 -128
  230. package/dist/task/remoteDelivery.js +6 -6
  231. package/dist/task/task.js +184 -18
  232. package/dist/task/taskActivation.js +327 -0
  233. package/dist/task/taskActivationService.js +408 -0
  234. package/dist/task/taskRecordReference.js +5 -4
  235. package/dist/task/taskRecordRetirement.js +1 -1
  236. package/dist/task/taskSubmission.js +236 -0
  237. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  238. package/dist/telemetry/telemetryConfig.js +14 -14
  239. package/dist/telemetry/telemetryWiring.js +2 -2
  240. package/dist/web/assets/assetManifest.js +2 -0
  241. package/dist/web/assets/client/app.js +121 -20
  242. package/dist/web/assets/client/components.js +87 -54
  243. package/dist/web/assets/client/i18n.js +83 -41
  244. package/dist/web/assets/client/markdown.js +1 -1
  245. package/dist/web/assets/client/taskSurface.js +442 -0
  246. package/dist/web/assets/client/view.js +49 -44
  247. package/dist/web/assets/shell.js +1 -1
  248. package/dist/web/assets/styles/cards.js +22 -4
  249. package/dist/web/controllerWeb.js +60 -0
  250. package/dist/web/webMutation.js +28 -0
  251. package/dist/web/webServer.js +133 -8
  252. package/dist/web/webSnapshot.js +81 -74
  253. package/dist/web/webTaskSurface.js +64 -0
  254. package/dist/workItem/dependencyGate.js +1 -1
  255. package/dist/workItem/workItem.js +84 -48
  256. package/dist/workspace/workItemChangeSetManager.js +16 -9
  257. package/docs/agent-result-consumption.md +96 -0
  258. package/docs/agent-result-consumption.zh-CN.md +81 -0
  259. package/docs/agent-runtime-drivers.md +93 -0
  260. package/docs/agent-runtime-drivers.zh-CN.md +77 -0
  261. package/docs/architecture/README.md +50 -0
  262. package/docs/architecture/README.zh-CN.md +43 -0
  263. package/docs/architecture/capabilities-and-resources.md +118 -0
  264. package/docs/architecture/capabilities-and-resources.zh-CN.md +83 -0
  265. package/docs/managed-turn-and-session-runtime.md +224 -0
  266. package/docs/managed-turn-and-session-runtime.zh-CN.md +180 -0
  267. package/docs/observability/README.md +83 -0
  268. package/docs/observability/README.zh-CN.md +71 -0
  269. package/docs/plugin-sdk.md +393 -0
  270. package/docs/plugin-sdk.zh-CN.md +293 -0
  271. package/docs/provider-runtime.md +165 -0
  272. package/docs/provider-runtime.zh-CN.md +132 -0
  273. package/docs/release-workflow.md +305 -0
  274. package/docs/release-workflow.zh-CN.md +237 -0
  275. package/docs/roles-and-configuration.md +115 -0
  276. package/docs/roles-and-configuration.zh-CN.md +96 -0
  277. package/docs/sqlite-control-plane-design.md +78 -0
  278. package/docs/sqlite-control-plane-design.zh-CN.md +62 -0
  279. package/docs/task-dag-semantics.md +80 -0
  280. package/docs/task-dag-semantics.zh-CN.md +59 -0
  281. package/docs/task-delivery.md +105 -0
  282. package/docs/task-delivery.zh-CN.md +82 -0
  283. package/docs/task-local-identity.md +8 -6
  284. package/docs/task-local-identity.zh-CN.md +58 -0
  285. package/docs/testing/verification-levels.md +88 -0
  286. package/docs/testing/verification-levels.zh-CN.md +69 -0
  287. package/i18n/README.zh-CN.md +270 -722
  288. package/package.json +3 -2
  289. package/skills/yui-leader/SKILL.md +88 -304
  290. package/skills/yui-leader/references/execution.md +303 -0
  291. package/skills/yui-leader/references/integration.md +39 -0
  292. package/skills/yui-leader/references/planning.md +109 -0
  293. package/skills/yui-leader/references/replicated-execution.md +42 -0
  294. package/skills/yui-leader/references/task-plugins.md +37 -0
  295. package/skills/yui-operator/SKILL.md +46 -62
  296. package/skills/yui-reviewer/SKILL.md +35 -36
  297. package/skills/yui-runtime/SKILL.md +88 -24
  298. package/skills/yui-runtime/references/publication.md +22 -0
  299. package/skills/yui-runtime/references/recovery.md +64 -0
  300. package/skills/yui-worker/SKILL.md +37 -39
  301. package/dist/cli/roleOptionCatalog.js +0 -68
  302. package/dist/context/sourceTurnContext.js +0 -30
  303. package/dist/execution/reviewMainTurn.js +0 -161
  304. package/dist/execution/workItemMainTurn.js +0 -164
  305. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  306. package/dist/runtime/preallocatedNativeSession.js +0 -13
  307. package/dist/runtime/runtimeStopReceipt.js +0 -42
  308. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
package/dist/cli.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync } from "node:child_process";
3
+ import { randomUUID } from "node:crypto";
4
+ import { agentAdapterLabel as adapterLabel } from "./agent/adapterCatalog.js";
3
5
  import { readFileSync } from "node:fs";
4
6
  import { resolve } from "node:path";
5
7
  import { createInterface } from "node:readline/promises";
@@ -43,7 +45,8 @@ import { assertTaskRemoteDeliveryIntegrated, createTaskRemoteDeliveryProof } fro
43
45
  import { runTaskPublicationVerifyCommand } from "./commands/taskPublicationVerifyCommand.js";
44
46
  import { createGitHubCliPublicationVerifier } from "./external/githubPublicationVerifier.js";
45
47
  import { createGitLabCliPublicationVerifier } from "./external/gitlabPublicationVerifier.js";
46
- import { taskActor } from "./commands/taskActor.js";
48
+ import { taskLocalActor, assertTaskDeliveryAuthority } from "./commands/taskActor.js";
49
+ import { saveArtifactCapability, readArtifactCapability, listArtifactsCapability } from "./artifacts/artifactCapability.js";
47
50
  import { parseTaskExecutionStartRequest, parseTaskExecutionStopRequest, finalizeStoppedTaskExecution, startTaskExecutionCommand, stopTaskExecutionCommand } from "./commands/taskExecutionCommands.js";
48
51
  import { runTaskIntegrationCommand } from "./commands/taskIntegrationCommands.js";
49
52
  import { runTaskChangeSetCommand } from "./commands/taskChangeSetCommands.js";
@@ -72,7 +75,8 @@ import { runRuntimeObservationHookCommand } from "./controller/runtimeObservatio
72
75
  import { buildDoctorReport, renderDoctor, runDoctorCommand } from "./doctor/doctor.js";
73
76
  import { agentNotFound, CliError, runtimeError, usageError } from "./errors/cliError.js";
74
77
  import { FileRoleLaunchPlanner } from "./executor/fileRoleLaunchPlanner.js";
75
- import { AGENT_HOST_CONTROL_PROTOCOL, runAgentHost, sendAgentHostAuthorityControl } from "./runtime/agentHost.js";
78
+ import { AGENT_HOST_CONTROL_PROTOCOL, inspectAgentHost, runAgentHost, sendAgentHostAuthorityControl } from "./runtime/agentHost.js";
79
+ import { unknownAgentRunConfiguration } from "./runtime/agentRunConfiguration.js";
76
80
  import { TaskWorkspaceCoordinator, WorkspaceCleanupBlockedError } from "./repository/taskWorkspaceCoordinator.js";
77
81
  import { FileTaskWorkspacePreparer } from "./repository/taskWorkspacePreparer.js";
78
82
  import { inspectStorageSchema } from "./storage/storageSchema.js";
@@ -85,15 +89,15 @@ import { NodeCommandExecutor } from "./tmux/commandExecutor.js";
85
89
  import { TmuxManager } from "./tmux/tmuxManager.js";
86
90
  import { WorkItemChangeSetManager } from "./workspace/workItemChangeSetManager.js";
87
91
  import { workspaceProjectEntry } from "./worktree/managedWorkspace.js";
88
- import { parseWebCommandOptions, startYuiWebServer } from "./web/webServer.js";
92
+ import { parseWebCommandOptions } from "./web/webServer.js";
89
93
  import { AgentConfigurationCatalogService, validateAgentLaunchConfiguration } from "./executor/agentConfigurationCatalog.js";
90
94
  import { resolveAgentProfileView } from "./profile/agentProfileRuntime.js";
91
- import { TmuxWebTerminalService } from "./web/tmuxWebTerminal.js";
92
95
  import { listOperatorSessions, operatorSessionRef } from "./operator/operatorSessionHistory.js";
93
96
  import { YUI_VERSION, yuiVersionIdentity } from "./version.js";
94
97
  import { SqliteSchemaMigrationError } from "./storage/sqliteSchema.js";
95
- import { assertRuntimeCoherence, } from "./runtime/runtimeCoherence.js";
96
- import { requireManagedTaskCaller } from "./runtime/managedCaller.js";
98
+ import { assertRuntimeCoherence } from "./runtime/runtimeCoherence.js";
99
+ import { requireManagedTaskCaller, resolveManagedTaskReader } from "./runtime/managedCaller.js";
100
+ import { operatorOfflineCommand, taskDiagnosticTarget } from "./cli/managedDiagnostics.js";
97
101
  import { readSessionBootstrapManifest, refreshManagedSessionCliWrappers } from "./context/sessionBootstrapManifest.js";
98
102
  import { createTaskFinalReviewContract, extractTaskFinalReviewRequest } from "./review/taskFinalReviewContract.js";
99
103
  import { resolveRecordedTaskFinalReviewContract } from "./review/taskFinalReviewContractResolution.js";
@@ -146,7 +150,7 @@ export async function main() {
146
150
  || routedForFence?.kind === "help"
147
151
  || routedForFence?.kind === "path-error"
148
152
  || routedForFence?.kind === "incomplete";
149
- if (managedInvocation || !homeFreeInvocation) {
153
+ if (!homeFreeInvocation) {
150
154
  assertCliHomeReleaseFence({
151
155
  home,
152
156
  packageRoot: fileURLToPath(new URL("../", import.meta.url)),
@@ -170,7 +174,6 @@ export async function main() {
170
174
  process.exitCode = delegated.status ?? 5;
171
175
  return;
172
176
  }
173
- const { contract: taskFinalReviewContract, verifiedStore } = await preflightManagedTaskControlPlane();
174
177
  if (args.length === 0) {
175
178
  emit(renderCommandHelp((await import("./cli/commandCatalog.js")).ROOT_COMMAND, VERSION));
176
179
  return;
@@ -192,6 +195,7 @@ export async function main() {
192
195
  }
193
196
  if (args[0] === "version")
194
197
  throw usageError("Version usage: yui version");
198
+ const { contract: taskFinalReviewContract, verifiedStore } = await preflightManagedTaskControlPlane();
195
199
  if (args[0] === "update") {
196
200
  if (jsonOutput)
197
201
  throw usageError("Update does not support --json.");
@@ -328,11 +332,10 @@ export async function main() {
328
332
  + `${result.current} already current, ${result.skipped} skipped.`, false, result);
329
333
  return;
330
334
  }
331
- if (args[1] === "agent-host" && args.length === 4) {
335
+ if (args[1] === "agent-host" && args.length === 3) {
332
336
  process.exitCode = await runAgentHost({
333
337
  home,
334
- runtimeGenerationId: args[2],
335
- ticket: args[3]
338
+ ticket: args[2]
336
339
  });
337
340
  return;
338
341
  }
@@ -343,7 +346,7 @@ export async function main() {
343
346
  if (args[1] === "runtime-hook" && args.length === 2) {
344
347
  // Provider lifecycle Hooks are observation channels, never execution
345
348
  // gates. A late/stale Hook must not make Claude reject an otherwise
346
- // valid Session or Turn; its exact fence is revalidated before any
349
+ // valid Session or AgentRun; its exact fence is revalidated before any
347
350
  // inbox fact is written, so dropping an invalid observation is safe.
348
351
  try {
349
352
  await runRuntimeObservationHookCommand(readFileSync(0, "utf8"), process.env);
@@ -549,7 +552,8 @@ export async function main() {
549
552
  emit(result.output, false, result.data);
550
553
  return;
551
554
  }
552
- await assertFileTaskControllerStorageCompatible(home);
555
+ if (!operatorOfflineCommand(args))
556
+ await assertFileTaskControllerStorageCompatible(home);
553
557
  // Reuse the store the exact runtime preflight already opened and read for
554
558
  // this same Home. Opening a second store would parse the unchanged large
555
559
  // state a second time; the per-instance fingerprint cache still invalidates
@@ -586,46 +590,37 @@ export async function main() {
586
590
  });
587
591
  const workspaceCoordinator = new TaskWorkspaceCoordinator(store, workspacePreparer, runtime);
588
592
  if (resolved[0] === "web") {
593
+ if (managedInvocation || process.env.YUI_ROLE || process.env.YUI_NATIVE_SESSION_ID) {
594
+ throw usageError("The Web user ingress must be started from a local user terminal, not a managed Session.");
595
+ }
596
+ if (resolved.length === 2 && (resolved[1] === "--status" || resolved[1] === "--stop")) {
597
+ const status = await callController(home, "web.status", {});
598
+ if (resolved[1] === "--status")
599
+ emit(status ? `Yui web control room: ${status.url}\n` : "Web is not running.\n", false, status);
600
+ else {
601
+ if (status)
602
+ await callController(home, "web.stop", { id: status.id });
603
+ emit("Web listener stopped; Controller and Agents are unchanged.\n");
604
+ }
605
+ return;
606
+ }
589
607
  if (jsonOutput)
590
- throw usageError("Web does not support --json.");
608
+ throw usageError("Web start does not support --json; use --status.");
591
609
  const options = parseWebCommandOptions(resolved.slice(1));
592
- const terminal = new TmuxWebTerminalService({
593
- yuiHome: home,
594
- tmuxBin: resolveTmuxBin(store.getConfig().tmuxBin),
595
- tmux,
596
- prepareGlobalRole: (roleName) => runtime.prepareGlobalRoleEnter(roleName),
597
- environment: process.env,
598
- onError: (error) => {
599
- const message = error instanceof Error ? error.message : String(error);
600
- process.stderr.write(`Web terminal cleanup error: ${message}\n`);
601
- }
602
- });
603
- await startYuiWebServer(store, options, {
604
- terminal,
605
- answerInput: async ({ taskId, inputId, answer }) => {
606
- const command = [
607
- "input", "answer", inputId, "--task", taskId,
608
- ...("choiceKey" in answer
609
- ? ["--choice", answer.choiceKey]
610
- : ["--text", answer.text])
611
- ];
612
- const result = runTaskCommand(command, store, {
613
- runtime,
614
- environment: {},
615
- yuiHome: home
616
- });
617
- if (result.kind !== "output") {
618
- throw new Error("Input answer returned an invalid control result.");
619
- }
620
- const data = result.data;
621
- if (data?.request === undefined) {
622
- throw new Error("Input answer did not return the updated request.");
623
- }
624
- return data.request;
625
- }
626
- });
610
+ const id = randomUUID();
611
+ await callController(home, "web.start", { ...options, id });
627
612
  const displayHost = options.host === "::1" ? "[::1]" : options.host;
628
613
  process.stdout.write(`Yui web control room: http://${displayHost}:${options.port}\n`);
614
+ await new Promise((resolve) => {
615
+ const stop = () => {
616
+ process.off("SIGINT", stop);
617
+ process.off("SIGTERM", stop);
618
+ resolve();
619
+ };
620
+ process.once("SIGINT", stop);
621
+ process.once("SIGTERM", stop);
622
+ });
623
+ await callController(home, "web.stop", { id });
629
624
  return;
630
625
  }
631
626
  if (resolved[0] === "config") {
@@ -779,6 +774,72 @@ export async function main() {
779
774
  return;
780
775
  }
781
776
  if (resolved[0] === "task") {
777
+ if (resolved[1] === "artifact") {
778
+ // File/directory artifacts live in the Task's local Git repository, so
779
+ // their save/read/list are asynchronous and handled here rather than in
780
+ // the synchronous runTaskCommand chain. Save commits exactly one path and
781
+ // returns a self-certifying commit-pinned reference; read pins to a commit
782
+ // for frozen evidence; list is an ordinary current read.
783
+ const action = resolved[2];
784
+ const taskId = resolved[3];
785
+ const usage = "Usage: yui task artifact list <task> | read <task> <relative-path> [<commit>] | "
786
+ + "save <task> <relative-path> <content> [--message <text>] [--expected-head <commit>]";
787
+ if (taskId === undefined || action === undefined || !["list", "read", "save"].includes(action)) {
788
+ throw usageError(usage);
789
+ }
790
+ if (process.env.YUI_SESSION_SCOPE === "task" && process.env.YUI_TASK_ID !== taskId) {
791
+ throw usageError("Artifact is outside the managed Task scope.");
792
+ }
793
+ if (store.getTask(taskId) === null)
794
+ throw usageError(`Task not found: ${taskId}.`);
795
+ let data;
796
+ if (action === "list") {
797
+ if (resolved.length !== 4)
798
+ throw usageError(usage);
799
+ data = await listArtifactsCapability(home, taskId);
800
+ }
801
+ else if (action === "read") {
802
+ const relativePath = resolved[4];
803
+ const commit = resolved[5];
804
+ if (relativePath === undefined || resolved.length > 6)
805
+ throw usageError(usage);
806
+ data = await readArtifactCapability(home, taskId, {
807
+ relativePath, ...(commit === undefined ? {} : { commit })
808
+ });
809
+ }
810
+ else {
811
+ // save: a delivery-authoritative action; a managed Task caller must be the current Leader.
812
+ taskLocalActor(store, process.env, taskId);
813
+ const relativePath = resolved[4];
814
+ const content = resolved[5];
815
+ if (relativePath === undefined || content === undefined)
816
+ throw usageError(usage);
817
+ const rest = resolved.slice(6);
818
+ let message;
819
+ let expectedHead;
820
+ for (let index = 0; index < rest.length; index += 1) {
821
+ const value = rest[index + 1];
822
+ if (rest[index] === "--message" && value !== undefined) {
823
+ message = value;
824
+ index += 1;
825
+ continue;
826
+ }
827
+ if (rest[index] === "--expected-head" && value !== undefined) {
828
+ expectedHead = value;
829
+ index += 1;
830
+ continue;
831
+ }
832
+ throw usageError(usage);
833
+ }
834
+ data = await saveArtifactCapability(home, taskId, {
835
+ relativePath, content,
836
+ ...(message === undefined ? {} : { message }),
837
+ ...(expectedHead === undefined ? {} : { expectedHead })
838
+ });
839
+ }
840
+ emit(JSON.stringify(data, null, 2), false, data);
841
+ return;
842
+ }
782
843
  if (resolved[1] === "execution") {
783
844
  if (resolved[2] === "stop") {
784
845
  const request = parseTaskExecutionStopRequest(resolved.slice(3));
@@ -803,7 +864,7 @@ export async function main() {
803
864
  if (task === null)
804
865
  throw usageError(`Task not found: ${taskId}.`);
805
866
  // Reject managed Task callers before inspecting or starting runtime resources.
806
- if (taskActor(process.env, taskId) === "leader") {
867
+ if (taskLocalActor(store, process.env, taskId) === "leader") {
807
868
  throw usageError("Task execution stop/start requires the global Operator or a human user.");
808
869
  }
809
870
  if (task.executionGate.state === "stopped") {
@@ -845,7 +906,7 @@ export async function main() {
845
906
  },
846
907
  candidateForTask: async (taskId) => {
847
908
  const status = store.getTask(taskId)?.status;
848
- return status === "active" || status === "retired"
909
+ return status === "active" || status === "cancelled"
849
910
  ? snapshotActualTaskReviewCandidate(taskId, store, workspacePreparer)
850
911
  : null;
851
912
  },
@@ -911,7 +972,7 @@ export async function main() {
911
972
  throw usageError("Task work capture usage: yui task work capture <task>/<work>.");
912
973
  }
913
974
  const reference = cliWorkItemReference(workItemId, process.env);
914
- taskActor(process.env, reference.taskId);
975
+ assertTaskDeliveryAuthority(store, process.env, reference.taskId);
915
976
  const changeSets = await new WorkItemChangeSetManager(store).capture(reference.taskId, reference.localId, taskFinalReviewContract === undefined
916
977
  ? {}
917
978
  : { taskFinalReviewContract });
@@ -932,7 +993,7 @@ export async function main() {
932
993
  }
933
994
  const reference = cliWorkItemReference(workItemId, process.env);
934
995
  const qualified = `${reference.taskId}/${reference.localId}`;
935
- taskActor(process.env, reference.taskId);
996
+ assertTaskDeliveryAuthority(store, process.env, reference.taskId);
936
997
  if (disposition === "--runtime-only") {
937
998
  let runtimeCleanup;
938
999
  try {
@@ -1024,7 +1085,7 @@ export async function main() {
1024
1085
  .flatMap(({ owner }) => owner.type === "work-item" ? [owner.workItemId] : []);
1025
1086
  for (const workItemId of workItemIds) {
1026
1087
  const item = store.getWorkItem(task.id, workItemId);
1027
- if (item?.status !== "completed" || disposition !== "integrated")
1088
+ if (item?.status !== "accepted" || disposition !== "integrated")
1028
1089
  continue;
1029
1090
  try {
1030
1091
  await new WorkItemChangeSetManager(store).assertIntegrated(task.id, item.id);
@@ -1071,15 +1132,15 @@ export async function main() {
1071
1132
  if (item !== null && task !== null) {
1072
1133
  // Authority and pure Lane-shape checks precede every physical or
1073
1134
  // durable workspace preparation performed for dispatch.
1074
- taskActor(process.env, task.id);
1135
+ assertTaskDeliveryAuthority(store, process.env, task.id);
1075
1136
  if (item.assignee !== undefined) {
1076
1137
  workItemDispatchLanePlan(resolved, store, item);
1077
1138
  }
1078
1139
  }
1079
1140
  // A rejected Candidate starts a new execution iteration. Release every
1080
1141
  // terminal Lane Role runtime before preparing the new Lane workspaces;
1081
- // durable Turns, Groups, Candidates, and workspace owners remain intact.
1082
- if (item?.status === "failed"
1142
+ // durable AgentRuns, Groups, Candidates, and workspace owners remain intact.
1143
+ if (item?.status === "open"
1083
1144
  && currentWorkItemExecutionGroup(item)?.lanes.every(({ disposition }) => disposition !== "open")) {
1084
1145
  await workspaceCoordinator.cleanupWorkItemRuntime(item.taskId, item.id);
1085
1146
  }
@@ -1118,7 +1179,7 @@ export async function main() {
1118
1179
  try {
1119
1180
  const reference = cliWorkItemReference(workItemId, process.env);
1120
1181
  workItemIntegrationProof = await new WorkItemChangeSetManager(store)
1121
- .assertIntegrated(reference.taskId, reference.localId) ?? undefined;
1182
+ .assertIntegrated(reference.taskId, reference.localId, optionValue(resolved, "--candidate")) ?? undefined;
1122
1183
  }
1123
1184
  catch (error) {
1124
1185
  throw usageError(error instanceof Error ? error.message : String(error));
@@ -1204,6 +1265,11 @@ export async function main() {
1204
1265
  ? await actualTaskReviewCandidateForTaskCommand(resolved, store, workspacePreparer, process.env)
1205
1266
  : archiveTaskReviewCandidate;
1206
1267
  const deltaRecheckPreflight = await deltaRecheckPreflightForTaskCommand(resolved.slice(1), store, actualTaskReviewCandidate);
1268
+ // Read-only, and only for a Session inspect. The command itself stays
1269
+ // synchronous over persisted state; this is the live reading it prints
1270
+ // beside those facts, prepared here because the Host is reached over a
1271
+ // socket.
1272
+ const liveRunConfiguration = await liveRunConfigurationForTaskCommand(resolved, store, home);
1207
1273
  // Physical preparation may precede the durable write, but Task status,
1208
1274
  // workspace identity/cwd, and ManagedWorkspace ownership are adopted by
1209
1275
  // one transaction. A failed attempt therefore leaves the Task Draft and
@@ -1213,7 +1279,8 @@ export async function main() {
1213
1279
  const taskId = resolved[2];
1214
1280
  const task = taskId === undefined ? null : store.getTask(taskId);
1215
1281
  if (task !== null && task.status === "draft") {
1216
- taskWorkspaceActivation = await workspacePreparer.activateTaskWorkspace(task.id);
1282
+ taskLocalActor(store, process.env, task.id);
1283
+ taskWorkspaceActivation = await workspacePreparer.activateTaskWorkspace(task.id, process.env);
1217
1284
  }
1218
1285
  }
1219
1286
  const result = runTaskCommand(resolved.slice(1), store, {
@@ -1242,6 +1309,9 @@ export async function main() {
1242
1309
  ...(deltaRecheckPreflight === undefined
1243
1310
  ? {}
1244
1311
  : { deltaRecheckPreflight }),
1312
+ ...(liveRunConfiguration === undefined
1313
+ ? {}
1314
+ : { liveRunConfiguration }),
1245
1315
  ...(taskRetirementProof === undefined ? {} : { taskRetirementProof }),
1246
1316
  ...(validateAgentConfiguration === undefined
1247
1317
  ? {}
@@ -1263,13 +1333,13 @@ export async function main() {
1263
1333
  let reviewData;
1264
1334
  const resumesReviewDispatch = (resolved[1] === "review" && resolved[2] === "request")
1265
1335
  || (resolved[1] === "work" && resolved[2] === "review")
1266
- || (resolved[1] === "turn" && resolved[2] === "retry");
1336
+ || (resolved[1] === "run" && resolved[2] === "retry");
1267
1337
  const reviewDispatchNeeded = requestedRound?.status === "pending"
1268
1338
  || (requestedRound?.status === "running"
1269
1339
  && resumesReviewDispatch
1270
1340
  && persistedRequestedRound?.executionGroup?.lanes.some((lane) => (lane.disposition === "open"
1271
- && (lane.currentTurnId === undefined
1272
- || store.getTurn(requestedRound.taskId, lane.currentTurnId)?.status === "failed"))) === true);
1341
+ && (lane.currentRunId === undefined
1342
+ || store.getRun(requestedRound.taskId, lane.currentRunId)?.status === "failed"))) === true);
1273
1343
  if (reviewDispatchNeeded) {
1274
1344
  try {
1275
1345
  const workspace = requestedRound.status === "running"
@@ -1319,7 +1389,7 @@ export async function main() {
1319
1389
  kind: "started",
1320
1390
  reviewerRoleName: requestedRound.reviewerRoleName,
1321
1391
  reviewRoundId: requestedRound.id,
1322
- turnId: run.id
1392
+ runId: run.id
1323
1393
  },
1324
1394
  reviewRound: store.getReviewRound(requestedRound.taskId, requestedRound.id),
1325
1395
  ...(run === null ? {} : { reviewRun: run }),
@@ -1372,7 +1442,6 @@ export async function main() {
1372
1442
  agentId: result.agentId,
1373
1443
  adapterId: result.adapterId,
1374
1444
  nativeSessionId: result.nativeSessionId,
1375
- ...(result.runtimeGenerationId === undefined ? {} : { runtimeGenerationId: result.runtimeGenerationId }),
1376
1445
  sessionUpdatedAt: result.sessionUpdatedAt
1377
1446
  });
1378
1447
  }
@@ -1446,7 +1515,7 @@ export async function main() {
1446
1515
  }
1447
1516
  finally {
1448
1517
  const currentTask = store.getTask(result.taskId);
1449
- // Completing or retiring the Task from inside the takeover Turn owns
1518
+ // Completing or retiring the Task from inside the takeover AgentRun owns
1450
1519
  // Provider shutdown and clears the live binding. Do not turn that
1451
1520
  // successful terminal transition into a failing best-effort release.
1452
1521
  if (currentTask?.status === "active") {
@@ -1530,21 +1599,38 @@ async function preflightManagedTaskControlPlane() {
1530
1599
  && ["agent-host", "session-notify", "runtime-hook"].includes(args[1] ?? "");
1531
1600
  const home = resolveYuiHome(process.env);
1532
1601
  const manifest = assertManagedSessionManifest(home, "task");
1602
+ const diagnosticTarget = taskDiagnosticTarget(args);
1603
+ const diagnostic = diagnosticTarget !== undefined
1604
+ && diagnosticTarget === process.env.YUI_TASK_ID;
1605
+ if (diagnosticTarget !== undefined && !diagnostic) {
1606
+ throw usageError("Diagnostics must remain within this Session's Task.");
1607
+ }
1533
1608
  // One gate for every managed command: the current CLI, Home, and Controller
1534
1609
  // must agree. Internal callbacks must still be able to append their immutable
1535
1610
  // fact while the Controller is offline.
1536
- await assertRuntimeCoherence({ actualHome: home }, { checkController: !internalCallback });
1611
+ await assertRuntimeCoherence({ actualHome: home }, { checkController: !internalCallback && !diagnostic });
1537
1612
  const verifiedStore = openCurrentTaskStore(home);
1538
1613
  // One authority for "may this process act as this Task Role?". Yui's own
1539
1614
  // internal callbacks run inside the Host process Yui itself launched; an Agent
1540
1615
  // command proves it is the Role's current runtime with its per-Session caller
1541
1616
  // key. Nothing here
1542
- // gates on the current Turn: which Turn is active is durable state that the
1617
+ // gates on the current AgentRun: which AgentRun is active is durable state that the
1543
1618
  // command needing it reads, never a fact frozen into a process environment.
1544
1619
  const runtime = internalCallback
1545
1620
  ? undefined
1546
- : requireManagedTaskCaller(verifiedStore, process.env);
1621
+ : diagnostic
1622
+ ? resolveManagedTaskReader(verifiedStore, process.env)
1623
+ : requireManagedTaskCaller(verifiedStore, process.env);
1624
+ if (diagnostic && runtime?.roleName !== "leader"
1625
+ && !(args[1] === "show"
1626
+ || (args[1] === "role" && args[2] === "session" && args[3] === "inspect"
1627
+ && args[5] === runtime?.roleName))) {
1628
+ // Non-Leaders keep their Assignment-scoped read authorization.
1629
+ requireManagedTaskCaller(verifiedStore, process.env);
1630
+ }
1547
1631
  const request = taskFinalReviewInvocation.request;
1632
+ if (request !== undefined && diagnostic)
1633
+ requireManagedTaskCaller(verifiedStore, process.env);
1548
1634
  if (request === undefined) {
1549
1635
  return { contract: undefined, verifiedStore };
1550
1636
  }
@@ -1579,7 +1665,14 @@ async function preflightManagedGlobalControlPlane() {
1579
1665
  || manifest.roleKind !== expectedRoleKind) {
1580
1666
  throw new Error("Managed global invocation does not match its Session Manifest.");
1581
1667
  }
1582
- await assertRuntimeCoherence({ actualHome: home });
1668
+ if (expectedRoleKind === "operator" && ["doctor", "upgrade", "update"].includes(args[0] ?? "")) {
1669
+ // These commands inspect/adopt the storage contract themselves. Requiring
1670
+ // current storage before reaching upgrade would make recovery impossible.
1671
+ return { contract: undefined, verifiedStore: undefined };
1672
+ }
1673
+ await assertRuntimeCoherence({ actualHome: home }, {
1674
+ checkController: !(expectedRoleKind === "operator" && operatorOfflineCommand(args))
1675
+ });
1583
1676
  return { contract: undefined, verifiedStore: openCurrentTaskStore(home) };
1584
1677
  }
1585
1678
  /**
@@ -1643,7 +1736,7 @@ function cliTaskRecordReference(value, kind, environment) {
1643
1736
  try {
1644
1737
  return resolveTaskRecordReference(value, {
1645
1738
  kind,
1646
- label: kind === "turn" ? "Turn reference" : "ReviewRound reference",
1739
+ label: kind === "run" ? "AgentRun reference" : "ReviewRound reference",
1647
1740
  ...(environment.YUI_TASK_ID === undefined
1648
1741
  ? {}
1649
1742
  : { contextTaskId: environment.YUI_TASK_ID })
@@ -1660,12 +1753,12 @@ function assertWorkItemExecutionDependenciesForCommand(args, store, environment)
1660
1753
  const reference = cliWorkItemReference(args[3], environment);
1661
1754
  item = store.getWorkItem(reference.taskId, reference.localId) ?? undefined;
1662
1755
  }
1663
- else if (args[0] === "task" && args[1] === "turn" && args[2] === "retry"
1756
+ else if (args[0] === "task" && args[1] === "run" && args[2] === "retry"
1664
1757
  && args[3] !== undefined) {
1665
- const reference = cliTaskRecordReference(args[3], "turn", environment);
1666
- const turn = store.getTurn(reference.taskId, reference.localId);
1667
- item = turn?.purpose === "execution" && turn.workItemId !== undefined
1668
- ? store.getWorkItem(turn.taskId, turn.workItemId) ?? undefined
1758
+ const reference = cliTaskRecordReference(args[3], "run", environment);
1759
+ const run = store.getRun(reference.taskId, reference.localId);
1760
+ item = run?.purpose === "execution" && run.workItemId !== undefined
1761
+ ? store.getWorkItem(run.taskId, run.workItemId) ?? undefined
1669
1762
  : undefined;
1670
1763
  }
1671
1764
  if (item === undefined)
@@ -1720,7 +1813,7 @@ async function prepareExecutionLaneWorkspacesForCommand(args, store, preparer, e
1720
1813
  if (store.getRole(item.taskId, roleName) === null) {
1721
1814
  throw usageError(`Task Role not found: ${item.taskId}/${roleName}.`);
1722
1815
  }
1723
- if (store.getActiveTurn(item.taskId, roleName) !== null) {
1816
+ if (store.getActiveRun(item.taskId, roleName) !== null) {
1724
1817
  throw usageError(`${item.taskId}/${roleName} already has an active turn.`);
1725
1818
  }
1726
1819
  }
@@ -1759,7 +1852,7 @@ function workItemDispatchLanePlan(args, store, item) {
1759
1852
  const roles = args.flatMap((value, index) => (value === "--lane-role" && args[index + 1] !== undefined
1760
1853
  ? [args[index + 1]]
1761
1854
  : []));
1762
- const groupId = `execution-group-${store.peekNextTurnId(item.taskId)}`;
1855
+ const groupId = `execution-group-${store.peekNextRunId(item.taskId)}`;
1763
1856
  return {
1764
1857
  groupId,
1765
1858
  ...planReplicatedWorkItemLanes(item.assignee, roles, groupId)
@@ -1855,11 +1948,11 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
1855
1948
  taskId = reference.taskId;
1856
1949
  }
1857
1950
  }
1858
- else if (args[1] === "turn"
1951
+ else if (args[1] === "run"
1859
1952
  && (args[2] === "retry" || args[2] === "settle")
1860
1953
  && args[3] !== undefined) {
1861
- const reference = cliTaskRecordReference(args[3], "turn", environment);
1862
- const run = store.getTurn(reference.taskId, reference.localId);
1954
+ const reference = cliTaskRecordReference(args[3], "run", environment);
1955
+ const run = store.getRun(reference.taskId, reference.localId);
1863
1956
  const round = run?.reviewRoundId === undefined
1864
1957
  ? null
1865
1958
  : store.getReviewRound(reference.taskId, run.reviewRoundId);
@@ -1875,7 +1968,6 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
1875
1968
  taskId = store.getTask(args[2])?.id;
1876
1969
  }
1877
1970
  else if ((args[1] === "show"
1878
- || args[1] === "context"
1879
1971
  || args[1] === "next-action"
1880
1972
  || args[1] === "remote-delivery")
1881
1973
  && args[2] !== undefined) {
@@ -1883,10 +1975,10 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
1883
1975
  decisionSupportRead = true;
1884
1976
  }
1885
1977
  const status = taskId === undefined ? undefined : store.getTask(taskId)?.status;
1886
- if (taskId === undefined || (status !== "active" && status !== "retired"))
1978
+ if (taskId === undefined || (status !== "active" && status !== "cancelled"))
1887
1979
  return undefined;
1888
1980
  try {
1889
- return await snapshotActualTaskReviewCandidate(taskId, store, preparer);
1981
+ return await snapshotActualTaskReviewCandidate(taskId, store, preparer, !decisionSupportRead);
1890
1982
  }
1891
1983
  catch (error) {
1892
1984
  if (decisionSupportRead && error instanceof CliError)
@@ -1894,16 +1986,18 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
1894
1986
  throw error;
1895
1987
  }
1896
1988
  }
1897
- async function snapshotActualTaskReviewCandidate(taskId, store, preparer) {
1989
+ async function snapshotActualTaskReviewCandidate(taskId, store, preparer, prepareWorkspace = true) {
1898
1990
  const task = store.getTask(taskId);
1899
1991
  if (task === null)
1900
1992
  throw usageError(`Task not found: ${taskId}.`);
1901
1993
  if (task.projectBindings.length === 0) {
1902
1994
  throw usageError(`Final Task Review requires a Project-backed Task: ${task.id}.`);
1903
1995
  }
1904
- // Reconcile the durable currentCommit facts from the authoritative Task
1905
- // clones before freezing a completion/review candidate.
1906
- await preparer.prepareTaskWorkspace(task.id);
1996
+ // Mutation preflights reconcile before freezing a candidate. A decision-
1997
+ // support read only observes existing heads; it must not migrate Sessions,
1998
+ // create worktrees or acquire workspace ownership as a side effect.
1999
+ if (prepareWorkspace)
2000
+ await preparer.prepareTaskWorkspace(task.id);
1907
2001
  const workspace = store.getTaskWorkspace(task.id);
1908
2002
  if (workspace === null
1909
2003
  || workspace.owner.type !== "task"
@@ -2075,13 +2169,6 @@ async function executeOperatorSessionControl(control, home, store, runtime, tmux
2075
2169
  await runtime.prepareGlobalRoleEnter(role.name);
2076
2170
  tmux.attachRole("operator", role.name, "auto");
2077
2171
  }
2078
- function adapterLabel(adapterId) {
2079
- return adapterId === "codex"
2080
- ? "Codex"
2081
- : adapterId === "claude"
2082
- ? "Claude"
2083
- : adapterId;
2084
- }
2085
2172
  function renderControllerResult(method, value) {
2086
2173
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
2087
2174
  return JSON.stringify(value);
@@ -2264,6 +2351,65 @@ async function warmLegacyRoleConfigurationMutation(commandArgs, store, catalogs)
2264
2351
  cwd: store.getConfig().defaultWorkspace ?? process.cwd()
2265
2352
  });
2266
2353
  }
2354
+ /**
2355
+ * Ask the live Agent Host what the Session is running under, for a Session
2356
+ * inspect.
2357
+ *
2358
+ * Only for `task role session inspect`. Every other command reads persisted
2359
+ * state and must keep doing so: a query that reached into a running Session
2360
+ * would make reading a Task's records depend on whether an Agent happened to be
2361
+ * up.
2362
+ *
2363
+ * The request is the Host's existing `status` control, which reads state the
2364
+ * Host already holds. It creates no Session, sends no prompt and changes nothing
2365
+ * — which is what lets a read-only inspect use it at all.
2366
+ *
2367
+ * Every failure resolves to `unknown` with the reason rather than propagating:
2368
+ * no Host is running for most Sessions ever inspected, and the persisted facts
2369
+ * the command prints are worth showing regardless of whether a live one answered.
2370
+ */
2371
+ async function liveRunConfigurationForTaskCommand(args, store, home) {
2372
+ if (args[0] !== "task" || args[1] !== "role" || args[2] !== "session"
2373
+ || args[3] !== "inspect" || args.length !== 6) {
2374
+ return undefined;
2375
+ }
2376
+ const taskId = args[4];
2377
+ const roleName = args[5];
2378
+ if (taskId === undefined || roleName === undefined)
2379
+ return undefined;
2380
+ // A Session must be recorded as active before asking. Probing a socket for a
2381
+ // Role that never ran would report a reach failure as if it were a fact about
2382
+ // that Role's Agent.
2383
+ const sessions = store.getTaskRoleSessionSet(taskId, roleName);
2384
+ const active = sessions === null
2385
+ ? undefined
2386
+ : sessions.sessions[sessions.activeAgentId];
2387
+ if (active === undefined)
2388
+ return undefined;
2389
+ if (active.status !== "active") {
2390
+ return unknownAgentRunConfiguration(`This Session is ${active.status}, so there is no live Agent to report what it `
2391
+ + "is running under.");
2392
+ }
2393
+ try {
2394
+ const snapshot = await inspectAgentHost({
2395
+ home,
2396
+ scope: "task",
2397
+ taskId,
2398
+ roleName
2399
+ });
2400
+ if (snapshot.nativeSessionId !== active.nativeSessionId
2401
+ || snapshot.adapterId !== active.adapterId
2402
+ || snapshot.state === "exited" || snapshot.state === "failed") {
2403
+ return unknownAgentRunConfiguration("The Agent Host has no live connection matching the recorded Session.");
2404
+ }
2405
+ return snapshot.runConfiguration ?? unknownAgentRunConfiguration("The Agent Host is running but has no Provider Session open, so no Agent "
2406
+ + "has reported a configuration yet.");
2407
+ }
2408
+ catch (error) {
2409
+ return unknownAgentRunConfiguration("The Agent Host for this Session could not be reached, so its live "
2410
+ + `configuration is unavailable: ${error instanceof Error ? error.message : String(error)}`);
2411
+ }
2412
+ }
2267
2413
  function hasModelOrEffortMutation(args) {
2268
2414
  const operation = (args[0] === "config" && args[1] === "role")
2269
2415
  || (args[0] === "task" && args[1] === "role");
@@ -2336,7 +2482,7 @@ function selectionCall(store, catalogs, method, params) {
2336
2482
  : store.listInputRequests(taskId);
2337
2483
  return params.all === true ? requests : requests.filter((request) => request.status === "open");
2338
2484
  }
2339
- case "task.turn.list": return callOptional(reader, "listTurns", [params.taskId]);
2485
+ case "task.turn.list": return callOptional(reader, "listRuns", [params.taskId]);
2340
2486
  case "task.decision.list": return callOptional(reader, "listDecisions", [params.taskId]);
2341
2487
  case "task.milestone.list": return presentSelectionTimes(callOptional(reader, "listMilestones", [params.taskId]), store);
2342
2488
  case "task.event.list": return presentSelectionTimes(callOptional(reader, "listEvents", [params.taskId]), store);
@@ -2434,6 +2580,10 @@ export function cliIdentity(env) {
2434
2580
  }
2435
2581
  function normalizeAliases(input) {
2436
2582
  const normalized = [...input];
2583
+ // Existing immutable Session Manifests (through 0.15.8) name this entry.
2584
+ // Remove once those Sessions are retired; both names share one handler.
2585
+ if (normalized[0] === "task" && normalized[1] === "turn")
2586
+ normalized[1] = "run";
2437
2587
  if (normalized.length === 1 && (normalized[0] === "-v" || normalized[0] === "--version")) {
2438
2588
  return ["version"];
2439
2589
  }