@zq-silk/yui 0.13.9 → 0.14.0

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 (229) hide show
  1. package/ARCHITECTURE.md +69 -428
  2. package/README.md +108 -298
  3. package/dist/agent/managedRuntimeEnvironment.js +2 -2
  4. package/dist/cli/commandCatalog.js +39 -77
  5. package/dist/cli/interactionCandidates.js +4 -4
  6. package/dist/cli/interactionPolicy.js +7 -10
  7. package/dist/cli/invocationRouter.js +1 -1
  8. package/dist/cli/updateCommand.js +6 -27
  9. package/dist/cli/updateOrchestrator.js +63 -484
  10. package/dist/cli/updatePorts.js +15 -333
  11. package/dist/cli/upgradeCommand.js +8 -65
  12. package/dist/cli.js +57 -242
  13. package/dist/commands/configCommands.js +11 -62
  14. package/dist/commands/executionAuditCommands.js +23 -23
  15. package/dist/commands/globalRoleCommands.js +2 -7
  16. package/dist/commands/jobCommands.js +1 -4
  17. package/dist/commands/projectCommands.js +5 -5
  18. package/dist/commands/releaseCommands.js +3 -10
  19. package/dist/commands/resourcesCommands.js +2 -2
  20. package/dist/commands/sessionCommands.js +2 -2
  21. package/dist/commands/taskActor.js +31 -39
  22. package/dist/commands/taskChangeSetCommands.js +5 -12
  23. package/dist/commands/taskCommands.js +464 -1249
  24. package/dist/commands/taskContextCommand.js +35 -36
  25. package/dist/commands/taskExecutionCommands.js +33 -46
  26. package/dist/commands/taskInputCommands.js +20 -42
  27. package/dist/commands/taskNextActionCommand.js +9 -9
  28. package/dist/commands/taskOverviewCommand.js +56 -95
  29. package/dist/commands/taskRoleRuntimeStatus.js +77 -107
  30. package/dist/commands/taskUpstreamCommands.js +3 -3
  31. package/dist/commands/taskWorkspaceCommands.js +7 -79
  32. package/dist/commands/telemetryCommands.js +32 -124
  33. package/dist/commands/workflowCommands.js +3 -3
  34. package/dist/completion/fileCompletionManager.js +1 -1
  35. package/dist/config/configCatalog.js +4 -6
  36. package/dist/config/yuiConfig.js +6 -43
  37. package/dist/context/dispatchContext.js +14 -30
  38. package/dist/context/roleSessionContext.js +2 -2
  39. package/dist/context/sessionBootstrapManifest.js +2 -2
  40. package/dist/context/{runContextPack.js → turnContextPack.js} +58 -73
  41. package/dist/context/turnInputContract.js +204 -0
  42. package/dist/context/wakeNotification.js +2 -2
  43. package/dist/controller/agentRuntimeObserver.js +18 -18
  44. package/dist/controller/clientRuntime.js +13 -20
  45. package/dist/controller/controller.js +89 -116
  46. package/dist/controller/fileSchedulerStoreAdapter.js +511 -742
  47. package/dist/controller/jobControl.js +17 -17
  48. package/dist/controller/resourceInventory.js +6 -6
  49. package/dist/controller/resourceInventoryLinux.js +38 -59
  50. package/dist/controller/resourceInventoryRpc.js +3 -3
  51. package/dist/controller/resourceInventoryWorker.js +1 -1
  52. package/dist/controller/runtime.js +46 -53
  53. package/dist/controller/runtimeEventInbox.js +23 -31
  54. package/dist/controller/runtimeEventProcessor.js +15 -15
  55. package/dist/controller/{runtimeHookRunFence.js → runtimeHookTurnFence.js} +87 -81
  56. package/dist/controller/runtimeLaunchCoordinator.js +3 -3
  57. package/dist/controller/runtimeObservationHook.js +11 -8
  58. package/dist/controller/sessionNotify.js +11 -11
  59. package/dist/controller/structuredProviderObservation.js +89 -16
  60. package/dist/coordination/workMailbox.js +309 -579
  61. package/dist/coordination/workMailboxQueue.js +5 -6
  62. package/dist/core/controllerClient.js +1 -91
  63. package/dist/core/controllerServer.js +3 -6
  64. package/dist/doctor/doctor.js +51 -314
  65. package/dist/execution/candidateConvergence.js +3 -3
  66. package/dist/execution/executionGroup.js +32 -33
  67. package/dist/execution/executionHealth.js +36 -38
  68. package/dist/execution/resourceBroker.js +12 -12
  69. package/dist/executor/agentExecutor.js +30 -265
  70. package/dist/executor/effectiveLaunch.js +9 -19
  71. package/dist/executor/executorRegistry.js +43 -17
  72. package/dist/executor/fileRoleLaunchPlanner.js +56 -56
  73. package/dist/executor/launchPlan.js +3 -3
  74. package/dist/executor/workspacePreflightClassification.js +16 -16
  75. package/dist/grant/capabilityGrant.js +20 -25
  76. package/dist/input/inputRequest.js +12 -12
  77. package/dist/integration/changeSet.js +9 -13
  78. package/dist/integration/changeSetManifest.js +1 -1
  79. package/dist/integration/gitIntegrationService.js +2 -2
  80. package/dist/integration/integrationQueueService.js +5 -21
  81. package/dist/integration/overlapDiagnostics.js +2 -2
  82. package/dist/interaction/operatorPresentation.js +1 -1
  83. package/dist/job/jobRunner.js +1 -1
  84. package/dist/lifecycle/canonicalLifecycleEvent.js +25 -25
  85. package/dist/lifecycle/{exactRunTerminalization.js → exactTurnTerminalization.js} +116 -232
  86. package/dist/message/message.js +6 -6
  87. package/dist/observability/executionAudit.js +74 -86
  88. package/dist/observability/faultClassification.js +7 -24
  89. package/dist/observability/orchestrationMetrics.js +5 -5
  90. package/dist/observability/runtimeIdentity.js +34 -101
  91. package/dist/profile/agentProfile.js +1 -1
  92. package/dist/release/cliHomeReleaseFence.js +3 -3
  93. package/dist/release/releaseWorkflowEngine.js +6 -10
  94. package/dist/release/releaseWorkflowPorts.js +2 -2
  95. package/dist/release/workflowFileLock.js +1 -1
  96. package/dist/repository/checkoutSwap.js +1 -1
  97. package/dist/repository/gitWorkspace.js +0 -13
  98. package/dist/repository/project.js +1 -1
  99. package/dist/repository/projectMaintenanceLock.js +1 -2
  100. package/dist/repository/taskBaseFreshness.js +13 -13
  101. package/dist/repository/taskWorkspaceCoordinator.js +21 -25
  102. package/dist/repository/taskWorkspaceIdentity.js +8 -21
  103. package/dist/repository/taskWorkspacePreparer.js +63 -620
  104. package/dist/resources/autoResourceGc.js +3 -3
  105. package/dist/resources/liveReferences.js +1 -1
  106. package/dist/resources/resourceGc.js +1 -1
  107. package/dist/resources/sqliteResourceRegistry.js +1 -1
  108. package/dist/review/reviewDecision.js +7 -7
  109. package/dist/review/reviewFindingLedger.js +1 -1
  110. package/dist/review/reviewOutcomeClassifier.js +35 -50
  111. package/dist/review/reviewRound.js +14 -25
  112. package/dist/review/reviewerAvailability.js +4 -4
  113. package/dist/review/taskFinalReviewContractResolution.js +41 -0
  114. package/dist/role/role.js +6 -3
  115. package/dist/runtime/agentDriver.js +4 -0
  116. package/dist/runtime/agentHost.js +151 -36
  117. package/dist/runtime/builtinAgentDrivers.js +79 -2
  118. package/dist/runtime/codexAppServerRuntime.js +122 -0
  119. package/dist/runtime/continuationManager.js +3 -5
  120. package/dist/runtime/exactControlPlane.js +17 -42
  121. package/dist/runtime/firstProgressAdvisory.js +1 -1
  122. package/dist/runtime/index.js +2 -2
  123. package/dist/runtime/launchDiagnostics.js +2 -2
  124. package/dist/runtime/lifecycleReservation.js +4 -4
  125. package/dist/runtime/processExitObservation.js +1 -1
  126. package/dist/runtime/processExitOutbox.js +0 -32
  127. package/dist/runtime/promptEnvelope.js +9 -9
  128. package/dist/runtime/providerContinuation.js +2 -2
  129. package/dist/runtime/providerContinuationReconciliationService.js +2 -2
  130. package/dist/runtime/providerRuntimeIdentity.js +76 -24
  131. package/dist/runtime/recentTurnIds.js +38 -0
  132. package/dist/runtime/runtimeContinuationProjection.js +2 -2
  133. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  134. package/dist/runtime/runtimeObservation.js +58 -21
  135. package/dist/runtime/runtimeProjection.js +19 -27
  136. package/dist/runtime/sessionLaunchRequest.js +2 -2
  137. package/dist/runtime/structuredProviderHost.js +177 -12
  138. package/dist/runtime/tmuxAdapters.js +46 -11
  139. package/dist/scheduler/activeRoleTurnDelivery.js +245 -0
  140. package/dist/scheduler/leaderWakeupProcessor.js +147 -445
  141. package/dist/scheduler/operatorEvent.js +4 -6
  142. package/dist/scheduler/resourceQueueProjection.js +71 -0
  143. package/dist/scheduler/{roleRunLiveness.js → roleTurnLiveness.js} +24 -28
  144. package/dist/scheduler/{roleRunStall.js → roleTurnStall.js} +162 -247
  145. package/dist/scheduler/taskExecutionProjection.js +99 -99
  146. package/dist/scheduler/taskObservabilityProjection.js +10 -10
  147. package/dist/scheduler/taskWake.js +4 -4
  148. package/dist/scheduler/wakeReason.js +6 -10
  149. package/dist/scheduler/wakeupQueue.js +0 -9
  150. package/dist/setup/setupCommand.js +2 -2
  151. package/dist/storage/currentTaskStore.js +46 -0
  152. package/dist/storage/persistenceWorker.js +1 -1
  153. package/dist/storage/sqliteSchema.js +81 -485
  154. package/dist/storage/sqliteStore.js +206 -365
  155. package/dist/storage/storageSchema.js +1 -15
  156. package/dist/storage/storageVersions.js +8 -9
  157. package/dist/storage/storeRpc.js +10 -34
  158. package/dist/storage/taskStore.js +63 -3415
  159. package/dist/storage/upgrade/recordVersions.js +55 -149
  160. package/dist/storage/upgrade/upgradeOrchestrator.js +89 -1752
  161. package/dist/task/completionReadiness.js +5 -5
  162. package/dist/task/deliveryGuard.js +10 -10
  163. package/dist/task/nextAction.js +74 -77
  164. package/dist/task/task.js +2 -4
  165. package/dist/task/taskRecordReference.js +3 -3
  166. package/dist/task/taskRecordRetirement.js +1 -1
  167. package/dist/telemetry/sqliteTelemetryStore.js +53 -53
  168. package/dist/telemetry/telemetryConfig.js +14 -14
  169. package/dist/telemetry/telemetryWiring.js +8 -14
  170. package/dist/turn/turn.js +356 -0
  171. package/dist/{run/runIdentity.js → turn/turnIdentity.js} +4 -4
  172. package/dist/verification/gateArtifactStore.js +2 -2
  173. package/dist/web/assets/client/app.js +1 -1
  174. package/dist/web/assets/client/components.js +29 -54
  175. package/dist/web/assets/client/i18n.js +17 -37
  176. package/dist/web/assets/client/view.js +37 -37
  177. package/dist/web/assets/shell.js +1 -1
  178. package/dist/web/assets/styles/cards.js +5 -5
  179. package/dist/web/assets/styles/widgets.js +1 -2
  180. package/dist/web/webSnapshot.js +65 -60
  181. package/dist/workItem/workItem.js +11 -11
  182. package/dist/workspace/workItemChangeSetManager.js +1 -1
  183. package/docs/task-local-identity.md +5 -5
  184. package/i18n/README.zh-CN.md +41 -54
  185. package/package.json +1 -1
  186. package/skills/yui-leader/SKILL.md +85 -83
  187. package/skills/yui-operator/SKILL.md +16 -16
  188. package/skills/yui-reviewer/SKILL.md +10 -10
  189. package/skills/yui-runtime/SKILL.md +17 -18
  190. package/skills/yui-worker/SKILL.md +16 -18
  191. package/dist/context/runContextContract.js +0 -162
  192. package/dist/executor/turnCompletion.js +0 -126
  193. package/dist/review/taskFinalReviewContractEvent.js +0 -1
  194. package/dist/review/taskFinalReviewContractRebind.js +0 -367
  195. package/dist/run/agentRun.js +0 -356
  196. package/dist/run/rejectedYieldAttempt.js +0 -221
  197. package/dist/run/runControlRequest.js +0 -50
  198. package/dist/run/yieldReceipt.js +0 -65
  199. package/dist/runtime/turnCompletion.js +0 -3
  200. package/dist/scheduler/actionability.js +0 -323
  201. package/dist/scheduler/activeRoleRunDelivery.js +0 -868
  202. package/dist/scheduler/activeTaskProgress.js +0 -126
  203. package/dist/storage/compatibleTaskStore.js +0 -248
  204. package/dist/storage/migration/baseline.js +0 -78
  205. package/dist/storage/migration/classifier.js +0 -51
  206. package/dist/storage/migration/compatibleCodec.js +0 -53
  207. package/dist/storage/migration/engine.js +0 -147
  208. package/dist/storage/migration/index.js +0 -33
  209. package/dist/storage/migration/planner.js +0 -154
  210. package/dist/storage/migration/productionRegistry.js +0 -3931
  211. package/dist/storage/migration/registry.js +0 -169
  212. package/dist/storage/migration/report.js +0 -54
  213. package/dist/storage/migration/types.js +0 -31
  214. package/dist/storage/upgrade/homeClassification.js +0 -353
  215. package/dist/storage/upgrade/homeMigrationTarget.js +0 -595
  216. package/dist/storage/upgrade/migrationReceipt.js +0 -67
  217. package/dist/storage/upgrade/offlineUpgradeInventory.js +0 -453
  218. package/dist/storage/upgrade/productionMigrationRegistry.js +0 -6
  219. package/dist/storage/upgrade/pseudoLayoutRepair.js +0 -241
  220. package/dist/storage/upgrade/recordVersionScan.js +0 -176
  221. package/dist/storage/upgrade/sqliteFileSet.js +0 -50
  222. package/dist/storage/upgrade/sqliteMigrationTarget.js +0 -375
  223. package/dist/storage/upgrade/sqliteRecordMigrationTarget.js +0 -305
  224. package/dist/storage/upgrade/sqliteStateMigration.js +0 -918
  225. package/dist/storage/upgrade/switchProgress.js +0 -80
  226. package/dist/storage/upgrade/upgradeReceipt.js +0 -161
  227. package/dist/storage/upgradeCoordination.js +0 -187
  228. package/dist/storage/upgradeFence.js +0 -366
  229. package/dist/telemetry/telemetryCompaction.js +0 -252
@@ -1,7 +1,6 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import { closeSync, constants, existsSync, fchmodSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
- import { withUpgradeCoordinationLock } from "../storage/upgradeCoordination.js";
5
4
  import { createRuntimeObservation, isRuntimeTokenEvidence } from "../runtime/runtimeObservation.js";
6
5
  export const MAX_RUNTIME_TURN_SUMMARY_BYTES = 32 * 1024;
7
6
  export const MAX_RUNTIME_EVENT_FILE_BYTES = 16 * 1024 * 1024;
@@ -10,7 +9,7 @@ const INVALID_RUNTIME_EVENT_DIRECTORY = join("runtime", "inbox-invalid");
10
9
  const EVENT_ID_PATTERN = /^turn-[a-f0-9]{64}$/;
11
10
  /**
12
11
  * Durable ingress for facts emitted by native Agent hooks. It deliberately
13
- * owns no FileTaskStore lock: immutable files are acknowledged only after the
12
+ * owns no TaskStore lock: immutable files are acknowledged only after the
14
13
  * Controller commits their authoritative aggregate effect.
15
14
  */
16
15
  export class FileRuntimeEventInbox {
@@ -156,24 +155,17 @@ export class FileRuntimeEventInbox {
156
155
  return acknowledged;
157
156
  }
158
157
  publish(event) {
159
- // The fence check and the complete durable write share one sibling
160
- // coordination lock with upgrade's final inbox scan/copy/two-step switch.
161
- // A hook that passed admission before the fence was placed either finishes
162
- // under this lock (so its event is copied) or waits and receives an
163
- // UpgradeFenceError after the cutover holder releases the lock.
164
- return withUpgradeCoordinationLock(this.home, () => {
165
- this.hooks.afterAdmission?.();
166
- if (event.type === "runtime-observation"
167
- && isRuntimeTokenEvidence(event.observation)) {
168
- const existing = this.list().find((candidate) => (candidate.type === "runtime-observation"
169
- && candidate.taskId === event.taskId
170
- && candidate.observation.eventId === event.observation.eventId));
171
- if (existing !== undefined) {
172
- return { event: existing, created: false };
173
- }
158
+ this.hooks.afterAdmission?.();
159
+ if (event.type === "runtime-observation"
160
+ && isRuntimeTokenEvidence(event.observation)) {
161
+ const existing = this.list().find((candidate) => (candidate.type === "runtime-observation"
162
+ && candidate.taskId === event.taskId
163
+ && candidate.observation.eventId === event.observation.eventId));
164
+ if (existing !== undefined) {
165
+ return { event: existing, created: false };
174
166
  }
175
- return this.publishUnlocked(event);
176
- });
167
+ }
168
+ return this.publishUnlocked(event);
177
169
  }
178
170
  publishUnlocked(event) {
179
171
  const content = `${JSON.stringify(event)}\n`;
@@ -285,8 +277,8 @@ function runtimeEventId(type, input) {
285
277
  provider.adapterId,
286
278
  provider.launchId ?? null,
287
279
  provider.nativeSessionId,
288
- "turnId" in provider ? provider.turnId : null,
289
- provider.runId ?? null
280
+ provider.nativeTurnId,
281
+ provider.turnId ?? null
290
282
  ];
291
283
  return `turn-${createHash("sha256").update(JSON.stringify(common)).digest("hex")}`;
292
284
  }
@@ -305,10 +297,10 @@ function normalizeNativeTurnCompletedInput(input) {
305
297
  ? {}
306
298
  : { launchId: requireIdentityText(input.launchId, "Launch id") }),
307
299
  nativeSessionId: requireIdentityText(input.nativeSessionId, "Native session id"),
308
- turnId: requireIdentityText(input.turnId, "Turn id"),
309
- ...(input.runId === undefined
300
+ nativeTurnId: requireIdentityText(input.nativeTurnId, "Provider native Turn id"),
301
+ ...(input.turnId === undefined
310
302
  ? {}
311
- : { runId: requireIdentityText(input.runId, "Run id") }),
303
+ : { turnId: requireIdentityText(input.turnId, "Turn id") }),
312
304
  ...(input.title === undefined
313
305
  ? {}
314
306
  : { title: requireIdentityText(input.title, "Session title") }),
@@ -393,16 +385,16 @@ function parseNativeTurnCompletedEvent(value) {
393
385
  const expected = scope === "task"
394
386
  ? [
395
387
  "schemaVersion", "id", "type", "receivedAt", "scope", "taskId",
396
- "roleName", "agentId", "adapterId", "nativeSessionId", "turnId", "summary",
388
+ "roleName", "agentId", "adapterId", "nativeSessionId", "nativeTurnId", "summary",
397
389
  ...(value.launchId === undefined ? [] : ["launchId"]),
398
- ...(value.runId === undefined ? [] : ["runId"]),
390
+ ...(value.turnId === undefined ? [] : ["turnId"]),
399
391
  ...(value.title === undefined ? [] : ["title"])
400
392
  ]
401
393
  : [
402
394
  "schemaVersion", "id", "type", "receivedAt", "scope",
403
- "roleName", "agentId", "adapterId", "nativeSessionId", "turnId", "summary",
395
+ "roleName", "agentId", "adapterId", "nativeSessionId", "nativeTurnId", "summary",
404
396
  ...(value.launchId === undefined ? [] : ["launchId"]),
405
- ...(value.runId === undefined ? [] : ["runId"]),
397
+ ...(value.turnId === undefined ? [] : ["turnId"]),
406
398
  ...(value.title === undefined ? [] : ["title"])
407
399
  ];
408
400
  if ((scope !== "task" && scope !== "global")
@@ -418,8 +410,8 @@ function parseNativeTurnCompletedEvent(value) {
418
410
  adapterId: value.adapterId,
419
411
  ...(value.launchId === undefined ? {} : { launchId: value.launchId }),
420
412
  nativeSessionId: value.nativeSessionId,
421
- turnId: value.turnId,
422
- ...(value.runId === undefined ? {} : { runId: value.runId }),
413
+ nativeTurnId: value.nativeTurnId,
414
+ ...(value.turnId === undefined ? {} : { turnId: value.turnId }),
423
415
  ...(value.title === undefined ? {} : { title: value.title }),
424
416
  summary: value.summary
425
417
  });
@@ -483,7 +475,7 @@ function hasSameIdentity(left, right) {
483
475
  && (!("nativeSessionId" in left)
484
476
  || !("nativeSessionId" in right)
485
477
  || left.nativeSessionId === right.nativeSessionId)
486
- && (!("runId" in left) || !("runId" in right) || left.runId === right.runId)
478
+ && (!("turnId" in left) || !("turnId" in right) || left.turnId === right.turnId)
487
479
  && (!("turnId" in left) || !("turnId" in right) || left.turnId === right.turnId)
488
480
  && (!("jobId" in left) || !("jobId" in right) || left.jobId === right.jobId);
489
481
  }
@@ -167,7 +167,7 @@ export class FileRuntimeEventProcessor {
167
167
  adapterId: this.drivers.require(fence.driverId).adapterId,
168
168
  launchId: fence.launchId,
169
169
  nativeSessionId: fence.nativeSessionId,
170
- ...(fence.runId === undefined ? {} : { runId: fence.runId })
170
+ ...(fence.turnId === undefined ? {} : { turnId: fence.turnId })
171
171
  });
172
172
  }
173
173
  }
@@ -179,7 +179,7 @@ export class FileRuntimeEventProcessor {
179
179
  adapterId: event.adapterId,
180
180
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
181
181
  nativeSessionId: event.nativeSessionId,
182
- ...(event.runId === undefined ? {} : { runId: event.runId })
182
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId })
183
183
  });
184
184
  }
185
185
  }
@@ -213,8 +213,8 @@ export class FileRuntimeEventProcessor {
213
213
  adapterId: event.adapterId,
214
214
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
215
215
  nativeSessionId: event.nativeSessionId,
216
- turnId: event.turnId,
217
- ...(event.runId === undefined ? {} : { runId: event.runId }),
216
+ nativeTurnId: event.nativeTurnId,
217
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
218
218
  summary: event.summary
219
219
  };
220
220
  if (task === null)
@@ -244,7 +244,7 @@ export class FileRuntimeEventProcessor {
244
244
  adapterId: event.adapterId,
245
245
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
246
246
  nativeSessionId: event.nativeSessionId,
247
- turnId: event.turnId,
247
+ nativeTurnId: event.nativeTurnId,
248
248
  ...(event.title === undefined ? {} : { title: event.title }),
249
249
  summary: event.summary
250
250
  };
@@ -267,7 +267,7 @@ export class FileRuntimeEventProcessor {
267
267
  taskId: event.taskId,
268
268
  roleName: fence.roleName,
269
269
  agentId: fence.agentId,
270
- ...(fence.runId === undefined ? {} : { runId: fence.runId }),
270
+ ...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
271
271
  launchId: fence.launchId,
272
272
  nativeSessionId: fence.nativeSessionId,
273
273
  reason
@@ -284,7 +284,7 @@ export class FileRuntimeEventProcessor {
284
284
  taskId: event.taskId,
285
285
  roleName: event.roleName,
286
286
  agentId: event.agentId,
287
- ...(event.runId === undefined ? {} : { runId: event.runId }),
287
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
288
288
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
289
289
  nativeSessionId: event.nativeSessionId,
290
290
  reason
@@ -418,7 +418,7 @@ function progressStreamKey(event) {
418
418
  fence.driverId,
419
419
  fence.launchId,
420
420
  fence.nativeSessionId ?? null,
421
- fence.runId ?? null,
421
+ fence.turnId ?? null,
422
422
  payload.activity,
423
423
  isRuntimeTokenEvidence(event.observation) ? "usage" : "signal"
424
424
  ]);
@@ -644,7 +644,7 @@ export class AsyncRuntimeEventProcessor {
644
644
  adapterId: this.drivers.require(fence.driverId).adapterId,
645
645
  launchId: fence.launchId,
646
646
  nativeSessionId: fence.nativeSessionId,
647
- ...(fence.runId === undefined ? {} : { runId: fence.runId })
647
+ ...(fence.turnId === undefined ? {} : { turnId: fence.turnId })
648
648
  });
649
649
  }
650
650
  return outcome;
@@ -660,8 +660,8 @@ export class AsyncRuntimeEventProcessor {
660
660
  adapterId: event.adapterId,
661
661
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
662
662
  nativeSessionId: event.nativeSessionId,
663
- turnId: event.turnId,
664
- ...(event.runId === undefined ? {} : { runId: event.runId }),
663
+ nativeTurnId: event.nativeTurnId,
664
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
665
665
  summary: event.summary
666
666
  };
667
667
  if (task === null)
@@ -689,7 +689,7 @@ export class AsyncRuntimeEventProcessor {
689
689
  adapterId: event.adapterId,
690
690
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
691
691
  nativeSessionId: event.nativeSessionId,
692
- ...(event.runId === undefined ? {} : { runId: event.runId })
692
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId })
693
693
  });
694
694
  return "applied";
695
695
  }
@@ -700,7 +700,7 @@ export class AsyncRuntimeEventProcessor {
700
700
  adapterId: event.adapterId,
701
701
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
702
702
  nativeSessionId: event.nativeSessionId,
703
- turnId: event.turnId,
703
+ nativeTurnId: event.nativeTurnId,
704
704
  ...(event.title === undefined ? {} : { title: event.title }),
705
705
  summary: event.summary
706
706
  };
@@ -723,7 +723,7 @@ export class AsyncRuntimeEventProcessor {
723
723
  taskId: event.taskId,
724
724
  roleName: fence.roleName,
725
725
  agentId: fence.agentId,
726
- ...(fence.runId === undefined ? {} : { runId: fence.runId }),
726
+ ...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
727
727
  launchId: fence.launchId,
728
728
  nativeSessionId: fence.nativeSessionId,
729
729
  reason
@@ -736,7 +736,7 @@ export class AsyncRuntimeEventProcessor {
736
736
  taskId: event.taskId,
737
737
  roleName: event.roleName,
738
738
  agentId: event.agentId,
739
- ...(event.runId === undefined ? {} : { runId: event.runId }),
739
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
740
740
  ...(event.launchId === undefined ? {} : { launchId: event.launchId }),
741
741
  nativeSessionId: event.nativeSessionId,
742
742
  reason
@@ -1,17 +1,18 @@
1
- import { openCompatibleFileTaskStore } from "../storage/compatibleTaskStore.js";
1
+ import { openCurrentTaskStore } from "../storage/currentTaskStore.js";
2
2
  import { hasRuntimeCleanupObligation, isRuntimeLaunchReservation, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
3
3
  import { nativeSessionIdForLaunch } from "../runtime/preallocatedNativeSession.js";
4
4
  import { runtimeObservationFromTaskEvent } from "../runtime/runtimeObservation.js";
5
5
  import { YUI_CONTROL_PLANE_DESCRIPTOR, YUI_TASK_RUNTIME_DESCRIPTOR, assertExactTaskRuntimeEnvironment, exactControlPlaneDigest, parseExactControlPlaneDescriptor, refreshReusedTaskRuntimeDescriptorSource } from "../runtime/exactControlPlane.js";
6
- import { agentRunDeliveryReceiptId } from "../run/agentRun.js";
6
+ import { formatTurnReceiptId } from "../task/taskRecordReference.js";
7
+ import { managedProviderTurnId } from "../runtime/providerRuntimeIdentity.js";
7
8
  /**
8
9
  * Resolves turn identity from the current durable in-flight fence. The one
9
10
  * exception is a Driver-declared startup Session Hook, which can arrive before
10
- * Session projection and is fenced by the exact Run-bound launch reservation.
11
+ * Session projection and is fenced by the exact Turn-bound launch reservation.
11
12
  * Preallocated identities are additionally checked against Yui's deterministic
12
13
  * launch identity. The immutable event is revalidated by the inbox fold.
13
14
  */
14
- export function resolveRuntimeHookRunFence(environment, adapterId, payloadNativeSessionId, options = {}) {
15
+ export function resolveRuntimeHookTurnFence(environment, adapterId, payloadNativeSessionId, options = {}) {
15
16
  if (environment.YUI_SESSION_SCOPE !== "task") {
16
17
  throw new Error("Runtime observation Hook requires a Task session scope.");
17
18
  }
@@ -34,12 +35,12 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
34
35
  && nativeSessionId !== requireIdentity(expectedNativeSessionId, "YUI native session id")) {
35
36
  throw new Error("Runtime observation Hook native Session does not match its launch envelope.");
36
37
  }
37
- const store = openCompatibleFileTaskStore(home);
38
+ const store = openCurrentTaskStore(home);
38
39
  const task = store.getTask(taskId);
39
40
  if (task === null
40
- || task.status !== "active"
41
- || task.executionGate.state !== "enabled") {
42
- throw new Error("Runtime observation Hook Task is not current and active.");
41
+ || (!(task.status === "active" && task.executionGate.state === "enabled")
42
+ && !(task.status === "completed" && (options.terminal === true || options.sessionOnly === true)))) {
43
+ throw new Error("Runtime observation Hook Task does not accept this lifecycle boundary.");
43
44
  }
44
45
  const role = store.getRole(taskId, roleName);
45
46
  if (role === null || role.activeAgentId !== agentId) {
@@ -49,20 +50,38 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
49
50
  if (sessions !== null && sessions.activeAgentId !== agentId) {
50
51
  throw new Error("Runtime observation Hook Session Agent is not current.");
51
52
  }
52
- const inFlight = sessions?.inFlight;
53
53
  const session = sessions?.sessions[agentId];
54
- const roleMailbox = store.getWorkMailbox({ kind: "role", taskId, roleName });
55
- const roleInputDelivery = roleMailbox?.inputDelivery;
56
- const roleExecution = roleMailbox?.processing?.executionRef;
57
- const activationReceiptId = roleInputDelivery?.executionRef?.type === "run"
58
- && roleInputDelivery.executionRef.taskId === taskId
59
- && roleInputDelivery.executionRef.id === inFlight?.runId
60
- ? roleInputDelivery.attemptId
61
- : roleExecution?.type === "run"
62
- && roleExecution.taskId === taskId
63
- && roleExecution.id === inFlight?.runId
64
- ? roleMailbox.processing.batchId
65
- : inFlight?.receiptId;
54
+ const activeTurn = store.getActiveTurn(taskId, roleName);
55
+ const providerTurn = sessions?.providerBinding?.turn;
56
+ const directProviderTurn = providerTurn !== null
57
+ && providerTurn !== undefined
58
+ && providerTurn.turnId === undefined
59
+ && ((options.attemptId !== undefined && providerTurn.attemptId === options.attemptId)
60
+ || (options.nativeTurnId !== undefined && providerTurn.nativeTurnId === options.nativeTurnId));
61
+ const sessionOnlyObservation = options.sessionOnly === true && activeTurn === null;
62
+ if (directProviderTurn || sessionOnlyObservation) {
63
+ if (session === undefined
64
+ || session.adapterId !== adapterId
65
+ || session.launchId !== launchId
66
+ || session.nativeSessionId !== nativeSessionId
67
+ || session.effective.workspace.root !== workspace) {
68
+ throw new Error("Runtime observation Hook Session does not match durable state.");
69
+ }
70
+ return {
71
+ taskId,
72
+ roleName,
73
+ agentId,
74
+ launchId,
75
+ ...(directProviderTurn ? { receiptId: providerTurn.attemptId } : {}),
76
+ nativeSessionId,
77
+ workspace
78
+ };
79
+ }
80
+ const activationReceiptId = providerTurn !== null
81
+ && providerTurn !== undefined
82
+ && managedProviderTurnId(providerTurn) === activeTurn?.id
83
+ ? providerTurn.attemptId
84
+ : activeTurn === null ? undefined : formatTurnReceiptId(taskId, activeTurn.id);
66
85
  const acceptedTurn = options.nativeTurnId === undefined
67
86
  ? null
68
87
  : acceptedTurnBinding(store.listEvents(taskId), {
@@ -87,21 +106,21 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
87
106
  }));
88
107
  const exactReservation = isRuntimeLaunchReservation(mailbox?.processing, launchId)
89
108
  && !hasRuntimeCleanupObligation(mailbox);
90
- const startupRunId = options.startupSession === undefined
109
+ const startupTurnId = options.startupSession === undefined
91
110
  ? undefined
92
- : requireIdentity(runtime?.runId
93
- ?? environment.YUI_RUN_ID, "Run id");
94
- const startupReservation = startupRunId !== undefined
111
+ : requireIdentity(runtime?.turnId
112
+ ?? environment.YUI_TURN_ID, "Turn id");
113
+ const startupReservation = startupTurnId !== undefined
95
114
  && exactReservation
96
115
  && !hasRuntimeCleanupObligation(mailbox);
97
- const startupRun = startupRunId === undefined
116
+ const startupTurn = startupTurnId === undefined
98
117
  ? null
99
- : store.getAgentRun(taskId, startupRunId);
118
+ : store.getTurn(taskId, startupTurnId);
100
119
  const replacementStartup = options.startupSession !== undefined
101
120
  && session !== undefined
102
121
  && sessions !== null
103
122
  && startupReservation
104
- && startupRun?.mode === "new"
123
+ && startupTurn?.mode === "new"
105
124
  && session.status === "ended";
106
125
  const preallocatedStartup = options.startupSession === "preallocated"
107
126
  && expectedNativeSessionId !== undefined
@@ -112,44 +131,31 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
112
131
  && expectedNativeSessionId === undefined
113
132
  && (session === undefined || replacementStartup)
114
133
  && startupReservation;
115
- const terminalRunId = options.terminal === true && acceptedBinding === null
116
- ? requireIdentity(environment.YUI_RUN_ID ?? runtime?.runId, "Run id")
134
+ const terminalTurnId = options.terminal === true && acceptedBinding === null
135
+ ? requireIdentity(environment.YUI_TURN_ID ?? runtime?.turnId, "Turn id")
117
136
  : undefined;
118
- const terminalRun = acceptedBinding !== null
119
- ? store.getAgentRun(taskId, acceptedBinding.fence.runId)
120
- : terminalRunId === undefined
137
+ const terminalTurn = acceptedBinding !== null
138
+ ? store.getTurn(taskId, acceptedBinding.fence.turnId)
139
+ : terminalTurnId === undefined
121
140
  ? null
122
- : store.getAgentRun(taskId, terminalRunId);
123
- const exactTerminal = terminalRun !== null
124
- && terminalRun.status !== "active"
125
- && terminalRun.roleName === roleName
126
- && terminalRun.effective.agentId === agentId
127
- && terminalRun.effective.adapterId === adapterId
128
- && session !== undefined
129
- && (acceptedBinding !== null || inFlight === null || inFlight === undefined);
130
- if ((inFlight === null || inFlight === undefined)
141
+ : store.getTurn(taskId, terminalTurnId);
142
+ const exactTerminal = terminalTurn !== null
143
+ && terminalTurn.status !== "active"
144
+ && terminalTurn.roleName === roleName
145
+ && terminalTurn.effective.agentId === agentId
146
+ && terminalTurn.effective.adapterId === adapterId
147
+ && session !== undefined;
148
+ if (activeTurn === null
131
149
  && !preallocatedStartup
132
150
  && !discoveredStartup
133
151
  && !exactTerminal
134
152
  && acceptedBinding === null) {
135
- throw new Error("Runtime observation Hook has no matching durable in-flight Run.");
136
- }
137
- if (acceptedBinding === null
138
- && inFlight !== null && inFlight !== undefined && inFlight.agentId !== agentId) {
139
- throw new Error("Runtime observation Hook has no matching durable in-flight Run.");
140
- }
141
- if ((preallocatedStartup || discoveredStartup)
142
- && inFlight !== null
143
- && inFlight !== undefined
144
- && (inFlight.runId !== startupRunId
145
- || startupRun === null
146
- || inFlight.receiptId !== agentRunDeliveryReceiptId(startupRun))) {
147
- throw new Error("Runtime observation Hook has no matching durable in-flight Run.");
153
+ throw new Error("Runtime observation Hook has no matching durable in-flight Turn.");
148
154
  }
149
- const runId = acceptedBinding?.fence.runId
150
- ?? inFlight?.runId
151
- ?? startupRunId
152
- ?? terminalRunId;
155
+ const turnId = acceptedBinding?.fence.turnId
156
+ ?? activeTurn?.id
157
+ ?? startupTurnId
158
+ ?? terminalTurnId;
153
159
  let effectiveRuntime = runtime;
154
160
  let effectiveLaunchId = acceptedBinding?.fence.launchId ?? launchId;
155
161
  const sessionLaunchId = session?.launchId;
@@ -160,35 +166,35 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
160
166
  && sessionLaunchId !== undefined
161
167
  && typeof runtimeSource === "string"
162
168
  && !runtimeSource.trimStart().startsWith("{")
163
- && (runtime.runId !== runId
169
+ && (runtime.turnId !== turnId
164
170
  || runtime.launchId !== sessionLaunchId
165
171
  || runtime.nativeSessionId !== session.nativeSessionId)) {
166
172
  // A reused native pane keeps its original descriptor source. Advance only
167
173
  // that Hook-owned source to the current durable generation before the
168
174
  // volatile fence; the Controller no longer scans history to keep it fresh.
169
175
  effectiveRuntime = refreshReusedTaskRuntimeDescriptorSource(runtimeSource, home, store, {
170
- runId,
176
+ turnId,
171
177
  launchId: sessionLaunchId,
172
178
  nativeSessionId: session.nativeSessionId
173
179
  });
174
180
  effectiveLaunchId = effectiveRuntime.launchId;
175
181
  }
176
182
  if (acceptedBinding === null
177
- && effectiveRuntime?.runId !== undefined && effectiveRuntime.runId !== runId) {
178
- throw new Error("Runtime observation Hook Run does not match its current descriptor.");
183
+ && effectiveRuntime?.turnId !== undefined && effectiveRuntime.turnId !== turnId) {
184
+ throw new Error("Runtime observation Hook Turn does not match its current descriptor.");
179
185
  }
180
- const run = acceptedBinding !== null || exactTerminal
181
- ? terminalRun
182
- : store.getActiveAgentRun(taskId, roleName);
183
- if (run === null
184
- || run.id !== runId
185
- || (acceptedBinding === null && !exactTerminal && run.status !== "active")
186
- || run.effective.agentId !== agentId
187
- || run.effective.adapterId !== adapterId) {
188
- throw new Error("Runtime observation Hook Run does not match durable active state.");
186
+ const turn = acceptedBinding !== null || exactTerminal
187
+ ? terminalTurn
188
+ : store.getActiveTurn(taskId, roleName);
189
+ if (turn === null
190
+ || turn.id !== turnId
191
+ || (acceptedBinding === null && !exactTerminal && turn.status !== "active")
192
+ || turn.effective.agentId !== agentId
193
+ || turn.effective.adapterId !== adapterId) {
194
+ throw new Error("Runtime observation Hook Turn does not match durable active state.");
189
195
  }
190
- if (run.effective.workspace.root !== workspace) {
191
- throw new Error("Runtime observation Hook workspace does not match the durable Run snapshot.");
196
+ if (turn.effective.workspace.root !== workspace) {
197
+ throw new Error("Runtime observation Hook workspace does not match the durable Turn snapshot.");
192
198
  }
193
199
  if (session !== undefined && acceptedBinding === null && !replacementStartup) {
194
200
  if (session.adapterId !== adapterId
@@ -208,7 +214,7 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
208
214
  roleName,
209
215
  agentId,
210
216
  launchId: effectiveLaunchId,
211
- runId,
217
+ turnId,
212
218
  ...(acceptedBinding?.fence.receiptId === undefined
213
219
  ? activationReceiptId === undefined ? {} : { receiptId: activationReceiptId }
214
220
  : { receiptId: acceptedBinding.fence.receiptId }),
@@ -227,7 +233,7 @@ function knownContinuationBinding(events, expected) {
227
233
  && observation.fence.nativeSessionId === expected.nativeSessionId
228
234
  && observation.fence.continuationId === expected.continuationId
229
235
  && observation.fence.continuationGeneration === expected.continuationGeneration
230
- && observation.fence.runId !== undefined)
236
+ && observation.fence.turnId !== undefined)
231
237
  .sort((left, right) => (left.receivedAt.localeCompare(right.receivedAt)
232
238
  || (left.sequence ?? -1) - (right.sequence ?? -1)
233
239
  || (left.ordinal ?? -1) - (right.ordinal ?? -1)
@@ -235,10 +241,10 @@ function knownContinuationBinding(events, expected) {
235
241
  const binding = matches.at(-1) ?? null;
236
242
  if (binding === null)
237
243
  return null;
238
- if (matches.some((candidate) => candidate.fence.runId !== binding.fence.runId
244
+ if (matches.some((candidate) => candidate.fence.turnId !== binding.fence.turnId
239
245
  || candidate.fence.launchId !== binding.fence.launchId
240
246
  || candidate.fence.receiptId !== binding.fence.receiptId)) {
241
- throw new Error("Runtime observation Hook continuation has conflicting durable Run bindings.");
247
+ throw new Error("Runtime observation Hook continuation has conflicting durable Turn bindings.");
242
248
  }
243
249
  return binding;
244
250
  }
@@ -252,7 +258,7 @@ function acceptedTurnBinding(events, expected) {
252
258
  && observation.fence.agentId === expected.agentId
253
259
  && observation.fence.nativeSessionId === expected.nativeSessionId
254
260
  && observation.fence.nativeTurnId === expected.nativeTurnId
255
- && observation.fence.runId !== undefined)
261
+ && observation.fence.turnId !== undefined)
256
262
  .sort((left, right) => (left.receivedAt.localeCompare(right.receivedAt)
257
263
  || (left.sequence ?? -1) - (right.sequence ?? -1)
258
264
  || (left.ordinal ?? -1) - (right.ordinal ?? -1)
@@ -260,10 +266,10 @@ function acceptedTurnBinding(events, expected) {
260
266
  const binding = matches.at(-1) ?? null;
261
267
  if (binding === null)
262
268
  return null;
263
- if (matches.some((candidate) => candidate.fence.runId !== binding.fence.runId
269
+ if (matches.some((candidate) => candidate.fence.turnId !== binding.fence.turnId
264
270
  || candidate.fence.launchId !== binding.fence.launchId
265
271
  || candidate.fence.receiptId !== binding.fence.receiptId)) {
266
- throw new Error("Runtime observation Hook native Turn has conflicting durable Run bindings.");
272
+ throw new Error("Runtime observation Hook native Turn has conflicting durable Turn bindings.");
267
273
  }
268
274
  return binding;
269
275
  }
@@ -188,7 +188,7 @@ export class RuntimeLaunchCoordinator {
188
188
  ...(runtimeIsolation === undefined
189
189
  ? {}
190
190
  : { runtimeIsolation: runtimeIsolation.descriptor }),
191
- ...(request.runId === undefined ? {} : { runId: request.runId }),
191
+ ...(request.turnId === undefined ? {} : { turnId: request.turnId }),
192
192
  ...(request.environment === undefined
193
193
  ? {}
194
194
  : { environment: request.environment })
@@ -204,7 +204,7 @@ export class RuntimeLaunchCoordinator {
204
204
  ...(runtimeIsolation === undefined
205
205
  ? {}
206
206
  : { runtimeIsolation: runtimeIsolation.descriptor }),
207
- ...(request.runId === undefined ? {} : { runId: request.runId }),
207
+ ...(request.turnId === undefined ? {} : { turnId: request.turnId }),
208
208
  ...(request.environment === undefined
209
209
  ? {}
210
210
  : { environment: request.environment }),
@@ -409,7 +409,7 @@ function validateRuntimeLaunchPreflight(preflight, request, launchId) {
409
409
  && preflight.owner.taskId === request.owner.taskId));
410
410
  if (preflight.launchId !== launchId
411
411
  || !ownerMatches
412
- || preflight.runId !== request.runId
412
+ || preflight.turnId !== request.turnId
413
413
  || preflight.agentId !== request.agentId
414
414
  || preflight.adapterId !== request.adapterId
415
415
  || !effectiveLaunchSnapshotsCompatible(preflight.effective, request.effective)
@@ -3,13 +3,13 @@ import { builtinAgentDriverRegistry } from "../runtime/builtinAgentDrivers.js";
3
3
  import { normalizeAgentDriverHookClassification } from "../runtime/agentDriver.js";
4
4
  import { mapAgentDriverHooks } from "../runtime/agentDriverObservation.js";
5
5
  import { runtimeLifecycleSignalKey } from "../runtime/lifecycleReservation.js";
6
- import { formatAgentRunReceiptId } from "../task/taskRecordReference.js";
6
+ import { formatTurnReceiptId } from "../task/taskRecordReference.js";
7
7
  import { FileRuntimeEventInbox, MAX_RUNTIME_EVENT_FILE_BYTES } from "./runtimeEventInbox.js";
8
- import { resolveRuntimeHookRunFence } from "./runtimeHookRunFence.js";
8
+ import { resolveRuntimeHookTurnFence } from "./runtimeHookTurnFence.js";
9
9
  /**
10
10
  * Single hidden ingress for every structured CLI Driver Hook. Native event
11
11
  * names and payload shapes terminate here; the durable inbox contains only a
12
- * provider-independent RuntimeObservation with an exact generation/Run fence.
12
+ * provider-independent RuntimeObservation with an exact generation/Turn fence.
13
13
  */
14
14
  export async function runRuntimeObservationHookCommand(stdinJson, environment = process.env, call = callController, now = new Date(), dependencies = {}) {
15
15
  if (environment.YUI_SESSION_SCOPE === "global") {
@@ -55,7 +55,7 @@ async function runGlobalRuntimeTurnHook(stdinJson, environment, call, now, depen
55
55
  adapterId: "claude",
56
56
  launchId: requireIdentity(environment.YUI_LAUNCH_ID, "Launch id"),
57
57
  nativeSessionId,
58
- turnId: optionalIdentity(driver.runtime.nativeTurnId(nativeHook)) ?? occurrenceId,
58
+ nativeTurnId: optionalIdentity(driver.runtime.nativeTurnId(nativeHook)) ?? occurrenceId,
59
59
  ...(environment.YUI_SESSION_TITLE === undefined
60
60
  ? {}
61
61
  : { title: requireIdentity(environment.YUI_SESSION_TITLE, "Session title") }),
@@ -84,7 +84,7 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
84
84
  const nativeSessionId = requireIdentity(driver.runtime.nativeSessionId(nativeHook), "Agent Driver native Session id");
85
85
  const nativeTurnId = optionalIdentity(driver.runtime.nativeTurnId(nativeHook));
86
86
  const classification = normalizeAgentDriverHookClassification(driver.runtime.classifyHook(nativeHook));
87
- const fence = (dependencies.resolveRunFence ?? resolveRuntimeHookRunFence)(environment, driver.adapterId, nativeSessionId, {
87
+ const fence = (dependencies.resolveTurnFence ?? resolveRuntimeHookTurnFence)(environment, driver.adapterId, nativeSessionId, {
88
88
  ...(classification.startupSession === undefined
89
89
  ? {}
90
90
  : { startupSession: classification.startupSession }),
@@ -95,6 +95,9 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
95
95
  }),
96
96
  ...(nativeTurnId === undefined ? {} : { nativeTurnId })
97
97
  });
98
+ if (fence.turnId === undefined) {
99
+ throw new Error("Agent Driver Hook requires a managed Turn.");
100
+ }
98
101
  const driverInput = {
99
102
  driver,
100
103
  hookEventName,
@@ -107,7 +110,7 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
107
110
  fence: {
108
111
  taskId: fence.taskId,
109
112
  roleName: fence.roleName,
110
- runId: fence.runId,
113
+ turnId: fence.turnId,
111
114
  agentId: fence.agentId,
112
115
  driverId,
113
116
  launchId: fence.launchId,
@@ -115,8 +118,8 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
115
118
  conversationId: fence.nativeSessionId,
116
119
  activationId: fence.launchId,
117
120
  nativeSessionId: fence.nativeSessionId,
118
- nativeTurnId: nativeTurnId ?? fence.runId,
119
- receiptId: fence.receiptId ?? formatAgentRunReceiptId(fence.taskId, fence.runId)
121
+ nativeTurnId: nativeTurnId ?? fence.turnId,
122
+ receiptId: fence.receiptId ?? formatTurnReceiptId(fence.taskId, fence.turnId)
120
123
  },
121
124
  payload
122
125
  };