@zq-silk/yui 0.15.6 → 0.15.8

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 (282) hide show
  1. package/ARCHITECTURE.md +192 -399
  2. package/README.md +127 -1149
  3. package/dist/agent/adapterCatalog.js +15 -2
  4. package/dist/agent/agent.js +23 -3
  5. package/dist/agent/argumentPolicy.js +7 -1
  6. package/dist/agent/connectionPlan.js +62 -0
  7. package/dist/agent/executionComponents.js +158 -0
  8. package/dist/agent/launchEnvironment.js +31 -3
  9. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  10. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  11. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  12. package/dist/brief/taskBrief.js +12 -0
  13. package/dist/cli/agentConfigurationPicker.js +13 -0
  14. package/dist/cli/commandCatalog.js +167 -70
  15. package/dist/cli/interactionCandidates.js +5 -5
  16. package/dist/cli/interactionPolicy.js +38 -8
  17. package/dist/cli/invocationRouter.js +1 -1
  18. package/dist/cli/managedDiagnostics.js +28 -0
  19. package/dist/cli/operatorWizard.js +1 -7
  20. package/dist/cli/roleOptionOrder.js +27 -0
  21. package/dist/cli/roleWizard.js +50 -14
  22. package/dist/cli/updateOrchestrator.js +1 -1
  23. package/dist/cli/updatePorts.js +3 -4
  24. package/dist/cli.js +188 -95
  25. package/dist/commands/agentCommands.js +72 -14
  26. package/dist/commands/capabilityCommands.js +57 -0
  27. package/dist/commands/configCommands.js +20 -20
  28. package/dist/commands/deliveryGuardPreflight.js +2 -2
  29. package/dist/commands/executionAuditCommands.js +24 -24
  30. package/dist/commands/globalRoleCommands.js +1 -1
  31. package/dist/commands/grantCommands.js +4 -4
  32. package/dist/commands/operatorCommands.js +1 -7
  33. package/dist/commands/projectCommands.js +4 -4
  34. package/dist/commands/resourcesCommands.js +2 -2
  35. package/dist/commands/roleConfiguration.js +25 -5
  36. package/dist/commands/roleRuntimeGuard.js +4 -5
  37. package/dist/commands/sessionCommands.js +3 -7
  38. package/dist/commands/taskActivationCommands.js +259 -0
  39. package/dist/commands/taskActor.js +28 -49
  40. package/dist/commands/taskCommands.js +1216 -730
  41. package/dist/commands/taskContextCommand.js +39 -583
  42. package/dist/commands/taskExecutionCommands.js +32 -32
  43. package/dist/commands/taskInputCommands.js +40 -104
  44. package/dist/commands/taskIntegrationCommands.js +3 -2
  45. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  46. package/dist/commands/taskNextActionCommand.js +8 -8
  47. package/dist/commands/taskOverviewCommand.js +33 -45
  48. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  49. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  50. package/dist/commands/telemetryCommands.js +36 -38
  51. package/dist/config/configCatalog.js +4 -4
  52. package/dist/config/yuiConfig.js +8 -8
  53. package/dist/context/contextSnapshot.js +10 -10
  54. package/dist/context/dispatchContext.js +11 -11
  55. package/dist/context/roleSessionContext.js +6 -3
  56. package/dist/context/{turnContextPack.js → runContextPack.js} +146 -81
  57. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  58. package/dist/context/sessionBootstrapManifest.js +21 -2
  59. package/dist/context/sourceRunContext.js +30 -0
  60. package/dist/context/taskContext.js +458 -0
  61. package/dist/context/wakeNotification.js +27 -27
  62. package/dist/controller/agentRuntimeObserver.js +21 -24
  63. package/dist/controller/capabilityBridge.js +77 -0
  64. package/dist/controller/clientRuntime.js +65 -92
  65. package/dist/controller/controller.js +127 -188
  66. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  67. package/dist/controller/jobControl.js +54 -85
  68. package/dist/controller/resourceInventory.js +8 -27
  69. package/dist/controller/resourceInventoryLinux.js +12 -13
  70. package/dist/controller/runtime.js +530 -476
  71. package/dist/controller/runtimeEventInbox.js +55 -25
  72. package/dist/controller/runtimeEventProcessor.js +22 -31
  73. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  74. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  75. package/dist/controller/runtimeObservationHook.js +14 -18
  76. package/dist/controller/sessionNotify.js +16 -24
  77. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  78. package/dist/controller/structuredProviderObservation.js +138 -99
  79. package/dist/coordination/workMailbox.js +3 -3
  80. package/dist/coordination/workMailboxQueue.js +36 -33
  81. package/dist/core/boundedRpc.js +8 -1
  82. package/dist/core/controllerClient.js +20 -1
  83. package/dist/core/controllerServer.js +4 -4
  84. package/dist/doctor/doctor.js +13 -2
  85. package/dist/domain/agentResultTransport.js +9 -9
  86. package/dist/execution/codexThreadNaming.js +2 -8
  87. package/dist/execution/executionHealth.js +51 -63
  88. package/dist/execution/reviewMainRun.js +137 -0
  89. package/dist/execution/workItemExecution.js +28 -29
  90. package/dist/execution/workItemExecutionProjection.js +99 -107
  91. package/dist/execution/workItemMainRun.js +141 -0
  92. package/dist/executor/agentAdapter.js +227 -20
  93. package/dist/executor/agentConfigurationCatalog.js +126 -4
  94. package/dist/executor/agentConfigurationProbe.js +162 -4
  95. package/dist/executor/agentExecutor.js +79 -78
  96. package/dist/executor/effectiveLaunch.js +105 -18
  97. package/dist/executor/executorRegistry.js +29 -44
  98. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  99. package/dist/executor/workspacePreflightClassification.js +16 -16
  100. package/dist/grant/capabilityGrant.js +6 -3
  101. package/dist/input/inputRequest.js +12 -10
  102. package/dist/integration/gitIntegrationService.js +4 -11
  103. package/dist/integration/integrationQueueService.js +4 -4
  104. package/dist/interaction/operatorPresentation.js +1 -1
  105. package/dist/kernel/builtinCapabilities.js +423 -0
  106. package/dist/kernel/capabilityRegistry.js +314 -0
  107. package/dist/kernel/capabilitySchema.js +91 -0
  108. package/dist/kernel/instanceHost.js +18 -1
  109. package/dist/kernel/kernelPorts.js +4 -1
  110. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  111. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  112. package/dist/message/message.js +62 -6
  113. package/dist/message/messageContinuation.js +204 -0
  114. package/dist/observability/executionAudit.js +70 -72
  115. package/dist/observability/faultClassification.js +2 -2
  116. package/dist/observability/orchestrationMetrics.js +8 -8
  117. package/dist/operator/operatorSessionHistory.js +1 -7
  118. package/dist/output/agentConfigurationPresentation.js +8 -3
  119. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  120. package/dist/output/rolePresentation.js +54 -3
  121. package/dist/plugins/pluginChild.js +104 -0
  122. package/dist/plugins/pluginIntent.js +26 -0
  123. package/dist/plugins/pluginInterpreter.js +43 -0
  124. package/dist/plugins/pluginPackage.js +101 -0
  125. package/dist/plugins/pluginProcess.js +112 -0
  126. package/dist/plugins/pluginService.js +380 -0
  127. package/dist/profile/agentProfile.js +1 -1
  128. package/dist/repository/gitWorkspace.js +26 -4
  129. package/dist/repository/project.js +19 -4
  130. package/dist/repository/taskBaseFreshness.js +13 -13
  131. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  132. package/dist/repository/taskWorkspacePreparer.js +344 -83
  133. package/dist/resources/autoResourceGc.js +3 -3
  134. package/dist/resources/liveReferences.js +3 -3
  135. package/dist/resources/projectResource.js +123 -0
  136. package/dist/resources/projectResourceService.js +421 -0
  137. package/dist/resources/resourceDiscovery.js +6 -6
  138. package/dist/resources/resourceGc.js +1 -1
  139. package/dist/resources/resourceRegistrar.js +1 -1
  140. package/dist/resources/resourceTypes.js +1 -1
  141. package/dist/review/deltaRecheck.js +3 -3
  142. package/dist/review/reviewAcceptance.js +16 -16
  143. package/dist/review/reviewDecision.js +7 -7
  144. package/dist/review/reviewRound.js +21 -20
  145. package/dist/review/reviewerAvailability.js +2 -2
  146. package/dist/role/role.js +51 -7
  147. package/dist/role/taskRoleUpdate.js +30 -0
  148. package/dist/runtime/acpProtocol.js +425 -0
  149. package/dist/runtime/acpSession.js +731 -0
  150. package/dist/runtime/acpSessionConfiguration.js +260 -0
  151. package/dist/runtime/agentDriver.js +30 -11
  152. package/dist/runtime/agentEndpoint.js +278 -0
  153. package/dist/runtime/agentEndpointIdentity.js +86 -0
  154. package/dist/runtime/agentEndpointOwnership.js +239 -0
  155. package/dist/runtime/agentError.js +2 -10
  156. package/dist/runtime/agentHost.js +565 -314
  157. package/dist/runtime/agentRunConfiguration.js +258 -0
  158. package/dist/runtime/builtinAgentDrivers.js +134 -18
  159. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  160. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  161. package/dist/runtime/claude-process-owner +0 -0
  162. package/dist/runtime/codexAppServerRuntime.js +38 -30
  163. package/dist/runtime/codexInteractiveHost.js +41 -6
  164. package/dist/runtime/continuationManager.js +2 -6
  165. package/dist/runtime/executionEnvironment.js +30 -0
  166. package/dist/runtime/firstProgressAdvisory.js +11 -11
  167. package/dist/runtime/index.js +4 -3
  168. package/dist/runtime/jsonLineChannel.js +109 -0
  169. package/dist/runtime/launchBroker.js +91 -16
  170. package/dist/runtime/launchDiagnostics.js +2 -2
  171. package/dist/runtime/lifecycleReservation.js +10 -18
  172. package/dist/runtime/managedCaller.js +61 -17
  173. package/dist/runtime/nativeSessionControl.js +102 -0
  174. package/dist/runtime/ports.js +6 -21
  175. package/dist/runtime/processExitObservation.js +8 -7
  176. package/dist/runtime/promptEnvelope.js +17 -6
  177. package/dist/runtime/providerContinuation.js +3 -9
  178. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  179. package/dist/runtime/providerControl.js +2 -7
  180. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  181. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  182. package/dist/runtime/runtimeBinding.js +0 -1
  183. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  184. package/dist/runtime/runtimeDeadlines.js +9 -0
  185. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  186. package/dist/runtime/runtimeObservation.js +29 -65
  187. package/dist/runtime/runtimeProjection.js +43 -51
  188. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  189. package/dist/runtime/sessionLaunchRequest.js +3 -7
  190. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  191. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  192. package/dist/runtime/sessionReconciliation.js +4 -8
  193. package/dist/runtime/sessionTerminationGuard.js +70 -259
  194. package/dist/runtime/sessionTokenMetrics.js +5 -16
  195. package/dist/runtime/structuredProviderHost.js +237 -117
  196. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  197. package/dist/runtime/tmuxAdapters.js +39 -86
  198. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  199. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  200. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  201. package/dist/scheduler/ports.js +80 -9
  202. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  203. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  204. package/dist/scheduler/taskExecutionProjection.js +120 -124
  205. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  206. package/dist/scheduler/taskWake.js +11 -4
  207. package/dist/scheduler/wakeReason.js +9 -1
  208. package/dist/setup/setupCommand.js +1 -0
  209. package/dist/storage/migrations/agentRunContract.js +159 -0
  210. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  211. package/dist/storage/sqliteSchema.js +431 -5
  212. package/dist/storage/sqliteStore.js +375 -220
  213. package/dist/storage/storageVersions.js +1 -1
  214. package/dist/storage/storeRpc.js +10 -5
  215. package/dist/storage/taskStore.js +13 -11
  216. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  217. package/dist/surface/surfaceContributions.js +102 -0
  218. package/dist/task/completionReadiness.js +32 -6
  219. package/dist/task/deliveryGuard.js +16 -16
  220. package/dist/task/draftPlan.js +72 -12
  221. package/dist/task/nextAction.js +144 -128
  222. package/dist/task/remoteDelivery.js +6 -6
  223. package/dist/task/task.js +184 -18
  224. package/dist/task/taskActivation.js +301 -0
  225. package/dist/task/taskActivationService.js +392 -0
  226. package/dist/task/taskRecordReference.js +5 -4
  227. package/dist/task/taskRecordRetirement.js +1 -1
  228. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  229. package/dist/telemetry/telemetryConfig.js +14 -14
  230. package/dist/telemetry/telemetryWiring.js +2 -2
  231. package/dist/web/assets/assetManifest.js +2 -0
  232. package/dist/web/assets/client/app.js +120 -20
  233. package/dist/web/assets/client/components.js +87 -54
  234. package/dist/web/assets/client/i18n.js +83 -41
  235. package/dist/web/assets/client/markdown.js +1 -1
  236. package/dist/web/assets/client/taskSurface.js +353 -0
  237. package/dist/web/assets/client/view.js +49 -44
  238. package/dist/web/assets/shell.js +1 -1
  239. package/dist/web/assets/styles/cards.js +22 -4
  240. package/dist/web/controllerWeb.js +60 -0
  241. package/dist/web/webMutation.js +28 -0
  242. package/dist/web/webServer.js +118 -8
  243. package/dist/web/webSnapshot.js +81 -74
  244. package/dist/web/webTaskSurface.js +64 -0
  245. package/dist/workItem/dependencyGate.js +1 -1
  246. package/dist/workItem/workItem.js +80 -48
  247. package/dist/workspace/workItemChangeSetManager.js +16 -9
  248. package/docs/agent-result-consumption.md +94 -0
  249. package/docs/agent-runtime-drivers.md +91 -0
  250. package/docs/architecture/README.md +38 -0
  251. package/docs/architecture/capabilities-and-resources.md +79 -0
  252. package/docs/managed-turn-and-session-runtime.md +222 -0
  253. package/docs/observability/README.md +81 -0
  254. package/docs/plugin-sdk.md +290 -0
  255. package/docs/provider-runtime.md +163 -0
  256. package/docs/release-workflow.md +303 -0
  257. package/docs/roles-and-configuration.md +113 -0
  258. package/docs/sqlite-control-plane-design.md +76 -0
  259. package/docs/task-dag-semantics.md +57 -0
  260. package/docs/task-delivery.md +103 -0
  261. package/docs/task-local-identity.md +6 -6
  262. package/docs/testing/verification-levels.md +86 -0
  263. package/i18n/README.zh-CN.md +98 -739
  264. package/package.json +5 -5
  265. package/skills/yui-leader/SKILL.md +130 -103
  266. package/skills/yui-leader/references/integration.md +39 -0
  267. package/skills/yui-leader/references/replicated-execution.md +42 -0
  268. package/skills/yui-leader/references/task-plugins.md +33 -0
  269. package/skills/yui-operator/SKILL.md +30 -59
  270. package/skills/yui-reviewer/SKILL.md +35 -36
  271. package/skills/yui-runtime/SKILL.md +88 -24
  272. package/skills/yui-runtime/references/publication.md +22 -0
  273. package/skills/yui-runtime/references/recovery.md +64 -0
  274. package/skills/yui-worker/SKILL.md +37 -39
  275. package/dist/cli/roleOptionCatalog.js +0 -68
  276. package/dist/context/sourceTurnContext.js +0 -30
  277. package/dist/execution/reviewMainTurn.js +0 -161
  278. package/dist/execution/workItemMainTurn.js +0 -164
  279. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  280. package/dist/runtime/preallocatedNativeSession.js +0 -13
  281. package/dist/runtime/runtimeStopReceipt.js +0 -42
  282. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -21,10 +21,12 @@
21
21
  * is a no-op; a crash mid-upgrade rolls the whole migration transaction back.
22
22
  */
23
23
  import { createHash } from "node:crypto";
24
+ import { REMOVE_RUNTIME_GENERATION_SQL, removeRuntimeGenerationRecords } from "./migrations/removeRuntimeGeneration.js";
25
+ import { migrateAgentRunContract } from "./migrations/agentRunContract.js";
24
26
  import { CURRENT_STORAGE_VERSION, MIN_SUPPORTED_STORAGE_VERSION } from "./storageVersions.js";
25
27
  /** Telemetry retention bounds (§4.4). Open question 3 in §11; defaults from the design. */
26
- export const TELEMETRY_KEEP_PER_GENERATION = 200;
27
- export const TELEMETRY_TURN_CAP = 50_000;
28
+ export const TELEMETRY_KEEP_PER_RUN = 200;
29
+ export const TELEMETRY_RUN_CAP = 50_000;
28
30
  /**
29
31
  * Version 1 migration: creates every table and index.
30
32
  *
@@ -697,6 +699,424 @@ ON durable_jobs(task_id, json_extract(payload, '$.operation.actorId'),
697
699
  // Accepted inputs/results can use an exact attempt without a native Turn id.
698
700
  // Preserve all valid historical records; never repair failed Turns or logs.
699
701
  sql: "SELECT 1; -- exact attempt identity without a fabricated native Turn id"
702
+ },
703
+ {
704
+ version: 4,
705
+ name: "session-and-process-identity",
706
+ introducedIn: "0.15.8",
707
+ sql: REMOVE_RUNTIME_GENERATION_SQL,
708
+ migrateData: removeRuntimeGenerationRecords
709
+ },
710
+ {
711
+ version: 5,
712
+ name: "project-resource-artifacts",
713
+ introducedIn: "0.15.8",
714
+ sql: `
715
+ CREATE TABLE artifacts (
716
+ task_id TEXT NOT NULL REFERENCES tasks_catalog(task_id),
717
+ id TEXT NOT NULL,
718
+ payload TEXT NOT NULL,
719
+ PRIMARY KEY (task_id, id)
720
+ );
721
+ CREATE TABLE local_resources (
722
+ id TEXT PRIMARY KEY,
723
+ canonical_identity TEXT NOT NULL UNIQUE,
724
+ payload TEXT NOT NULL
725
+ );
726
+ CREATE TABLE environment_preparations (
727
+ task_id TEXT NOT NULL REFERENCES tasks_catalog(task_id),
728
+ id TEXT NOT NULL,
729
+ payload TEXT NOT NULL,
730
+ PRIMARY KEY (task_id, id)
731
+ );
732
+ UPDATE projects SET payload = json_set(payload,
733
+ '$.schemaVersion', 6, '$.resourceRefs', json('[]'),
734
+ '$.defaultCapabilityProviders', json('{}'));
735
+ `
736
+ },
737
+ {
738
+ version: 6,
739
+ name: "session-endpoint-implementation",
740
+ introducedIn: "0.15.8",
741
+ // Valid earlier Sessions used these two built-in protocols. Generation 1
742
+ // retains those codecs and identities behind the new execution boundary.
743
+ // Preserve native IDs, effective snapshots and all historical results.
744
+ sql: `
745
+ UPDATE role_session_sets SET payload = json_set(payload, '$.sessions', json((
746
+ SELECT json_group_object(key, json_set(value, '$.schemaVersion', 6,
747
+ '$.endpointImplementation', json_object(
748
+ 'id', 'yui.agent-endpoint.' || json_extract(value, '$.adapterId'), 'generation', '1')))
749
+ FROM json_each(payload, '$.sessions')
750
+ )));
751
+ UPDATE role_session_sets SET payload = json_set(payload, '$.history', json((
752
+ SELECT json_group_array(json_set(value, '$.schemaVersion', 6,
753
+ '$.endpointImplementation', json_object(
754
+ 'id', 'yui.agent-endpoint.' || json_extract(value, '$.adapterId'), 'generation', '1')))
755
+ FROM json_each(payload, '$.history')
756
+ ))) WHERE json_type(payload, '$.history') = 'array';
757
+ UPDATE global_role_session_sets SET payload = json_set(payload, '$.sessions', json((
758
+ SELECT json_group_object(key, json_set(value, '$.schemaVersion', 6,
759
+ '$.endpointImplementation', json_object(
760
+ 'id', 'yui.agent-endpoint.' || json_extract(value, '$.adapterId'), 'generation', '1')))
761
+ FROM json_each(payload, '$.sessions')
762
+ )));
763
+ UPDATE global_role_session_sets SET payload = json_set(payload, '$.history', json((
764
+ SELECT json_group_object(key, json_set(value, '$.schemaVersion', 6,
765
+ '$.endpointImplementation', json_object(
766
+ 'id', 'yui.agent-endpoint.' || json_extract(value, '$.adapterId'), 'generation', '1')))
767
+ FROM json_each(payload, '$.history')
768
+ ))) WHERE json_type(payload, '$.history') = 'object';
769
+ `
770
+ },
771
+ {
772
+ version: 7,
773
+ name: "task-facts-and-explicit-acceptance",
774
+ introducedIn: "0.15.8",
775
+ // Retain the complete retirement metadata/events and diagnostic facts.
776
+ // Only the public lifecycle changes; ordinary stores read one shape.
777
+ sql: `
778
+ UPDATE task_records SET payload = json_set(payload, '$.status', 'cancelled')
779
+ WHERE json_extract(payload, '$.status') = 'retired';
780
+ UPDATE task_records SET payload = json_set(payload, '$.retirementIsolation', json('true'))
781
+ WHERE json_extract(payload, '$.retiredAt') IS NOT NULL;
782
+ UPDATE tasks_catalog SET status = 'cancelled' WHERE status = 'retired';
783
+ UPDATE tasks_catalog SET lifecycle = 'cancelled' WHERE lifecycle = 'retired';
784
+ UPDATE task_records SET brief = json_set(brief, '$.revision', 1) WHERE brief IS NOT NULL;
785
+ UPDATE work_items SET payload = json_set(payload,
786
+ '$.historicalState', json_patch(json('{}'), json_object(
787
+ 'status', json_extract(payload, '$.status'),
788
+ 'outcome', json_extract(payload, '$.outcome'),
789
+ 'endedAt', json_extract(payload, '$.endedAt'))),
790
+ '$.status', CASE status WHEN 'completed' THEN 'accepted' WHEN 'retired' THEN 'retired' ELSE 'open' END);
791
+ UPDATE work_items SET payload = json_remove(payload, '$.outcome', '$.endedAt')
792
+ WHERE json_extract(payload, '$.status') = 'open';
793
+ UPDATE work_items SET status = json_extract(payload, '$.status');
794
+ UPDATE work_items SET payload = json_set(payload, '$.currentCandidateId',
795
+ json_extract(payload, '$.candidates[#-1].id'))
796
+ WHERE json_extract(payload, '$.historicalState.status') = 'awaiting_acceptance';
797
+ UPDATE work_items SET payload = json_set(payload, '$.acceptedCandidateId',
798
+ json_extract(payload, '$.candidates[#-1].id'))
799
+ WHERE status = 'accepted' AND json_array_length(payload, '$.candidates') > 0;
800
+ `
801
+ },
802
+ {
803
+ version: 8,
804
+ name: "event-owned-edit-history",
805
+ introducedIn: "0.15.8",
806
+ // Move embedded histories to one immutable import event per Task.
807
+ // Existing events stay byte-identical; imports supply otherwise missing
808
+ // historical fields and are evidence only, never executable lifecycle input.
809
+ // Candidates may now carry optional fixed Artifact refs; absent refs remain
810
+ // valid for historical Candidates, so this payload addition needs no backfill.
811
+ sql: `
812
+ CREATE TEMP TABLE migrated_edit_history AS
813
+ SELECT records.task_id,
814
+ COALESCE(sequences.high_water, 0) + 1 AS sequence,
815
+ strftime('%Y-%m-%dT%H:%M:%fZ', 'now') AS imported_at,
816
+ json_object(
817
+ 'sourceStorageVersion', '7',
818
+ 'taskOutcomes', '' || COALESCE(json_extract(records.payload, '$.outcomeHistory'), '[]'),
819
+ 'workAcceptances', '' || COALESCE((
820
+ SELECT json_group_array(json_object(
821
+ 'workItemId', work_item_id,
822
+ 'history', json_extract(payload, '$.acceptanceHistory')))
823
+ FROM (SELECT * FROM work_items
824
+ WHERE task_id = records.task_id
825
+ AND json_array_length(payload, '$.acceptanceHistory') > 0
826
+ ORDER BY work_item_id)
827
+ ), '[]')
828
+ ) AS history
829
+ FROM task_records AS records
830
+ LEFT JOIN id_sequences AS sequences
831
+ ON sequences.task_id = records.task_id AND sequences.kind = 'event'
832
+ WHERE json_array_length(records.payload, '$.outcomeHistory') > 0
833
+ OR EXISTS (SELECT 1 FROM work_items
834
+ WHERE task_id = records.task_id AND json_array_length(payload, '$.acceptanceHistory') > 0);
835
+
836
+ INSERT INTO events (task_id, event_id, type, occurred_at, payload)
837
+ SELECT task_id, 'event-' || sequence, 'history.imported', imported_at,
838
+ json_object('schemaVersion', 2, 'id', 'event-' || sequence,
839
+ 'taskId', task_id, 'type', 'history.imported',
840
+ 'createdAt', imported_at, 'payload', json(history))
841
+ FROM migrated_edit_history;
842
+ INSERT INTO id_sequences (task_id, kind, high_water)
843
+ SELECT task_id, 'event', sequence FROM migrated_edit_history WHERE true
844
+ ON CONFLICT(task_id, kind) DO UPDATE SET high_water = excluded.high_water;
845
+ DROP TABLE migrated_edit_history;
846
+
847
+ UPDATE task_records SET payload = json_remove(payload, '$.outcomeHistory'),
848
+ brief = CASE WHEN brief IS NULL THEN NULL ELSE json_remove(brief, '$.revision') END;
849
+ UPDATE work_items SET payload = json_remove(payload, '$.acceptanceHistory');
850
+ `
851
+ },
852
+ {
853
+ version: 9,
854
+ name: "adopted-agent-execution-environment",
855
+ introducedIn: "0.15.8",
856
+ // Optional Role selection and immutable Session/Turn effective snapshot.
857
+ // Existing records deliberately keep their managed-workspace execution;
858
+ // adopted preparations must never be inferred as an automatic binding.
859
+ sql: "SELECT 1; -- explicit adopted execution environment; absent means managed workspace"
860
+ },
861
+ {
862
+ version: 10,
863
+ name: "plugin-validation-evidence",
864
+ introducedIn: "0.15.8",
865
+ sql: `
866
+ CREATE TABLE plugin_validations (
867
+ task_id TEXT NOT NULL REFERENCES tasks_catalog(task_id),
868
+ id TEXT NOT NULL,
869
+ payload TEXT NOT NULL,
870
+ PRIMARY KEY (task_id, id)
871
+ );
872
+ `
873
+ },
874
+ {
875
+ version: 11,
876
+ name: "plugin-enable-intent",
877
+ introducedIn: "0.15.8",
878
+ // A v10 validation proves no enable/disable choice. Preserve it unchanged;
879
+ // never infer desired configuration from historical reports or processes.
880
+ sql: `
881
+ CREATE TABLE plugin_intents (
882
+ task_id TEXT NOT NULL REFERENCES tasks_catalog(task_id),
883
+ plugin_id TEXT NOT NULL,
884
+ payload TEXT NOT NULL,
885
+ PRIMARY KEY (task_id, plugin_id)
886
+ );
887
+ `
888
+ },
889
+ {
890
+ // Renumbered from 10 to 12 when this branch adopted upstream master: PR320
891
+ // took 10 and 11 while this work was in review. Both are already merged, so
892
+ // they own those numbers; this migration appends after them rather than
893
+ // competing for a number, and no released entry is touched.
894
+ version: 12,
895
+ name: "draft-planning-and-deferred-activation",
896
+ // Same unreleased release as migrations 4-11: this does not bump the version.
897
+ introducedIn: "0.15.8",
898
+ // One current-version migration for everything this change adds. No existing
899
+ // record is rewritten and no payload is backfilled:
900
+ //
901
+ // - the optional Task activation request: absent means activation was
902
+ // never explicitly requested, so a Draft is never inferred to have
903
+ // requested it;
904
+ // - its bounded settled-request history: absent means no request ever
905
+ // reached a terminal disposition on this Task. This is a display
906
+ // projection, not the authority: whether an explicitly cancelled or
907
+ // adopted requestId may be replayed is decided from the durable
908
+ // activation event ledger (never compacted), so eviction from this
909
+ // bounded list never resurrects a decided outcome — per-request state
910
+ // inside the Task that owns it, not a second scheduling or operation
911
+ // ledger;
912
+ // - the planning Turn purpose: historical Turns keep their execution or
913
+ // review purpose untouched.
914
+ //
915
+ // The partial indexes bound Draft planning selection and pending-activation
916
+ // recovery to the few rows that qualify, so no execution phase scans Task
917
+ // history to find them. Creating an index adds no row and rewrites no
918
+ // payload.
919
+ sql: `
920
+ -- explicit activation request, its bounded settled history, and planning Turn
921
+ -- purpose; absent means activation was never requested
922
+ CREATE INDEX IF NOT EXISTS idx_turns_planning_active ON turns(task_id, turn_id)
923
+ WHERE status = 'active' AND json_extract(payload, '$.purpose') = 'planning';
924
+ CREATE INDEX IF NOT EXISTS idx_tasks_activation_pending ON task_records(task_id)
925
+ WHERE json_extract(payload, '$.activationRequest.disposition') = 'pending';
926
+ `
927
+ },
928
+ {
929
+ version: 13,
930
+ name: "session-authority-and-execution-admission",
931
+ introducedIn: "0.15.9",
932
+ sql: "SELECT 1; -- AgentRun contract, notification admission and Session authority",
933
+ migrateData: migrateAgentRunContract
934
+ },
935
+ {
936
+ version: 14,
937
+ name: "acp-session-workspace-configuration",
938
+ introducedIn: "0.15.10",
939
+ // ACP is a new legal adapter/configuration value, including its optional
940
+ // additional workspace roots. The v13 baseline has no ACP bindings; existing
941
+ // Codex/Claude configuration and Session history remain valid unchanged.
942
+ // This widens the persistent contract without rewriting payloads or earlier
943
+ // migration checksums. Workspace delivery is negotiated at initialize, not
944
+ // stored as another configuration authority.
945
+ sql: "SELECT 1; -- ACP bindings may carry additionalDirectories; history stays valid"
946
+ },
947
+ {
948
+ version: 15,
949
+ name: "agent-execution-component",
950
+ introducedIn: "0.15.10",
951
+ // Which product executes is now its own recorded fact, separate from the
952
+ // connection plan that reaches it. The plan keeps its `adapterId` name and
953
+ // its meaning; only the product identity is new.
954
+ //
955
+ // The backfill is a total function of the stored plan, never of a command
956
+ // string. `codex` and `claude` each have exactly one component, so those
957
+ // rows gain their true value. Every `acp` row becomes `unknown-acp-agent`:
958
+ // a v14 Home cannot say which product answered, and an executable named
959
+ // `claude-agent-acp` is not evidence that it was the Claude Agent SDK. The
960
+ // unidentified value is the honest one and stays correctable by hand.
961
+ //
962
+ // Sessions keep their own recorded component, so a Session started before
963
+ // this migration continues against exactly the implementation it began on.
964
+ //
965
+ // Every persisted effective snapshot must be reached, not only the ones on
966
+ // Session sets: `validateEffectiveLaunchSnapshot` demands schemaVersion 4,
967
+ // and the upgrade verifier replays it over Runs, WorkItem ExecutionLanes
968
+ // and ReviewRound ExecutionLanes too. A Home holding any of those would
969
+ // otherwise fail the upgrade and roll back. The list below is the
970
+ // verifier's own reachable set, not a scan for fields that look similar.
971
+ sql: `
972
+ UPDATE configured_agents SET payload = json_set(payload,
973
+ '$.schemaVersion', 3,
974
+ '$.component', CASE json_extract(payload, '$.adapterId')
975
+ WHEN 'codex' THEN 'codex-cli'
976
+ WHEN 'claude' THEN 'claude-code-cli'
977
+ ELSE 'unknown-acp-agent' END)
978
+ WHERE json_extract(payload, '$.component') IS NULL;
979
+
980
+ UPDATE global_roles SET payload = json_set(payload, '$.agentBindings', json((
981
+ SELECT json_group_object(key, json_set(value, '$.component',
982
+ CASE json_extract(value, '$.adapterId')
983
+ WHEN 'codex' THEN 'codex-cli'
984
+ WHEN 'claude' THEN 'claude-code-cli'
985
+ ELSE 'unknown-acp-agent' END))
986
+ FROM json_each(payload, '$.agentBindings')
987
+ ))) WHERE json_type(payload, '$.agentBindings') = 'object';
988
+
989
+ UPDATE task_roles SET payload = json_set(payload, '$.agentBindings', json((
990
+ SELECT json_group_object(key, json_set(value, '$.component',
991
+ CASE json_extract(value, '$.adapterId')
992
+ WHEN 'codex' THEN 'codex-cli'
993
+ WHEN 'claude' THEN 'claude-code-cli'
994
+ ELSE 'unknown-acp-agent' END))
995
+ FROM json_each(payload, '$.agentBindings')
996
+ ))) WHERE json_type(payload, '$.agentBindings') = 'object';
997
+
998
+ UPDATE global_role_session_sets SET payload = json_set(payload, '$.sessions', json((
999
+ SELECT json_group_object(key, json_set(value, '$.effective.schemaVersion', 4,
1000
+ '$.effective.component', CASE json_extract(value, '$.effective.adapterId')
1001
+ WHEN 'codex' THEN 'codex-cli'
1002
+ WHEN 'claude' THEN 'claude-code-cli'
1003
+ ELSE 'unknown-acp-agent' END))
1004
+ FROM json_each(payload, '$.sessions')
1005
+ ))) WHERE json_type(payload, '$.sessions') = 'object';
1006
+ UPDATE global_role_session_sets SET payload = json_set(payload, '$.history', json((
1007
+ SELECT json_group_object(key, json_set(value, '$.effective.schemaVersion', 4,
1008
+ '$.effective.component', CASE json_extract(value, '$.effective.adapterId')
1009
+ WHEN 'codex' THEN 'codex-cli'
1010
+ WHEN 'claude' THEN 'claude-code-cli'
1011
+ ELSE 'unknown-acp-agent' END))
1012
+ FROM json_each(payload, '$.history')
1013
+ ))) WHERE json_type(payload, '$.history') = 'object';
1014
+
1015
+ UPDATE role_session_sets SET payload = json_set(payload, '$.sessions', json((
1016
+ SELECT json_group_object(key, json_set(value, '$.effective.schemaVersion', 4,
1017
+ '$.effective.component', CASE json_extract(value, '$.effective.adapterId')
1018
+ WHEN 'codex' THEN 'codex-cli'
1019
+ WHEN 'claude' THEN 'claude-code-cli'
1020
+ ELSE 'unknown-acp-agent' END))
1021
+ FROM json_each(payload, '$.sessions')
1022
+ ))) WHERE json_type(payload, '$.sessions') = 'object';
1023
+ UPDATE role_session_sets SET payload = json_set(payload, '$.history', json((
1024
+ SELECT json_group_array(json_set(value, '$.effective.schemaVersion', 4,
1025
+ '$.effective.component', CASE json_extract(value, '$.effective.adapterId')
1026
+ WHEN 'codex' THEN 'codex-cli'
1027
+ WHEN 'claude' THEN 'claude-code-cli'
1028
+ ELSE 'unknown-acp-agent' END))
1029
+ FROM json_each(payload, '$.history')
1030
+ ))) WHERE json_type(payload, '$.history') = 'array';
1031
+
1032
+ -- A Turn records the launch it actually ran on, one snapshot per row.
1033
+ UPDATE turns SET payload = json_set(payload,
1034
+ '$.effective.schemaVersion', 4,
1035
+ '$.effective.component', CASE json_extract(payload, '$.effective.adapterId')
1036
+ WHEN 'codex' THEN 'codex-cli'
1037
+ WHEN 'claude' THEN 'claude-code-cli'
1038
+ ELSE 'unknown-acp-agent' END)
1039
+ WHERE json_type(payload, '$.effective') = 'object';
1040
+
1041
+ -- ExecutionLane launch facts are frozen per Lane, inside an array of Groups
1042
+ -- that each hold an array of Lanes. A Lane that was never dispatched has no
1043
+ -- effective at all, and must keep that absence: json_set would otherwise
1044
+ -- create a partial snapshot the Lane validator rejects as incomplete.
1045
+ UPDATE work_items SET payload = json_set(payload, '$.executionGroups', json((
1046
+ SELECT json_group_array(json_set(grp.value, '$.lanes', json((
1047
+ SELECT json_group_array(CASE
1048
+ WHEN json_type(lane.value, '$.effective') = 'object'
1049
+ THEN json_set(lane.value, '$.effective.schemaVersion', 4,
1050
+ '$.effective.component', CASE json_extract(lane.value, '$.effective.adapterId')
1051
+ WHEN 'codex' THEN 'codex-cli'
1052
+ WHEN 'claude' THEN 'claude-code-cli'
1053
+ ELSE 'unknown-acp-agent' END)
1054
+ ELSE lane.value END)
1055
+ FROM json_each(grp.value, '$.lanes') AS lane
1056
+ ))))
1057
+ FROM json_each(payload, '$.executionGroups') AS grp
1058
+ ))) WHERE json_type(payload, '$.executionGroups') = 'array';
1059
+
1060
+ -- A ReviewRound holds at most one Group, so only the Lane array nests here.
1061
+ UPDATE review_rounds SET payload = json_set(payload, '$.executionGroup.lanes', json((
1062
+ SELECT json_group_array(CASE
1063
+ WHEN json_type(lane.value, '$.effective') = 'object'
1064
+ THEN json_set(lane.value, '$.effective.schemaVersion', 4,
1065
+ '$.effective.component', CASE json_extract(lane.value, '$.effective.adapterId')
1066
+ WHEN 'codex' THEN 'codex-cli'
1067
+ WHEN 'claude' THEN 'claude-code-cli'
1068
+ ELSE 'unknown-acp-agent' END)
1069
+ ELSE lane.value END)
1070
+ FROM json_each(payload, '$.executionGroup.lanes') AS lane
1071
+ ))) WHERE json_type(payload, '$.executionGroup.lanes') = 'array';
1072
+ `
1073
+ },
1074
+ {
1075
+ version: 16,
1076
+ name: "acp-session-run-configuration",
1077
+ introducedIn: "0.15.10",
1078
+ // An ACP Role binding may now carry a model, a reasoning effort and a
1079
+ // permission strategy beyond `default`, because Yui's ACP client implements
1080
+ // `session/set_config_option` and pushes those values to the Session before
1081
+ // it prompts. Previously the adapter rejected all three, so no stored
1082
+ // payload can contain them.
1083
+ //
1084
+ // This widens the contract without rewriting anything, and the absence of a
1085
+ // payload update is the substantive decision rather than an omission. A v10
1086
+ // ACP binding holds `permission.strategy = "default"`, which keeps exactly
1087
+ // the meaning it always had: Yui sends no mode, so the Agent's own default
1088
+ // stands. Rewriting those rows to `bypass` — or to any newly expressible
1089
+ // value — would grant authority the user never chose, on Homes whose owner
1090
+ // did nothing but upgrade. `bypass` is reachable only by asking for it.
1091
+ //
1092
+ // Effective launch snapshots need no change either. They already carry
1093
+ // optional `model` and `effort` on the shared base, and their ACP permission
1094
+ // is the same object the adapter canonicalizes, so a historical snapshot
1095
+ // still validates unchanged at schemaVersion 4 across Sessions, Session
1096
+ // history, Turns, WorkItem ExecutionLanes and ReviewRound ExecutionLanes.
1097
+ // A frozen snapshot therefore keeps describing the launch it actually ran,
1098
+ // which is what makes replaying old history honest.
1099
+ sql: "SELECT 1; -- ACP bindings may carry model/effort and a chosen "
1100
+ + "permission mode; existing `default` bindings keep their meaning"
1101
+ },
1102
+ {
1103
+ version: 17,
1104
+ name: "session-origin-input-requests",
1105
+ introducedIn: "0.15.8",
1106
+ // Widen requester provenance: notifications originate in a current Leader
1107
+ // Session without an AgentRun. Existing schemaVersion-3 requests keep their
1108
+ // exact Run/Session origin, including frozen historical Context values.
1109
+ // No guessed native identity or history rewrite is needed.
1110
+ sql: "SELECT 1; -- InputRequest requester.runId is optional when an exact nativeSessionId is present"
1111
+ },
1112
+ {
1113
+ version: 18,
1114
+ name: "replaceable-session-process-custody",
1115
+ introducedIn: "0.15.8",
1116
+ // Existing Session/Run history remains unchanged. Runtime mailboxes may
1117
+ // now retain explicit replacement intent; OS owner records may identify
1118
+ // the dedicated execution child, independently of a disposable Host.
1119
+ sql: "SELECT 1; -- Replacement intent, independent retained native control evidence/process custody, and optional fixed TaskWake refs"
700
1120
  }
701
1121
  ]);
702
1122
  for (let index = 0; index < MIGRATIONS.length; index += 1) {
@@ -713,8 +1133,9 @@ if (MIGRATIONS.at(-1)?.version !== CURRENT_STORAGE_VERSION) {
713
1133
  /** Current hot-path indexes whose absence would invalidate a current Home. */
714
1134
  const REQUIRED_SCHEMA_INDEXES = [
715
1135
  "idx_mailboxes_ready",
716
- "idx_runtime_session_cleanup_required",
717
- "idx_input_requests_open_hot"
1136
+ "idx_input_requests_open_hot",
1137
+ "idx_turns_planning_active",
1138
+ "idx_tasks_activation_pending"
718
1139
  ];
719
1140
  function checksum(sql) {
720
1141
  return createHash("sha256").update(sql).digest("hex");
@@ -937,6 +1358,7 @@ export function migrateSqliteSchema(db, options) {
937
1358
  const newlyApplied = [];
938
1359
  for (const migration of pending) {
939
1360
  db.exec(migration.sql);
1361
+ migration.migrateData?.(db);
940
1362
  const appliedAt = new Date().toISOString();
941
1363
  db.prepare(`INSERT INTO schema_migrations (version, name, applied_at, checksum)
942
1364
  VALUES (?, ?, ?, ?)`).run(migration.version, migration.name, appliedAt, checksum(migration.sql));
@@ -952,6 +1374,11 @@ export function migrateSqliteSchema(db, options) {
952
1374
  }
953
1375
  /** The names of every table the schema creates (for tests/introspection). */
954
1376
  export const SQLITE_SCHEMA_TABLES = [
1377
+ "plugin_intents",
1378
+ "plugin_validations",
1379
+ "artifacts",
1380
+ "local_resources",
1381
+ "environment_preparations",
955
1382
  "schema_migrations",
956
1383
  "home_meta",
957
1384
  "config",
@@ -967,7 +1394,6 @@ export const SQLITE_SCHEMA_TABLES = [
967
1394
  "coordination_locks",
968
1395
  "integration_queue",
969
1396
  "durable_jobs",
970
- "job_caller_key_hashes",
971
1397
  "outbox",
972
1398
  "mailboxes",
973
1399
  "task_records",