@zq-silk/yui 0.15.7 → 0.15.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/ARCHITECTURE.md +194 -399
  2. package/ARCHITECTURE.zh-CN.md +151 -0
  3. package/README.md +306 -1131
  4. package/dist/agent/adapterCatalog.js +15 -2
  5. package/dist/agent/agent.js +23 -3
  6. package/dist/agent/argumentPolicy.js +7 -1
  7. package/dist/agent/connectionPlan.js +62 -0
  8. package/dist/agent/executionComponents.js +158 -0
  9. package/dist/agent/launchEnvironment.js +31 -3
  10. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  11. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  12. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  13. package/dist/artifacts/artifactCapability.js +74 -0
  14. package/dist/artifacts/artifactCommitLock.js +249 -0
  15. package/dist/artifacts/artifactPaths.js +151 -0
  16. package/dist/artifacts/gitArtifactRef.js +146 -0
  17. package/dist/artifacts/managedGit.js +332 -0
  18. package/dist/artifacts/taskArtifactRepository.js +277 -0
  19. package/dist/brief/taskBrief.js +12 -0
  20. package/dist/cli/agentConfigurationPicker.js +13 -0
  21. package/dist/cli/commandCatalog.js +165 -74
  22. package/dist/cli/interactionCandidates.js +5 -5
  23. package/dist/cli/interactionPolicy.js +38 -8
  24. package/dist/cli/invocationRouter.js +1 -1
  25. package/dist/cli/managedDiagnostics.js +28 -0
  26. package/dist/cli/operatorWizard.js +1 -7
  27. package/dist/cli/roleOptionOrder.js +27 -0
  28. package/dist/cli/roleWizard.js +50 -14
  29. package/dist/cli/updateOrchestrator.js +1 -1
  30. package/dist/cli/updatePorts.js +3 -4
  31. package/dist/cli.js +245 -95
  32. package/dist/commands/agentCommands.js +72 -14
  33. package/dist/commands/capabilityCommands.js +9 -6
  34. package/dist/commands/configCommands.js +20 -20
  35. package/dist/commands/deliveryGuardPreflight.js +2 -2
  36. package/dist/commands/executionAuditCommands.js +24 -24
  37. package/dist/commands/globalRoleCommands.js +1 -1
  38. package/dist/commands/grantCommands.js +4 -4
  39. package/dist/commands/operatorCommands.js +34 -9
  40. package/dist/commands/projectCommands.js +4 -4
  41. package/dist/commands/resourcesCommands.js +2 -2
  42. package/dist/commands/roleConfiguration.js +25 -5
  43. package/dist/commands/roleRuntimeGuard.js +4 -5
  44. package/dist/commands/sessionCommands.js +3 -7
  45. package/dist/commands/taskActivationCommands.js +281 -0
  46. package/dist/commands/taskActor.js +28 -49
  47. package/dist/commands/taskCommands.js +1461 -720
  48. package/dist/commands/taskContextCommand.js +39 -583
  49. package/dist/commands/taskExecutionCommands.js +32 -32
  50. package/dist/commands/taskInputCommands.js +40 -104
  51. package/dist/commands/taskIntegrationCommands.js +3 -2
  52. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  53. package/dist/commands/taskNextActionCommand.js +8 -8
  54. package/dist/commands/taskOverviewCommand.js +33 -45
  55. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  56. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  57. package/dist/commands/telemetryCommands.js +36 -38
  58. package/dist/config/configCatalog.js +4 -4
  59. package/dist/config/yuiConfig.js +8 -8
  60. package/dist/context/contextSnapshot.js +10 -10
  61. package/dist/context/dispatchContext.js +11 -11
  62. package/dist/context/roleSessionContext.js +6 -3
  63. package/dist/context/{turnContextPack.js → runContextPack.js} +158 -81
  64. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  65. package/dist/context/sessionBootstrapManifest.js +21 -2
  66. package/dist/context/sourceRunContext.js +30 -0
  67. package/dist/context/taskContext.js +481 -0
  68. package/dist/context/wakeNotification.js +27 -27
  69. package/dist/controller/agentRuntimeObserver.js +21 -24
  70. package/dist/controller/capabilityBridge.js +17 -6
  71. package/dist/controller/clientRuntime.js +65 -92
  72. package/dist/controller/controller.js +120 -188
  73. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  74. package/dist/controller/jobControl.js +54 -85
  75. package/dist/controller/resourceInventory.js +8 -27
  76. package/dist/controller/resourceInventoryLinux.js +12 -13
  77. package/dist/controller/runtime.js +529 -479
  78. package/dist/controller/runtimeEventInbox.js +55 -25
  79. package/dist/controller/runtimeEventProcessor.js +22 -31
  80. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  81. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  82. package/dist/controller/runtimeObservationHook.js +14 -18
  83. package/dist/controller/sessionNotify.js +16 -24
  84. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  85. package/dist/controller/structuredProviderObservation.js +138 -99
  86. package/dist/coordination/workMailbox.js +3 -3
  87. package/dist/coordination/workMailboxQueue.js +36 -33
  88. package/dist/core/boundedRpc.js +8 -1
  89. package/dist/core/controllerClient.js +20 -1
  90. package/dist/core/controllerServer.js +4 -4
  91. package/dist/doctor/doctor.js +13 -2
  92. package/dist/domain/agentResultTransport.js +9 -9
  93. package/dist/execution/codexThreadNaming.js +2 -8
  94. package/dist/execution/executionHealth.js +51 -63
  95. package/dist/execution/reviewMainRun.js +137 -0
  96. package/dist/execution/workItemExecution.js +28 -29
  97. package/dist/execution/workItemExecutionProjection.js +99 -107
  98. package/dist/execution/workItemMainRun.js +141 -0
  99. package/dist/executor/agentAdapter.js +227 -20
  100. package/dist/executor/agentConfigurationCatalog.js +126 -4
  101. package/dist/executor/agentConfigurationProbe.js +162 -4
  102. package/dist/executor/agentExecutor.js +79 -78
  103. package/dist/executor/effectiveLaunch.js +105 -18
  104. package/dist/executor/executorRegistry.js +29 -44
  105. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  106. package/dist/executor/workspacePreflightClassification.js +16 -16
  107. package/dist/grant/capabilityGrant.js +6 -3
  108. package/dist/input/inputRequest.js +12 -10
  109. package/dist/integration/gitIntegrationService.js +4 -11
  110. package/dist/integration/integrationQueueService.js +4 -4
  111. package/dist/interaction/operatorPresentation.js +1 -1
  112. package/dist/kernel/builtinCapabilities.js +255 -12
  113. package/dist/kernel/capabilityRegistry.js +64 -18
  114. package/dist/kernel/instanceHost.js +12 -1
  115. package/dist/kernel/kernelPorts.js +2 -2
  116. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  117. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  118. package/dist/message/message.js +118 -6
  119. package/dist/message/messageContinuation.js +204 -0
  120. package/dist/observability/executionAudit.js +70 -72
  121. package/dist/observability/faultClassification.js +2 -2
  122. package/dist/observability/orchestrationMetrics.js +8 -8
  123. package/dist/operator/operatorSessionHistory.js +1 -7
  124. package/dist/output/agentConfigurationPresentation.js +8 -3
  125. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  126. package/dist/output/rolePresentation.js +54 -3
  127. package/dist/plugins/pluginChild.js +104 -0
  128. package/dist/plugins/pluginIntent.js +26 -0
  129. package/dist/plugins/pluginInterpreter.js +43 -0
  130. package/dist/plugins/pluginPackage.js +101 -0
  131. package/dist/plugins/pluginProcess.js +112 -0
  132. package/dist/plugins/pluginService.js +388 -0
  133. package/dist/profile/agentProfile.js +1 -1
  134. package/dist/repository/gitWorkspace.js +26 -4
  135. package/dist/repository/project.js +19 -4
  136. package/dist/repository/taskBaseFreshness.js +13 -13
  137. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  138. package/dist/repository/taskWorkspacePreparer.js +344 -83
  139. package/dist/resources/autoResourceGc.js +3 -3
  140. package/dist/resources/liveReferences.js +3 -3
  141. package/dist/resources/projectResource.js +75 -0
  142. package/dist/resources/projectResourceService.js +343 -0
  143. package/dist/resources/resourceDiscovery.js +6 -6
  144. package/dist/resources/resourceGc.js +1 -1
  145. package/dist/resources/resourceRegistrar.js +1 -1
  146. package/dist/resources/resourceTypes.js +1 -1
  147. package/dist/review/deltaRecheck.js +3 -3
  148. package/dist/review/reviewAcceptance.js +16 -16
  149. package/dist/review/reviewDecision.js +7 -7
  150. package/dist/review/reviewRound.js +21 -20
  151. package/dist/review/reviewerAvailability.js +2 -2
  152. package/dist/role/role.js +51 -7
  153. package/dist/role/taskRoleUpdate.js +30 -0
  154. package/dist/runtime/acpProtocol.js +425 -0
  155. package/dist/runtime/acpSession.js +731 -0
  156. package/dist/runtime/acpSessionConfiguration.js +260 -0
  157. package/dist/runtime/agentDriver.js +30 -11
  158. package/dist/runtime/agentEndpoint.js +278 -0
  159. package/dist/runtime/agentEndpointIdentity.js +86 -0
  160. package/dist/runtime/agentEndpointOwnership.js +239 -0
  161. package/dist/runtime/agentError.js +2 -10
  162. package/dist/runtime/agentHost.js +565 -314
  163. package/dist/runtime/agentRunConfiguration.js +258 -0
  164. package/dist/runtime/builtinAgentDrivers.js +134 -18
  165. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  166. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  167. package/dist/runtime/claude-process-owner +0 -0
  168. package/dist/runtime/codexAppServerRuntime.js +38 -30
  169. package/dist/runtime/codexInteractiveHost.js +41 -6
  170. package/dist/runtime/continuationManager.js +2 -6
  171. package/dist/runtime/executionEnvironment.js +30 -0
  172. package/dist/runtime/firstProgressAdvisory.js +11 -11
  173. package/dist/runtime/index.js +4 -3
  174. package/dist/runtime/jsonLineChannel.js +109 -0
  175. package/dist/runtime/launchBroker.js +91 -16
  176. package/dist/runtime/launchDiagnostics.js +2 -2
  177. package/dist/runtime/lifecycleReservation.js +10 -18
  178. package/dist/runtime/managedCaller.js +61 -17
  179. package/dist/runtime/nativeSessionControl.js +102 -0
  180. package/dist/runtime/ports.js +6 -21
  181. package/dist/runtime/processExitObservation.js +8 -7
  182. package/dist/runtime/promptEnvelope.js +17 -6
  183. package/dist/runtime/providerContinuation.js +3 -9
  184. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  185. package/dist/runtime/providerControl.js +2 -7
  186. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  187. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  188. package/dist/runtime/runtimeBinding.js +0 -1
  189. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  190. package/dist/runtime/runtimeDeadlines.js +9 -0
  191. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  192. package/dist/runtime/runtimeObservation.js +29 -65
  193. package/dist/runtime/runtimeProjection.js +43 -51
  194. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  195. package/dist/runtime/sessionLaunchRequest.js +3 -7
  196. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  197. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  198. package/dist/runtime/sessionReconciliation.js +4 -8
  199. package/dist/runtime/sessionTerminationGuard.js +70 -259
  200. package/dist/runtime/sessionTokenMetrics.js +5 -16
  201. package/dist/runtime/structuredProviderHost.js +237 -117
  202. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  203. package/dist/runtime/tmuxAdapters.js +39 -86
  204. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  205. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  206. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  207. package/dist/scheduler/ports.js +80 -9
  208. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  209. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  210. package/dist/scheduler/taskExecutionProjection.js +120 -124
  211. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  212. package/dist/scheduler/taskWake.js +11 -4
  213. package/dist/scheduler/wakeReason.js +9 -1
  214. package/dist/setup/setupCommand.js +3 -7
  215. package/dist/storage/migrations/agentRunContract.js +159 -0
  216. package/dist/storage/migrations/artifactsToGit.js +338 -0
  217. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  218. package/dist/storage/migrations/submitIntent.js +126 -0
  219. package/dist/storage/sqliteSchema.js +467 -7
  220. package/dist/storage/sqliteStore.js +355 -220
  221. package/dist/storage/storageVersions.js +1 -1
  222. package/dist/storage/storeRpc.js +10 -5
  223. package/dist/storage/taskStore.js +13 -11
  224. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  225. package/dist/surface/surfaceContributions.js +102 -0
  226. package/dist/task/completionReadiness.js +32 -6
  227. package/dist/task/deliveryGuard.js +16 -16
  228. package/dist/task/draftPlan.js +72 -12
  229. package/dist/task/nextAction.js +144 -128
  230. package/dist/task/remoteDelivery.js +6 -6
  231. package/dist/task/task.js +184 -18
  232. package/dist/task/taskActivation.js +327 -0
  233. package/dist/task/taskActivationService.js +408 -0
  234. package/dist/task/taskRecordReference.js +5 -4
  235. package/dist/task/taskRecordRetirement.js +1 -1
  236. package/dist/task/taskSubmission.js +236 -0
  237. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  238. package/dist/telemetry/telemetryConfig.js +14 -14
  239. package/dist/telemetry/telemetryWiring.js +2 -2
  240. package/dist/web/assets/assetManifest.js +2 -0
  241. package/dist/web/assets/client/app.js +121 -20
  242. package/dist/web/assets/client/components.js +87 -54
  243. package/dist/web/assets/client/i18n.js +83 -41
  244. package/dist/web/assets/client/markdown.js +1 -1
  245. package/dist/web/assets/client/taskSurface.js +442 -0
  246. package/dist/web/assets/client/view.js +49 -44
  247. package/dist/web/assets/shell.js +1 -1
  248. package/dist/web/assets/styles/cards.js +22 -4
  249. package/dist/web/controllerWeb.js +60 -0
  250. package/dist/web/webMutation.js +28 -0
  251. package/dist/web/webServer.js +133 -8
  252. package/dist/web/webSnapshot.js +81 -74
  253. package/dist/web/webTaskSurface.js +64 -0
  254. package/dist/workItem/dependencyGate.js +1 -1
  255. package/dist/workItem/workItem.js +84 -48
  256. package/dist/workspace/workItemChangeSetManager.js +16 -9
  257. package/docs/agent-result-consumption.md +96 -0
  258. package/docs/agent-result-consumption.zh-CN.md +81 -0
  259. package/docs/agent-runtime-drivers.md +93 -0
  260. package/docs/agent-runtime-drivers.zh-CN.md +77 -0
  261. package/docs/architecture/README.md +50 -0
  262. package/docs/architecture/README.zh-CN.md +43 -0
  263. package/docs/architecture/capabilities-and-resources.md +118 -0
  264. package/docs/architecture/capabilities-and-resources.zh-CN.md +83 -0
  265. package/docs/managed-turn-and-session-runtime.md +224 -0
  266. package/docs/managed-turn-and-session-runtime.zh-CN.md +180 -0
  267. package/docs/observability/README.md +83 -0
  268. package/docs/observability/README.zh-CN.md +71 -0
  269. package/docs/plugin-sdk.md +393 -0
  270. package/docs/plugin-sdk.zh-CN.md +293 -0
  271. package/docs/provider-runtime.md +165 -0
  272. package/docs/provider-runtime.zh-CN.md +132 -0
  273. package/docs/release-workflow.md +305 -0
  274. package/docs/release-workflow.zh-CN.md +237 -0
  275. package/docs/roles-and-configuration.md +115 -0
  276. package/docs/roles-and-configuration.zh-CN.md +96 -0
  277. package/docs/sqlite-control-plane-design.md +78 -0
  278. package/docs/sqlite-control-plane-design.zh-CN.md +62 -0
  279. package/docs/task-dag-semantics.md +80 -0
  280. package/docs/task-dag-semantics.zh-CN.md +59 -0
  281. package/docs/task-delivery.md +105 -0
  282. package/docs/task-delivery.zh-CN.md +82 -0
  283. package/docs/task-local-identity.md +8 -6
  284. package/docs/task-local-identity.zh-CN.md +58 -0
  285. package/docs/testing/verification-levels.md +88 -0
  286. package/docs/testing/verification-levels.zh-CN.md +69 -0
  287. package/i18n/README.zh-CN.md +270 -722
  288. package/package.json +3 -2
  289. package/skills/yui-leader/SKILL.md +88 -304
  290. package/skills/yui-leader/references/execution.md +303 -0
  291. package/skills/yui-leader/references/integration.md +39 -0
  292. package/skills/yui-leader/references/planning.md +109 -0
  293. package/skills/yui-leader/references/replicated-execution.md +42 -0
  294. package/skills/yui-leader/references/task-plugins.md +37 -0
  295. package/skills/yui-operator/SKILL.md +46 -62
  296. package/skills/yui-reviewer/SKILL.md +35 -36
  297. package/skills/yui-runtime/SKILL.md +88 -24
  298. package/skills/yui-runtime/references/publication.md +22 -0
  299. package/skills/yui-runtime/references/recovery.md +64 -0
  300. package/skills/yui-worker/SKILL.md +37 -39
  301. package/dist/cli/roleOptionCatalog.js +0 -68
  302. package/dist/context/sourceTurnContext.js +0 -30
  303. package/dist/execution/reviewMainTurn.js +0 -161
  304. package/dist/execution/workItemMainTurn.js +0 -164
  305. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  306. package/dist/runtime/preallocatedNativeSession.js +0 -13
  307. package/dist/runtime/runtimeStopReceipt.js +0 -42
  308. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -1,407 +0,0 @@
1
- import { isDeepStrictEqual } from "node:util";
2
- import { completeProcessing } from "../coordination/workMailbox.js";
3
- import { captureRoleTurnDispatch, settleRoleTurnDispatch } from "../coordination/workMailboxQueue.js";
4
- import { finishReviewRound, updateReviewExecutionGroup } from "../review/reviewRound.js";
5
- import { completeTurn, failTurn } from "../turn/turn.js";
6
- import { boundedTurnFailureDiagnostic } from "../domain/agentResultTransport.js";
7
- import { updateExecutionLane, updateWorkItemExecutionLane } from "../execution/workItemExecution.js";
8
- import { reconcileWorkItemMainTurns } from "../execution/workItemMainTurn.js";
9
- import { reconcileReviewMainTurns } from "../execution/reviewMainTurn.js";
10
- import { isRuntimeLaunchReservation, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
11
- import { managedProviderTurnId } from "../runtime/providerRuntimeIdentity.js";
12
- import { latestTurnDurableProgressAt } from "../scheduler/roleTurnStall.js";
13
- import { markTaskWakeConsumed } from "../scheduler/taskWake.js";
14
- import { workItemExecutionGroupById, updateWorkItemExecutionGroup } from "../workItem/workItem.js";
15
- /**
16
- * Validate every immutable identity and frozen Project head needed before a
17
- * review Turn can settle any mailbox or Round state. This is deliberately
18
- * read-only: callers use it as the compare-and-swap fence immediately before
19
- * their aggregate mutation.
20
- */
21
- export function validateExactTurnReviewRound(store, turn, options = {}) {
22
- if (turn.purpose !== "review")
23
- return { disposition: "applied", round: null };
24
- if (turn.reviewRoundId === undefined) {
25
- return { disposition: "obsolete", round: null, reason: "review-round-missing" };
26
- }
27
- const round = store.getReviewRound(turn.taskId, turn.reviewRoundId);
28
- if (round === null) {
29
- return { disposition: "obsolete", round: null, reason: "review-round-missing" };
30
- }
31
- if (!options.allowTerminal
32
- && round.status !== "pending" && round.status !== "running") {
33
- return { disposition: "obsolete", round, reason: "review-round-terminal" };
34
- }
35
- const lane = round.executionGroup?.lanes.find(({ id }) => id === turn.executionLaneId);
36
- const exactReviewerTurn = round.reviewerTurnId === turn.id
37
- || lane?.currentTurnId === turn.id;
38
- const exactReviewerRole = round.reviewerRoleName === turn.roleName || lane?.roleName === turn.roleName;
39
- if (!exactReviewerTurn
40
- || !exactReviewerRole
41
- || round.workItemId !== turn.workItemId
42
- || round.reviewBaseCommit !== turn.effective.reviewBaseCommit) {
43
- return { disposition: "obsolete", round, reason: "review-round-mismatch" };
44
- }
45
- const laneWorkspaceRoot = lane?.workspace?.root;
46
- if (turn.workspace === undefined || round.workspace === undefined
47
- || (laneWorkspaceRoot === undefined && !isDeepStrictEqual(turn.workspace, round.workspace))
48
- || (laneWorkspaceRoot !== undefined && turn.workspace.root !== laneWorkspaceRoot)) {
49
- return { disposition: "obsolete", round, reason: "review-workspace-mismatch" };
50
- }
51
- const storedWorkspace = turn.workspace.owner.type === "execution-lane"
52
- ? store.getManagedWorkspace(turn.workspace.owner)
53
- : store.getReviewRoundWorkspace(turn.taskId, round.id);
54
- if (storedWorkspace === null
55
- || (turn.workspace.owner.type !== "execution-lane"
56
- && !isDeepStrictEqual(storedWorkspace, round.workspace))
57
- || !isDeepStrictEqual(storedWorkspace, turn.workspace)) {
58
- return { disposition: "obsolete", round, reason: "review-workspace-drift" };
59
- }
60
- if (turn.workspace.owner.type !== "execution-lane") {
61
- if (storedWorkspace.owner.type !== "review-round"
62
- || storedWorkspace.owner.taskId !== turn.taskId
63
- || storedWorkspace.owner.reviewRoundId !== round.id) {
64
- return { disposition: "obsolete", round, reason: "review-workspace-owner-mismatch" };
65
- }
66
- }
67
- if (turn.workspace.owner.type === "execution-lane"
68
- && (turn.workspace.owner.purpose !== "review"
69
- || turn.workspace.owner.executionGroupId !== turn.executionGroupId
70
- || turn.workspace.owner.executionLaneId !== turn.executionLaneId
71
- || turn.workspace.owner.reviewRoundId !== round.id)) {
72
- return { disposition: "obsolete", round, reason: "review-lane-workspace-owner-mismatch" };
73
- }
74
- if (turn.workspace.owner.type === "execution-lane") {
75
- if (lane === undefined
76
- || lane.currentTurnId !== turn.id
77
- || lane.roleName !== turn.roleName
78
- || lane.workspace?.root !== turn.workspace.root
79
- || lane.workspace.writableProjectIds.length !== turn.workspace.entries.length
80
- || turn.workspace.entries.some((entry) => (entry.access !== "write"
81
- || !lane.workspace.writableProjectIds.includes(entry.projectId)))) {
82
- return { disposition: "obsolete", round, reason: "review-lane-workspace-lineage-mismatch" };
83
- }
84
- }
85
- const task = store.getTask(turn.taskId);
86
- const taskScope = (round.scope ?? "work-item") === "task";
87
- const item = taskScope || round.workItemId === undefined
88
- ? null
89
- : store.getWorkItem(turn.taskId, round.workItemId);
90
- if (!taskScope && item === null) {
91
- return { disposition: "obsolete", round, reason: "review-work-item-missing" };
92
- }
93
- const candidate = taskScope
94
- ? undefined
95
- : item.candidates.find(({ id }) => id === round.candidateId);
96
- if (!taskScope && candidate === undefined) {
97
- return { disposition: "obsolete", round, reason: "review-candidate-missing" };
98
- }
99
- const frozenProjects = taskScope
100
- ? round.taskCandidate?.projects
101
- : candidate?.gitSnapshot?.projects;
102
- if (taskScope) {
103
- if (task === null || round.taskCandidate === undefined) {
104
- return { disposition: "obsolete", round, reason: "review-task-candidate-missing" };
105
- }
106
- if (frozenProjects === undefined
107
- || new Set(frozenProjects.map(({ projectId }) => projectId)).size
108
- !== task.projectBindings.length
109
- || task.projectBindings.some(({ projectId }) => (!frozenProjects.some((project) => project.projectId === projectId)))) {
110
- return { disposition: "obsolete", round, reason: "review-frozen-project-scope-drift" };
111
- }
112
- }
113
- else if (candidate?.gitSnapshot !== undefined
114
- && candidate.gitSnapshot.reviewBaseCommit !== round.reviewBaseCommit) {
115
- return { disposition: "obsolete", round, reason: "review-candidate-snapshot-drift" };
116
- }
117
- if (!taskScope && frozenProjects === undefined) {
118
- return { disposition: "applied", round };
119
- }
120
- if (frozenProjects === undefined
121
- || storedWorkspace.entries.length !== frozenProjects.length) {
122
- return { disposition: "obsolete", round, reason: "review-frozen-project-scope-drift" };
123
- }
124
- const frozenByProject = new Map(frozenProjects.map(({ projectId, commit }) => [projectId, commit]));
125
- if (storedWorkspace.entries.some((entry) => (entry.access !== "write"
126
- || frozenByProject.get(entry.projectId) !== entry.baseCommit
127
- || entry.baseRef !== entry.baseCommit))) {
128
- return { disposition: "obsolete", round, reason: "review-frozen-head-drift" };
129
- }
130
- return { disposition: "applied", round };
131
- }
132
- /**
133
- * Atomically terminalizes the exact ReviewRound bound to a review Turn.
134
- * The round must still be pending/running and its reviewer identity must match
135
- * the Turn exactly. This is the sole review-round convergence primitive shared
136
- * by the exact Turn terminalization path and the pre-delivery launch-failure
137
- * path: a failed review Turn must never leave its Round stranded.
138
- */
139
- export function terminalizeExactTurnReviewRound(store, input, now) {
140
- const validation = validateExactTurnReviewRound(store, input.turn);
141
- if (validation.disposition !== "applied" || validation.round === null) {
142
- return validation;
143
- }
144
- const reviewRound = validation.round;
145
- if (input.turn.executionGroupId !== undefined
146
- && input.turn.executionLaneId !== undefined) {
147
- // Producer Turns own only their immutable Turn result. The unified Group
148
- // is advanced after that result is validated and stored below.
149
- return { disposition: "applied", round: reviewRound };
150
- }
151
- const terminal = finishReviewRound(reviewRound, input.outcome.status, now, input.outcome.status === "failed"
152
- ? { kind: "execution", message: input.outcome.diagnostic }
153
- : undefined);
154
- store.saveReviewRound(input.taskId, terminal);
155
- return { disposition: "applied", round: terminal };
156
- }
157
- /**
158
- * Retire one stranded active Turn only after its exact Provider Turn is
159
- * terminal and every durable execution fence is quiet. The caller owns the
160
- * surrounding aggregate transaction so the Turn, ReviewRound/Lane, mailbox,
161
- * Session, and append-only retirement record commit together.
162
- */
163
- export function retireExactActiveTurn(store, input, now) {
164
- const current = store.getTurn(input.taskId, input.turnId);
165
- const stateChanged = (reason) => ({
166
- disposition: "state-changed",
167
- turn: current,
168
- ...(current === null ? {} : { progressAt: latestTurnDurableProgressAt(store, input.taskId, input.roleName, input.turnId)?.progressAt }),
169
- reason
170
- });
171
- const task = store.getTask(input.taskId);
172
- if (task === null)
173
- return stateChanged("task-missing");
174
- if (task.status !== "active")
175
- return stateChanged("task-terminal");
176
- if (current === null)
177
- return stateChanged("turn-missing");
178
- if (current.status !== "active")
179
- return stateChanged("turn-terminal");
180
- if (current.taskId !== input.taskId || current.roleName !== input.roleName) {
181
- return stateChanged("turn-owner-mismatch");
182
- }
183
- if (current.effective.agentId !== input.agentId
184
- || current.effective.adapterId !== input.adapterId) {
185
- return stateChanged("turn-launch-identity-mismatch");
186
- }
187
- const active = current.executionGroupId !== undefined && current.executionLaneId !== undefined
188
- ? store.getActiveExecutionLaneTurn(input.taskId, current.executionGroupId, current.executionLaneId)
189
- : store.getActiveTurn(input.taskId, input.roleName);
190
- if (active?.id !== current.id)
191
- return stateChanged("active-turn-mismatch");
192
- const progress = latestTurnDurableProgressAt(store, input.taskId, input.roleName, input.turnId);
193
- if (progress === null)
194
- return stateChanged("progress-unavailable");
195
- if (progress.progressAt !== input.expectedProgressAt) {
196
- return { ...stateChanged("progress-fence-mismatch"), progressAt: progress.progressAt };
197
- }
198
- const sessions = store.getTaskRoleSessionSet(input.taskId, input.roleName);
199
- const terminalInput = {
200
- taskId: input.taskId,
201
- roleName: input.roleName,
202
- agentId: input.agentId,
203
- turnId: input.turnId,
204
- ...(input.nativeSessionId === undefined ? {} : { nativeSessionId: input.nativeSessionId }),
205
- ...(input.runtimeGenerationId === undefined ? {} : { runtimeGenerationId: input.runtimeGenerationId }),
206
- outcome: { status: "failed", diagnostic: input.reason, failureReason: "missing-result" }
207
- };
208
- const session = sessions?.sessions[input.agentId];
209
- const providerBinding = sessions?.providerBinding;
210
- const providerTurn = providerBinding?.turn;
211
- const providerSettled = managedProviderTurnId(providerTurn) === current.id
212
- && (providerTurn?.status === "completed"
213
- || providerTurn?.status === "failed"
214
- || providerTurn?.status === "cancelled"
215
- || providerTurn?.status === "rejected");
216
- if (session?.status === "active" && !providerSettled) {
217
- return {
218
- disposition: "blocked",
219
- turn: current,
220
- progressAt: progress.progressAt,
221
- reason: "runtime-not-terminal"
222
- };
223
- }
224
- const terminal = terminalizeExactTaskTurn(store, terminalInput, now);
225
- if (terminal.disposition !== "applied" || terminal.turn === null) {
226
- return stateChanged(terminal.reason ?? "terminalization-fence-mismatch");
227
- }
228
- return {
229
- disposition: "applied",
230
- turn: terminal.turn,
231
- progressAt: progress.progressAt
232
- };
233
- }
234
- /**
235
- * Applies one exact application-level terminal fact inside the caller's
236
- * TaskStore transaction. All caller-owned outcome records can therefore
237
- * be saved in the same aggregate commit.
238
- */
239
- export function terminalizeExactTaskTurn(store, input, now) {
240
- const turn = store.getTurn(input.taskId, input.turnId);
241
- if (turn === null)
242
- return obsolete(null, "turn-missing");
243
- if (turn.status !== "active")
244
- return obsolete(turn, "turn-terminal");
245
- if (turn.taskId !== input.taskId || turn.roleName !== input.roleName) {
246
- return obsolete(turn, "turn-owner-mismatch");
247
- }
248
- if (turn.effective.agentId !== input.agentId) {
249
- return obsolete(turn, "turn-agent-mismatch");
250
- }
251
- const role = store.getRole(input.taskId, input.roleName);
252
- if (role === null)
253
- return obsolete(turn, "role-missing");
254
- const active = turn.executionGroupId !== undefined && turn.executionLaneId !== undefined
255
- ? store.getActiveExecutionLaneTurn(input.taskId, turn.executionGroupId, turn.executionLaneId)
256
- : store.getActiveTurn(input.taskId, input.roleName);
257
- if (active?.id !== turn.id)
258
- return obsolete(turn, "active-turn-mismatch");
259
- const sessions = store.getTaskRoleSessionSet(input.taskId, input.roleName);
260
- // Validate the exact ReviewRound, Candidate, stored workspace, and frozen
261
- // Project heads before any mailbox or Round write.
262
- const reviewValidation = validateExactTurnReviewRound(store, turn);
263
- if (reviewValidation.disposition !== "applied") {
264
- return obsolete(turn, reviewValidation.reason ?? "review-round-mismatch");
265
- }
266
- const requiredSnapshotProjects = [...new Set(turn.effective.writeProjectIds)].sort();
267
- const observedSnapshotProjects = input.systemEvidence?.workspaceSnapshot?.projects
268
- .map(({ projectId }) => projectId)
269
- .sort();
270
- const laneSnapshotRequired = input.outcome.status === "completed"
271
- && turn.executionGroupId !== undefined
272
- && turn.executionLaneId !== undefined
273
- && requiredSnapshotProjects.length > 0;
274
- const missingLaneSnapshot = laneSnapshotRequired
275
- && (observedSnapshotProjects === undefined
276
- || !isDeepStrictEqual(observedSnapshotProjects, requiredSnapshotProjects));
277
- const workspaceFailure = laneSnapshotRequired
278
- ? input.workspaceFailure ?? (missingLaneSnapshot
279
- ? {
280
- failureReason: "workspace-unavailable",
281
- diagnostic: "Core could not freeze the exact clean writable Lane workspace."
282
- }
283
- : undefined)
284
- : undefined;
285
- const effectiveOutcome = input.outcome.status === "completed" && workspaceFailure !== undefined
286
- ? {
287
- status: "failed",
288
- output: input.outcome.output,
289
- diagnostic: workspaceFailure.diagnostic,
290
- failureReason: workspaceFailure.failureReason,
291
- ...(input.outcome.provider === undefined ? {} : { provider: input.outcome.provider })
292
- }
293
- : input.outcome;
294
- const terminalOutcome = effectiveOutcome.status === "failed"
295
- ? {
296
- ...effectiveOutcome,
297
- diagnostic: boundedTurnFailureDiagnostic(effectiveOutcome.diagnostic)
298
- }
299
- : effectiveOutcome;
300
- // All Turn, active-pointer, Session, launch, and mailbox fences have passed.
301
- // Only now may the exact ReviewRound be terminalized alongside the Turn so a
302
- // stale fence never leaves a Round written while the Turn stays active.
303
- const reviewRoundTerminalization = terminalizeExactTurnReviewRound(store, {
304
- taskId: input.taskId,
305
- turn,
306
- outcome: terminalOutcome
307
- }, now);
308
- if (reviewRoundTerminalization.disposition !== "applied") {
309
- return obsolete(turn, reviewRoundTerminalization.reason ?? "review-round-mismatch");
310
- }
311
- const terminal = terminalOutcome.status === "completed"
312
- ? completeTurn(turn, terminalOutcome.output, now, terminalOutcome.provider, input.systemEvidence)
313
- : failTurn(turn, terminalOutcome.failureReason, terminalOutcome.diagnostic, now, terminalOutcome.provider, terminalOutcome.output);
314
- if (turn.executionGroupId !== undefined
315
- && turn.executionLaneId !== undefined
316
- && turn.purpose === "execution"
317
- && turn.workItemId !== undefined) {
318
- const item = store.getWorkItem(input.taskId, turn.workItemId);
319
- const group = item === null
320
- ? undefined
321
- : workItemExecutionGroupById(item, turn.executionGroupId);
322
- if (item !== null && group !== undefined) {
323
- if (terminal.status === "completed") {
324
- const grouped = updateWorkItemExecutionLane(group, turn.executionLaneId, {
325
- currentTurnId: turn.id,
326
- successfulTurnId: turn.id,
327
- disposition: "succeeded"
328
- }, now);
329
- store.saveWorkItem(input.taskId, updateWorkItemExecutionGroup(item, grouped, now));
330
- }
331
- }
332
- }
333
- if (turn.executionGroupId !== undefined
334
- && turn.executionLaneId !== undefined
335
- && turn.purpose === "review"
336
- && turn.reviewRoundId !== undefined) {
337
- const round = store.getReviewRound(input.taskId, turn.reviewRoundId);
338
- const group = round?.executionGroup;
339
- if (round !== null
340
- && round !== undefined
341
- && group !== undefined
342
- && group.id === turn.executionGroupId) {
343
- if (terminal.status === "completed") {
344
- const grouped = updateExecutionLane(group, turn.executionLaneId, {
345
- currentTurnId: turn.id,
346
- successfulTurnId: turn.id,
347
- disposition: "succeeded"
348
- }, now);
349
- store.saveReviewRound(input.taskId, updateReviewExecutionGroup(round, grouped));
350
- }
351
- }
352
- }
353
- store.saveTurn(terminal);
354
- const dispatchIdentity = {
355
- taskId: terminal.taskId,
356
- roleName: terminal.roleName,
357
- turnId: terminal.id
358
- };
359
- const dispatchToken = captureRoleTurnDispatch(store.getWorkMailbox({
360
- kind: "role",
361
- taskId: terminal.taskId,
362
- roleName: terminal.roleName
363
- }), dispatchIdentity);
364
- settleRoleTurnDispatch(store, dispatchIdentity, dispatchToken);
365
- if (terminal.roleName === "leader") {
366
- const wake = store.listTaskWakes(input.taskId)
367
- .find((candidate) => candidate.turnId === terminal.id && candidate.status === "dispatched");
368
- if (wake !== undefined) {
369
- store.saveTaskWake(input.taskId, markTaskWakeConsumed(wake, now));
370
- }
371
- }
372
- if (terminal.executionGroupId !== undefined && terminal.executionLaneId !== undefined) {
373
- store.clearActiveExecutionLaneTurn(input.taskId, terminal.executionGroupId, terminal.executionLaneId);
374
- }
375
- else {
376
- store.clearActiveTurn(input.taskId, input.roleName);
377
- }
378
- settleLaunchReservation(store, sessions, input);
379
- reconcileWorkItemMainTurns(store, input.taskId, now);
380
- reconcileReviewMainTurns(store, input.taskId, now);
381
- return { disposition: "applied", turn: terminal };
382
- }
383
- function settleLaunchReservation(store, sessions, input) {
384
- const target = runtimeLifecycleTarget({
385
- scope: "task",
386
- taskId: input.taskId,
387
- roleName: input.roleName
388
- });
389
- const mailbox = store.getWorkMailbox(target);
390
- const reservation = mailbox?.processing;
391
- const session = sessions?.sessions[input.agentId];
392
- // A late result releases only its original launch, never a successor's
393
- // reservation merely because both Turns reused the same native Session.
394
- const runtimeGenerationId = input.runtimeGenerationId ?? session?.runtimeGenerationId;
395
- if (runtimeGenerationId === undefined || !isRuntimeLaunchReservation(reservation, runtimeGenerationId))
396
- return;
397
- const settled = completeProcessing(mailbox, reservation.batchId);
398
- if (settled.processing === null && settled.pending === null) {
399
- store.removeWorkMailbox(target);
400
- }
401
- else {
402
- store.saveWorkMailbox(settled);
403
- }
404
- }
405
- function obsolete(turn, reason) {
406
- return { disposition: "obsolete", turn, reason };
407
- }
@@ -1,13 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { resolve } from "node:path";
3
- import { requireText } from "./validation.js";
4
- /** Deterministic native identity preallocated for one exact provider launch. */
5
- export function nativeSessionIdForLaunch(home, runtimeGenerationId, agentId, adapterId) {
6
- const hex = createHash("sha256").update(JSON.stringify([
7
- resolve(requireText(home, "YUI_HOME")),
8
- requireText(runtimeGenerationId, "Runtime generation id"),
9
- requireText(agentId, "Agent id"),
10
- requireText(adapterId, "Agent adapter id")
11
- ])).digest("hex");
12
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
13
- }
@@ -1,42 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { chmodSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
- import { join, resolve } from "node:path";
4
- export function writeRuntimeStopReceipt(home, runtimeGenerationId, requestedAt) {
5
- const receipt = Object.freeze({
6
- schemaVersion: 1,
7
- receiptId: `runtime-stop-${createHash("sha256")
8
- .update(`${runtimeGenerationId}\0${requestedAt.toISOString()}`)
9
- .digest("hex")}`,
10
- runtimeGenerationId,
11
- requestedAt: requestedAt.toISOString()
12
- });
13
- const path = stopReceiptPath(home, runtimeGenerationId);
14
- mkdirSync(resolve(join(home, "runtime", "stop-receipts")), { recursive: true, mode: 0o700 });
15
- const temporary = `${path}.tmp-${process.pid}`;
16
- writeFileSync(temporary, `${JSON.stringify(receipt)}\n`, { mode: 0o600 });
17
- renameSync(temporary, path);
18
- chmodSync(path, 0o600);
19
- return receipt;
20
- }
21
- export function readRuntimeStopReceipt(home, runtimeGenerationId) {
22
- try {
23
- const value = JSON.parse(readFileSync(stopReceiptPath(home, runtimeGenerationId), "utf8"));
24
- if (value.schemaVersion !== 1 || value.runtimeGenerationId !== runtimeGenerationId
25
- || typeof value.receiptId !== "string" || !Number.isFinite(Date.parse(value.requestedAt))) {
26
- throw new Error("Runtime stop receipt is invalid.");
27
- }
28
- return Object.freeze({ ...value });
29
- }
30
- catch (error) {
31
- if (error.code === "ENOENT")
32
- return null;
33
- throw error;
34
- }
35
- }
36
- export function removeRuntimeStopReceipt(home, runtimeGenerationId) {
37
- rmSync(stopReceiptPath(home, runtimeGenerationId), { force: true });
38
- }
39
- function stopReceiptPath(home, runtimeGenerationId) {
40
- const name = createHash("sha256").update(runtimeGenerationId).digest("hex");
41
- return resolve(join(home, "runtime", "stop-receipts", `${name}.json`));
42
- }