@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,30 +1,27 @@
1
1
  import { isDeepStrictEqual } from "node:util";
2
2
  import { completeProcessing } from "../coordination/workMailbox.js";
3
- import { settleExactWorkExecution } from "../coordination/workMailboxQueue.js";
4
- import { terminalizeTaskRoleRunSession } from "../executor/agentExecutor.js";
5
3
  import { finishReviewRound, updateReviewExecutionGroup } from "../review/reviewRound.js";
6
4
  import { reconcileReviewFindingsAfterReview } from "../review/reviewFindingLedger.js";
7
- import { agentRunDeliveryReceiptId, failAgentRun, withYieldReceipt, yieldAgentRun } from "../run/agentRun.js";
8
- import { createYieldReceipt } from "../run/yieldReceipt.js";
5
+ import { completeTurn, failTurn } from "../turn/turn.js";
9
6
  import { recordExecutionLaneResult, resolveExecutionGroup } from "../execution/executionGroup.js";
10
7
  import { isRuntimeLaunchReservation, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
11
- import { runOwnsBlockingProviderContinuation } from "../runtime/runtimeContinuationProjection.js";
12
- import { latestRunDurableProgressAt } from "../scheduler/roleRunStall.js";
8
+ import { managedProviderTurnId } from "../runtime/providerRuntimeIdentity.js";
9
+ import { latestTurnDurableProgressAt } from "../scheduler/roleTurnStall.js";
13
10
  import { markTaskWakeConsumed } from "../scheduler/taskWake.js";
14
11
  import { workItemExecutionGroupById, updateWorkItemExecutionGroup } from "../workItem/workItem.js";
15
12
  /**
16
13
  * Validate every immutable identity and frozen Project head needed before a
17
- * review Run can settle any mailbox or Round state. This is deliberately
14
+ * review Turn can settle any mailbox or Round state. This is deliberately
18
15
  * read-only: callers use it as the compare-and-swap fence immediately before
19
16
  * their aggregate mutation.
20
17
  */
21
- export function validateExactRunReviewRound(store, run, options = {}) {
22
- if (run.purpose !== "review")
18
+ export function validateExactTurnReviewRound(store, turn, options = {}) {
19
+ if (turn.purpose !== "review")
23
20
  return { disposition: "applied", round: null };
24
- if (run.reviewRoundId === undefined) {
21
+ if (turn.reviewRoundId === undefined) {
25
22
  return { disposition: "obsolete", round: null, reason: "review-round-missing" };
26
23
  }
27
- const round = store.getReviewRound(run.taskId, run.reviewRoundId);
24
+ const round = store.getReviewRound(turn.taskId, turn.reviewRoundId);
28
25
  if (round === null) {
29
26
  return { disposition: "obsolete", round: null, reason: "review-round-missing" };
30
27
  }
@@ -32,60 +29,60 @@ export function validateExactRunReviewRound(store, run, options = {}) {
32
29
  && round.status !== "pending" && round.status !== "running") {
33
30
  return { disposition: "obsolete", round, reason: "review-round-terminal" };
34
31
  }
35
- const lane = round.executionGroup?.lanes.find(({ id }) => id === run.executionLaneId);
36
- const exactReviewerRun = round.reviewerRunId === run.id || lane?.runId === run.id;
37
- const exactReviewerRole = round.reviewerRoleName === run.roleName || lane?.roleName === run.roleName;
38
- if (!exactReviewerRun
32
+ const lane = round.executionGroup?.lanes.find(({ id }) => id === turn.executionLaneId);
33
+ const exactReviewerTurn = round.reviewerTurnId === turn.id || lane?.turnId === turn.id;
34
+ const exactReviewerRole = round.reviewerRoleName === turn.roleName || lane?.roleName === turn.roleName;
35
+ if (!exactReviewerTurn
39
36
  || !exactReviewerRole
40
- || round.workItemId !== run.workItemId
41
- || round.reviewBaseCommit !== run.effective.reviewBaseCommit) {
37
+ || round.workItemId !== turn.workItemId
38
+ || round.reviewBaseCommit !== turn.effective.reviewBaseCommit) {
42
39
  return { disposition: "obsolete", round, reason: "review-round-mismatch" };
43
40
  }
44
41
  const laneWorkspaceRoot = lane?.workspace?.root;
45
- if (run.workspace === undefined || round.workspace === undefined
46
- || (laneWorkspaceRoot === undefined && !isDeepStrictEqual(run.workspace, round.workspace))
47
- || (laneWorkspaceRoot !== undefined && run.workspace.root !== laneWorkspaceRoot)) {
42
+ if (turn.workspace === undefined || round.workspace === undefined
43
+ || (laneWorkspaceRoot === undefined && !isDeepStrictEqual(turn.workspace, round.workspace))
44
+ || (laneWorkspaceRoot !== undefined && turn.workspace.root !== laneWorkspaceRoot)) {
48
45
  return { disposition: "obsolete", round, reason: "review-workspace-mismatch" };
49
46
  }
50
- const storedWorkspace = run.workspace.owner.type === "execution-lane"
51
- ? store.getManagedWorkspace(run.workspace.owner)
52
- : store.getReviewRoundWorkspace(run.taskId, round.id);
47
+ const storedWorkspace = turn.workspace.owner.type === "execution-lane"
48
+ ? store.getManagedWorkspace(turn.workspace.owner)
49
+ : store.getReviewRoundWorkspace(turn.taskId, round.id);
53
50
  if (storedWorkspace === null
54
- || (run.workspace.owner.type !== "execution-lane"
51
+ || (turn.workspace.owner.type !== "execution-lane"
55
52
  && !isDeepStrictEqual(storedWorkspace, round.workspace))
56
- || !isDeepStrictEqual(storedWorkspace, run.workspace)) {
53
+ || !isDeepStrictEqual(storedWorkspace, turn.workspace)) {
57
54
  return { disposition: "obsolete", round, reason: "review-workspace-drift" };
58
55
  }
59
- if (run.workspace.owner.type !== "execution-lane") {
56
+ if (turn.workspace.owner.type !== "execution-lane") {
60
57
  if (storedWorkspace.owner.type !== "review-round"
61
- || storedWorkspace.owner.taskId !== run.taskId
58
+ || storedWorkspace.owner.taskId !== turn.taskId
62
59
  || storedWorkspace.owner.reviewRoundId !== round.id) {
63
60
  return { disposition: "obsolete", round, reason: "review-workspace-owner-mismatch" };
64
61
  }
65
62
  }
66
- if (run.workspace.owner.type === "execution-lane"
67
- && (run.workspace.owner.purpose !== "review"
68
- || run.workspace.owner.executionGroupId !== run.executionGroupId
69
- || run.workspace.owner.executionLaneId !== run.executionLaneId
70
- || run.workspace.owner.reviewRoundId !== round.id)) {
63
+ if (turn.workspace.owner.type === "execution-lane"
64
+ && (turn.workspace.owner.purpose !== "review"
65
+ || turn.workspace.owner.executionGroupId !== turn.executionGroupId
66
+ || turn.workspace.owner.executionLaneId !== turn.executionLaneId
67
+ || turn.workspace.owner.reviewRoundId !== round.id)) {
71
68
  return { disposition: "obsolete", round, reason: "review-lane-workspace-owner-mismatch" };
72
69
  }
73
- if (run.workspace.owner.type === "execution-lane") {
70
+ if (turn.workspace.owner.type === "execution-lane") {
74
71
  if (lane === undefined
75
- || lane.runId !== run.id
76
- || lane.roleName !== run.roleName
77
- || lane.workspace?.root !== run.workspace.root
78
- || lane.workspace.writableProjectIds.length !== run.workspace.entries.length
79
- || run.workspace.entries.some((entry) => (entry.access !== "write"
72
+ || lane.turnId !== turn.id
73
+ || lane.roleName !== turn.roleName
74
+ || lane.workspace?.root !== turn.workspace.root
75
+ || lane.workspace.writableProjectIds.length !== turn.workspace.entries.length
76
+ || turn.workspace.entries.some((entry) => (entry.access !== "write"
80
77
  || !lane.workspace.writableProjectIds.includes(entry.projectId)))) {
81
78
  return { disposition: "obsolete", round, reason: "review-lane-workspace-lineage-mismatch" };
82
79
  }
83
80
  }
84
- const task = store.getTask(run.taskId);
81
+ const task = store.getTask(turn.taskId);
85
82
  const taskScope = (round.scope ?? "work-item") === "task";
86
83
  const item = taskScope || round.workItemId === undefined
87
84
  ? null
88
- : store.getWorkItem(run.taskId, round.workItemId);
85
+ : store.getWorkItem(turn.taskId, round.workItemId);
89
86
  if (!taskScope && item === null) {
90
87
  return { disposition: "obsolete", round, reason: "review-work-item-missing" };
91
88
  }
@@ -129,22 +126,22 @@ export function validateExactRunReviewRound(store, run, options = {}) {
129
126
  return { disposition: "applied", round };
130
127
  }
131
128
  /**
132
- * Atomically terminalizes the exact ReviewRound bound to a review AgentRun.
129
+ * Atomically terminalizes the exact ReviewRound bound to a review Turn.
133
130
  * The round must still be pending/running and its reviewer identity must match
134
- * the Run exactly. This is the sole review-round convergence primitive shared
135
- * by the exact Run terminalization path and the pre-delivery launch-failure
136
- * path: a failed review Run must never leave its Round stranded.
131
+ * the Turn exactly. This is the sole review-round convergence primitive shared
132
+ * by the exact Turn terminalization path and the pre-delivery launch-failure
133
+ * path: a failed review Turn must never leave its Round stranded.
137
134
  */
138
- export function terminalizeExactRunReviewRound(store, input, now) {
139
- const validation = validateExactRunReviewRound(store, input.run);
135
+ export function terminalizeExactTurnReviewRound(store, input, now) {
136
+ const validation = validateExactTurnReviewRound(store, input.turn);
140
137
  if (validation.disposition !== "applied" || validation.round === null) {
141
138
  return validation;
142
139
  }
143
140
  const reviewRound = validation.round;
144
- let groupedRound = input.run.executionGroupId !== undefined
145
- && input.run.executionLaneId !== undefined
141
+ let groupedRound = input.turn.executionGroupId !== undefined
142
+ && input.turn.executionLaneId !== undefined
146
143
  && reviewRound.executionGroup !== undefined
147
- ? updateReviewExecutionGroup(reviewRound, recordExecutionLaneResult(reviewRound.executionGroup, input.run.executionLaneId, {
144
+ ? updateReviewExecutionGroup(reviewRound, recordExecutionLaneResult(reviewRound.executionGroup, input.turn.executionLaneId, {
148
145
  summary: input.outcome.summary,
149
146
  ...(input.reviewResult?.report === undefined ? {} : { report: input.reviewResult.report }),
150
147
  ...(input.reviewResult?.checks === undefined
@@ -168,14 +165,13 @@ export function terminalizeExactRunReviewRound(store, input, now) {
168
165
  ...(input.reviewResult?.gitSnapshot === undefined
169
166
  ? {}
170
167
  : { gitSnapshot: input.reviewResult.gitSnapshot })
171
- }, input.outcome.status === "yielded" ? "completed" : "failed", now))
168
+ }, input.outcome.status, now))
172
169
  : reviewRound;
173
170
  if (input.settleFailedExecutionGroup === true
174
171
  && input.outcome.status === "failed"
175
172
  && groupedRound.executionGroup !== undefined
176
173
  && groupedRound.executionGroup.resolution === undefined
177
- && groupedRound.executionGroup.lanes.every((lane) => (lane.status === "yielded"
178
- || lane.status === "completed"
174
+ && groupedRound.executionGroup.lanes.every((lane) => (lane.status === "completed"
179
175
  || lane.status === "failed"
180
176
  || lane.status === "skipped"))) {
181
177
  groupedRound = updateReviewExecutionGroup(groupedRound, resolveExecutionGroup(groupedRound.executionGroup, {
@@ -195,7 +191,7 @@ export function terminalizeExactRunReviewRound(store, input, now) {
195
191
  store.saveReviewRound(input.taskId, groupedRound);
196
192
  return { disposition: "applied", round: groupedRound };
197
193
  }
198
- const terminal = finishReviewRound(groupedRound, input.outcome.status === "yielded" ? "completed" : "failed", input.outcome.summary, now, input.reviewResult);
194
+ const terminal = finishReviewRound(groupedRound, input.outcome.status, input.outcome.summary, now, input.reviewResult);
199
195
  store.saveReviewRound(input.taskId, terminal);
200
196
  // Issue 06: a completed (semantic) Round feeds the finding ledger; a failed
201
197
  // execution attempt is skipped by the classifier and never creates findings.
@@ -205,17 +201,17 @@ export function terminalizeExactRunReviewRound(store, input, now) {
205
201
  return { disposition: "applied", round: terminal };
206
202
  }
207
203
  /**
208
- * Retire one stranded active Run only after its exact Provider Turn is
204
+ * Retire one stranded active Turn only after its exact Provider Turn is
209
205
  * terminal and every durable execution fence is quiet. The caller owns the
210
- * surrounding aggregate transaction so the Run, ReviewRound/Lane, mailbox,
206
+ * surrounding aggregate transaction so the Turn, ReviewRound/Lane, mailbox,
211
207
  * Session, and append-only retirement record commit together.
212
208
  */
213
- export function retireExactActiveAgentRun(store, input, now) {
214
- const current = store.getAgentRun(input.taskId, input.runId);
209
+ export function retireExactActiveTurn(store, input, now) {
210
+ const current = store.getTurn(input.taskId, input.turnId);
215
211
  const stateChanged = (reason) => ({
216
212
  disposition: "state-changed",
217
- run: current,
218
- ...(current === null ? {} : { progressAt: latestRunDurableProgressAt(store, input.taskId, input.roleName, input.runId)?.progressAt }),
213
+ turn: current,
214
+ ...(current === null ? {} : { progressAt: latestTurnDurableProgressAt(store, input.taskId, input.roleName, input.turnId)?.progressAt }),
219
215
  reason
220
216
  });
221
217
  const task = store.getTask(input.taskId);
@@ -224,22 +220,22 @@ export function retireExactActiveAgentRun(store, input, now) {
224
220
  if (task.status !== "active")
225
221
  return stateChanged("task-terminal");
226
222
  if (current === null)
227
- return stateChanged("run-missing");
223
+ return stateChanged("turn-missing");
228
224
  if (current.status !== "active")
229
- return stateChanged("run-terminal");
225
+ return stateChanged("turn-terminal");
230
226
  if (current.taskId !== input.taskId || current.roleName !== input.roleName) {
231
- return stateChanged("run-owner-mismatch");
227
+ return stateChanged("turn-owner-mismatch");
232
228
  }
233
229
  if (current.effective.agentId !== input.agentId
234
230
  || current.effective.adapterId !== input.adapterId) {
235
- return stateChanged("run-launch-identity-mismatch");
231
+ return stateChanged("turn-launch-identity-mismatch");
236
232
  }
237
233
  const active = current.executionGroupId !== undefined && current.executionLaneId !== undefined
238
- ? store.getActiveExecutionLaneRun(input.taskId, current.executionGroupId, current.executionLaneId)
239
- : store.getActiveAgentRun(input.taskId, input.roleName);
234
+ ? store.getActiveExecutionLaneTurn(input.taskId, current.executionGroupId, current.executionLaneId)
235
+ : store.getActiveTurn(input.taskId, input.roleName);
240
236
  if (active?.id !== current.id)
241
- return stateChanged("active-run-mismatch");
242
- const progress = latestRunDurableProgressAt(store, input.taskId, input.roleName, input.runId);
237
+ return stateChanged("active-turn-mismatch");
238
+ const progress = latestTurnDurableProgressAt(store, input.taskId, input.roleName, input.turnId);
243
239
  if (progress === null)
244
240
  return stateChanged("progress-unavailable");
245
241
  if (progress.progressAt !== input.expectedProgressAt) {
@@ -250,21 +246,16 @@ export function retireExactActiveAgentRun(store, input, now) {
250
246
  taskId: input.taskId,
251
247
  roleName: input.roleName,
252
248
  agentId: input.agentId,
253
- runId: input.runId,
254
- receiptId: agentRunDeliveryReceiptId(current),
249
+ turnId: input.turnId,
255
250
  ...(input.nativeSessionId === undefined ? {} : { nativeSessionId: input.nativeSessionId }),
256
251
  ...(input.launchId === undefined ? {} : { launchId: input.launchId }),
257
252
  settleFailedExecutionGroup: true,
258
- outcome: { status: "failed", summary: input.reason }
253
+ outcome: { status: "failed", summary: input.reason, failureReason: "missing-result" }
259
254
  };
260
- if (!matchesSessionFence(sessions, terminalInput)
261
- || !matchesLaunchFence(store, sessions, terminalInput)) {
262
- return stateChanged("session-or-launch-fence-mismatch");
263
- }
264
255
  const session = sessions?.sessions[input.agentId];
265
256
  const providerBinding = sessions?.providerBinding;
266
257
  const providerTurn = providerBinding?.turn;
267
- const providerSettled = providerTurn?.runId === current.id
258
+ const providerSettled = managedProviderTurnId(providerTurn) === current.id
268
259
  && (providerTurn?.status === "completed"
269
260
  || providerTurn?.status === "failed"
270
261
  || providerTurn?.status === "cancelled"
@@ -272,107 +263,59 @@ export function retireExactActiveAgentRun(store, input, now) {
272
263
  if (session?.status === "active" && !providerSettled) {
273
264
  return {
274
265
  disposition: "blocked",
275
- run: current,
266
+ turn: current,
276
267
  progressAt: progress.progressAt,
277
268
  reason: "runtime-not-terminal"
278
269
  };
279
270
  }
280
- const terminal = terminalizeExactTaskRun(store, terminalInput, now);
281
- if (terminal.disposition !== "applied" || terminal.run === null) {
271
+ const terminal = terminalizeExactTaskTurn(store, terminalInput, now);
272
+ if (terminal.disposition !== "applied" || terminal.turn === null) {
282
273
  return stateChanged(terminal.reason ?? "terminalization-fence-mismatch");
283
274
  }
284
275
  return {
285
276
  disposition: "applied",
286
- run: terminal.run,
277
+ turn: terminal.turn,
287
278
  progressAt: progress.progressAt
288
279
  };
289
280
  }
290
281
  /**
291
282
  * Applies one exact application-level terminal fact inside the caller's
292
- * FileTaskStore transaction. All caller-owned outcome records can therefore
283
+ * TaskStore transaction. All caller-owned outcome records can therefore
293
284
  * be saved in the same aggregate commit.
294
285
  */
295
- export function terminalizeExactTaskRun(store, input, now) {
296
- const run = store.getAgentRun(input.taskId, input.runId);
297
- if (run === null)
298
- return obsolete(null, "run-missing");
299
- if (run.status !== "active")
300
- return obsolete(run, "run-terminal");
301
- if (run.taskId !== input.taskId || run.roleName !== input.roleName) {
302
- return obsolete(run, "run-owner-mismatch");
303
- }
304
- if (run.effective.agentId !== input.agentId) {
305
- return obsolete(run, "run-agent-mismatch");
286
+ export function terminalizeExactTaskTurn(store, input, now) {
287
+ const turn = store.getTurn(input.taskId, input.turnId);
288
+ if (turn === null)
289
+ return obsolete(null, "turn-missing");
290
+ if (turn.status !== "active")
291
+ return obsolete(turn, "turn-terminal");
292
+ if (turn.taskId !== input.taskId || turn.roleName !== input.roleName) {
293
+ return obsolete(turn, "turn-owner-mismatch");
294
+ }
295
+ if (turn.effective.agentId !== input.agentId) {
296
+ return obsolete(turn, "turn-agent-mismatch");
306
297
  }
307
298
  const role = store.getRole(input.taskId, input.roleName);
308
299
  if (role === null)
309
- return obsolete(run, "role-missing");
310
- const active = run.executionGroupId !== undefined && run.executionLaneId !== undefined
311
- ? store.getActiveExecutionLaneRun(input.taskId, run.executionGroupId, run.executionLaneId)
312
- : store.getActiveAgentRun(input.taskId, input.roleName);
313
- if (active?.id !== run.id)
314
- return obsolete(run, "active-run-mismatch");
300
+ return obsolete(turn, "role-missing");
301
+ const active = turn.executionGroupId !== undefined && turn.executionLaneId !== undefined
302
+ ? store.getActiveExecutionLaneTurn(input.taskId, turn.executionGroupId, turn.executionLaneId)
303
+ : store.getActiveTurn(input.taskId, input.roleName);
304
+ if (active?.id !== turn.id)
305
+ return obsolete(turn, "active-turn-mismatch");
315
306
  const sessions = store.getTaskRoleSessionSet(input.taskId, input.roleName);
316
- if (!matchesSessionFence(sessions, input)) {
317
- return obsolete(run, "session-fence-mismatch");
318
- }
319
- if (!matchesLaunchFence(store, sessions, input)) {
320
- return obsolete(run, "launch-fence-mismatch");
321
- }
322
- if (input.settleFailedExecutionGroup !== true
323
- && runOwnsBlockingProviderContinuation(store.listEvents(input.taskId), {
324
- taskId: run.taskId,
325
- roleName: run.roleName,
326
- runId: run.id,
327
- agentId: run.effective.agentId
328
- })) {
329
- return obsolete(run, "provider-continuation-writer-owned");
330
- }
331
307
  // Validate the exact ReviewRound, Candidate, stored workspace, and frozen
332
308
  // Project heads before any mailbox or Round write.
333
- const reviewValidation = validateExactRunReviewRound(store, run);
309
+ const reviewValidation = validateExactTurnReviewRound(store, turn);
334
310
  if (reviewValidation.disposition !== "applied") {
335
- return obsolete(run, reviewValidation.reason ?? "review-round-mismatch");
336
- }
337
- const roleTarget = {
338
- kind: "role",
339
- taskId: input.taskId,
340
- roleName: input.roleName
341
- };
342
- if (input.mailboxDisposition === "discard") {
343
- store.removeWorkMailbox(roleTarget);
344
- }
345
- else {
346
- // For review Runs the mailbox must carry an exact pending or processing
347
- // entry for this Run: an absent or unrelated mailbox means the review
348
- // dispatch was never recorded and the terminalization must fail closed.
349
- // Execution/Leader Runs keep the historical absent-is-clean behavior so
350
- // direct Leader completion and normal execution are unaffected.
351
- const isReview = run.purpose === "review";
352
- const mailbox = store.getWorkMailbox(roleTarget);
353
- const processing = mailbox?.processing;
354
- if (mailbox !== null && processing !== null && processing !== undefined) {
355
- if (processing.executionRef === undefined
356
- || processing.executionRef.type !== "run"
357
- || processing.executionRef.taskId !== run.taskId
358
- || processing.executionRef.id !== run.id) {
359
- return obsolete(run, "mailbox-busy");
360
- }
361
- store.saveWorkMailbox(completeProcessing(mailbox, processing.batchId));
362
- }
363
- else {
364
- const mailboxSettlement = settleExactWorkExecution(store, roleTarget, { type: "run", taskId: run.taskId, id: run.id });
365
- if (mailboxSettlement === "absent" && isReview && run.deliveredAt === undefined) {
366
- return obsolete(run, "review-mailbox-missing");
367
- }
368
- }
311
+ return obsolete(turn, reviewValidation.reason ?? "review-round-mismatch");
369
312
  }
370
- // All Run, active-pointer, Session, launch, and mailbox fences have passed.
371
- // Only now may the exact ReviewRound be terminalized alongside the Run so a
372
- // stale fence never leaves a Round written while the Run stays active.
373
- const reviewRoundTerminalization = terminalizeExactRunReviewRound(store, {
313
+ // All Turn, active-pointer, Session, launch, and mailbox fences have passed.
314
+ // Only now may the exact ReviewRound be terminalized alongside the Turn so a
315
+ // stale fence never leaves a Round written while the Turn stays active.
316
+ const reviewRoundTerminalization = terminalizeExactTurnReviewRound(store, {
374
317
  taskId: input.taskId,
375
- run,
318
+ turn,
376
319
  outcome: input.outcome,
377
320
  reviewResult: input.reviewResult,
378
321
  ...(input.settleFailedExecutionGroup === undefined
@@ -380,38 +323,21 @@ export function terminalizeExactTaskRun(store, input, now) {
380
323
  : { settleFailedExecutionGroup: input.settleFailedExecutionGroup })
381
324
  }, now);
382
325
  if (reviewRoundTerminalization.disposition !== "applied") {
383
- return obsolete(run, reviewRoundTerminalization.reason ?? "review-round-mismatch");
384
- }
385
- const terminal = input.outcome.status === "yielded"
386
- ? withYieldReceipt(yieldAgentRun(run, input.outcome.summary, now), createYieldReceipt(input.taskId, input.runId, {
387
- status: "yielded",
388
- summary: input.outcome.summary,
389
- ...(input.reviewResult === undefined
390
- ? {}
391
- : {
392
- reviewResult: {
393
- ...(input.reviewResult.report === undefined ? {} : { report: input.reviewResult.report }),
394
- ...(input.reviewResult.checks === undefined ? {} : { checks: input.reviewResult.checks }),
395
- ...(input.reviewResult.findings === undefined ? {} : { findings: input.reviewResult.findings }),
396
- ...(input.reviewResult.evidence === undefined ? {} : { evidence: input.reviewResult.evidence }),
397
- ...(input.reviewResult.evidenceCommit === undefined ? {} : { evidenceCommit: input.reviewResult.evidenceCommit }),
398
- ...(input.reviewResult.gitSnapshot === undefined ? {} : { gitSnapshot: input.reviewResult.gitSnapshot }),
399
- ...(input.reviewResult.deltaDisposition === undefined ? {} : { deltaDisposition: input.reviewResult.deltaDisposition }),
400
- ...(input.reviewResult.deltaReasoning === undefined ? {} : { deltaReasoning: input.reviewResult.deltaReasoning })
401
- }
402
- })
403
- }, now))
404
- : failAgentRun(run, input.outcome.summary, now);
405
- if (run.executionGroupId !== undefined
406
- && run.executionLaneId !== undefined
407
- && run.purpose === "execution"
408
- && run.workItemId !== undefined) {
409
- const item = store.getWorkItem(input.taskId, run.workItemId);
326
+ return obsolete(turn, reviewRoundTerminalization.reason ?? "review-round-mismatch");
327
+ }
328
+ const terminal = input.outcome.status === "completed"
329
+ ? completeTurn(turn, input.outcome.summary, now, input.outcome.provider)
330
+ : failTurn(turn, input.outcome.failureReason ?? "runtime-failed", input.outcome.summary, now, input.outcome.provider);
331
+ if (turn.executionGroupId !== undefined
332
+ && turn.executionLaneId !== undefined
333
+ && turn.purpose === "execution"
334
+ && turn.workItemId !== undefined) {
335
+ const item = store.getWorkItem(input.taskId, turn.workItemId);
410
336
  const group = item === null
411
337
  ? undefined
412
- : workItemExecutionGroupById(item, run.executionGroupId);
338
+ : workItemExecutionGroupById(item, turn.executionGroupId);
413
339
  if (item !== null && group !== undefined) {
414
- let grouped = recordExecutionLaneResult(group, run.executionLaneId, {
340
+ let grouped = recordExecutionLaneResult(group, turn.executionLaneId, {
415
341
  summary: input.outcome.summary,
416
342
  ...(input.reviewResult?.report === undefined ? {} : { report: input.reviewResult.report }),
417
343
  ...(input.reviewResult?.checks === undefined ? {} : { checks: input.reviewResult.checks }),
@@ -419,12 +345,11 @@ export function terminalizeExactTaskRun(store, input, now) {
419
345
  ...(input.reviewResult?.evidence === undefined ? {} : { evidence: input.reviewResult.evidence }),
420
346
  ...(input.reviewResult?.evidenceCommit === undefined ? {} : { evidenceCommit: input.reviewResult.evidenceCommit }),
421
347
  ...(input.reviewResult?.gitSnapshot === undefined ? {} : { gitSnapshot: input.reviewResult.gitSnapshot })
422
- }, input.outcome.status === "yielded" ? "completed" : "failed", now);
348
+ }, input.outcome.status, now);
423
349
  if (input.settleFailedExecutionGroup === true
424
350
  && input.outcome.status === "failed"
425
351
  && grouped.resolution === undefined
426
- && grouped.lanes.every((lane) => (lane.status === "yielded"
427
- || lane.status === "completed"
352
+ && grouped.lanes.every((lane) => (lane.status === "completed"
428
353
  || lane.status === "failed"
429
354
  || lane.status === "skipped"))) {
430
355
  grouped = resolveExecutionGroup(grouped, {
@@ -435,63 +360,22 @@ export function terminalizeExactTaskRun(store, input, now) {
435
360
  store.saveWorkItem(input.taskId, updateWorkItemExecutionGroup(item, grouped, now));
436
361
  }
437
362
  }
438
- store.saveAgentRun(terminal);
363
+ store.saveTurn(terminal);
439
364
  if (terminal.roleName === "leader") {
440
365
  const wake = store.listTaskWakes(input.taskId)
441
- .find((candidate) => candidate.runId === terminal.id && candidate.status === "dispatched");
366
+ .find((candidate) => candidate.turnId === terminal.id && candidate.status === "dispatched");
442
367
  if (wake !== undefined) {
443
368
  store.saveTaskWake(input.taskId, markTaskWakeConsumed(wake, now));
444
369
  }
445
370
  }
446
371
  if (terminal.executionGroupId !== undefined && terminal.executionLaneId !== undefined) {
447
- store.clearActiveExecutionLaneRun(input.taskId, terminal.executionGroupId, terminal.executionLaneId);
372
+ store.clearActiveExecutionLaneTurn(input.taskId, terminal.executionGroupId, terminal.executionLaneId);
448
373
  }
449
374
  else {
450
- store.clearActiveAgentRun(input.taskId, input.roleName);
451
- }
452
- if (sessions !== null) {
453
- store.saveTaskRoleSessionSet(terminalizeTaskRoleRunSession(sessions, {
454
- agentId: input.agentId,
455
- runId: input.runId,
456
- receiptId: input.receiptId
457
- }, now));
375
+ store.clearActiveTurn(input.taskId, input.roleName);
458
376
  }
459
377
  settleLaunchReservation(store, sessions, input);
460
- return { disposition: "applied", run: terminal };
461
- }
462
- function matchesSessionFence(sessions, input) {
463
- if (sessions === null)
464
- return input.nativeSessionId === undefined;
465
- if (sessions.activeAgentId !== input.agentId)
466
- return false;
467
- const session = sessions.sessions[input.agentId];
468
- if (input.nativeSessionId !== undefined) {
469
- if (session?.nativeSessionId !== input.nativeSessionId)
470
- return false;
471
- }
472
- const inFlight = sessions.inFlight;
473
- return inFlight === null || (inFlight.agentId === input.agentId
474
- && inFlight.runId === input.runId
475
- && inFlight.receiptId === input.receiptId);
476
- }
477
- function matchesLaunchFence(store, sessions, input) {
478
- // A resumed Run shares the native Provider Session whose process environment
479
- // was created for an earlier Run. Once that exact native Session has passed
480
- // matchesSessionFence, its immutable per-launch environment is not a second
481
- // Run identity. Opaque hosts still require the launch fence below.
482
- if (input.nativeSessionId !== undefined)
483
- return true;
484
- if (input.launchId === undefined)
485
- return true;
486
- const session = sessions?.sessions[input.agentId];
487
- if (session?.launchId === input.launchId)
488
- return true;
489
- const mailbox = store.getWorkMailbox(runtimeLifecycleTarget({
490
- scope: "task",
491
- taskId: input.taskId,
492
- roleName: input.roleName
493
- }));
494
- return isRuntimeLaunchReservation(mailbox?.processing, input.launchId);
378
+ return { disposition: "applied", turn: terminal };
495
379
  }
496
380
  function settleLaunchReservation(store, sessions, input) {
497
381
  const target = runtimeLifecycleTarget({
@@ -515,6 +399,6 @@ function settleLaunchReservation(store, sessions, input) {
515
399
  store.saveWorkMailbox(settled);
516
400
  }
517
401
  }
518
- function obsolete(run, reason) {
519
- return { disposition: "obsolete", run, reason };
402
+ function obsolete(turn, reason) {
403
+ return { disposition: "obsolete", turn, reason };
520
404
  }
@@ -12,9 +12,9 @@ export function createTaskMessage(id, taskId, body, kind, author, now, context =
12
12
  ...(context.wakePolicy === undefined
13
13
  ? {}
14
14
  : { wakePolicy: context.wakePolicy }),
15
- ...(context.runId === undefined
15
+ ...(context.turnId === undefined
16
16
  ? {}
17
- : { runId: requireSafeIdentity(context.runId, "Message Run id") }),
17
+ : { turnId: requireSafeIdentity(context.turnId, "Message Turn id") }),
18
18
  ...(context.workItemId === undefined
19
19
  ? {}
20
20
  : { workItemId: requireSafeIdentity(context.workItemId, "Message Work item id") }),
@@ -43,16 +43,16 @@ export function validateTaskMessage(message) {
43
43
  && message.kind !== "operator") {
44
44
  throw new Error("Message wakePolicy is only valid for user/operator messages.");
45
45
  }
46
- if (message.runId !== undefined)
47
- requireSafeIdentity(message.runId, "Message Run id");
46
+ if (message.turnId !== undefined)
47
+ requireSafeIdentity(message.turnId, "Message Turn id");
48
48
  if (message.workItemId !== undefined) {
49
49
  validateTaskRecordReference({
50
50
  taskId: message.taskId,
51
51
  localId: message.workItemId
52
52
  }, "workItem");
53
53
  }
54
- if (message.runId !== undefined) {
55
- validateTaskRecordReference({ taskId: message.taskId, localId: message.runId }, "agentRun");
54
+ if (message.turnId !== undefined) {
55
+ validateTaskRecordReference({ taskId: message.taskId, localId: message.turnId }, "turn");
56
56
  }
57
57
  if (typeof message.createdAt !== "string" || Number.isNaN(Date.parse(message.createdAt))) {
58
58
  throw new Error("Message createdAt is invalid.");