@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
@@ -78,12 +78,12 @@ export function attachReviewRoundWorkspace(round, workspace) {
78
78
  }
79
79
  return validateReviewRound({ ...round, workspace });
80
80
  }
81
- export function startReviewRound(round, reviewerTurnId) {
81
+ export function startReviewRound(round, reviewerRunId) {
82
82
  validateReviewRound(round);
83
83
  if (round.status !== "pending"
84
84
  && !(round.status === "running"
85
85
  && round.executionGroup !== undefined
86
- && round.reviewerTurnId === undefined)) {
86
+ && round.reviewerRunId === undefined)) {
87
87
  throw new Error(`ReviewRound cannot start from ${round.status}: ${round.id}.`);
88
88
  }
89
89
  if (round.workspace === undefined) {
@@ -91,7 +91,7 @@ export function startReviewRound(round, reviewerTurnId) {
91
91
  }
92
92
  return validateReviewRound({
93
93
  ...round,
94
- reviewerTurnId: requireIdentity(reviewerTurnId, "Reviewer Turn id"),
94
+ reviewerRunId: requireIdentity(reviewerRunId, "Reviewer AgentRun id"),
95
95
  status: "running"
96
96
  });
97
97
  }
@@ -125,7 +125,7 @@ export function finishReviewRound(round, status, now, failure) {
125
125
  }
126
126
  /**
127
127
  * Retry a failed review execution attempt under the same semantic Round
128
- * identity. Turn history remains the attempt trail; the Round itself returns
128
+ * identity. AgentRun history remains the attempt trail; the Round itself returns
129
129
  * to pending so infrastructure retries do not manufacture a new semantic
130
130
  * ReviewRound or duplicate findings.
131
131
  */
@@ -172,12 +172,13 @@ export function retryReviewRound(round, requestedBy, now) {
172
172
  deletedLines: round.deltaRecheck.deletedLines
173
173
  })
174
174
  }),
175
- // A replicated retry preserves settled successful Producers and reopens
176
- // only failed Lanes. If every Producer succeeded, only the main Reviewer
177
- // Turn is retried.
175
+ // A main retry consumes its already selected sources and leaves every
176
+ // Producer attempt untouched. A pre-main retry reopens failed Lanes only.
178
177
  ...(round.executionGroup === undefined
179
178
  ? {}
180
- : { executionGroup: retryFailedExecutionLanes(round.executionGroup, now) }),
179
+ : { executionGroup: round.reviewerRunId === undefined
180
+ ? retryFailedExecutionLanes(round.executionGroup, now)
181
+ : round.executionGroup }),
181
182
  requestedBy: validateReviewRequestSource(requestedBy),
182
183
  status: "pending",
183
184
  ...(round.workspace === undefined ? {} : { workspace: round.workspace }),
@@ -191,16 +192,16 @@ export function retryTaskReviewRound(round, requestedBy, now) {
191
192
  }
192
193
  return retryReviewRound(round, requestedBy, now);
193
194
  }
194
- /** A failed producer attempt leaves its logical Lane open for another Turn. */
195
- export function retryRunningReviewExecutionLane(round, executionLaneId, turnId) {
195
+ /** A failed producer attempt leaves its logical Lane open for another AgentRun. */
196
+ export function retryRunningReviewExecutionLane(round, executionLaneId, runId) {
196
197
  validateReviewRound(round);
197
198
  if (round.status !== "running" || round.executionGroup === undefined) {
198
199
  throw new Error(`ReviewRound ${round.id} has no running ExecutionGroup.`);
199
200
  }
200
201
  const lane = round.executionGroup.lanes.find(({ id }) => id === executionLaneId);
201
- if (lane === undefined || lane.disposition !== "open" || lane.currentTurnId !== turnId) {
202
+ if (lane === undefined || lane.disposition !== "open" || lane.currentRunId !== runId) {
202
203
  throw new Error(`Review retry does not target the current failed Lane attempt: `
203
- + `${round.executionGroup.id}/${executionLaneId}/${turnId}.`);
204
+ + `${round.executionGroup.id}/${executionLaneId}/${runId}.`);
204
205
  }
205
206
  return round;
206
207
  }
@@ -268,7 +269,7 @@ export function validateReviewRound(round) {
268
269
  "workItemId",
269
270
  "candidateId",
270
271
  "reviewerRoleName",
271
- "reviewerTurnId",
272
+ "reviewerRunId",
272
273
  "reviewBaseCommit",
273
274
  "scope",
274
275
  "taskCandidate",
@@ -338,19 +339,19 @@ export function validateReviewRound(round) {
338
339
  }
339
340
  validateDeltaRecheckRecord(round.deltaRecheck);
340
341
  }
341
- if (round.reviewerTurnId !== undefined) {
342
+ if (round.reviewerRunId !== undefined) {
342
343
  validateTaskRecordReference({
343
344
  taskId: round.taskId,
344
- localId: round.reviewerTurnId
345
- }, "turn");
345
+ localId: round.reviewerRunId
346
+ }, "run");
346
347
  }
347
348
  if (round.workspace !== undefined)
348
349
  validateReviewWorkspace(round, round.workspace);
349
350
  requireTimestamp(round.createdAt, "ReviewRound createdAt");
350
351
  const terminal = round.status === "completed" || round.status === "failed";
351
352
  if (terminal) {
352
- if (round.status === "completed" && round.reviewerTurnId === undefined) {
353
- throw new Error("A completed ReviewRound requires its exact main Reviewer Turn.");
353
+ if (round.status === "completed" && round.reviewerRunId === undefined) {
354
+ throw new Error("A completed ReviewRound requires its exact main Reviewer AgentRun.");
354
355
  }
355
356
  if (round.status === "completed" && round.failure !== undefined) {
356
357
  throw new Error("A completed ReviewRound cannot carry failure metadata.");
@@ -370,9 +371,9 @@ export function validateReviewRound(round) {
370
371
  throw new Error("A running ReviewRound requires its main Reviewer workspace.");
371
372
  }
372
373
  if (round.status === "running"
373
- && round.reviewerTurnId === undefined
374
+ && round.reviewerRunId === undefined
374
375
  && round.executionGroup === undefined) {
375
- throw new Error("A running ReviewRound requires a direct Reviewer Turn or replicated Group.");
376
+ throw new Error("A running ReviewRound requires a direct Reviewer AgentRun or replicated Group.");
376
377
  }
377
378
  if (round.workspaceDisposition !== undefined) {
378
379
  if (!terminal || round.workspace === undefined) {
@@ -2,13 +2,13 @@ import { nextPendingBatch, mailboxHasWork } from "../coordination/workMailbox.js
2
2
  import { runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
3
3
  /** One authoritative read-only projection for a Task Reviewer Role slot. */
4
4
  export function projectReviewerAvailability(store, taskId, reviewerRoleName) {
5
- const active = store.getActiveTurn(taskId, reviewerRoleName);
5
+ const active = store.getActiveRun(taskId, reviewerRoleName);
6
6
  if (active !== null) {
7
7
  return {
8
8
  kind: "busy",
9
9
  reviewerRoleName,
10
10
  phase: "active-turn",
11
- activeTurnId: active.id,
11
+ activeRunId: active.id,
12
12
  ...(active.reviewRoundId === undefined
13
13
  ? {}
14
14
  : { activeReviewRoundId: active.reviewRoundId }),
package/dist/role/role.js CHANGED
@@ -1,9 +1,20 @@
1
1
  import { isDeepStrictEqual } from "node:util";
2
+ import { validateExecutionEnvironmentSnapshot } from "../resources/projectResource.js";
3
+ import { isAgentAdapterId } from "../agent/adapterCatalog.js";
4
+ import { adapterIdForExecutionComponent, resolveAgentExecutionComponent } from "../agent/executionComponents.js";
2
5
  import { defaultRoleAgentConfig, resolveAgentAdapter } from "../executor/agentAdapter.js";
3
6
  import { validateRoleSessionSet } from "../executor/agentExecutor.js";
7
+ /**
8
+ * The Agent argument is the stored record, not a hand-picked pair of fields.
9
+ * `component` is required for exactly that reason: an Agent registered as the
10
+ * Claude Agent SDK that reached a Role binding as `unknown-acp-agent` would be
11
+ * silently demoted, and an optional parameter makes that a quiet default
12
+ * instead of a compile error at the call site that forgot it.
13
+ */
4
14
  export function createRoleAgentBinding(agent, config) {
5
15
  const agentId = requireSafeIdentity(agent.id, "Role Agent id");
6
16
  const adapterId = requireSupportedAdapterId(agent.adapterId);
17
+ const component = resolveAgentExecutionComponent(adapterId, agent.component);
7
18
  const defaults = defaultRoleAgentConfig(adapterId);
8
19
  const effectiveConfig = config === undefined
9
20
  ? defaults
@@ -13,7 +24,7 @@ export function createRoleAgentBinding(agent, config) {
13
24
  if (effectiveConfig.adapterId !== adapterId) {
14
25
  throw new Error(`Role Agent config adapter does not match Agent: ${agentId}.`);
15
26
  }
16
- return cloneBinding({ agentId, adapterId, config: effectiveConfig });
27
+ return cloneBinding({ agentId, component, adapterId, config: effectiveConfig });
17
28
  }
18
29
  export function createRole(taskId, name, bindings, activeAgentId, workspace, now, profile = {}, defaultAccess = "write") {
19
30
  const owner = createRoleOwner(name, bindings, activeAgentId, workspace, now, profile, defaultAccess);
@@ -72,6 +83,11 @@ export function updateRole(role, patch, now) {
72
83
  ...cloneRolePatch(patch),
73
84
  updatedAt: now.toISOString()
74
85
  };
86
+ if (patch.executionEnvironment === null)
87
+ delete updated.executionEnvironment;
88
+ else if (patch.executionEnvironment !== undefined) {
89
+ updated.executionEnvironment = cloneJson(patch.executionEnvironment);
90
+ }
75
91
  clearProfileFields(updated, patch);
76
92
  updated.launchRevision = isDeepStrictEqual(desiredBefore, desiredLaunchProjection(updated))
77
93
  ? role.launchRevision
@@ -93,7 +109,7 @@ export function switchActiveRoleAgent(role, sessions, targetAgentId, runtime, no
93
109
  : updateGlobalRole(role, { activeAgentId: normalizedTarget }, now);
94
110
  // A running process keeps its immutable effective identity. The desired
95
111
  // switch becomes visible only when the next launch is planned.
96
- const updatedSessions = runtime.activeTurn || runtime.nativeProcessRunning
112
+ const updatedSessions = runtime.activeRun || runtime.nativeProcessRunning
97
113
  ? sessions
98
114
  : {
99
115
  ...sessions,
@@ -129,11 +145,11 @@ export function unbindRoleAgent(role, sessions, agentId, now) {
129
145
  const taskSessions = sessions.owner.scope === "task"
130
146
  ? sessions
131
147
  : null;
132
- if (taskSessions?.providerBinding?.turn !== null
133
- && taskSessions?.providerBinding?.turn !== undefined
148
+ if (taskSessions?.providerBinding?.run !== null
149
+ && taskSessions?.providerBinding?.run !== undefined
134
150
  && taskSessions.activeAgentId === normalizedAgentId
135
- && ["submitting", "accepted", "running"].includes(taskSessions.providerBinding.turn.status)) {
136
- throw new Error(`Cannot unbind Role Agent with an active Turn: ${normalizedAgentId}.`);
151
+ && ["submitting", "accepted", "running"].includes(taskSessions.providerBinding.run.status)) {
152
+ throw new Error(`Cannot unbind Role Agent with an active AgentRun: ${normalizedAgentId}.`);
137
153
  }
138
154
  const targetSession = sessions.sessions[normalizedAgentId];
139
155
  if (targetSession !== undefined && targetSession.status === "active") {
@@ -215,6 +231,14 @@ function validateRoleOwner(role) {
215
231
  requireSafeIdentity(role.name, "Role name");
216
232
  requireSafeIdentity(role.activeAgentId, "Role active Agent id");
217
233
  requireText(role.workspace, "Role workspace");
234
+ if ("executionEnvironment" in role && role.executionEnvironment !== undefined) {
235
+ if (!("taskId" in role))
236
+ throw new Error("Only a Task Role may bind an execution environment.");
237
+ validateExecutionEnvironmentSnapshot(role.executionEnvironment);
238
+ if (role.executionEnvironment.taskId !== role.taskId) {
239
+ throw new Error("Role execution environment belongs to another Task.");
240
+ }
241
+ }
218
242
  const entries = Object.entries(role.agentBindings);
219
243
  if (entries.length === 0)
220
244
  throw new Error("Role requires at least one Agent binding.");
@@ -232,6 +256,16 @@ function validateRoleOwner(role) {
232
256
  function validateRoleAgentBinding(binding) {
233
257
  const agentId = requireSafeIdentity(binding.agentId, "Role Agent id");
234
258
  const adapterId = requireSupportedAdapterId(binding.adapterId);
259
+ // Storage 10 backfilled every stored binding, so a missing component here is
260
+ // a corrupt record rather than an old one. Defaulting it would invent a
261
+ // product identity for data that never lost one.
262
+ if (binding.component === undefined) {
263
+ throw new Error(`Role Agent binding is missing its execution component: ${agentId}.`);
264
+ }
265
+ const component = resolveAgentExecutionComponent(adapterId, binding.component);
266
+ if (adapterIdForExecutionComponent(component) !== adapterId) {
267
+ throw new Error(`Role Agent binding execution component is inconsistent: ${agentId}.`);
268
+ }
235
269
  if (binding.config === null || typeof binding.config !== "object" || Array.isArray(binding.config)) {
236
270
  throw new Error(`Role Agent config is invalid: ${agentId}.`);
237
271
  }
@@ -272,6 +306,9 @@ function desiredLaunchProjection(role) {
272
306
  agentBindings: role.agentBindings,
273
307
  workspace: role.workspace,
274
308
  defaultAccess: role.defaultAccess,
309
+ ...("taskId" in role && role.executionEnvironment !== undefined
310
+ ? { executionEnvironment: role.executionEnvironment }
311
+ : {}),
275
312
  ...cloneProfile(role)
276
313
  };
277
314
  }
@@ -281,6 +318,10 @@ function cloneBindings(bindings) {
281
318
  function cloneBinding(binding) {
282
319
  return {
283
320
  agentId: binding.agentId,
321
+ // Copied, never re-derived. Cloning is not the place to decide what an
322
+ // absent component means: validation above already refuses that record,
323
+ // and resolving here would hide the refusal behind a plausible default.
324
+ component: binding.component,
284
325
  adapterId: binding.adapterId,
285
326
  config: cloneJson(binding.config)
286
327
  };
@@ -313,7 +354,10 @@ function cloneJson(value) {
313
354
  }
314
355
  function requireSupportedAdapterId(value) {
315
356
  const normalized = requireText(value, "Role Agent adapter id");
316
- if (normalized !== "codex" && normalized !== "claude") {
357
+ // The catalog defines which adapters exist. A second list here would let a
358
+ // catalogued adapter be registered as an Agent and then rejected when a Role
359
+ // binds to it, which reads as corruption rather than as the missing entry.
360
+ if (!isAgentAdapterId(normalized)) {
317
361
  throw new Error(`Role Agent adapter is unsupported: ${normalized}.`);
318
362
  }
319
363
  return normalized;
@@ -0,0 +1,30 @@
1
+ import { createTaskEvent } from "../event/taskEvent.js";
2
+ import { enqueueWork } from "../coordination/workMailboxQueue.js";
3
+ /** Called inside the owner's transaction, after authorization and validation.
4
+ * Current Role, history and durable wake are one mutation. Runtime notification
5
+ * belongs to the entry point, only after the outer transaction commits.
6
+ */
7
+ export function saveTaskRoleUpdate(store, previous, current, now, source) {
8
+ store.saveRole(current.taskId, current);
9
+ store.saveEvent(current.taskId, createTaskEvent(store.nextEventId(current.taskId), current.taskId, "role.updated", {
10
+ ...source,
11
+ role: current.name,
12
+ ...roleLaunchEventPayload(current, store.getTaskRoleSessionSet(current.taskId, current.name)),
13
+ previous: JSON.stringify(previous),
14
+ current: JSON.stringify(current)
15
+ }, now));
16
+ enqueueWork(store, { kind: "task", taskId: current.taskId }, "role-updated", now, [{ type: "task", id: current.taskId }]);
17
+ }
18
+ export function roleLaunchEventPayload(role, sessions) {
19
+ const effective = sessions?.sessions[sessions.activeAgentId]?.effective;
20
+ return {
21
+ desiredRevision: String(role.launchRevision),
22
+ defaultAccess: role.defaultAccess,
23
+ effectiveRevision: effective === undefined ? "none" : String(effective.sourceDesiredRevision),
24
+ profileAccess: effective?.profileAccess ?? "none",
25
+ effectivePermission: effective?.permission.strategy ?? "none",
26
+ desiredDrift: effective === undefined
27
+ ? "not-started"
28
+ : effective.sourceDesiredRevision === role.launchRevision ? "none" : "pending-next-launch"
29
+ };
30
+ }