@zq-silk/yui 0.15.11 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/ARCHITECTURE.md +11 -6
  2. package/ARCHITECTURE.zh-CN.md +8 -4
  3. package/README.md +13 -5
  4. package/dist/agentRun/agentRun.js +3 -0
  5. package/dist/artifacts/artifactCommitLock.js +16 -55
  6. package/dist/artifacts/taskArtifactRepository.js +3 -3
  7. package/dist/cli/agentConfigurationPicker.js +1 -1
  8. package/dist/cli/commandCatalog.js +92 -48
  9. package/dist/cli/completion.js +18 -18
  10. package/dist/cli/completionWizard.js +1 -1
  11. package/dist/cli/dynamicCompletion.js +1 -1
  12. package/dist/cli/interactionPolicy.js +11 -3
  13. package/dist/cli/invocationAuthority.js +64 -0
  14. package/dist/cli/managedDiagnostics.js +2 -2
  15. package/dist/cli/parseRepeatable.js +35 -0
  16. package/dist/cli/updatePorts.js +26 -5
  17. package/dist/cli.js +1303 -1235
  18. package/dist/commands/agentCommands.js +4 -4
  19. package/dist/commands/capabilityCommands.js +1 -1
  20. package/dist/commands/configCommands.js +6 -57
  21. package/dist/commands/configOverview.js +2 -2
  22. package/dist/commands/durableJobCommands.js +12 -6
  23. package/dist/commands/executionAuditCommands.js +10 -0
  24. package/dist/commands/globalRoleCommands.js +78 -29
  25. package/dist/commands/grantCommands.js +0 -3
  26. package/dist/commands/jobCommands.js +1 -4
  27. package/dist/commands/operatorCommands.js +3 -3
  28. package/dist/commands/projectCommands.js +45 -25
  29. package/dist/commands/resourcesCommands.js +10 -40
  30. package/dist/commands/roleConfiguration.js +2 -6
  31. package/dist/commands/taskActivationCommands.js +4 -8
  32. package/dist/commands/taskAgentCapabilities.js +9 -0
  33. package/dist/commands/taskCommandSupport.js +155 -0
  34. package/dist/commands/taskCommandTypes.js +1 -0
  35. package/dist/commands/taskCommands.js +355 -732
  36. package/dist/commands/taskCompletionGate.js +1 -1
  37. package/dist/commands/taskExecutionCommands.js +1 -1
  38. package/dist/commands/taskFactCommands.js +325 -0
  39. package/dist/commands/taskInputCommands.js +12 -42
  40. package/dist/commands/taskIntegrationCommands.js +20 -58
  41. package/dist/commands/taskNextActionCommand.js +7 -6
  42. package/dist/commands/taskPublicationAdoptCommand.js +127 -0
  43. package/dist/commands/taskPublicationCommands.js +12 -3
  44. package/dist/commands/taskPublicationVerifyCommand.js +24 -40
  45. package/dist/commands/taskRemoteDeliveryCommand.js +5 -86
  46. package/dist/commands/taskUpstreamCommands.js +19 -8
  47. package/dist/commands/workflowCommands.js +6 -1
  48. package/dist/completion/completionInstaller.js +26 -26
  49. package/dist/completion/completionState.js +26 -26
  50. package/dist/completion/fileCompletionManager.js +6 -11
  51. package/dist/config/configCatalog.js +0 -2
  52. package/dist/config/timeZone.js +14 -0
  53. package/dist/config/yuiConfig.js +0 -29
  54. package/dist/context/runContextPack.js +5 -3
  55. package/dist/context/taskCatalog.js +185 -0
  56. package/dist/context/taskContext.js +152 -151
  57. package/dist/context/wakeRunReferences.js +11 -0
  58. package/dist/controller/agentCapabilities.js +58 -0
  59. package/dist/controller/agentRuntimeObserver.js +6 -11
  60. package/dist/controller/clientRuntime.js +22 -14
  61. package/dist/controller/controller.js +20 -24
  62. package/dist/controller/fileSchedulerStoreAdapter.js +191 -225
  63. package/dist/controller/globalInputDelivery.js +13 -0
  64. package/dist/controller/jobClient.js +4 -4
  65. package/dist/controller/jobControl.js +60 -25
  66. package/dist/controller/jobSupervisor.js +4 -4
  67. package/dist/controller/providerRetryAdmission.js +100 -0
  68. package/dist/controller/providerRetryDelivery.js +218 -0
  69. package/dist/controller/runtime.js +85 -43
  70. package/dist/controller/runtimeEventProcessor.js +0 -5
  71. package/dist/controller/sessionOwnerReconciliation.js +5 -0
  72. package/dist/controller/taskAgentError.js +35 -0
  73. package/dist/coordination/workMailboxQueue.js +2 -24
  74. package/dist/core/controllerClient.js +2 -2
  75. package/dist/core/fileLockOwner.js +74 -0
  76. package/dist/decision/decision.js +17 -0
  77. package/dist/doctor/doctor.js +18 -9
  78. package/dist/event/taskEvent.js +12 -0
  79. package/dist/execution/workItemExecutionProjection.js +2 -2
  80. package/dist/executor/agentCapabilityConfig.js +43 -0
  81. package/dist/executor/agentConfigurationCatalog.js +49 -11
  82. package/dist/executor/agentExecutor.js +5 -8
  83. package/dist/executor/fileRoleLaunchPlanner.js +11 -53
  84. package/dist/executor/taskAgentCapabilities.js +64 -0
  85. package/dist/integration/deliveryObligation.js +1 -69
  86. package/dist/integration/gitIntegrationService.js +79 -90
  87. package/dist/integration/integrationAttempt.js +3 -14
  88. package/dist/integration/integrationSourceApplication.js +4 -12
  89. package/dist/integration/manifestTags.js +2 -2
  90. package/dist/job/durableJob.js +4 -25
  91. package/dist/job/jobAssignmentScope.js +22 -0
  92. package/dist/job/jobOperation.js +16 -0
  93. package/dist/job/jobRunner.js +2 -1
  94. package/dist/job/stepDirectory.js +15 -0
  95. package/dist/kernel/builtinCapabilities.js +15 -11
  96. package/dist/kernel/kernelPorts.js +1 -17
  97. package/dist/lifecycle/exactRunTerminalization.js +5 -10
  98. package/dist/message/globalProviderRetry.js +15 -0
  99. package/dist/message/inputControlResolution.js +3 -4
  100. package/dist/message/message.js +17 -20
  101. package/dist/message/messageContinuation.js +1 -1
  102. package/dist/milestone/milestone.js +11 -0
  103. package/dist/observability/executionAudit.js +19 -0
  104. package/dist/observability/orchestrationMetrics.js +24 -1
  105. package/dist/observability/runtimeIdentity.js +1 -17
  106. package/dist/output/agentConfigurationPresentation.js +2 -0
  107. package/dist/output/timePresentation.js +1 -14
  108. package/dist/plugins/pluginService.js +12 -4
  109. package/dist/release/releaseWorkflowPorts.js +45 -96
  110. package/dist/release/runtimeRelease.js +9 -15
  111. package/dist/repository/gitWorkspace.js +371 -105
  112. package/dist/repository/projectMaintenanceLock.js +98 -82
  113. package/dist/repository/taskBaseFreshness.js +1 -1
  114. package/dist/repository/taskWorkspaceCoordinator.js +82 -144
  115. package/dist/repository/taskWorkspacePreparer.js +113 -47
  116. package/dist/repository/workspaceCleanupInspection.js +187 -0
  117. package/dist/resources/autoResourceGc.js +4 -77
  118. package/dist/resources/liveReferences.js +7 -54
  119. package/dist/resources/resourceDiscovery.js +5 -118
  120. package/dist/resources/resourceGc.js +233 -181
  121. package/dist/resources/resourceRegistrar.js +5 -4
  122. package/dist/resources/resourceRegistry.js +3 -37
  123. package/dist/resources/resourceRegistryStore.js +13 -36
  124. package/dist/resources/sqliteResourceRegistry.js +43 -26
  125. package/dist/review/deltaRecheck.js +1 -1
  126. package/dist/review/reviewAcceptance.js +1 -1
  127. package/dist/review/reviewDecision.js +1 -1
  128. package/dist/review/reviewRound.js +8 -7
  129. package/dist/review/taskFinalReviewContractResolution.js +1 -1
  130. package/dist/runtime/acpProtocol.js +4 -51
  131. package/dist/runtime/acpSession.js +10 -75
  132. package/dist/runtime/acpSessionConfiguration.js +1 -8
  133. package/dist/runtime/agentEndpoint.js +3 -2
  134. package/dist/runtime/agentError.js +5 -3
  135. package/dist/runtime/agentFailureContext.js +43 -0
  136. package/dist/runtime/agentHost.js +42 -25
  137. package/dist/runtime/builtinAgentErrorMappers.js +91 -0
  138. package/dist/runtime/codexAppServerRuntime.js +34 -3
  139. package/dist/runtime/codexInteractiveHost.js +2 -2
  140. package/dist/runtime/index.js +0 -1
  141. package/dist/runtime/managedCaller.js +21 -1
  142. package/dist/runtime/providerControl.js +5 -1
  143. package/dist/runtime/providerErrors.js +38 -0
  144. package/dist/runtime/providerRetry.js +198 -0
  145. package/dist/runtime/providerRuntimeIdentity.js +28 -2
  146. package/dist/runtime/runtimeObservation.js +0 -5
  147. package/dist/runtime/runtimeSessionCandidate.js +2 -3
  148. package/dist/runtime/sessionOwnerIdentity.js +1 -1
  149. package/dist/runtime/sessionTokenMetrics.js +15 -5
  150. package/dist/runtime/structuredProviderHost.js +10 -43
  151. package/dist/runtime/taskUsageMetrics.js +275 -0
  152. package/dist/runtime/tmuxAdapters.js +6 -8
  153. package/dist/scheduler/activeRoleRunDelivery.js +19 -7
  154. package/dist/scheduler/leaderWakeupProcessor.js +24 -6
  155. package/dist/scheduler/operatorEvent.js +12 -20
  156. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  157. package/dist/scheduler/ports.js +5 -8
  158. package/dist/scheduler/roleRunLiveness.js +4 -4
  159. package/dist/scheduler/roleRunStall.js +16 -23
  160. package/dist/scheduler/taskExecutionProjection.js +49 -36
  161. package/dist/scheduler/taskObservabilityProjection.js +6 -45
  162. package/dist/scheduler/taskWake.js +5 -10
  163. package/dist/scheduler/wakeReason.js +2 -0
  164. package/dist/scheduler/wakeupQueue.js +2 -4
  165. package/dist/setup/setupCommand.js +1 -1
  166. package/dist/storage/contextRecords.js +106 -0
  167. package/dist/storage/currentTaskStore.js +1 -1
  168. package/dist/storage/homeLayout.js +13 -17
  169. package/dist/storage/migrations/agentFailureContext.js +22 -0
  170. package/dist/storage/migrations/currentInputContract.js +86 -0
  171. package/dist/storage/migrations/currentRuntimeContract.js +228 -0
  172. package/dist/storage/migrations/historicalVerificationPlan.js +35 -0
  173. package/dist/storage/migrations/integrationContinuation.js +5 -4
  174. package/dist/storage/migrations/narrowAgentFailureContext.js +65 -0
  175. package/dist/storage/migrations/notificationOnlyWakes.js +74 -0
  176. package/dist/storage/migrations/verificationPlanV1.js +162 -0
  177. package/dist/storage/migrations/verificationPolicy.js +74 -0
  178. package/dist/storage/migrations/workItemHistory.js +46 -0
  179. package/dist/storage/persistenceWorker.js +12 -4
  180. package/dist/storage/recordValidation.js +87 -0
  181. package/dist/storage/sqliteSchema.js +173 -1
  182. package/dist/storage/sqliteStore.js +172 -161
  183. package/dist/storage/storageSchema.js +2 -14
  184. package/dist/storage/storageVersions.js +1 -1
  185. package/dist/storage/storeRpc.js +16 -7
  186. package/dist/storage/taskCatalog.js +123 -0
  187. package/dist/storage/taskStore.js +5 -7
  188. package/dist/storage/upgrade/upgradeOrchestrator.js +25 -37
  189. package/dist/task/archiveDiagnostics.js +1 -0
  190. package/dist/task/archivePreflight.js +124 -0
  191. package/dist/task/completionReadiness.js +5 -24
  192. package/dist/task/draftPlan.js +0 -53
  193. package/dist/task/nextAction.js +7 -13
  194. package/dist/task/publicationAdoption.js +56 -0
  195. package/dist/task/publicationReference.js +10 -0
  196. package/dist/task/remoteDelivery.js +31 -16
  197. package/dist/task/remoteDeliveryService.js +89 -0
  198. package/dist/task/taskActivation.js +2 -25
  199. package/dist/task/taskActivationService.js +0 -2
  200. package/dist/task/taskRecordReference.js +0 -1
  201. package/dist/task/taskSubmission.js +3 -14
  202. package/dist/telemetry/sqliteTelemetryBatch.js +29 -0
  203. package/dist/telemetry/sqliteTelemetryStore.js +49 -49
  204. package/dist/telemetry/telemetryWiring.js +4 -3
  205. package/dist/tmux/tmuxManager.js +29 -20
  206. package/dist/verification/gateArtifact.js +15 -24
  207. package/dist/verification/gateArtifactStore.js +14 -7
  208. package/dist/verification/verificationGateService.js +29 -88
  209. package/dist/verification/verificationPlan.js +27 -72
  210. package/dist/web/assets/client/app.js +92 -17
  211. package/dist/web/assets/client/components.js +55 -13
  212. package/dist/web/assets/client/i18n.js +72 -4
  213. package/dist/web/assets/client/taskSurface.js +6 -5
  214. package/dist/web/assets/client/view.js +35 -7
  215. package/dist/web/assets/shell.js +6 -0
  216. package/dist/web/assets/styles/layout.js +7 -0
  217. package/dist/web/webServer.js +12 -3
  218. package/dist/web/webSnapshot.js +14 -85
  219. package/dist/web/webTaskSurface.js +17 -46
  220. package/dist/workItem/workItem.js +1 -12
  221. package/dist/workspace/cleanupInspection.js +63 -0
  222. package/dist/workspace/workItemChangeSetManager.js +110 -50
  223. package/docs/agent-result-consumption.md +4 -0
  224. package/docs/agent-result-consumption.zh-CN.md +3 -0
  225. package/docs/agent-runtime-drivers.md +7 -0
  226. package/docs/agent-runtime-drivers.zh-CN.md +5 -0
  227. package/docs/architecture/README.md +2 -0
  228. package/docs/architecture/README.zh-CN.md +3 -1
  229. package/docs/architecture/capabilities-and-resources.md +42 -5
  230. package/docs/architecture/capabilities-and-resources.zh-CN.md +33 -3
  231. package/docs/managed-turn-and-session-runtime.md +121 -1
  232. package/docs/managed-turn-and-session-runtime.zh-CN.md +96 -2
  233. package/docs/observability/README.md +62 -0
  234. package/docs/observability/README.zh-CN.md +47 -0
  235. package/docs/plugin-sdk.md +4 -2
  236. package/docs/project-refresh.md +77 -0
  237. package/docs/project-refresh.zh-CN.md +59 -0
  238. package/docs/provider-retry.md +70 -0
  239. package/docs/provider-runtime.md +3 -1
  240. package/docs/provider-runtime.zh-CN.md +4 -2
  241. package/docs/release-workflow.md +190 -7
  242. package/docs/release-workflow.zh-CN.md +139 -5
  243. package/docs/roles-and-configuration.md +29 -0
  244. package/docs/roles-and-configuration.zh-CN.md +21 -0
  245. package/docs/sqlite-control-plane-design.md +16 -3
  246. package/docs/sqlite-control-plane-design.zh-CN.md +13 -2
  247. package/docs/task-dag-semantics.md +3 -3
  248. package/docs/task-dag-semantics.zh-CN.md +2 -2
  249. package/docs/task-delivery.md +223 -17
  250. package/docs/task-delivery.zh-CN.md +171 -14
  251. package/docs/task-discovery.md +101 -0
  252. package/docs/task-discovery.zh-CN.md +85 -0
  253. package/docs/testing/verification-levels.md +161 -9
  254. package/docs/testing/verification-levels.zh-CN.md +116 -9
  255. package/i18n/README.zh-CN.md +13 -7
  256. package/package.json +1 -1
  257. package/skills/yui-leader/SKILL.md +5 -0
  258. package/skills/yui-leader/references/execution.md +3 -2
  259. package/skills/yui-leader/references/integration.md +9 -5
  260. package/skills/yui-leader/references/planning.md +9 -3
  261. package/skills/yui-operator/SKILL.md +24 -8
  262. package/skills/yui-reviewer/SKILL.md +4 -0
  263. package/skills/yui-runtime/SKILL.md +17 -2
  264. package/skills/yui-runtime/references/publication.md +26 -4
  265. package/skills/yui-runtime/references/recovery.md +71 -0
  266. package/dist/agent/agentRegistry.js +0 -10
  267. package/dist/agentRun/runIdentity.js +0 -22
  268. package/dist/commands/deliveryGuardPreflight.js +0 -30
  269. package/dist/commands/taskIntegrationQueueCommands.js +0 -226
  270. package/dist/commands/taskOverviewCommand.js +0 -376
  271. package/dist/completion/completionWizard.js +0 -125
  272. package/dist/context/dispatchContext.js +0 -110
  273. package/dist/context/wakeNotification.js +0 -144
  274. package/dist/integration/integrationCheckEvidenceReuse.js +0 -53
  275. package/dist/integration/integrationQueueEntry.js +0 -191
  276. package/dist/integration/integrationQueueService.js +0 -810
  277. package/dist/release/fakeReleasePorts.js +0 -55
  278. package/dist/runtime/sessionOwnerRegistry.js +0 -137
  279. package/dist/task/deliveryGuard.js +0 -226
  280. /package/dist/{commands/taskActor.js → task/taskAuthority.js} +0 -0
@@ -4,6 +4,7 @@ import { homedir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import { writeTextFileAtomically } from "../storage/durableFile.js";
6
6
  import { resolveAgentAdapter } from "./agentAdapter.js";
7
+ import { redactAgentErrorText } from "../runtime/agentError.js";
7
8
  const DEFAULT_TIMEOUT_MS = 8_000;
8
9
  export class AgentConfigurationCatalogService {
9
10
  yuiHome;
@@ -11,20 +12,39 @@ export class AgentConfigurationCatalogService {
11
12
  #timeoutMs;
12
13
  #now;
13
14
  #discover;
15
+ #memoryCacheLimit;
14
16
  #requests = new Map();
17
+ #completed = new Map();
15
18
  constructor(yuiHome, options = {}) {
16
19
  this.yuiHome = yuiHome;
17
20
  this.#environment = options.environment ?? process.env;
18
21
  this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
19
22
  this.#now = options.now ?? (() => new Date());
20
23
  this.#discover = options.discover ?? ((input) => resolveAgentAdapter(input.agent.adapterId).discoverConfiguration(input));
24
+ this.#memoryCacheLimit = options.memoryCacheLimit ?? 64;
25
+ if (!Number.isSafeInteger(this.#memoryCacheLimit) || this.#memoryCacheLimit < 1) {
26
+ throw new Error("Agent metadata memory cache limit must be positive.");
27
+ }
21
28
  }
22
29
  resolve(input) {
23
30
  const fingerprint = catalogFingerprint(input, this.#environment);
24
- const existing = this.#requests.get(fingerprint);
25
- if (existing !== undefined)
26
- return existing;
27
- const request = this.#resolve(input, fingerprint);
31
+ const active = this.#requests.get(fingerprint);
32
+ if (active !== undefined)
33
+ return active;
34
+ const cached = this.#completed.get(fingerprint);
35
+ if (cached !== undefined && input.refresh !== true) {
36
+ this.#completed.delete(fingerprint);
37
+ this.#completed.set(fingerprint, cached);
38
+ return Promise.resolve(cached.source === "live" ? { ...cached, source: "cache" } : cached);
39
+ }
40
+ const request = this.#resolve(input, fingerprint).then(result => {
41
+ this.#completed.delete(fingerprint);
42
+ this.#completed.set(fingerprint, result);
43
+ while (this.#completed.size > this.#memoryCacheLimit) {
44
+ this.#completed.delete(this.#completed.keys().next().value);
45
+ }
46
+ return result;
47
+ }).finally(() => { this.#requests.delete(fingerprint); });
28
48
  this.#requests.set(fingerprint, request);
29
49
  return request;
30
50
  }
@@ -174,24 +194,42 @@ export function defaultModel(catalog) {
174
194
  export function modelChoice(catalog, value) {
175
195
  return value === undefined
176
196
  ? defaultModel(catalog)
177
- : catalog.models.find((model) => model.value === value);
197
+ : catalog.models.find((model) => model.value === value)
198
+ ?? catalog.models.find((model) => model.resolvedModel === value && !model.isDefault)
199
+ ?? catalog.models.find((model) => model.resolvedModel === value);
200
+ }
201
+ /** Observed choices, not an invented complete list of a Provider's model IDs. */
202
+ export function agentModelOptionsSummary(catalog) {
203
+ const choices = catalog.models.map(model => `${JSON.stringify(model.value)}${model.resolvedModel === undefined
204
+ || model.resolvedModel === model.value ? "" : ` -> ${JSON.stringify(model.resolvedModel)}`}`);
205
+ return [
206
+ choices.length === 0
207
+ ? "No native model options were reported."
208
+ : `Native model options: ${choices.join(", ")}.`,
209
+ ...(configurationField(catalog, "model")?.allowCustom === true
210
+ ? ["Custom model IDs are validated by the Provider; this list is not exhaustive."] : [])
211
+ ].join(" ");
178
212
  }
179
213
  /**
180
- * Validates the launch-time model/effort against a live or cached capability
181
- * catalog. A fallback catalog intentionally carries no model list, so an
182
- * unavailable Provider probe does not block a supported launch.
214
+ * Validate known model/effort constraints. An explicitly open model field
215
+ * delegates unlisted IDs to the Provider; aliases are not a complete whitelist.
216
+ * A fallback has no model list and makes no claim about native acceptance.
183
217
  */
184
218
  export function validateAgentLaunchConfiguration(catalog, config) {
185
219
  if (catalog.models.length === 0)
186
220
  return;
187
221
  const model = modelChoice(catalog, config.model);
188
222
  if (model === undefined) {
189
- throw new Error(`Unsupported ${catalog.adapterId} launch configuration: field=model actual=${JSON.stringify(config.model ?? "")} supported=${JSON.stringify(catalog.models.map(({ value }) => value))}.`);
223
+ if (config.model !== undefined && configurationField(catalog, "model")?.allowCustom === true)
224
+ return;
225
+ throw new Error(`Unsupported ${catalog.adapterId} launch configuration: field=model actual=${JSON.stringify(config.model ?? "")}. ${agentModelOptionsSummary(catalog)} `
226
+ + `Inspect current options: yui config agent capabilities ${catalog.agentId}.`);
190
227
  }
191
228
  if (config.effort !== undefined
192
229
  && model.efforts.length > 0
193
230
  && !model.efforts.some((effort) => effort.value === config.effort)) {
194
- throw new Error(`Unsupported ${catalog.adapterId} launch configuration: field=effort actual=${JSON.stringify(config.effort)} model=${JSON.stringify(model.value)} supported=${JSON.stringify(model.efforts.map(({ value }) => value))}.`);
231
+ throw new Error(`Unsupported ${catalog.adapterId} launch configuration: field=effort actual=${JSON.stringify(config.effort)} model=${JSON.stringify(model.value)} supported=${JSON.stringify(model.efforts.map(({ value }) => value))}. ${agentModelOptionsSummary(catalog)} `
232
+ + `Inspect current options: yui config agent capabilities ${catalog.agentId}.`);
195
233
  }
196
234
  }
197
235
  function field(key, choices, allowCustom) {
@@ -442,7 +480,7 @@ function catalogFailure(error) {
442
480
  code: code === "ETIMEDOUT" || candidate.name === "AbortError"
443
481
  ? "timeout"
444
482
  : code === "ENOENT" ? "missing-command" : "probe-failed",
445
- message: candidate.message || "Agent capability discovery failed."
483
+ message: redactAgentErrorText(candidate.message || "Agent capability discovery failed.")
446
484
  };
447
485
  }
448
486
  function record(value) {
@@ -33,7 +33,7 @@ export function createRoleSessionSet(owner, activeAgentId, now) {
33
33
  updatedAt: now.toISOString()
34
34
  };
35
35
  return owner.scope === "global"
36
- ? { ...base, schemaVersion: 5 }
36
+ ? { ...base, schemaVersion: 5, providerBinding: null }
37
37
  : {
38
38
  ...base,
39
39
  schemaVersion: 12,
@@ -486,13 +486,10 @@ export function validateRoleSessionSet(set) {
486
486
  }
487
487
  }
488
488
  }
489
- // A Global Role now carries the same optional Provider Runtime Binding shape
490
- // as a Task Role (decision-3 §6/§9). It stays absent on every legacy set;
491
- // when present, it is the exact native control evidence a Global steer or
492
- // interrupt targets, validated identically to the Task branch. A fabricated
493
- // Task binding is never accepted here, and its presence never upgrades the
494
- // schemaVersion these raw-JSON sets are read at.
495
- if (Object.hasOwn(globalSet, "providerBinding") && globalSet.providerBinding != null) {
489
+ if (!Object.hasOwn(globalSet, "providerBinding")) {
490
+ throw new Error("Global Role session set must contain its Provider Runtime Binding.");
491
+ }
492
+ if (globalSet.providerBinding !== null) {
496
493
  const providerBinding = validateProviderRuntimeBinding(globalSet.providerBinding);
497
494
  const conversationId = currentProviderConversation(providerBinding).conversationId;
498
495
  const session = [...Object.values(globalSet.sessions), ...Object.values(globalSet.history ?? {})]
@@ -1,30 +1,30 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import { spawnSync } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
3
  import { mkdirSync, realpathSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { isDeepStrictEqual } from "node:util";
7
- import { assertExecutionEnvironmentCurrent } from "../runtime/executionEnvironment.js";
8
7
  import { runPurposeAdmitsTaskState } from "../agentRun/agentRun.js";
8
+ import { assertExecutionEnvironmentCurrent } from "../runtime/executionEnvironment.js";
9
9
  import { taskOwnsManagedWorkspace } from "../task/task.js";
10
10
  import { configuredAgentToDefinition, resolveAgentEnvironment } from "../agent/agent.js";
11
11
  import { NATIVE_AGENT_ENVIRONMENT_NAMES, nativeAgentEnvironmentNames, operationalAgentEnvironment, selectEnvironment } from "../agent/launchEnvironment.js";
12
- import { activeRoleAgentBinding } from "../role/role.js";
13
- import { planningRuntimeCwd } from "../storage/homeLayout.js";
14
12
  import { compileRoleSessionContext, roleSessionKind } from "../context/roleSessionContext.js";
15
13
  import { materializeSessionBootstrap } from "../context/sessionBootstrapManifest.js";
16
- import { resolveAgentAdapter } from "./agentAdapter.js";
17
- import { resolveTaskRoleSessionTitle } from "../runtime/sessionTitle.js";
18
- import { classifyWorkspacePreflight, formatWorkspacePreflightError } from "./workspacePreflightClassification.js";
19
- import { activeLiveRoleAgentSession, taskRoleControlTarget } from "./agentExecutor.js";
20
- import { roleSessionMayContinue, effectiveRoleForLaunch, resolveEffectiveLaunch } from "./effectiveLaunch.js";
21
- import { parseTaskRuntimeIsolationDescriptor, taskRuntimeIsolationEnvironment } from "../runtime/taskRuntimeIsolation.js";
22
14
  import { ResourceRegistrar } from "../resources/resourceRegistrar.js";
23
- import { builtinAgentDriverRegistry, builtinDriverIdForAdapter } from "../runtime/builtinAgentDrivers.js";
15
+ import { activeRoleAgentBinding } from "../role/role.js";
24
16
  import { managedRuntimeAdmission } from "../runtime/agentDriver.js";
25
17
  import { builtinAgentEndpointImplementation, validateAgentEndpointImplementation } from "../runtime/agentEndpointIdentity.js";
18
+ import { builtinAgentDriverRegistry, builtinDriverIdForAdapter } from "../runtime/builtinAgentDrivers.js";
26
19
  import { assertProviderConversationReplaceable } from "../runtime/providerRuntimeIdentity.js";
20
+ import { resolveTaskRoleSessionTitle } from "../runtime/sessionTitle.js";
21
+ import { parseTaskRuntimeIsolationDescriptor, taskRuntimeIsolationEnvironment } from "../runtime/taskRuntimeIsolation.js";
22
+ import { planningRuntimeCwd } from "../storage/homeLayout.js";
23
+ import { resolveAgentAdapter } from "./agentAdapter.js";
24
+ import { activeLiveRoleAgentSession, taskRoleControlTarget } from "./agentExecutor.js";
27
25
  import { assertCodexLaunchOverridesAvailable, inspectCodexLaunchConfig } from "./codexConfigConflict.js";
26
+ import { effectiveRoleForLaunch, resolveEffectiveLaunch, roleSessionMayContinue } from "./effectiveLaunch.js";
27
+ import { classifyWorkspacePreflight, formatWorkspacePreflightError } from "./workspacePreflightClassification.js";
28
28
  /** Builds managed native Agent launches from the authoritative Task records. */
29
29
  export class FileRoleLaunchPlanner {
30
30
  home;
@@ -791,9 +791,6 @@ const inspectWorkspacePhysicalState = (entry) => {
791
791
  recordedBaseIsAncestor: ancestorResult.status === 0
792
792
  };
793
793
  };
794
- function shellQuote(value) {
795
- return `'${value.replaceAll("'", "'\"'\"'")}'`;
796
- }
797
794
  function patchEnvironment(current, names, values) {
798
795
  const next = { ...current };
799
796
  for (const name of names)
@@ -830,45 +827,6 @@ function codexShellEnvironmentConfig(environment) {
830
827
  .map(([name, value]) => `${JSON.stringify(name)}=${JSON.stringify(value)}`);
831
828
  return `shell_environment_policy.set={${entries.join(",")}}`;
832
829
  }
833
- /**
834
- * Codex 0.145 discovers lifecycle hooks from its effective config. Keep Yui's
835
- * two handlers invocation-local: this avoids mutating CODEX_HOME or the Task
836
- * workspace, while the exact launch environment supplies the durable AgentRun fence.
837
- */
838
- function codexLifecycleHooksConfig(cliPath) {
839
- const command = [
840
- shellQuote(canonicalPath(process.execPath)),
841
- shellQuote(canonicalPath(cliPath)),
842
- "internal",
843
- "runtime-hook"
844
- ].join(" ");
845
- const handler = `{hooks=[{type="command",command=${JSON.stringify(command)}}]}`;
846
- return `hooks={`
847
- + `SessionStart=[${handler}],`
848
- + `UserPromptSubmit=[${handler}],`
849
- + `PreToolUse=[${handler}],`
850
- + `PermissionRequest=[${handler}],`
851
- + `PostToolUse=[${handler}],`
852
- + `SubagentStart=[${handler}],`
853
- + `SubagentStop=[${handler}],`
854
- + `Stop=[${handler}]`
855
- + `}`;
856
- }
857
- function addCodexLifecycleHooks(args, mode, cliPath) {
858
- // Session flags are Yui-owned and exact to this launch. Hook trust bypass is
859
- // still explicit because these handlers execute a local command.
860
- const managed = [
861
- "--enable", "hooks",
862
- "--config", codexLifecycleHooksConfig(cliPath),
863
- "--dangerously-bypass-hook-trust"
864
- ];
865
- if (mode === "new")
866
- return [...args, ...managed];
867
- if (args.length < 2 || args.at(-2) !== "resume") {
868
- throw new Error("Codex resume launch shape is invalid.");
869
- }
870
- return [...args.slice(0, -2), ...managed, ...args.slice(-2)];
871
- }
872
830
  function withCodexThreadEnvironment(launch) {
873
831
  const control = launch.providerControl;
874
832
  if (control?.adapterId !== "codex" || control.codexThread === undefined)
@@ -0,0 +1,64 @@
1
+ import { usageError, taskNotFound, roleNotFound, agentNotFound } from "../errors/cliError.js";
2
+ import { projectAgentCapabilityConfig } from "./agentCapabilityConfig.js";
3
+ import { activeRoleAgentBinding } from "../role/role.js";
4
+ import { configuredAgentFingerprint, readAgentFailureContext } from "../runtime/agentFailureContext.js";
5
+ import { resolveManagedTaskReader } from "../runtime/managedCaller.js";
6
+ import { assertContextRecordReadable } from "../context/taskContext.js";
7
+ /** Resolve authority and scope before any native metadata process is started. */
8
+ export function resolveTaskAgentCapabilities(query, store, environment = {}) {
9
+ const { taskId, roleName, errorId } = query;
10
+ const reader = resolveManagedTaskReader(store, environment);
11
+ if (reader !== undefined && (reader.taskId !== taskId
12
+ || reader.roleName !== "leader" && reader.roleName !== roleName)) {
13
+ throw usageError("Agent capability query is outside the caller's Task/Role.");
14
+ }
15
+ const task = store.getTask(taskId);
16
+ if (task === null)
17
+ throw taskNotFound(taskId);
18
+ let agentId, cwd, config;
19
+ let expectedFingerprint;
20
+ let expectedComponent;
21
+ if (errorId !== undefined) {
22
+ assertContextRecordReadable(store, taskId, "task-event", errorId, environment);
23
+ const event = store.listEventsByType(taskId, ["runtime.agent-error"]).find(event => event.id === errorId);
24
+ if (event === undefined || event.payload.roleName !== roleName) {
25
+ throw usageError("Agent failure is not owned by this Task/Role.");
26
+ }
27
+ const captured = readAgentFailureContext(event.payload.capabilityContext);
28
+ if (captured.status === "unavailable") {
29
+ throw usageError(`${captured.reason} No historical configuration was inferred. `
30
+ + `Inspect current desired configuration explicitly with yui task role capabilities ${taskId} ${roleName} --refresh.`);
31
+ }
32
+ ({ agentId, cwd, config } = captured);
33
+ expectedFingerprint = captured.agentFingerprint;
34
+ }
35
+ else {
36
+ const role = store.getRole(taskId, roleName);
37
+ if (role === null)
38
+ throw roleNotFound(roleName);
39
+ const binding = activeRoleAgentBinding(role);
40
+ agentId = binding.agentId;
41
+ expectedComponent = binding.component;
42
+ cwd = role.workspace;
43
+ config = projectAgentCapabilityConfig(binding.config);
44
+ }
45
+ const agent = store.getConfiguredAgent(agentId);
46
+ if (agent === null)
47
+ throw agentNotFound(agentId);
48
+ if (agent.adapterId !== config.adapterId
49
+ || expectedComponent !== undefined && agent.component !== expectedComponent) {
50
+ throw usageError("The Role capability binding no longer matches the configured Agent implementation.");
51
+ }
52
+ if (expectedFingerprint !== undefined && configuredAgentFingerprint(agent) !== expectedFingerprint) {
53
+ throw usageError("The configured Agent command or environment bindings changed since this failure. "
54
+ + "The historical capability query was not run; inspect current desired configuration explicitly.");
55
+ }
56
+ return {
57
+ input: { agent, cwd, config,
58
+ refresh: query.refresh === true },
59
+ context: { taskId, roleName, selection: errorId === undefined ? "desired-role" : "failed-launch",
60
+ ...(errorId === undefined ? {} : { errorId }), agentId: agent.id,
61
+ ...(config.model === undefined ? {} : { requestedModel: config.model }),
62
+ cwd }
63
+ };
64
+ }
@@ -33,78 +33,10 @@ export function workItemDeliverySettled(delivery, integrations) {
33
33
  && attempt.source.startCommit === delivery.startCommit
34
34
  && attempt.source.resultCommit === delivery.resultCommit));
35
35
  }
36
- /**
37
- * Delivery obligations follow the Candidate that currently governs each
38
- * WorkItem. Older Candidates and their ChangeSets remain audit evidence, but
39
- * they do not keep a Task open after a replacement Candidate is accepted.
40
- */
41
- export function governingChangeSets(workItems, changeSets) {
42
- const selected = new Map();
43
- for (const item of workItems) {
44
- const candidate = governingWorkItemCandidate(item);
45
- if (candidate === undefined)
46
- continue;
47
- for (const changeSet of changeSets) {
48
- if (changeSet.workItemId !== item.id)
49
- continue;
50
- const expectedHead = candidateProjectHead(candidate, changeSet.projectId);
51
- if (expectedHead !== undefined && changeSet.headCommit !== expectedHead)
52
- continue;
53
- const key = `${item.id}\0${changeSet.projectId}`;
54
- const current = selected.get(key);
55
- if (current === undefined || compareChangeSets(current, changeSet) < 0) {
56
- selected.set(key, changeSet);
57
- }
58
- }
59
- }
60
- return [...selected.values()].sort(compareChangeSets);
61
- }
62
- export function changeSetDeliverySettled(changeSet, integrations, queueEntries = []) {
63
- if (integrations.some((attempt) => (attempt.status === "committed"
64
- && attempt.projectId === changeSet.projectId
65
- && attempt.source.kind === "work-item"
66
- && attempt.source.workItemId === changeSet.workItemId
67
- && attempt.source.resultCommit === changeSet.headCommit)))
68
- return true;
69
- const latestQueueEntry = queueEntries
70
- .filter((entry) => entry.changeSetId === changeSet.id)
71
- .sort(compareQueueEntries)
72
- .at(-1);
73
- return latestQueueEntry?.status === "superseded";
74
- }
75
- export function latestGoverningQueueEntries(changeSets, queueEntries) {
76
- const governingIds = new Set(changeSets.map(({ id }) => id));
77
- const latest = new Map();
78
- for (const entry of queueEntries) {
79
- if (!governingIds.has(entry.changeSetId))
80
- continue;
81
- const current = latest.get(entry.changeSetId);
82
- if (current === undefined || compareQueueEntries(current, entry) < 0) {
83
- latest.set(entry.changeSetId, entry);
84
- }
85
- }
86
- return [...latest.values()].sort(compareQueueEntries);
87
- }
88
- /**
89
- * Historical blocked attempts are audit evidence once every ChangeSet they
90
- * reference has been replaced by a newer governing Candidate. Attempts that
91
- * may still be writing remain blockers regardless of Candidate history.
92
- */
36
+ /** Unsettled Integration attempts remain blockers independently of Agent ordering. */
93
37
  export function integrationAttemptRequiresSettlement(attempt) {
94
38
  return attempt.status === "running"
95
39
  || attempt.status === "validating"
96
40
  || attempt.status === "blocked"
97
41
  || attempt.status === "conflicted";
98
42
  }
99
- function candidateProjectHead(candidate, projectId) {
100
- return candidate.gitSnapshot?.projects.find((project) => project.projectId === projectId)?.commit
101
- ?? candidate.taskMainSnapshot?.projects.find((project) => project.projectId === projectId)?.headCommit;
102
- }
103
- function compareChangeSets(left, right) {
104
- return left.createdAt.localeCompare(right.createdAt)
105
- || left.id.localeCompare(right.id, undefined, { numeric: true });
106
- }
107
- function compareQueueEntries(left, right) {
108
- return left.updatedAt.localeCompare(right.updatedAt)
109
- || left.id.localeCompare(right.id, undefined, { numeric: true });
110
- }