@zq-silk/yui 0.13.10 → 0.14.1

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 (230) hide show
  1. package/ARCHITECTURE.md +69 -428
  2. package/README.md +113 -300
  3. package/dist/agent/argumentPolicy.js +2 -1
  4. package/dist/agent/managedRuntimeEnvironment.js +2 -2
  5. package/dist/cli/commandCatalog.js +39 -77
  6. package/dist/cli/interactionCandidates.js +4 -4
  7. package/dist/cli/interactionPolicy.js +7 -10
  8. package/dist/cli/invocationRouter.js +1 -1
  9. package/dist/cli/updateCommand.js +6 -27
  10. package/dist/cli/updateOrchestrator.js +63 -484
  11. package/dist/cli/updatePorts.js +15 -333
  12. package/dist/cli/upgradeCommand.js +8 -65
  13. package/dist/cli.js +57 -242
  14. package/dist/commands/configCommands.js +11 -62
  15. package/dist/commands/executionAuditCommands.js +23 -23
  16. package/dist/commands/globalRoleCommands.js +2 -7
  17. package/dist/commands/jobCommands.js +1 -4
  18. package/dist/commands/projectCommands.js +5 -5
  19. package/dist/commands/releaseCommands.js +3 -10
  20. package/dist/commands/resourcesCommands.js +2 -2
  21. package/dist/commands/sessionCommands.js +2 -2
  22. package/dist/commands/taskActor.js +31 -39
  23. package/dist/commands/taskChangeSetCommands.js +5 -12
  24. package/dist/commands/taskCommands.js +464 -1249
  25. package/dist/commands/taskContextCommand.js +35 -36
  26. package/dist/commands/taskExecutionCommands.js +33 -46
  27. package/dist/commands/taskInputCommands.js +20 -42
  28. package/dist/commands/taskNextActionCommand.js +9 -9
  29. package/dist/commands/taskOverviewCommand.js +56 -95
  30. package/dist/commands/taskRoleRuntimeStatus.js +77 -107
  31. package/dist/commands/taskUpstreamCommands.js +3 -3
  32. package/dist/commands/taskWorkspaceCommands.js +7 -79
  33. package/dist/commands/telemetryCommands.js +32 -124
  34. package/dist/commands/workflowCommands.js +3 -3
  35. package/dist/completion/fileCompletionManager.js +1 -1
  36. package/dist/config/configCatalog.js +4 -6
  37. package/dist/config/yuiConfig.js +6 -43
  38. package/dist/context/dispatchContext.js +14 -30
  39. package/dist/context/roleSessionContext.js +2 -2
  40. package/dist/context/sessionBootstrapManifest.js +20 -3
  41. package/dist/context/{runContextPack.js → turnContextPack.js} +58 -73
  42. package/dist/context/turnInputContract.js +204 -0
  43. package/dist/context/wakeNotification.js +2 -2
  44. package/dist/controller/agentRuntimeObserver.js +18 -18
  45. package/dist/controller/clientRuntime.js +13 -20
  46. package/dist/controller/controller.js +89 -116
  47. package/dist/controller/fileSchedulerStoreAdapter.js +511 -742
  48. package/dist/controller/jobControl.js +17 -17
  49. package/dist/controller/resourceInventory.js +6 -6
  50. package/dist/controller/resourceInventoryLinux.js +38 -59
  51. package/dist/controller/resourceInventoryRpc.js +3 -3
  52. package/dist/controller/resourceInventoryWorker.js +1 -1
  53. package/dist/controller/runtime.js +46 -53
  54. package/dist/controller/runtimeEventInbox.js +23 -31
  55. package/dist/controller/runtimeEventProcessor.js +15 -15
  56. package/dist/controller/{runtimeHookRunFence.js → runtimeHookTurnFence.js} +87 -81
  57. package/dist/controller/runtimeLaunchCoordinator.js +3 -3
  58. package/dist/controller/runtimeObservationHook.js +11 -8
  59. package/dist/controller/sessionNotify.js +11 -11
  60. package/dist/controller/structuredProviderObservation.js +89 -16
  61. package/dist/coordination/workMailbox.js +309 -579
  62. package/dist/coordination/workMailboxQueue.js +5 -6
  63. package/dist/core/controllerClient.js +1 -91
  64. package/dist/core/controllerServer.js +3 -6
  65. package/dist/doctor/doctor.js +51 -314
  66. package/dist/execution/candidateConvergence.js +3 -3
  67. package/dist/execution/executionGroup.js +32 -33
  68. package/dist/execution/executionHealth.js +36 -38
  69. package/dist/execution/resourceBroker.js +12 -12
  70. package/dist/executor/agentExecutor.js +30 -265
  71. package/dist/executor/effectiveLaunch.js +9 -19
  72. package/dist/executor/executorRegistry.js +43 -17
  73. package/dist/executor/fileRoleLaunchPlanner.js +91 -57
  74. package/dist/executor/launchPlan.js +3 -3
  75. package/dist/executor/workspacePreflightClassification.js +16 -16
  76. package/dist/grant/capabilityGrant.js +20 -25
  77. package/dist/input/inputRequest.js +12 -12
  78. package/dist/integration/changeSet.js +9 -13
  79. package/dist/integration/changeSetManifest.js +1 -1
  80. package/dist/integration/gitIntegrationService.js +2 -2
  81. package/dist/integration/integrationQueueService.js +5 -21
  82. package/dist/integration/overlapDiagnostics.js +2 -2
  83. package/dist/interaction/operatorPresentation.js +1 -1
  84. package/dist/job/jobRunner.js +1 -1
  85. package/dist/lifecycle/canonicalLifecycleEvent.js +25 -25
  86. package/dist/lifecycle/{exactRunTerminalization.js → exactTurnTerminalization.js} +116 -232
  87. package/dist/message/message.js +6 -6
  88. package/dist/observability/executionAudit.js +74 -86
  89. package/dist/observability/faultClassification.js +7 -24
  90. package/dist/observability/orchestrationMetrics.js +5 -5
  91. package/dist/observability/runtimeIdentity.js +34 -101
  92. package/dist/profile/agentProfile.js +1 -1
  93. package/dist/release/cliHomeReleaseFence.js +3 -3
  94. package/dist/release/releaseWorkflowEngine.js +6 -10
  95. package/dist/release/releaseWorkflowPorts.js +2 -2
  96. package/dist/release/workflowFileLock.js +1 -1
  97. package/dist/repository/checkoutSwap.js +1 -1
  98. package/dist/repository/gitWorkspace.js +0 -13
  99. package/dist/repository/project.js +1 -1
  100. package/dist/repository/projectMaintenanceLock.js +1 -2
  101. package/dist/repository/taskBaseFreshness.js +13 -13
  102. package/dist/repository/taskWorkspaceCoordinator.js +21 -25
  103. package/dist/repository/taskWorkspaceIdentity.js +8 -21
  104. package/dist/repository/taskWorkspacePreparer.js +63 -620
  105. package/dist/resources/autoResourceGc.js +3 -3
  106. package/dist/resources/liveReferences.js +1 -1
  107. package/dist/resources/resourceGc.js +1 -1
  108. package/dist/resources/sqliteResourceRegistry.js +1 -1
  109. package/dist/review/reviewDecision.js +7 -7
  110. package/dist/review/reviewFindingLedger.js +1 -1
  111. package/dist/review/reviewOutcomeClassifier.js +35 -50
  112. package/dist/review/reviewRound.js +14 -25
  113. package/dist/review/reviewerAvailability.js +4 -4
  114. package/dist/review/taskFinalReviewContractResolution.js +41 -0
  115. package/dist/role/role.js +6 -3
  116. package/dist/runtime/agentDriver.js +4 -0
  117. package/dist/runtime/agentHost.js +151 -36
  118. package/dist/runtime/builtinAgentDrivers.js +79 -2
  119. package/dist/runtime/codexAppServerRuntime.js +122 -0
  120. package/dist/runtime/continuationManager.js +3 -5
  121. package/dist/runtime/exactControlPlane.js +17 -42
  122. package/dist/runtime/firstProgressAdvisory.js +1 -1
  123. package/dist/runtime/index.js +2 -2
  124. package/dist/runtime/launchDiagnostics.js +2 -2
  125. package/dist/runtime/lifecycleReservation.js +4 -4
  126. package/dist/runtime/processExitObservation.js +1 -1
  127. package/dist/runtime/processExitOutbox.js +0 -32
  128. package/dist/runtime/promptEnvelope.js +9 -9
  129. package/dist/runtime/providerContinuation.js +2 -2
  130. package/dist/runtime/providerContinuationReconciliationService.js +2 -2
  131. package/dist/runtime/providerRuntimeIdentity.js +76 -24
  132. package/dist/runtime/recentTurnIds.js +38 -0
  133. package/dist/runtime/runtimeContinuationProjection.js +2 -2
  134. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  135. package/dist/runtime/runtimeObservation.js +58 -21
  136. package/dist/runtime/runtimeProjection.js +19 -27
  137. package/dist/runtime/sessionLaunchRequest.js +2 -2
  138. package/dist/runtime/structuredProviderHost.js +177 -12
  139. package/dist/runtime/tmuxAdapters.js +46 -11
  140. package/dist/scheduler/activeRoleTurnDelivery.js +245 -0
  141. package/dist/scheduler/leaderWakeupProcessor.js +147 -445
  142. package/dist/scheduler/operatorEvent.js +4 -6
  143. package/dist/scheduler/resourceQueueProjection.js +71 -0
  144. package/dist/scheduler/{roleRunLiveness.js → roleTurnLiveness.js} +24 -28
  145. package/dist/scheduler/{roleRunStall.js → roleTurnStall.js} +162 -247
  146. package/dist/scheduler/taskExecutionProjection.js +99 -99
  147. package/dist/scheduler/taskObservabilityProjection.js +10 -10
  148. package/dist/scheduler/taskWake.js +4 -4
  149. package/dist/scheduler/wakeReason.js +6 -10
  150. package/dist/scheduler/wakeupQueue.js +0 -9
  151. package/dist/setup/setupCommand.js +2 -2
  152. package/dist/storage/currentTaskStore.js +46 -0
  153. package/dist/storage/persistenceWorker.js +1 -1
  154. package/dist/storage/sqliteSchema.js +81 -485
  155. package/dist/storage/sqliteStore.js +206 -365
  156. package/dist/storage/storageSchema.js +1 -15
  157. package/dist/storage/storageVersions.js +8 -9
  158. package/dist/storage/storeRpc.js +10 -34
  159. package/dist/storage/taskStore.js +63 -3415
  160. package/dist/storage/upgrade/recordVersions.js +55 -149
  161. package/dist/storage/upgrade/upgradeOrchestrator.js +89 -1752
  162. package/dist/task/completionReadiness.js +5 -5
  163. package/dist/task/deliveryGuard.js +10 -10
  164. package/dist/task/nextAction.js +74 -77
  165. package/dist/task/task.js +2 -4
  166. package/dist/task/taskRecordReference.js +3 -3
  167. package/dist/task/taskRecordRetirement.js +1 -1
  168. package/dist/telemetry/sqliteTelemetryStore.js +53 -53
  169. package/dist/telemetry/telemetryConfig.js +14 -14
  170. package/dist/telemetry/telemetryWiring.js +8 -14
  171. package/dist/turn/turn.js +356 -0
  172. package/dist/{run/runIdentity.js → turn/turnIdentity.js} +4 -4
  173. package/dist/verification/gateArtifactStore.js +2 -2
  174. package/dist/web/assets/client/app.js +1 -1
  175. package/dist/web/assets/client/components.js +29 -54
  176. package/dist/web/assets/client/i18n.js +17 -37
  177. package/dist/web/assets/client/view.js +37 -37
  178. package/dist/web/assets/shell.js +1 -1
  179. package/dist/web/assets/styles/cards.js +5 -5
  180. package/dist/web/assets/styles/widgets.js +1 -2
  181. package/dist/web/webSnapshot.js +65 -60
  182. package/dist/workItem/workItem.js +11 -11
  183. package/dist/workspace/workItemChangeSetManager.js +1 -1
  184. package/docs/task-local-identity.md +5 -5
  185. package/i18n/README.zh-CN.md +42 -55
  186. package/package.json +1 -1
  187. package/skills/yui-leader/SKILL.md +85 -83
  188. package/skills/yui-operator/SKILL.md +16 -16
  189. package/skills/yui-reviewer/SKILL.md +10 -10
  190. package/skills/yui-runtime/SKILL.md +22 -24
  191. package/skills/yui-worker/SKILL.md +16 -18
  192. package/dist/context/runContextContract.js +0 -162
  193. package/dist/executor/turnCompletion.js +0 -126
  194. package/dist/review/taskFinalReviewContractEvent.js +0 -1
  195. package/dist/review/taskFinalReviewContractRebind.js +0 -367
  196. package/dist/run/agentRun.js +0 -356
  197. package/dist/run/rejectedYieldAttempt.js +0 -221
  198. package/dist/run/runControlRequest.js +0 -50
  199. package/dist/run/yieldReceipt.js +0 -65
  200. package/dist/runtime/turnCompletion.js +0 -3
  201. package/dist/scheduler/actionability.js +0 -323
  202. package/dist/scheduler/activeRoleRunDelivery.js +0 -868
  203. package/dist/scheduler/activeTaskProgress.js +0 -126
  204. package/dist/storage/compatibleTaskStore.js +0 -248
  205. package/dist/storage/migration/baseline.js +0 -78
  206. package/dist/storage/migration/classifier.js +0 -51
  207. package/dist/storage/migration/compatibleCodec.js +0 -53
  208. package/dist/storage/migration/engine.js +0 -147
  209. package/dist/storage/migration/index.js +0 -33
  210. package/dist/storage/migration/planner.js +0 -154
  211. package/dist/storage/migration/productionRegistry.js +0 -3931
  212. package/dist/storage/migration/registry.js +0 -169
  213. package/dist/storage/migration/report.js +0 -54
  214. package/dist/storage/migration/types.js +0 -31
  215. package/dist/storage/upgrade/homeClassification.js +0 -353
  216. package/dist/storage/upgrade/homeMigrationTarget.js +0 -595
  217. package/dist/storage/upgrade/migrationReceipt.js +0 -67
  218. package/dist/storage/upgrade/offlineUpgradeInventory.js +0 -453
  219. package/dist/storage/upgrade/productionMigrationRegistry.js +0 -6
  220. package/dist/storage/upgrade/pseudoLayoutRepair.js +0 -241
  221. package/dist/storage/upgrade/recordVersionScan.js +0 -176
  222. package/dist/storage/upgrade/sqliteFileSet.js +0 -50
  223. package/dist/storage/upgrade/sqliteMigrationTarget.js +0 -375
  224. package/dist/storage/upgrade/sqliteRecordMigrationTarget.js +0 -305
  225. package/dist/storage/upgrade/sqliteStateMigration.js +0 -926
  226. package/dist/storage/upgrade/switchProgress.js +0 -80
  227. package/dist/storage/upgrade/upgradeReceipt.js +0 -161
  228. package/dist/storage/upgradeCoordination.js +0 -187
  229. package/dist/storage/upgradeFence.js +0 -366
  230. package/dist/telemetry/telemetryCompaction.js +0 -252
@@ -0,0 +1,245 @@
1
+ import { serializeTurnInputEnvelope } from "../context/turnInputContract.js";
2
+ import { effectiveLaunchSnapshotsCompatible, effectiveLaunchSnapshotsCompatibleForTaskSession } from "../executor/effectiveLaunch.js";
3
+ import { RuntimeLifecycleBusyError } from "../runtime/lifecycleReservation.js";
4
+ import { managedProviderTurnId } from "../runtime/providerRuntimeIdentity.js";
5
+ import { serializeAgentErrorRaw } from "../runtime/agentError.js";
6
+ import { RuntimeLaunchFailure } from "../runtime/launchDiagnostics.js";
7
+ import { RuntimeLaunchError } from "../runtime/ports.js";
8
+ import { formatTurnReceiptId } from "../task/taskRecordReference.js";
9
+ import { turnInputEnvelope } from "../turn/turn.js";
10
+ import { isSchedulerTaskWorkspaceReady, selectedActiveSchedulerTasks, selectedSchedulerRoles } from "./ports.js";
11
+ /**
12
+ * Sole managed Provider write path. A Turn is durable workflow intent;
13
+ * each invocation here is an ordinary Provider-native Turn on the Role's
14
+ * shared conversation. Stable request ids make a repeated submit idempotent
15
+ * without copying Provider delivery state into Turn or WorkMailbox.
16
+ */
17
+ export async function processActiveRoleTurnDeliveries(store, delivery, now, selection) {
18
+ const results = [];
19
+ for (const task of selectedActiveSchedulerTasks(store, selection)) {
20
+ for (const role of selectedSchedulerRoles(store, task.id, selection)) {
21
+ const turn = store.getActiveTurn(task.id, role.name);
22
+ if (turn === null)
23
+ continue;
24
+ results.push(await deliverActiveTurn(store, delivery, task, role, turn, now));
25
+ }
26
+ }
27
+ return results;
28
+ }
29
+ async function deliverActiveTurn(store, delivery, task, role, turn, now) {
30
+ const base = { taskId: task.id, roleName: role.name, turnId: turn.id };
31
+ if (!isSchedulerTaskWorkspaceReady(task, store.getTaskWorkspace(task.id))) {
32
+ return { ...base, status: "skipped", reason: "workspace-not-ready" };
33
+ }
34
+ const sessionSet = store.getTaskRoleSessionSet?.(task.id, role.name) ?? null;
35
+ const binding = sessionSet?.providerBinding ?? null;
36
+ const observedTurn = binding?.turn ?? null;
37
+ const initialAttemptId = formatTurnReceiptId(task.id, turn.id);
38
+ const currentProviderTurn = managedProviderTurnId(observedTurn) === turn.id ? observedTurn : null;
39
+ if (binding?.authority.owner === "human"
40
+ || binding?.authority.owner === "unknown") {
41
+ return { ...base, status: "skipped", reason: "writer-attached" };
42
+ }
43
+ if (currentProviderTurn !== null
44
+ && ["submitting", "accepted"].includes(currentProviderTurn.status)) {
45
+ return { ...base, status: "skipped", reason: "not-ready" };
46
+ }
47
+ if (currentProviderTurn?.status === "delivery-unknown") {
48
+ return failTurnDelivery(store, turn, now, "delivery-unknown", currentProviderTurn.terminalReason ?? "Provider could not determine whether the Turn was accepted.");
49
+ }
50
+ if (currentProviderTurn !== null) {
51
+ const reason = currentProviderTurn.terminalReason
52
+ ?? `Provider Turn ended with status ${currentProviderTurn.status} without recording its Turn result.`;
53
+ return failTurnDelivery(store, turn, now, "missing-result", reason);
54
+ }
55
+ const attemptId = initialAttemptId;
56
+ const mode = turn.mode;
57
+ const existingSession = store.getRoleSession(task.id, role.name, turn.effective.agentId);
58
+ let prepared;
59
+ let submitted = false;
60
+ try {
61
+ const nativeSessionId = mode === "resume"
62
+ ? requireResumeSession(role, turn, existingSession)
63
+ : undefined;
64
+ prepared = await delivery.prepareRoleSession({
65
+ taskId: task.id,
66
+ roleName: role.name,
67
+ agentId: turn.effective.agentId,
68
+ adapterId: turn.effective.adapterId,
69
+ effective: turn.effective,
70
+ workspace: turn.effective.workspace.root,
71
+ ...(turn.workspace === undefined ? {} : { managedWorkspace: turn.workspace }),
72
+ mode,
73
+ turnId: turn.id,
74
+ ...(nativeSessionId === undefined ? {} : { nativeSessionId }),
75
+ ...(mode !== "resume" || existingSession?.launchId === undefined
76
+ ? {}
77
+ : { hostActivationId: existingSession.launchId }),
78
+ beforeHostStart: (preflight) => persistPreStartSession(store, task, role, turn, existingSession, mode, preflight, now)
79
+ });
80
+ const preparedSession = prepared.session === undefined
81
+ ? existingSession
82
+ : validateRoleSession(role, turn, existingSession, mode, prepared.session);
83
+ store.saveRoleTurnPrepared({
84
+ task,
85
+ role,
86
+ turn,
87
+ session: preparedSession,
88
+ ...(prepared.launchId === undefined ? {} : { launchId: prepared.launchId }),
89
+ now
90
+ });
91
+ const ready = await delivery.waitUntilReady(prepared);
92
+ const readySession = validateRoleSession(role, turn, existingSession, mode, ready.session);
93
+ store.saveRoleTurnPrepared({
94
+ task,
95
+ role,
96
+ turn,
97
+ session: readySession,
98
+ ...(ready.prepared.launchId === undefined ? {} : { launchId: ready.prepared.launchId }),
99
+ now
100
+ });
101
+ submitted = true;
102
+ const outcome = await delivery.sendOnce({
103
+ delivery: ready,
104
+ receiptId: attemptId,
105
+ text: serializeTurnInputEnvelope(turnInputEnvelope(turn))
106
+ });
107
+ if (outcome === "busy" || outcome === "unavailable") {
108
+ forget(delivery, task.id, role.name, turn.id, ready.prepared.launchId);
109
+ return {
110
+ ...base,
111
+ status: "skipped",
112
+ reason: outcome === "busy" ? "not-ready" : "runtime-unavailable"
113
+ };
114
+ }
115
+ if (outcome === "rejected" || outcome === "delivery-unknown") {
116
+ forget(delivery, task.id, role.name, turn.id, ready.prepared.launchId);
117
+ return failTurnDelivery(store, turn, now, outcome === "delivery-unknown" ? "delivery-unknown" : "runtime-failed", outcome === "delivery-unknown"
118
+ ? "Provider Turn delivery is ambiguous; Yui will not replay it automatically."
119
+ : "Provider rejected the managed Turn.");
120
+ }
121
+ forget(delivery, task.id, role.name, turn.id, ready.prepared.launchId);
122
+ return {
123
+ ...base,
124
+ status: outcome === "sent" ? "delivered" : "already-delivered"
125
+ };
126
+ }
127
+ catch (error) {
128
+ const message = error instanceof Error ? error.message : String(error);
129
+ store.recordAgentError?.({
130
+ taskId: task.id,
131
+ roleName: role.name,
132
+ turnId: turn.id,
133
+ source: error instanceof RuntimeLaunchError || error instanceof RuntimeLaunchFailure ? "host" : "yui",
134
+ phase: submitted ? "turn-submit" : mode === "new" ? "session-start" : "session-restore",
135
+ message,
136
+ raw: serializeAgentErrorRaw(error),
137
+ inputDisposition: submitted ? "unknown" : "not-accepted"
138
+ }, now);
139
+ if (error instanceof RuntimeLifecycleBusyError
140
+ || (error instanceof RuntimeLaunchError && error.retryable)) {
141
+ return {
142
+ ...base,
143
+ status: "skipped",
144
+ reason: error instanceof RuntimeLaunchError && error.reason === "writable-client"
145
+ ? "writer-attached"
146
+ : "runtime-unavailable",
147
+ error: message
148
+ };
149
+ }
150
+ forget(delivery, task.id, role.name, turn.id, prepared?.launchId);
151
+ return failTurnDelivery(store, turn, now, submitted ? "delivery-unknown" : "startup-failed", message);
152
+ }
153
+ }
154
+ function failTurnDelivery(store, turn, now, failureReason, summary) {
155
+ const disposition = store.saveRoleTurnDeliveryFailure({
156
+ taskId: turn.taskId,
157
+ roleName: turn.roleName,
158
+ agentId: turn.effective.agentId,
159
+ adapterId: turn.effective.adapterId,
160
+ turnId: turn.id,
161
+ failureReason,
162
+ summary,
163
+ now
164
+ });
165
+ return {
166
+ taskId: turn.taskId,
167
+ roleName: turn.roleName,
168
+ turnId: turn.id,
169
+ status: disposition === "failed" ? "failed" : "skipped",
170
+ reason: failureReason === "delivery-unknown" ? "delivery-uncertain" : "launch-failed",
171
+ error: summary,
172
+ ...(disposition === "failed" ? { terminalized: true } : {})
173
+ };
174
+ }
175
+ function persistPreStartSession(store, task, role, turn, existing, mode, preflight, now) {
176
+ if (preflight.owner.scope !== "task"
177
+ || preflight.owner.taskId !== task.id
178
+ || preflight.owner.roleName !== role.name
179
+ || preflight.turnId !== turn.id
180
+ || preflight.launchId.trim().length === 0) {
181
+ throw new Error(`Pre-start launch fence changed the active Role Turn: ${task.id}/${role.name}.`);
182
+ }
183
+ const session = preflight.nativeSessionId === undefined ? null : {
184
+ agentId: preflight.agentId,
185
+ adapterId: preflight.adapterId,
186
+ nativeSessionId: preflight.nativeSessionId,
187
+ launchId: preflight.launchId,
188
+ ...(preflight.sessionTitle === undefined ? {} : { title: preflight.sessionTitle }),
189
+ status: "active",
190
+ effective: preflight.effective
191
+ };
192
+ store.saveRoleTurnPrepared({
193
+ task,
194
+ role,
195
+ turn,
196
+ session: validateRoleSession(role, turn, existing, mode, session),
197
+ launchId: preflight.launchId,
198
+ now
199
+ });
200
+ }
201
+ function validateRoleSession(role, turn, existing, mode, session) {
202
+ if (mode === "new" && session === null)
203
+ return null;
204
+ if (session === null || !hasText(session.nativeSessionId)) {
205
+ throw new Error(`Ready Role session has no native session id: ${role.taskId}/${role.name}.`);
206
+ }
207
+ if (session.agentId !== turn.effective.agentId
208
+ || session.adapterId !== turn.effective.adapterId) {
209
+ throw new Error(`Ready Role session identity changed: ${role.taskId}/${role.name}.`);
210
+ }
211
+ const compatible = mode === "resume"
212
+ ? effectiveLaunchSnapshotsCompatibleForTaskSession(session.effective, turn.effective)
213
+ : effectiveLaunchSnapshotsCompatible(session.effective, turn.effective);
214
+ if (!compatible) {
215
+ throw new Error(`Ready Role session effective snapshot changed: ${role.taskId}/${role.name}.`);
216
+ }
217
+ if (mode === "resume" && session.nativeSessionId !== existing?.nativeSessionId) {
218
+ throw new Error(`Role resume changed the fixed native session id: ${role.taskId}/${role.name}.`);
219
+ }
220
+ return {
221
+ ...session,
222
+ status: "active",
223
+ ...(mode === "resume" && existing !== null ? { effective: existing.effective } : {})
224
+ };
225
+ }
226
+ function requireResumeSession(role, turn, session) {
227
+ if (session === null || !hasText(session.nativeSessionId)) {
228
+ throw new Error(`Role resume has no fixed native session: ${role.taskId}/${role.name}.`);
229
+ }
230
+ if (!effectiveLaunchSnapshotsCompatibleForTaskSession(session.effective, turn.effective)) {
231
+ throw new Error(`Role resume effective snapshot drifted: ${role.taskId}/${role.name}.`);
232
+ }
233
+ return session.nativeSessionId;
234
+ }
235
+ function forget(delivery, taskId, roleName, turnId, launchId) {
236
+ delivery.forgetPrepared?.({
237
+ taskId,
238
+ roleName,
239
+ turnId,
240
+ ...(launchId === undefined ? {} : { launchId })
241
+ });
242
+ }
243
+ function hasText(value) {
244
+ return typeof value === "string" && value.trim().length > 0;
245
+ }