@zq-silk/yui 0.15.7 → 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 (281) 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 +157 -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 +178 -95
  25. package/dist/commands/agentCommands.js +72 -14
  26. package/dist/commands/capabilityCommands.js +9 -6
  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 +1188 -710
  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 +17 -6
  64. package/dist/controller/clientRuntime.js +65 -92
  65. package/dist/controller/controller.js +114 -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 +529 -479
  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 +247 -12
  106. package/dist/kernel/capabilityRegistry.js +64 -18
  107. package/dist/kernel/instanceHost.js +12 -1
  108. package/dist/kernel/kernelPorts.js +2 -2
  109. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  110. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  111. package/dist/message/message.js +62 -6
  112. package/dist/message/messageContinuation.js +204 -0
  113. package/dist/observability/executionAudit.js +70 -72
  114. package/dist/observability/faultClassification.js +2 -2
  115. package/dist/observability/orchestrationMetrics.js +8 -8
  116. package/dist/operator/operatorSessionHistory.js +1 -7
  117. package/dist/output/agentConfigurationPresentation.js +8 -3
  118. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  119. package/dist/output/rolePresentation.js +54 -3
  120. package/dist/plugins/pluginChild.js +104 -0
  121. package/dist/plugins/pluginIntent.js +26 -0
  122. package/dist/plugins/pluginInterpreter.js +43 -0
  123. package/dist/plugins/pluginPackage.js +101 -0
  124. package/dist/plugins/pluginProcess.js +112 -0
  125. package/dist/plugins/pluginService.js +380 -0
  126. package/dist/profile/agentProfile.js +1 -1
  127. package/dist/repository/gitWorkspace.js +26 -4
  128. package/dist/repository/project.js +19 -4
  129. package/dist/repository/taskBaseFreshness.js +13 -13
  130. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  131. package/dist/repository/taskWorkspacePreparer.js +344 -83
  132. package/dist/resources/autoResourceGc.js +3 -3
  133. package/dist/resources/liveReferences.js +3 -3
  134. package/dist/resources/projectResource.js +123 -0
  135. package/dist/resources/projectResourceService.js +421 -0
  136. package/dist/resources/resourceDiscovery.js +6 -6
  137. package/dist/resources/resourceGc.js +1 -1
  138. package/dist/resources/resourceRegistrar.js +1 -1
  139. package/dist/resources/resourceTypes.js +1 -1
  140. package/dist/review/deltaRecheck.js +3 -3
  141. package/dist/review/reviewAcceptance.js +16 -16
  142. package/dist/review/reviewDecision.js +7 -7
  143. package/dist/review/reviewRound.js +21 -20
  144. package/dist/review/reviewerAvailability.js +2 -2
  145. package/dist/role/role.js +51 -7
  146. package/dist/role/taskRoleUpdate.js +30 -0
  147. package/dist/runtime/acpProtocol.js +425 -0
  148. package/dist/runtime/acpSession.js +731 -0
  149. package/dist/runtime/acpSessionConfiguration.js +260 -0
  150. package/dist/runtime/agentDriver.js +30 -11
  151. package/dist/runtime/agentEndpoint.js +278 -0
  152. package/dist/runtime/agentEndpointIdentity.js +86 -0
  153. package/dist/runtime/agentEndpointOwnership.js +239 -0
  154. package/dist/runtime/agentError.js +2 -10
  155. package/dist/runtime/agentHost.js +565 -314
  156. package/dist/runtime/agentRunConfiguration.js +258 -0
  157. package/dist/runtime/builtinAgentDrivers.js +134 -18
  158. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  159. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  160. package/dist/runtime/claude-process-owner +0 -0
  161. package/dist/runtime/codexAppServerRuntime.js +38 -30
  162. package/dist/runtime/codexInteractiveHost.js +41 -6
  163. package/dist/runtime/continuationManager.js +2 -6
  164. package/dist/runtime/executionEnvironment.js +30 -0
  165. package/dist/runtime/firstProgressAdvisory.js +11 -11
  166. package/dist/runtime/index.js +4 -3
  167. package/dist/runtime/jsonLineChannel.js +109 -0
  168. package/dist/runtime/launchBroker.js +91 -16
  169. package/dist/runtime/launchDiagnostics.js +2 -2
  170. package/dist/runtime/lifecycleReservation.js +10 -18
  171. package/dist/runtime/managedCaller.js +61 -17
  172. package/dist/runtime/nativeSessionControl.js +102 -0
  173. package/dist/runtime/ports.js +6 -21
  174. package/dist/runtime/processExitObservation.js +8 -7
  175. package/dist/runtime/promptEnvelope.js +17 -6
  176. package/dist/runtime/providerContinuation.js +3 -9
  177. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  178. package/dist/runtime/providerControl.js +2 -7
  179. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  180. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  181. package/dist/runtime/runtimeBinding.js +0 -1
  182. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  183. package/dist/runtime/runtimeDeadlines.js +9 -0
  184. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  185. package/dist/runtime/runtimeObservation.js +29 -65
  186. package/dist/runtime/runtimeProjection.js +43 -51
  187. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  188. package/dist/runtime/sessionLaunchRequest.js +3 -7
  189. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  190. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  191. package/dist/runtime/sessionReconciliation.js +4 -8
  192. package/dist/runtime/sessionTerminationGuard.js +70 -259
  193. package/dist/runtime/sessionTokenMetrics.js +5 -16
  194. package/dist/runtime/structuredProviderHost.js +237 -117
  195. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  196. package/dist/runtime/tmuxAdapters.js +39 -86
  197. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  198. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  199. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  200. package/dist/scheduler/ports.js +80 -9
  201. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  202. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  203. package/dist/scheduler/taskExecutionProjection.js +120 -124
  204. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  205. package/dist/scheduler/taskWake.js +11 -4
  206. package/dist/scheduler/wakeReason.js +9 -1
  207. package/dist/setup/setupCommand.js +1 -0
  208. package/dist/storage/migrations/agentRunContract.js +159 -0
  209. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  210. package/dist/storage/sqliteSchema.js +431 -5
  211. package/dist/storage/sqliteStore.js +375 -220
  212. package/dist/storage/storageVersions.js +1 -1
  213. package/dist/storage/storeRpc.js +10 -5
  214. package/dist/storage/taskStore.js +13 -11
  215. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  216. package/dist/surface/surfaceContributions.js +102 -0
  217. package/dist/task/completionReadiness.js +32 -6
  218. package/dist/task/deliveryGuard.js +16 -16
  219. package/dist/task/draftPlan.js +72 -12
  220. package/dist/task/nextAction.js +144 -128
  221. package/dist/task/remoteDelivery.js +6 -6
  222. package/dist/task/task.js +184 -18
  223. package/dist/task/taskActivation.js +301 -0
  224. package/dist/task/taskActivationService.js +392 -0
  225. package/dist/task/taskRecordReference.js +5 -4
  226. package/dist/task/taskRecordRetirement.js +1 -1
  227. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  228. package/dist/telemetry/telemetryConfig.js +14 -14
  229. package/dist/telemetry/telemetryWiring.js +2 -2
  230. package/dist/web/assets/assetManifest.js +2 -0
  231. package/dist/web/assets/client/app.js +120 -20
  232. package/dist/web/assets/client/components.js +87 -54
  233. package/dist/web/assets/client/i18n.js +83 -41
  234. package/dist/web/assets/client/markdown.js +1 -1
  235. package/dist/web/assets/client/taskSurface.js +353 -0
  236. package/dist/web/assets/client/view.js +49 -44
  237. package/dist/web/assets/shell.js +1 -1
  238. package/dist/web/assets/styles/cards.js +22 -4
  239. package/dist/web/controllerWeb.js +60 -0
  240. package/dist/web/webMutation.js +28 -0
  241. package/dist/web/webServer.js +118 -8
  242. package/dist/web/webSnapshot.js +81 -74
  243. package/dist/web/webTaskSurface.js +64 -0
  244. package/dist/workItem/dependencyGate.js +1 -1
  245. package/dist/workItem/workItem.js +80 -48
  246. package/dist/workspace/workItemChangeSetManager.js +16 -9
  247. package/docs/agent-result-consumption.md +94 -0
  248. package/docs/agent-runtime-drivers.md +91 -0
  249. package/docs/architecture/README.md +38 -0
  250. package/docs/architecture/capabilities-and-resources.md +79 -0
  251. package/docs/managed-turn-and-session-runtime.md +222 -0
  252. package/docs/observability/README.md +81 -0
  253. package/docs/plugin-sdk.md +290 -0
  254. package/docs/provider-runtime.md +163 -0
  255. package/docs/release-workflow.md +303 -0
  256. package/docs/roles-and-configuration.md +113 -0
  257. package/docs/sqlite-control-plane-design.md +76 -0
  258. package/docs/task-dag-semantics.md +57 -0
  259. package/docs/task-delivery.md +103 -0
  260. package/docs/task-local-identity.md +6 -6
  261. package/docs/testing/verification-levels.md +86 -0
  262. package/i18n/README.zh-CN.md +98 -739
  263. package/package.json +2 -2
  264. package/skills/yui-leader/SKILL.md +130 -103
  265. package/skills/yui-leader/references/integration.md +39 -0
  266. package/skills/yui-leader/references/replicated-execution.md +42 -0
  267. package/skills/yui-leader/references/task-plugins.md +33 -0
  268. package/skills/yui-operator/SKILL.md +30 -59
  269. package/skills/yui-reviewer/SKILL.md +35 -36
  270. package/skills/yui-runtime/SKILL.md +88 -24
  271. package/skills/yui-runtime/references/publication.md +22 -0
  272. package/skills/yui-runtime/references/recovery.md +64 -0
  273. package/skills/yui-worker/SKILL.md +37 -39
  274. package/dist/cli/roleOptionCatalog.js +0 -68
  275. package/dist/context/sourceTurnContext.js +0 -30
  276. package/dist/execution/reviewMainTurn.js +0 -161
  277. package/dist/execution/workItemMainTurn.js +0 -164
  278. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  279. package/dist/runtime/preallocatedNativeSession.js +0 -13
  280. package/dist/runtime/runtimeStopReceipt.js +0 -42
  281. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -1,6 +1,16 @@
1
1
  import { capabilitySchemaError, checkCapabilitySchema } from "./capabilitySchema.js";
2
+ import { checkSurfaceDescriptors } from "../surface/surfaceContributions.js";
3
+ /** Trusted owners may accompany a failed operation with its current read model.
4
+ * This is diagnostic data, not an operation receipt or an authority token. */
5
+ export class CapabilityExecutionError extends Error {
6
+ value;
7
+ constructor(message, value) {
8
+ super(message);
9
+ this.value = structuredClone(value);
10
+ }
11
+ }
2
12
  const effectRank = { query: 0, "local-mutation": 1, "external-operation": 2 };
3
- const reserved = new Set(["yui", "task", "config", "job", "resource", "plugin", "runtime", "grant", "capability"]);
13
+ const reserved = new Set(["yui", "task", "context", "config", "job", "resource", "plugin", "runtime", "grant", "capability", "artifact", "environment", "project"]);
4
14
  /** One rebuildable descriptor view over the composition root's existing Host.
5
15
  * Only the trusted root owns this object. Extensions receive a bound invocation
6
16
  * port, never the registry/Host or an actor-selecting call interface. */
@@ -21,6 +31,30 @@ export class CapabilityRegistry {
21
31
  register(descriptors) {
22
32
  this.#publish(descriptors, false);
23
33
  }
34
+ /** Data-only candidate check before author initialization; no acquisition or
35
+ * publication. Repeat immediately before publishing after any async work. */
36
+ checkRegistration(context, descriptors) {
37
+ const prepared = this.#prepare(descriptors, false);
38
+ if (!prepared.length)
39
+ throw new Error("Plugin must contribute capabilities.");
40
+ const available = [
41
+ ...this.search(context).filter((entry) => entry.provider.id !== prepared[0].provider.id),
42
+ ...prepared
43
+ ];
44
+ const check = (entry, path) => {
45
+ this.authorize(context, entry);
46
+ if (path.has(entry))
47
+ throw new Error("Required capability dependency cycle.");
48
+ for (const dependency of entry.required ?? []) {
49
+ const matches = available.filter((candidate) => candidate.name === dependency.name
50
+ && candidate.contractVersion === dependency.contractVersion && candidate.unavailable === undefined);
51
+ if (matches.length !== 1)
52
+ throw new Error(`Required capability is missing or ambiguous: ${dependency.name}.`);
53
+ check(matches[0], new Set([...path, entry]));
54
+ }
55
+ };
56
+ prepared.forEach((entry) => check(entry, new Set()));
57
+ }
24
58
  disable(providerId) {
25
59
  this.#descriptors = this.#descriptors.filter((entry) => entry.provider.id !== providerId);
26
60
  }
@@ -70,7 +104,7 @@ export class CapabilityRegistry {
70
104
  call(context, request) {
71
105
  return this.#call(context, request, "external-operation");
72
106
  }
73
- async #call(context, request, ceiling) {
107
+ async #call(context, request, ceiling, permissions) {
74
108
  // Freeze one input snapshot across validation/acquisition and async nesting.
75
109
  try {
76
110
  request = deepFreeze(structuredClone(request));
@@ -86,6 +120,9 @@ export class CapabilityRegistry {
86
120
  if (effectRank[descriptor.effect] > effectRank[ceiling]) {
87
121
  return { ...result("denied", "Nested call exceeds the parent's effect boundary."), ...origin };
88
122
  }
123
+ if (permissions !== undefined && descriptor.requiredPermissions.some((permission) => !permissions.includes(permission))) {
124
+ return { ...result("denied", "Nested call exceeds the parent's declared permissions."), ...origin };
125
+ }
89
126
  const inputError = capabilitySchemaError(descriptor.inputSchema, request.input);
90
127
  if (inputError)
91
128
  return { ...result("invalid", inputError), ...origin };
@@ -121,7 +158,7 @@ export class CapabilityRegistry {
121
158
  call: (nested) => {
122
159
  if (!open)
123
160
  return Promise.resolve(result("denied", "Capability invocation has ended."));
124
- const child = this.#call(context, nested, descriptor.effect).then((outcome) => {
161
+ const child = this.#call(context, nested, descriptor.effect, descriptor.requiredPermissions).then((outcome) => {
125
162
  outcome.operations.forEach(observe);
126
163
  effect = accumulatedEffect(effect, outcome.effect);
127
164
  return outcome;
@@ -177,6 +214,7 @@ export class CapabilityRegistry {
177
214
  return {
178
215
  kind: entered ? "failed" : "unavailable",
179
216
  detail: error instanceof Error ? error.message : "Capability invocation failed.",
217
+ ...(error instanceof CapabilityExecutionError ? { value: error.value } : {}),
180
218
  effect, operations, ...origin
181
219
  };
182
220
  }
@@ -200,6 +238,27 @@ export class CapabilityRegistry {
200
238
  #publish(descriptors, core) {
201
239
  if (!descriptors.length)
202
240
  return;
241
+ const prepared = this.#prepare(descriptors, core);
242
+ const provider = prepared[0].provider;
243
+ // Validate acquisition before publishing; no implementation is invoked.
244
+ if (prepared.some((entry) => !entry.unavailable)) {
245
+ const handle = this.host.acquire(provider);
246
+ try {
247
+ if (typeof handle.value?.invoke !== "function")
248
+ throw new Error("Provider has no capability implementation.");
249
+ }
250
+ finally {
251
+ void handle.release();
252
+ }
253
+ }
254
+ this.#descriptors = [
255
+ ...this.#descriptors.filter((entry) => entry.provider.id !== provider.id),
256
+ ...prepared.map((entry) => deepFreeze(entry))
257
+ ];
258
+ }
259
+ #prepare(descriptors, core) {
260
+ if (!descriptors.length)
261
+ return [];
203
262
  const prepared = structuredClone(descriptors);
204
263
  const provider = prepared[0].provider;
205
264
  if (!core && this.#coreProviders.has(provider.id))
@@ -227,26 +286,13 @@ export class CapabilityRegistry {
227
286
  names.add(key);
228
287
  checkCapabilitySchema(entry.inputSchema);
229
288
  checkCapabilitySchema(entry.outputSchema);
289
+ checkSurfaceDescriptors(entry);
230
290
  for (const dependency of entry.required ?? []) {
231
291
  if (!dependency.name?.trim() || !dependency.contractVersion?.trim())
232
292
  throw new Error("Invalid required capability.");
233
293
  }
234
294
  }
235
- // Validate acquisition before publishing; no implementation is invoked.
236
- if (prepared.some((entry) => !entry.unavailable)) {
237
- const handle = this.host.acquire(provider);
238
- try {
239
- if (typeof handle.value?.invoke !== "function")
240
- throw new Error("Provider has no capability implementation.");
241
- }
242
- finally {
243
- void handle.release();
244
- }
245
- }
246
- this.#descriptors = [
247
- ...this.#descriptors.filter((entry) => entry.provider.id !== provider.id),
248
- ...prepared.map((entry) => deepFreeze(entry))
249
- ];
295
+ return [...prepared];
250
296
  }
251
297
  }
252
298
  function visible(scope, visibility) {
@@ -14,7 +14,7 @@ export class InstanceHost {
14
14
  void drained.catch(() => undefined);
15
15
  const ref = Object.freeze({ ...implementation });
16
16
  this.#instances.set(key, {
17
- implementation: ref, value, references: 0, detached: false,
17
+ implementation: ref, value, references: 0, detached: false, disposed: false,
18
18
  disposers: [...ownedDisposers], drained, resolve, reject
19
19
  });
20
20
  return ref;
@@ -25,6 +25,16 @@ export class InstanceHost {
25
25
  const instance = this.#instances.get(implementationKey(implementation));
26
26
  return !this.#closed && instance !== undefined && !instance.detached;
27
27
  }
28
+ /** Only the Host reports actual reference/disposal facts. Metadata consumers
29
+ * must not persist these observations as independently writable state. */
30
+ inspect(providerId) {
31
+ return [...this.#instances.values()].filter((instance) => instance.implementation.id === providerId && !instance.disposed)
32
+ .map((instance) => Object.freeze({
33
+ implementation: instance.implementation,
34
+ references: instance.references,
35
+ accepting: !this.#closed && !instance.detached
36
+ }));
37
+ }
28
38
  acquire(implementation) {
29
39
  const instance = this.#instances.get(implementationKey(implementation));
30
40
  if (this.#closed || instance === undefined || instance.detached) {
@@ -86,6 +96,7 @@ export class InstanceHost {
86
96
  // Re-attaching a generation must not resurrect an old reference.
87
97
  instance.value = undefined;
88
98
  instance.disposers = [];
99
+ instance.disposed = true;
89
100
  if (errors.length)
90
101
  throw new AggregateError(errors, "Instance cleanup failed.");
91
102
  })();
@@ -6,14 +6,14 @@ import { createBuiltinCapabilities } from "./builtinCapabilities.js";
6
6
  * another Controller, or provide arbitrary persistence to plugin code.
7
7
  * T02 registers contributions on this Host and wraps this same Job control.
8
8
  */
9
- export function createKernelPorts(store, runner, signal = () => undefined) {
9
+ export function createKernelPorts(store, runner, signal = () => undefined, contextProviders = []) {
10
10
  const host = new InstanceHost();
11
11
  const runnerImplementation = host.attach(JOB_RUNNER_IMPLEMENTATION, runner);
12
12
  const runnerHandle = host.acquire(runnerImplementation);
13
13
  const jobImplementation = host.attach({ id: "yui:job-control", generation: "1" }, createDurableJobControl(store));
14
14
  // The Controller is a long-lived consumer of this exact implementation.
15
15
  const jobHandle = host.acquire(jobImplementation);
16
- const capabilities = createBuiltinCapabilities(host, store, jobHandle.value, signal);
16
+ const capabilities = createBuiltinCapabilities(host, store, jobHandle.value, signal, contextProviders);
17
17
  return {
18
18
  host,
19
19
  capabilities,
@@ -1,3 +1,12 @@
1
+ /**
2
+ * The smallest stable, provider-neutral Yui lifecycle vocabulary.
3
+ *
4
+ * Each phase is a durable semantic fact about a managed Agent Session or the
5
+ * AgentRun whose prompt it carries. Agent Drivers translate native signals into
6
+ * these phases; the scheduler and durable fold reason about phases, sources,
7
+ * and evidence — never about provider names.
8
+ */
9
+ import { isAgentAdapterId } from "../agent/adapterCatalog.js";
1
10
  export function isPreInputReadinessSupported(capability) {
2
11
  return capability.status === "supported";
3
12
  }
@@ -9,17 +18,17 @@ export class CanonicalLifecycleError extends Error {
9
18
  this.name = "CanonicalLifecycleError";
10
19
  }
11
20
  }
12
- const TURN_SCOPED_PHASES = new Set([
21
+ const RUN_SCOPED_PHASES = new Set([
13
22
  "prompt-pushed",
14
23
  "provider-accepted",
15
24
  "turn-progress",
16
25
  "turn-terminal"
17
26
  ]);
18
27
  /**
19
- * Phases that assert durable provider truth about a Turn. Every one must carry
20
- * the complete turn-scoped identity — turnId AND the generation fences
21
- * (nativeSessionId + runtimeGenerationId) AND, where the transport owns it, the receiptId —
22
- * because a missing or wrong fence must fail closed rather than advance a Turn or
28
+ * Phases that assert durable provider truth about a AgentRun. Every one must carry
29
+ * the complete turn-scoped identity — turnId AND the Session fences
30
+ * (nativeSessionId) AND, where the transport owns it, the receiptId —
31
+ * because a missing or wrong fence must fail closed rather than advance a AgentRun or
23
32
  * its successor.
24
33
  */
25
34
  const PROVIDER_TRUTH_PHASES = new Set([
@@ -34,7 +43,7 @@ const PROVIDER_TRUTH_PHASES = new Set([
34
43
  * (acceptance/progress/terminal), so neither a transport/liveness signal nor a
35
44
  * shape-only `adapter-mapped` observation can ever forge or terminalize a turn.
36
45
  * `adapter-mapped` remains permissible only for the pre-acceptance
37
- * session-started/ready phases, whose fold never advances Turn truth.
46
+ * session-started/ready phases, whose fold never advances AgentRun truth.
38
47
  */
39
48
  const PHASE_EVIDENCE_MATRIX = {
40
49
  "host-process-created": { sources: ["controller"], evidence: ["controller"] },
@@ -77,18 +86,15 @@ export function createCanonicalLifecycleEvent(input) {
77
86
  throw new CanonicalLifecycleError(`Phase ${input.phase} rejects evidence ${input.evidence}; only ${rule.evidence.join("/")} may prove it.`);
78
87
  }
79
88
  const fence = normalizeFence(input.fence);
80
- if (TURN_SCOPED_PHASES.has(input.phase) && fence.turnId === undefined) {
81
- throw new CanonicalLifecycleError(`Phase ${input.phase} requires a turnId fence.`);
89
+ if (RUN_SCOPED_PHASES.has(input.phase) && fence.runId === undefined) {
90
+ throw new CanonicalLifecycleError(`Phase ${input.phase} requires a runId fence.`);
82
91
  }
83
- // Provider-truth phases must carry the complete generation fence so a stale or
84
- // wrong generation can never advance the Turn.
92
+ // Provider-truth phases must carry the complete Session fence so a stale or
93
+ // wrong Session can never advance the AgentRun.
85
94
  if (PROVIDER_TRUTH_PHASES.has(input.phase)) {
86
95
  if (fence.nativeSessionId === undefined) {
87
96
  throw new CanonicalLifecycleError(`Phase ${input.phase} requires a nativeSessionId fence.`);
88
97
  }
89
- if (fence.runtimeGenerationId === undefined) {
90
- throw new CanonicalLifecycleError(`Phase ${input.phase} requires a runtimeGenerationId fence.`);
91
- }
92
98
  }
93
99
  if (input.phase === "prompt-pushed" && fence.receiptId === undefined) {
94
100
  throw new CanonicalLifecycleError("A prompt-pushed event requires a transport receiptId.");
@@ -133,7 +139,7 @@ export function createCanonicalLifecycleEvent(input) {
133
139
  * The provider-neutral decision. Given a validated canonical event and the
134
140
  * consumer's current expectation, it returns what should happen — idempotent for
135
141
  * duplicates, deferred for not-yet-applicable facts, obsolete for stale/wrong
136
- * generation, fail-closed for contract violations. It reads only phase / source
142
+ * Session, fail-closed for contract violations. It reads only phase / source
137
143
  * / evidence / identity, never the adapter name, and mutates nothing.
138
144
  */
139
145
  export function foldCanonicalLifecycleEvent(event, expectation) {
@@ -154,10 +160,7 @@ export function foldCanonicalLifecycleEvent(event, expectation) {
154
160
  }
155
161
  // Discovery may bind a previously-unknown native id, but only under the
156
162
  // exact launch fence and only when none is bound yet.
157
- if (expectation.boundNativeSessionId === undefined
158
- && event.fence.nativeSessionId !== undefined
159
- && event.fence.runtimeGenerationId !== undefined
160
- && event.fence.runtimeGenerationId === expectation.fence.runtimeGenerationId) {
163
+ if (expectation.boundNativeSessionId === undefined && event.fence.nativeSessionId !== undefined) {
161
164
  return { outcome: "bind-native-session", nativeSessionId: event.fence.nativeSessionId };
162
165
  }
163
166
  return { outcome: "mark-session-started" };
@@ -176,7 +179,7 @@ export function foldCanonicalLifecycleEvent(event, expectation) {
176
179
  return { outcome: "obsolete", reason: "push-after-terminal" };
177
180
  if (expectation.accepted)
178
181
  return { outcome: "obsolete", reason: "push-after-accepted" };
179
- // Exactly one push: a repeat for an already-pushed Turn is a no-op, never a
182
+ // Exactly one push: a repeat for an already-pushed AgentRun is a no-op, never a
180
183
  // second Enter.
181
184
  if (expectation.pushed)
182
185
  return { outcome: "idempotent", reason: "already-pushed" };
@@ -209,7 +212,7 @@ export function foldCanonicalLifecycleEvent(event, expectation) {
209
212
  return { outcome: "idempotent", reason: "already-terminal" };
210
213
  if (expectation.accepted)
211
214
  return { outcome: "advance-terminal" };
212
- // A terminal for a pushed-but-unaccepted Turn must NOT promote acceptance;
215
+ // A terminal for a pushed-but-unaccepted AgentRun must NOT promote acceptance;
213
216
  // hold the immutable fact until (or unless) acceptance folds first.
214
217
  if (expectation.pushed)
215
218
  return { outcome: "deferred", reason: "terminal-before-accept" };
@@ -219,12 +222,12 @@ export function foldCanonicalLifecycleEvent(event, expectation) {
219
222
  }
220
223
  }
221
224
  /**
222
- * Returns null when the event belongs to the expected generation/Turn, or a
225
+ * Returns null when the event belongs to the expected Session/AgentRun, or a
223
226
  * mismatch reason otherwise. Owner/adapter and turn-scoped turnId are always
224
227
  * compared. Provider-truth phases (acceptance/progress/terminal) require the
225
- * COMPLETE generation fence — nativeSessionId, runtimeGenerationId, and (for acceptance)
226
- * receiptId must be present and equal, so a missing or wrong generation/receipt
227
- * fails closed rather than advancing a Turn or its successor. Where a native id
228
+ * COMPLETE Session fence — nativeSessionId, and (for acceptance)
229
+ * receiptId must be present and equal, so a missing or wrong Session/receipt
230
+ * fails closed rather than advancing a AgentRun or its successor. Where a native id
228
231
  * is already bound, every turn-scoped fact must match it.
229
232
  */
230
233
  function matchesFence(expectation, event) {
@@ -239,29 +242,23 @@ function matchesFence(expectation, event) {
239
242
  return "fence-mismatch:agentId";
240
243
  if (expected.adapterId !== actual.adapterId)
241
244
  return "fence-mismatch:adapterId";
242
- // Turn-scoped phases must name the exact expected Turn.
243
- if (TURN_SCOPED_PHASES.has(phase)) {
244
- if (expected.turnId === undefined)
245
+ // AgentRun-scoped phases must name the exact expected AgentRun.
246
+ if (RUN_SCOPED_PHASES.has(phase)) {
247
+ if (expected.runId === undefined)
245
248
  return "fence-mismatch:expected-turn-missing";
246
- if (actual.turnId !== expected.turnId)
247
- return "fence-mismatch:turnId";
249
+ if (actual.runId !== expected.runId)
250
+ return "fence-mismatch:runId";
248
251
  }
249
- else if (actual.turnId !== undefined
250
- && expected.turnId !== undefined
251
- && actual.turnId !== expected.turnId) {
252
- return "fence-mismatch:turnId";
252
+ else if (actual.runId !== undefined
253
+ && expected.runId !== undefined
254
+ && actual.runId !== expected.runId) {
255
+ return "fence-mismatch:runId";
253
256
  }
254
- // Provider-truth phases require the complete, equal generation fence. A
257
+ // Provider-truth phases require the complete, equal Session fence. A
255
258
  // provider-accepted event additionally must carry the exact receipt it accepts.
256
259
  if (PROVIDER_TRUTH_PHASES.has(phase)) {
257
260
  if (actual.nativeSessionId === undefined)
258
261
  return "fence-mismatch:missing-native-session";
259
- if (actual.runtimeGenerationId === undefined) {
260
- return "fence-mismatch:missing-runtime-generation";
261
- }
262
- if (expected.runtimeGenerationId !== undefined && actual.runtimeGenerationId !== expected.runtimeGenerationId) {
263
- return "fence-mismatch:runtimeGenerationId";
264
- }
265
262
  // Once a native id is bound, every provider-truth fact must match it. Before
266
263
  // binding (discovery still open) the expected fence's own nativeSessionId, if
267
264
  // present, still constrains it.
@@ -279,7 +276,7 @@ function matchesFence(expectation, event) {
279
276
  return null;
280
277
  }
281
278
  // Pre-acceptance phases (host/session/ready and the transport push): compare
282
- // the generation dimensions that are present on both sides. A push must match
279
+ // the Session dimensions that are present on both sides. A push must match
283
280
  // its expected receipt when both name one.
284
281
  if (actual.nativeSessionId !== undefined
285
282
  && expectation.boundNativeSessionId !== undefined
@@ -291,11 +288,6 @@ function matchesFence(expectation, event) {
291
288
  && actual.nativeSessionId !== expected.nativeSessionId) {
292
289
  return "fence-mismatch:nativeSessionId";
293
290
  }
294
- if (actual.runtimeGenerationId !== undefined
295
- && expected.runtimeGenerationId !== undefined
296
- && actual.runtimeGenerationId !== expected.runtimeGenerationId) {
297
- return "fence-mismatch:runtimeGenerationId";
298
- }
299
291
  if (phase === "prompt-pushed"
300
292
  && actual.receiptId !== undefined
301
293
  && expected.receiptId !== undefined
@@ -308,7 +300,11 @@ function normalizeFence(fence) {
308
300
  const taskId = requireFenceText(fence.taskId, "taskId");
309
301
  const roleName = requireFenceText(fence.roleName, "roleName");
310
302
  const agentId = requireFenceText(fence.agentId, "agentId");
311
- if (fence.adapterId !== "codex" && fence.adapterId !== "claude") {
303
+ // The fence names an adapter, and the catalog is what defines which adapters
304
+ // exist. Re-listing them here would silently exclude a catalogued adapter
305
+ // from the durable fold, which reads as an identity mismatch rather than as
306
+ // the missing registration it actually is.
307
+ if (!isAgentAdapterId(fence.adapterId)) {
312
308
  throw new CanonicalLifecycleError(`Unsupported adapter fence: ${String(fence.adapterId)}.`);
313
309
  }
314
310
  return Object.freeze({
@@ -316,11 +312,10 @@ function normalizeFence(fence) {
316
312
  roleName,
317
313
  agentId,
318
314
  adapterId: fence.adapterId,
319
- ...(fence.turnId === undefined ? {} : { turnId: requireFenceText(fence.turnId, "turnId") }),
315
+ ...(fence.runId === undefined ? {} : { runId: requireFenceText(fence.runId, "runId") }),
320
316
  ...(fence.nativeSessionId === undefined
321
317
  ? {}
322
318
  : { nativeSessionId: requireFenceText(fence.nativeSessionId, "nativeSessionId") }),
323
- ...(fence.runtimeGenerationId === undefined ? {} : { runtimeGenerationId: requireFenceText(fence.runtimeGenerationId, "runtimeGenerationId") }),
324
319
  ...(fence.receiptId === undefined ? {} : { receiptId: requireFenceText(fence.receiptId, "receiptId") })
325
320
  });
326
321
  }