@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,13 +1,12 @@
1
- import { rejectedYieldAttemptFromTaskEvent, RUN_YIELD_REJECTED_EVENT } from "../run/rejectedYieldAttempt.js";
2
1
  import { operationalTaskRecords } from "../task/taskRecordRetirement.js";
3
2
  import { TASK_COMPLETION_PUBLISHED_TREE_AUTHORIZED_EVENT } from "../task/publicationReference.js";
4
- import { RUN_BOOTSTRAP_MAX_DELTAS } from "./runContextContract.js";
3
+ import { TURN_INPUT_MAX_DELTAS } from "./turnInputContract.js";
5
4
  import { contextContentDigest, contextSnapshotRef, createContextSnapshot, validateContextSnapshot } from "./contextSnapshot.js";
6
- export const RUN_CONTEXT_PACK_SCHEMA_VERSION = 1;
7
- export const RUN_CONTEXT_PACK_MAX_REFS = 256;
8
- export const RUN_CONTEXT_PACK_MAX_BYTES = 8 * 1024 * 1024;
9
- export const RUN_CONTEXT_EXPAND_MAX_BYTES = 4 * 1024 * 1024;
10
- export function freezeRunContextSnapshot(store, run, now, frozenBy = "controller", baselineRef) {
5
+ export const TURN_CONTEXT_PACK_SCHEMA_VERSION = 1;
6
+ export const TURN_CONTEXT_PACK_MAX_REFS = 256;
7
+ export const TURN_CONTEXT_PACK_MAX_BYTES = 8 * 1024 * 1024;
8
+ export const TURN_CONTEXT_EXPAND_MAX_BYTES = 4 * 1024 * 1024;
9
+ export function freezeTurnContextSnapshot(store, run, now, frozenBy = "controller", baselineRef) {
11
10
  if (baselineRef !== undefined) {
12
11
  const baseline = store.getContextSnapshot(run.taskId, baselineRef.id);
13
12
  if (baseline === null
@@ -18,10 +17,10 @@ export function freezeRunContextSnapshot(store, run, now, frozenBy = "controller
18
17
  || baseline.scope !== "stage"
19
18
  || baselineRef.scope !== baseline.scope
20
19
  || baseline.scopeRef !== baselineRef.scopeRef) {
21
- throw new Error(`Run Context baseline is missing or drifted: ${baselineRef.id}.`);
20
+ throw new Error(`Turn Context baseline is missing or drifted: ${baselineRef.id}.`);
22
21
  }
23
22
  validateContextSnapshot(baseline);
24
- const overlays = collectRunContextOverlays(store, run);
23
+ const overlays = collectTurnContextOverlays(store, run);
25
24
  const resources = [...new Map([...baseline.resources, ...overlays].map((entry) => [
26
25
  contextRefIdentity(entry.ref),
27
26
  entry
@@ -77,7 +76,7 @@ export function freezeRunContextSnapshot(store, run, now, frozenBy = "controller
77
76
  }
78
77
  /**
79
78
  * Freeze the shared, role-neutral ContextSnapshot anchored by one WorkItem
80
- * exploration stage Group. AgentRun snapshots remain role-specific; this
79
+ * exploration stage Group. Turn snapshots remain role-specific; this
81
80
  * record is the durable stage baseline and derives from a fresh WorkItem
82
81
  * snapshot so the Group never depends on ambient latest state.
83
82
  */
@@ -102,7 +101,7 @@ export function freezeExecutionStageContextSnapshot(store, input, now) {
102
101
  for (const binding of task.projectBindings) {
103
102
  const project = store.getProject(binding.projectId);
104
103
  if (project === null)
105
- throw new Error(`Run Project not found: ${binding.projectId}.`);
104
+ throw new Error(`Turn Project not found: ${binding.projectId}.`);
106
105
  const { knowledge, ...projectPolicy } = project;
107
106
  materialized.push(materialize("L1", "project-policy", project.id, projectPolicy));
108
107
  for (const entry of knowledge.filter(({ status }) => status === "active")) {
@@ -217,27 +216,27 @@ export function contextSnapshotDeltaRefIds(store, snapshot) {
217
216
  || before.store !== ref.store
218
217
  || before.layer !== ref.layer;
219
218
  }).map(({ refId }) => refId);
220
- return Object.freeze([...new Set(changed)].sort().slice(0, RUN_BOOTSTRAP_MAX_DELTAS));
219
+ return Object.freeze([...new Set(changed)].sort().slice(0, TURN_INPUT_MAX_DELTAS));
221
220
  }
222
- export function buildRunContextPack(store, taskId, runId) {
223
- const run = requireExactRun(store, taskId, runId);
221
+ export function buildTurnContextPack(store, taskId, turnId) {
222
+ const run = requireExactTurn(store, taskId, turnId);
224
223
  const current = collectAuthorizedContext(store, run);
225
224
  let pointers = current.map(({ ref }) => ref);
226
225
  let snapshotRef;
227
- if (run.assignment.contextSnapshotRef !== undefined) {
228
- const expected = run.assignment.contextSnapshotRef;
226
+ if (run.inputs[0].input.contextSnapshotRef !== undefined) {
227
+ const expected = run.inputs[0].input.contextSnapshotRef;
229
228
  const snapshot = store.getContextSnapshot(taskId, expected.id);
230
229
  if (snapshot === null)
231
- throw new Error(`Run Context Snapshot is missing: ${expected.id}.`);
230
+ throw new Error(`Turn Context Snapshot is missing: ${expected.id}.`);
232
231
  validateContextSnapshot(snapshot);
233
232
  if (snapshot.digest !== expected.digest || snapshot.taskId !== taskId) {
234
- throw new Error(`Run Context Snapshot identity drifted: ${expected.id}.`);
233
+ throw new Error(`Turn Context Snapshot identity drifted: ${expected.id}.`);
235
234
  }
236
235
  pointers = snapshot.refs;
237
236
  snapshotRef = contextSnapshotRef(snapshot);
238
237
  }
239
- if (pointers.length > RUN_CONTEXT_PACK_MAX_REFS) {
240
- throw new Error(`Run Context exceeds ${RUN_CONTEXT_PACK_MAX_REFS} authorized refs.`);
238
+ if (pointers.length > TURN_CONTEXT_PACK_MAX_REFS) {
239
+ throw new Error(`Turn Context exceeds ${TURN_CONTEXT_PACK_MAX_REFS} authorized refs.`);
241
240
  }
242
241
  const view = contextView(run);
243
242
  const writableProjectIds = writableProjects(store, run, view);
@@ -248,10 +247,10 @@ export function buildRunContextPack(store, taskId, runId) {
248
247
  digest: ref.digest
249
248
  }));
250
249
  const body = {
251
- schemaVersion: RUN_CONTEXT_PACK_SCHEMA_VERSION,
250
+ schemaVersion: TURN_CONTEXT_PACK_SCHEMA_VERSION,
252
251
  identity: Object.freeze({
253
252
  taskId,
254
- runId,
253
+ turnId: turnId,
255
254
  roleName: run.roleName,
256
255
  purpose: run.purpose,
257
256
  agentId: run.effective.agentId,
@@ -259,27 +258,27 @@ export function buildRunContextPack(store, taskId, runId) {
259
258
  workspace: run.effective.workspace.root
260
259
  }),
261
260
  ...(snapshotRef === undefined ? {} : { snapshot: snapshotRef }),
262
- assignment: run.assignment,
261
+ input: run.inputs[0].input,
263
262
  authority: Object.freeze({ view, readableRefs: pointers, writableProjectIds }),
264
263
  pointers,
265
264
  summaries,
266
- deltas: pointers.filter((ref) => run.assignment.deltaRefIds.includes(ref.refId)),
265
+ deltas: pointers.filter((ref) => run.inputs[0].input.deltaRefIds.includes(ref.refId)),
267
266
  completion: Object.freeze({
268
267
  allowedActions: completionActions(view),
269
- exactRunRef: `${taskId}/${runId}`
268
+ exactTurnRef: `${taskId}/${turnId}`
270
269
  })
271
270
  };
272
271
  const digest = contextContentDigest(body);
273
272
  const preliminaryBytes = Buffer.byteLength(JSON.stringify({ ...body, digest }), "utf8");
274
- if (preliminaryBytes > RUN_CONTEXT_PACK_MAX_BYTES) {
275
- throw new Error(`Run Context Pack exceeds ${RUN_CONTEXT_PACK_MAX_BYTES} bytes.`);
273
+ if (preliminaryBytes > TURN_CONTEXT_PACK_MAX_BYTES) {
274
+ throw new Error(`Turn Context Pack exceeds ${TURN_CONTEXT_PACK_MAX_BYTES} bytes.`);
276
275
  }
277
276
  const pack = Object.freeze({
278
277
  ...body,
279
278
  budget: Object.freeze({
280
- maxRefs: RUN_CONTEXT_PACK_MAX_REFS,
279
+ maxRefs: TURN_CONTEXT_PACK_MAX_REFS,
281
280
  returnedRefs: pointers.length,
282
- maxBytes: RUN_CONTEXT_PACK_MAX_BYTES,
281
+ maxBytes: TURN_CONTEXT_PACK_MAX_BYTES,
283
282
  returnedBytes: preliminaryBytes,
284
283
  truncated: false
285
284
  }),
@@ -287,24 +286,24 @@ export function buildRunContextPack(store, taskId, runId) {
287
286
  });
288
287
  return pack;
289
288
  }
290
- export function expandRunContextRef(store, taskId, runId, refId, refStore) {
291
- const pack = buildRunContextPack(store, taskId, runId);
289
+ export function expandTurnContextRef(store, taskId, turnId, refId, refStore) {
290
+ const pack = buildTurnContextPack(store, taskId, turnId);
292
291
  const authorized = pack.pointers.filter((ref) => (ref.refId === refId && (refStore === undefined || ref.store === refStore)));
293
292
  const selector = refStore === undefined ? refId : `${refStore}/${refId}`;
294
293
  if (authorized.length !== 1) {
295
- throw new Error(`Run Context ref is not uniquely authorized: ${selector}.`);
294
+ throw new Error(`Turn Context ref is not uniquely authorized: ${selector}.`);
296
295
  }
297
- const run = requireExactRun(store, taskId, runId);
298
- const snapshotRef = run.assignment.contextSnapshotRef;
296
+ const run = requireExactTurn(store, taskId, turnId);
297
+ const snapshotRef = run.inputs[0].input.contextSnapshotRef;
299
298
  const materialized = snapshotRef === undefined
300
299
  ? collectAuthorizedContext(store, run).find(({ ref }) => (contextRefIdentity(ref) === contextRefIdentity(authorized[0])))
301
300
  : store.getContextSnapshot(taskId, snapshotRef.id)?.resources.find(({ ref }) => (contextRefIdentity(ref) === contextRefIdentity(authorized[0])));
302
301
  if (materialized === undefined || materialized.ref.digest !== authorized[0].digest) {
303
- throw new Error(`Run Context ref is unavailable or drifted: ${selector}.`);
302
+ throw new Error(`Turn Context ref is unavailable or drifted: ${selector}.`);
304
303
  }
305
304
  const bytes = Buffer.byteLength(JSON.stringify(materialized.value), "utf8");
306
- if (bytes > RUN_CONTEXT_EXPAND_MAX_BYTES) {
307
- throw new Error(`Run Context expansion exceeds ${RUN_CONTEXT_EXPAND_MAX_BYTES} bytes.`);
305
+ if (bytes > TURN_CONTEXT_EXPAND_MAX_BYTES) {
306
+ throw new Error(`Turn Context expansion exceeds ${TURN_CONTEXT_EXPAND_MAX_BYTES} bytes.`);
308
307
  }
309
308
  return Object.freeze({
310
309
  ref: materialized.ref,
@@ -312,21 +311,21 @@ export function expandRunContextRef(store, taskId, runId, refId, refStore) {
312
311
  digest: contextContentDigest({ ref: materialized.ref, value: materialized.value })
313
312
  });
314
313
  }
315
- /** Fail-closed delta cursor resolution for one immutable Run lineage. */
316
- export function buildRunContextDelta(store, taskId, runId, after) {
317
- const pack = buildRunContextPack(store, taskId, runId);
314
+ /** Fail-closed delta cursor resolution for one immutable Turn lineage. */
315
+ export function buildTurnContextDelta(store, taskId, turnId, after) {
316
+ const pack = buildTurnContextPack(store, taskId, turnId);
318
317
  if (after === pack.digest || after === pack.snapshot?.digest) {
319
318
  return Object.freeze({ schemaVersion: 1, after, cursor: pack.digest, refs: [] });
320
319
  }
321
- const run = requireExactRun(store, taskId, runId);
322
- const snapshotRef = run.assignment.contextSnapshotRef;
320
+ const run = requireExactTurn(store, taskId, turnId);
321
+ const snapshotRef = run.inputs[0].input.contextSnapshotRef;
323
322
  const snapshot = snapshotRef === undefined
324
323
  ? null
325
324
  : store.getContextSnapshot(taskId, snapshotRef.id);
326
325
  const parentDigest = snapshot?.parentRef?.digest;
327
326
  if (!((parentDigest !== undefined && after === parentDigest)
328
327
  || (parentDigest === undefined && after === "none"))) {
329
- throw new Error("Run Context delta cursor is outside the frozen Snapshot lineage.");
328
+ throw new Error("Turn Context delta cursor is outside the frozen Snapshot lineage.");
330
329
  }
331
330
  return Object.freeze({
332
331
  schemaVersion: 1,
@@ -335,10 +334,10 @@ export function buildRunContextDelta(store, taskId, runId, after) {
335
334
  refs: pack.deltas
336
335
  });
337
336
  }
338
- function requireExactRun(store, taskId, runId) {
339
- const run = store.getAgentRun(taskId, runId);
340
- if (run === null || run.taskId !== taskId || run.id !== runId) {
341
- throw new Error(`Agent Run not found: ${taskId}/${runId}.`);
337
+ function requireExactTurn(store, taskId, turnId) {
338
+ const run = store.getTurn(taskId, turnId);
339
+ if (run === null || run.taskId !== taskId || run.id !== turnId) {
340
+ throw new Error(`Turn not found: ${taskId}/${turnId}.`);
342
341
  }
343
342
  return run;
344
343
  }
@@ -352,18 +351,18 @@ function collectAuthorizedContext(store, run) {
352
351
  if (brief !== null && view === "leader") {
353
352
  result.push(materialize("L2", "task-brief", task.id, brief));
354
353
  }
355
- result.push(...collectRunContextOverlays(store, run));
354
+ result.push(...collectTurnContextOverlays(store, run));
356
355
  if (run.workItemId !== undefined) {
357
356
  const item = store.getWorkItem(task.id, run.workItemId);
358
357
  if (item === null)
359
- throw new Error(`Run WorkItem not found: ${run.workItemId}.`);
358
+ throw new Error(`Turn WorkItem not found: ${run.workItemId}.`);
360
359
  result.push(materialize("L3", "work-item", item.id, item));
361
360
  if (view === "worker") {
362
361
  for (const dependencyId of item.dependsOn) {
363
362
  const dependency = store.getWorkItem(task.id, dependencyId);
364
363
  if (dependency === null
365
364
  || (dependency.status !== "completed" && dependency.status !== "retired")) {
366
- throw new Error(`Run WorkItem dependency is not accepted: ${dependencyId}.`);
365
+ throw new Error(`Turn WorkItem dependency is not accepted: ${dependencyId}.`);
367
366
  }
368
367
  if (dependency.status === "retired")
369
368
  continue;
@@ -374,7 +373,7 @@ function collectAuthorizedContext(store, run) {
374
373
  if (run.reviewRoundId !== undefined) {
375
374
  const round = store.getReviewRound(task.id, run.reviewRoundId);
376
375
  if (round === null)
377
- throw new Error(`Run ReviewRound not found: ${run.reviewRoundId}.`);
376
+ throw new Error(`Turn ReviewRound not found: ${run.reviewRoundId}.`);
378
377
  result.push(materialize("L3", "review-round", round.id, round));
379
378
  for (const finding of store.listReviewFindings(task.id).filter((candidate) => (candidate.firstReviewRoundId === round.id
380
379
  || candidate.lastReviewRoundId === round.id
@@ -385,7 +384,7 @@ function collectAuthorizedContext(store, run) {
385
384
  for (const binding of task.projectBindings) {
386
385
  const project = store.getProject(binding.projectId);
387
386
  if (project === null)
388
- throw new Error(`Run Project not found: ${binding.projectId}.`);
387
+ throw new Error(`Turn Project not found: ${binding.projectId}.`);
389
388
  const { knowledge, ...projectPolicy } = project;
390
389
  result.push(materialize("L1", "project-policy", project.id, projectPolicy));
391
390
  for (const entry of knowledge.filter(({ status }) => status === "active")) {
@@ -409,8 +408,8 @@ function collectAuthorizedContext(store, run) {
409
408
  for (const finding of store.listReviewFindings(task.id)) {
410
409
  result.push(materialize("L3", "review-finding", finding.id, finding));
411
410
  }
412
- for (const agentRun of operationalTaskRecords(store.listAgentRuns(task.id), events, "agent-run").slice(-24)) {
413
- result.push(materialize("L4", "agent-run", agentRun.id, agentRun));
411
+ for (const turn of operationalTaskRecords(store.listTurns(task.id), events, "turn").slice(-24)) {
412
+ result.push(materialize("L4", "turn", turn.id, turn));
414
413
  }
415
414
  for (const message of operationalTaskRecords(store.listMessages(task.id), events, "message").slice(-16)) {
416
415
  result.push(materialize("L4", "task-message", message.id, message));
@@ -427,20 +426,6 @@ function collectAuthorizedContext(store, run) {
427
426
  for (const event of publishedTreeAuthorizations.reverse().slice(-16)) {
428
427
  result.push(materialize("L4", "task-event", event.id, event));
429
428
  }
430
- for (const event of events.filter(({ type }) => (type === RUN_YIELD_REJECTED_EVENT)).slice(-16)) {
431
- result.push(materialize("L4", "task-event", event.id, event));
432
- const attempt = rejectedYieldAttemptFromTaskEvent(event);
433
- if (attempt === null)
434
- continue;
435
- const rejectedRun = store.getAgentRun(task.id, attempt.runId);
436
- if (rejectedRun !== null) {
437
- result.push(materialize("L4", "agent-run", rejectedRun.id, rejectedRun));
438
- }
439
- const rejectedRound = store.getReviewRound(task.id, attempt.reviewRoundId);
440
- if (rejectedRound !== null) {
441
- result.push(materialize("L3", "review-round", rejectedRound.id, rejectedRound));
442
- }
443
- }
444
429
  for (const request of store.listOpenInputRequests([task.id])) {
445
430
  result.push(materialize("L4", "input-request", request.id, request));
446
431
  }
@@ -449,10 +434,10 @@ function collectAuthorizedContext(store, run) {
449
434
  return [...unique.values()].sort((left, right) => (contextRefIdentity(left.ref).localeCompare(contextRefIdentity(right.ref))));
450
435
  }
451
436
  /** Lane-specific context that may be layered over an immutable stage base. */
452
- function collectRunContextOverlays(store, run) {
437
+ function collectTurnContextOverlays(store, run) {
453
438
  const role = store.getRole(run.taskId, run.roleName);
454
439
  if (role === null)
455
- throw new Error(`Run Role not found: ${run.taskId}/${run.roleName}.`);
440
+ throw new Error(`Turn Role not found: ${run.taskId}/${run.roleName}.`);
456
441
  return [
457
442
  materialize("L1", "role-profile", role.name, {
458
443
  name: role.name,
@@ -514,10 +499,10 @@ function writableProjects(store, run, view) {
514
499
  }
515
500
  function completionActions(view) {
516
501
  if (view === "leader")
517
- return Object.freeze(["yield", "complete-task", "request-input"]);
502
+ return Object.freeze(["finish-turn", "complete-task", "request-input"]);
518
503
  if (view === "reviewer")
519
- return Object.freeze(["checkpoint", "yield-review"]);
504
+ return Object.freeze(["checkpoint", "finish-turn"]);
520
505
  if (view === "operator")
521
506
  return Object.freeze(["answer-input", "recover"]);
522
- return Object.freeze(["checkpoint", "yield"]);
507
+ return Object.freeze(["checkpoint", "finish-turn"]);
523
508
  }
@@ -0,0 +1,204 @@
1
+ import { normalizedUniqueIdentities, requireIdentity, requireText } from "../domain/validation.js";
2
+ import { validateContextSnapshotRef } from "./contextSnapshot.js";
3
+ export const TURN_INPUT_PROTOCOL_VERSION = 1;
4
+ export const TURN_INPUT_PROTOCOL = "yui-turn/v1";
5
+ export const TURN_INPUT_MAX_BYTES = 4 * 1024;
6
+ export const TURN_INPUT_MAX_DELTAS = 16;
7
+ export const YUI_TURN_INPUT_CHANNELS = [
8
+ "user-message",
9
+ "input-response",
10
+ "task-dispatch",
11
+ "workitem-dispatch",
12
+ "leader-wakeup",
13
+ "leader-forced-wakeup"
14
+ ];
15
+ export function createTurnInput(input) {
16
+ const common = normalizeInput(input);
17
+ return Object.freeze({
18
+ schemaVersion: TURN_INPUT_PROTOCOL_VERSION,
19
+ ...common,
20
+ ...(input.directive === undefined
21
+ ? {}
22
+ : { directive: requireText(input.directive, "Turn input directive") })
23
+ });
24
+ }
25
+ export function validateTurnInput(value) {
26
+ if (value.schemaVersion !== TURN_INPUT_PROTOCOL_VERSION) {
27
+ throw new Error("Turn input must use schemaVersion 1.");
28
+ }
29
+ const normalized = createTurnInput(value);
30
+ if (JSON.stringify(normalized) !== JSON.stringify(value)) {
31
+ throw new Error("Turn input is not canonical.");
32
+ }
33
+ return value;
34
+ }
35
+ export function createTurnInputEnvelope(context, input) {
36
+ validateTurnInput(input);
37
+ const normalized = normalizeEnvelopeContext(context, input);
38
+ return Object.freeze({
39
+ protocol: TURN_INPUT_PROTOCOL,
40
+ turnId: normalized.turnId,
41
+ source: input.source,
42
+ roleName: normalized.roleName,
43
+ purpose: normalized.purpose,
44
+ subject: normalized.subject,
45
+ ...(input.contextSnapshotRef === undefined
46
+ ? {}
47
+ : { contextSnapshotRef: input.contextSnapshotRef }),
48
+ deltaRefIds: input.deltaRefIds
49
+ });
50
+ }
51
+ export function validateTurnInputEnvelope(value) {
52
+ if (value.protocol !== TURN_INPUT_PROTOCOL) {
53
+ throw new Error("Turn input protocol is unsupported.");
54
+ }
55
+ normalizeEnvelope(value);
56
+ const serialized = serializeTurnInputEnvelope(value);
57
+ if (Buffer.byteLength(serialized, "utf8") > TURN_INPUT_MAX_BYTES) {
58
+ throw new Error("Turn input envelope exceeds its protocol byte limit.");
59
+ }
60
+ return value;
61
+ }
62
+ export function serializeTurnInputEnvelope(value) {
63
+ if (value.protocol !== TURN_INPUT_PROTOCOL) {
64
+ throw new Error("Turn input protocol is unsupported.");
65
+ }
66
+ const normalized = normalizeEnvelope(value);
67
+ const subject = Object.entries(normalized.subject)
68
+ .map(([key, id]) => `${key}:${id}`)
69
+ .join(",");
70
+ const snapshot = normalized.contextSnapshotRef;
71
+ const lines = [
72
+ "Yui Turn input. Follow the Session Manifest and injected Skills.",
73
+ `${normalized.subject.taskId === undefined ? "" : `task=${normalized.subject.taskId} `}turn=${normalized.turnId} role=${normalized.roleName}`,
74
+ `source=${normalized.source.type}/${normalized.source.channel} purpose=${normalized.purpose} subject=${subject || "global"} snapshot=${snapshot === undefined ? "none" : `${snapshot.id}@${snapshot.digest}`}`,
75
+ normalized.deltaRefIds.length === 0
76
+ ? "delta=none"
77
+ : `delta=${normalized.deltaRefIds.join(",")}`,
78
+ "Load the exact Turn context before acting; fail closed if it is unavailable or mismatched."
79
+ ];
80
+ const serialized = lines.join("\n");
81
+ if (Buffer.byteLength(serialized, "utf8") > TURN_INPUT_MAX_BYTES) {
82
+ throw new Error("Turn input envelope exceeds its protocol byte limit.");
83
+ }
84
+ return serialized;
85
+ }
86
+ /**
87
+ * Bounded infrastructure-recovery input for an already-submitted Turn. It resumes
88
+ * the provider-native transcript after Host/child replacement and never
89
+ * replays the Assignment or its directive.
90
+ */
91
+ export function serializeTurnHostRecoveryEnvelope(value) {
92
+ const normalized = normalizeEnvelope(value);
93
+ const serialized = [
94
+ "Yui Host recovery for an existing Turn.",
95
+ `${normalized.subject.taskId === undefined ? "" : `task=${normalized.subject.taskId} `}turn=${normalized.turnId} role=${normalized.roleName}`,
96
+ "Resume the same native conversation from its latest durable state. Do not repeat completed work or replay the original input.",
97
+ "Load the exact Turn context or delta only if needed, then continue the same Turn."
98
+ ].join("\n");
99
+ if (Buffer.byteLength(serialized, "utf8") > TURN_INPUT_MAX_BYTES) {
100
+ throw new Error("Turn Host recovery envelope exceeds its protocol byte limit.");
101
+ }
102
+ return serialized;
103
+ }
104
+ function normalizeInput(input) {
105
+ const source = normalizeSource(input.source);
106
+ const snapshot = input.contextSnapshotRef === undefined
107
+ ? undefined
108
+ : validateContextSnapshotRef(input.contextSnapshotRef);
109
+ const deltaRefIds = normalizedUniqueIdentities(input.deltaRefIds, "Turn input delta ref");
110
+ if (deltaRefIds.length > TURN_INPUT_MAX_DELTAS) {
111
+ throw new Error(`Turn input supports at most ${TURN_INPUT_MAX_DELTAS} delta refs.`);
112
+ }
113
+ return {
114
+ source,
115
+ ...(snapshot === undefined ? {} : { contextSnapshotRef: snapshot }),
116
+ deltaRefIds
117
+ };
118
+ }
119
+ function normalizeEnvelopeContext(context, input) {
120
+ const normalized = normalizeEnvelope({
121
+ protocol: TURN_INPUT_PROTOCOL,
122
+ turnId: context.turnId,
123
+ source: input.source,
124
+ roleName: context.roleName,
125
+ purpose: context.purpose,
126
+ subject: context.subject,
127
+ ...(input.contextSnapshotRef === undefined
128
+ ? {}
129
+ : { contextSnapshotRef: input.contextSnapshotRef }),
130
+ deltaRefIds: input.deltaRefIds
131
+ });
132
+ return {
133
+ turnId: normalized.turnId,
134
+ roleName: normalized.roleName,
135
+ purpose: normalized.purpose,
136
+ subject: normalized.subject
137
+ };
138
+ }
139
+ function normalizeEnvelope(input) {
140
+ if (!["execution", "review", "global"].includes(input.purpose)) {
141
+ throw new Error("Turn input purpose is invalid.");
142
+ }
143
+ const normalizedInput = normalizeInput(input);
144
+ const subject = normalizeSubject(input.subject);
145
+ if (normalizedInput.contextSnapshotRef !== undefined
146
+ && normalizedInput.contextSnapshotRef.taskId !== subject.taskId) {
147
+ throw new Error("Turn input Context Snapshot belongs to another Task.");
148
+ }
149
+ if (input.purpose !== "global" && subject.taskId === undefined) {
150
+ throw new Error("A Task Turn input requires a Task subject.");
151
+ }
152
+ if (input.purpose === "review" && subject.reviewRoundId === undefined) {
153
+ throw new Error("A review Turn input requires a ReviewRound subject.");
154
+ }
155
+ return {
156
+ protocol: TURN_INPUT_PROTOCOL,
157
+ turnId: requireIdentity(input.turnId, "Turn input Turn id"),
158
+ source: normalizedInput.source,
159
+ roleName: requireIdentity(input.roleName, "Turn input Role name"),
160
+ purpose: input.purpose,
161
+ subject,
162
+ ...(normalizedInput.contextSnapshotRef === undefined
163
+ ? {}
164
+ : { contextSnapshotRef: normalizedInput.contextSnapshotRef }),
165
+ deltaRefIds: normalizedInput.deltaRefIds
166
+ };
167
+ }
168
+ function normalizeSubject(subject) {
169
+ const normalized = Object.fromEntries(Object.entries(subject).map(([key, value]) => [
170
+ key,
171
+ requireIdentity(value, `Turn input ${key}`)
172
+ ]));
173
+ const allowed = [
174
+ "taskId",
175
+ "workItemId",
176
+ "reviewRoundId",
177
+ "executionGroupId",
178
+ "executionLaneId"
179
+ ];
180
+ if (Object.keys(normalized).some((key) => !allowed.includes(key))) {
181
+ throw new Error("Turn input subject contains an unknown field.");
182
+ }
183
+ if ((normalized.executionGroupId === undefined) !== (normalized.executionLaneId === undefined)) {
184
+ throw new Error("Turn input execution lineage is incomplete.");
185
+ }
186
+ if (normalized.taskId === undefined
187
+ && (normalized.workItemId !== undefined || normalized.reviewRoundId !== undefined
188
+ || normalized.executionGroupId !== undefined)) {
189
+ throw new Error("Turn input child subject requires a Task id.");
190
+ }
191
+ return Object.freeze(normalized);
192
+ }
193
+ function normalizeSource(source) {
194
+ if (source.type === "yui" && YUI_TURN_INPUT_CHANNELS.includes(source.channel)) {
195
+ return Object.freeze({ type: "yui", channel: source.channel });
196
+ }
197
+ if (source.type === "user" && source.channel === "direct") {
198
+ return Object.freeze({ type: "user", channel: "direct" });
199
+ }
200
+ if (source.type === "provider" && source.channel === "goal-continuation") {
201
+ return Object.freeze({ type: "provider", channel: "goal-continuation" });
202
+ }
203
+ throw new Error("Turn input source is invalid.");
204
+ }
@@ -33,7 +33,7 @@ export function buildTaskWakeEnvelope(reader, request) {
33
33
  .filter((record) => Date.parse(record.createdAt) > fromTime).length,
34
34
  messages: operationalTaskRecords(reader.listMessages(request.taskId), events, "message")
35
35
  .filter((record) => Date.parse(record.createdAt) > fromTime).length,
36
- runs: operationalTaskRecords(reader.listAgentRuns(request.taskId), events, "agent-run")
36
+ turns: operationalTaskRecords(reader.listTurns(request.taskId), events, "turn")
37
37
  .filter((record) => Date.parse(record.createdAt) > fromTime).length
38
38
  };
39
39
  const activeReviews = reader.listReviewRounds(request.taskId).filter((round) => ((round.scope ?? "work-item") === "task"
@@ -50,7 +50,7 @@ export function buildTaskWakeEnvelope(reader, request) {
50
50
  const lines = [
51
51
  `Wake: ${request.wakeId} — delta since ${request.fromCursor}`,
52
52
  ` Reasons: ${renderReasons(request.reasons)}`,
53
- ` Changed: ${counts.events} events, ${counts.messages} messages, ${counts.runs} runs`
53
+ ` Changed: ${counts.events} events, ${counts.messages} messages, ${counts.turns} Turns`
54
54
  + ` → yui task wake show ${request.taskId} ${request.wakeId}`,
55
55
  ` Active Task Reviews: ${activeReviews.length === 0
56
56
  ? "none"
@@ -5,7 +5,7 @@ const DEFAULT_MAX_CONCURRENT_SAMPLES = 8;
5
5
  const MAX_CONCURRENT_SAMPLES = 64;
6
6
  /**
7
7
  * Controller-owned, provider-independent sampler. Drivers own source parsing;
8
- * this component owns active-Run discovery, cursor lifetime, canonical event
8
+ * this component owns active-Turn discovery, cursor lifetime, canonical event
9
9
  * creation, and low-latency mailbox wakes.
10
10
  */
11
11
  export class AgentRuntimeObserver {
@@ -73,7 +73,7 @@ export class AgentRuntimeObserver {
73
73
  if (state.usage === undefined) {
74
74
  // Cumulative counters need a lower bound. An exact initial sample
75
75
  // proves the complete Session-generation history even when the
76
- // current Run resumed that Session, so preserve every occurrence and
76
+ // current Turn resumed that Session, so preserve every occurrence and
77
77
  // anchor it at zero. A partial sample cannot prove the omitted request
78
78
  // boundaries; retain its latest total as a partial baseline, plus the
79
79
  // smallest ordered witness if the visible counter already rolled back.
@@ -239,8 +239,8 @@ export class AgentRuntimeObserver {
239
239
  activeSources() {
240
240
  const result = [];
241
241
  const indexedTaskIds = this.store.listActiveTaskIds?.();
242
- // FileTaskStore remains a development/compatibility fallback. The normal
243
- // Controller store is SQLite and must discover only its indexed hot set.
242
+ // Stores without the indexed projection remain useful for deterministic
243
+ // tests. The production SQLite store discovers only its indexed hot set.
244
244
  const activeTasks = indexedTaskIds === undefined
245
245
  ? this.store.listTasks().filter((task) => (task.status === "active" && task.executionGate.state === "enabled"))
246
246
  : [...new Set(indexedTaskIds)]
@@ -251,43 +251,43 @@ export class AgentRuntimeObserver {
251
251
  && task.executionGate.state === "enabled"));
252
252
  for (const task of activeTasks) {
253
253
  // A Task still incurs one O(E) event projection. Group those observations
254
- // by Run and sort each group once so every active Run can reuse the same
254
+ // by Turn and sort each group once so every active Turn can reuse the same
255
255
  // ordered slice instead of repeatedly filtering/sorting all E events.
256
- const observationsByRunId = new Map();
256
+ const observationsByTurnId = new Map();
257
257
  const taskObservations = [];
258
258
  for (const event of this.store.listEvents(task.id)) {
259
259
  const observation = runtimeObservationFromTaskEvent(event);
260
- const runId = observation?.fence.runId;
261
- if (observation === null || runId === undefined)
260
+ const turnId = observation?.fence.turnId;
261
+ if (observation === null || turnId === undefined)
262
262
  continue;
263
263
  taskObservations.push(observation);
264
- const grouped = observationsByRunId.get(runId);
264
+ const grouped = observationsByTurnId.get(turnId);
265
265
  if (grouped === undefined) {
266
- observationsByRunId.set(runId, [observation]);
266
+ observationsByTurnId.set(turnId, [observation]);
267
267
  }
268
268
  else {
269
269
  grouped.push(observation);
270
270
  }
271
271
  }
272
- for (const observations of observationsByRunId.values()) {
272
+ for (const observations of observationsByTurnId.values()) {
273
273
  observations.sort(compareObservations);
274
274
  }
275
275
  taskObservations.sort(compareObservations);
276
- for (const run of this.store.listAgentRuns(task.id)) {
276
+ for (const run of this.store.listTurns(task.id)) {
277
277
  if (run.status !== "active"
278
- || this.store.getActiveAgentRun(task.id, run.roleName)?.id !== run.id)
278
+ || this.store.getActiveTurn(task.id, run.roleName)?.id !== run.id)
279
279
  continue;
280
- const observations = observationsByRunId.get(run.id) ?? [];
280
+ const observations = observationsByTurnId.get(run.id) ?? [];
281
281
  const accepted = observations
282
282
  .filter((observation) => observation.kind === "turn.accepted"
283
- && observation.fence.runId === run.id
283
+ && observation.fence.turnId === run.id
284
284
  && observation.fence.roleName === run.roleName
285
285
  && observation.fence.agentId === run.effective.agentId
286
286
  && observation.payload.observerSource !== undefined)
287
287
  .at(-1);
288
288
  const source = accepted?.payload.observerSource;
289
289
  if (accepted === undefined || source === undefined
290
- || accepted.fence.taskId === undefined || accepted.fence.runId === undefined)
290
+ || accepted.fence.taskId === undefined || accepted.fence.turnId === undefined)
291
291
  continue;
292
292
  try {
293
293
  if (this.drivers.require(accepted.fence.driverId).runtime.observer === undefined)
@@ -313,7 +313,7 @@ export class AgentRuntimeObserver {
313
313
  key: JSON.stringify([
314
314
  fence.taskId,
315
315
  fence.roleName,
316
- fence.runId,
316
+ fence.turnId,
317
317
  fence.agentId,
318
318
  fence.driverId,
319
319
  fence.launchId,
@@ -374,7 +374,7 @@ function sampleConcurrency(value) {
374
374
  if (!Number.isSafeInteger(resolved)
375
375
  || resolved < 1
376
376
  || resolved > MAX_CONCURRENT_SAMPLES) {
377
- throw new Error(`Agent runtime observer maxConcurrentSamples must be between 1 and ${MAX_CONCURRENT_SAMPLES}.`);
377
+ throw new Error(`AgentRuntime observer maxConcurrentSamples must be between 1 and ${MAX_CONCURRENT_SAMPLES}.`);
378
378
  }
379
379
  return resolved;
380
380
  }