@zq-silk/yui 0.13.7 → 0.13.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/ARCHITECTURE.md +40 -4
  2. package/README.md +23 -4
  3. package/dist/cli/commandCatalog.js +21 -2
  4. package/dist/cli/updatePorts.js +4 -4
  5. package/dist/cli.js +43 -14
  6. package/dist/commands/agentCommands.js +1 -1
  7. package/dist/commands/configCommands.js +1 -86
  8. package/dist/commands/executionAuditCommands.js +17 -16
  9. package/dist/commands/globalRoleCommands.js +4 -4
  10. package/dist/commands/sessionCommands.js +2 -6
  11. package/dist/commands/taskActor.js +1 -2
  12. package/dist/commands/taskCommands.js +93 -21
  13. package/dist/commands/taskContextCommand.js +1 -1
  14. package/dist/commands/taskExecutionCommands.js +0 -5
  15. package/dist/commands/taskOverviewCommand.js +5 -1
  16. package/dist/commands/taskRoleRuntimeStatus.js +3 -16
  17. package/dist/config/configCatalog.js +1 -6
  18. package/dist/config/yuiConfig.js +0 -79
  19. package/dist/context/sessionBootstrapManifest.js +26 -23
  20. package/dist/controller/clientRuntime.js +40 -3
  21. package/dist/controller/controller.js +29 -54
  22. package/dist/controller/fileSchedulerStoreAdapter.js +372 -1117
  23. package/dist/controller/runtime.js +12 -5
  24. package/dist/controller/runtimeHookRunFence.js +3 -9
  25. package/dist/controller/runtimeLaunchCoordinator.js +44 -67
  26. package/dist/controller/structuredProviderObservation.js +18 -5
  27. package/dist/coordination/workMailbox.js +4 -4
  28. package/dist/execution/executionHealth.js +1 -1
  29. package/dist/executor/agentExecutor.js +103 -93
  30. package/dist/executor/executorRegistry.js +8 -20
  31. package/dist/executor/fileRoleLaunchPlanner.js +26 -93
  32. package/dist/executor/turnCompletion.js +5 -5
  33. package/dist/lifecycle/exactRunTerminalization.js +2 -4
  34. package/dist/observability/executionAudit.js +40 -94
  35. package/dist/operator/operatorSessionHistory.js +7 -5
  36. package/dist/output/rolePresentation.js +0 -1
  37. package/dist/repository/taskWorkspacePreparer.js +0 -1
  38. package/dist/role/role.js +13 -21
  39. package/dist/run/agentRun.js +4 -54
  40. package/dist/runtime/agentDriver.js +2 -0
  41. package/dist/runtime/agentError.js +114 -0
  42. package/dist/runtime/agentHost.js +55 -82
  43. package/dist/runtime/builtinAgentDrivers.js +21 -9
  44. package/dist/runtime/builtinAgentErrorMappers.js +150 -0
  45. package/dist/runtime/exactControlPlane.js +6 -12
  46. package/dist/runtime/index.js +1 -2
  47. package/dist/runtime/launchBroker.js +5 -19
  48. package/dist/runtime/lifecycleReservation.js +20 -4
  49. package/dist/runtime/providerRuntimeIdentity.js +11 -19
  50. package/dist/runtime/runtimeBinding.js +0 -27
  51. package/dist/runtime/runtimeObservation.js +7 -16
  52. package/dist/runtime/runtimeSessionCandidate.js +3 -10
  53. package/dist/runtime/sessionLaunchRequest.js +1 -2
  54. package/dist/runtime/sessionReconciliation.js +2 -2
  55. package/dist/runtime/structuredProviderHost.js +44 -79
  56. package/dist/runtime/taskRuntimeIsolation.js +0 -7
  57. package/dist/runtime/tmuxAdapters.js +6 -49
  58. package/dist/scheduler/activeRoleRunDelivery.js +220 -178
  59. package/dist/scheduler/activeTaskProgress.js +1 -4
  60. package/dist/scheduler/leaderWakeupProcessor.js +123 -88
  61. package/dist/scheduler/roleRunLiveness.js +4 -1
  62. package/dist/scheduler/roleRunStall.js +10 -14
  63. package/dist/scheduler/wakeReason.js +4 -0
  64. package/dist/storage/migration/productionRegistry.js +475 -0
  65. package/dist/storage/sqliteSchema.js +54 -2
  66. package/dist/storage/sqliteStore.js +11 -44
  67. package/dist/storage/taskStore.js +8 -36
  68. package/dist/web/webSnapshot.js +3 -0
  69. package/i18n/README.zh-CN.md +11 -3
  70. package/package.json +1 -1
  71. package/skills/yui-leader/SKILL.md +30 -8
  72. package/skills/yui-operator/SKILL.md +14 -6
  73. package/skills/yui-runtime/SKILL.md +11 -8
  74. package/dist/lifecycle/providerErrorClass.js +0 -152
  75. package/dist/run/providerRetry.js +0 -226
  76. package/dist/run/providerRetryConfig.js +0 -27
  77. package/dist/runtime/providerErrorCodes.js +0 -278
  78. package/dist/runtime/providerRecoveryDecision.js +0 -55
@@ -57,6 +57,11 @@ export async function runControllerSchedulerPass(store, delivery, now, workspace
57
57
  // event-loop turn. Give already-written requests a poll boundary before the
58
58
  // next durable phase; later phases retain their existing CAS fences.
59
59
  await controlEventLoopTurn();
60
+ // A dormant Session may still name a Host that disappeared after its last
61
+ // Provider Turn. Detach that disposable Host before claiming the next Run,
62
+ // so retained Agent intent restores the same Session instead of first
63
+ // connecting to a known-dead control socket.
64
+ await reconcileDormantRuntimeOwners(store, delivery, lifecycleHost, scope, now, blockedTaskIds);
60
65
  const failedCleanupRoles = await processSelectedRoleRuntimeCleanups(store, delivery, lifecycleHost, scope, now, runtimeCleanupOutcomes, blockedTaskIds);
61
66
  const roleSelection = selectionWithoutFailedCleanupRoles(store, selection, failedCleanupRoles);
62
67
  const availableWakeupSelection = () => (leaderWakeFence?.() === true
@@ -79,7 +84,6 @@ export async function runControllerSchedulerPass(store, delivery, now, workspace
79
84
  // Issue 04: reopen due in-place Provider retries on their original
80
85
  // Sessions before delivery, so the existing delivery path re-pushes the
81
86
  // exact same input in this same pass.
82
- resolveDueProviderRetries(store, roleSelection, now);
83
87
  const activeRunDeliveries = await processActiveRoleRunDeliveries(store, delivery, now, roleSelection, inputDeliveryRecoveryCutoff);
84
88
  await controlEventLoopTurn();
85
89
  const unsettledRunRefs = new Set(activeRunDeliveries.flatMap((result) => (result.reason === "delivery-uncertain" || result.terminalFailure !== undefined
@@ -96,8 +100,6 @@ export async function runControllerSchedulerPass(store, delivery, now, workspace
96
100
  }
97
101
  const newlyIdleBusyTaskIds = new Set(initialWakeupResults.flatMap((result) => (result.reason === "busy"
98
102
  && store.getActiveAgentRun(result.taskId, "leader") === null
99
- && (typeof store.hasInFlightTurn !== "function"
100
- || !store.hasInFlightTurn(result.taskId, "leader"))
101
103
  ? [result.taskId]
102
104
  : [])));
103
105
  // Phase-one Leader Runs did not exist at the pass's liveness boundary.
@@ -255,10 +257,10 @@ function queueSelectedCompletedTaskRuntimeCleanups(store, selection, now) {
255
257
  }
256
258
  }
257
259
  function schedulerSessionRequiresRuntimeCleanup(session) {
258
- if (session === null || session.status === "stopped" || session.status === "broken") {
260
+ if (session === null || session.status === "ended") {
259
261
  return false;
260
262
  }
261
- return session.status === "running" || session.launchId !== undefined;
263
+ return session.launchId !== undefined;
262
264
  }
263
265
  async function processSelectedRoleRuntimeCleanups(store, delivery, lifecycleHost, scope, now, outcomes, blockedTaskIds = new Set()) {
264
266
  const targets = selectedRuntimeLifecycleTargets(store, scope, blockedTaskIds);
@@ -353,14 +355,18 @@ async function processSelectedRoleRuntimeCleanups(store, delivery, lifecycleHost
353
355
  return failedRoles;
354
356
  }
355
357
  async function reconcileDormantRuntimeOwners(store, delivery, lifecycleHost, scope, now, blockedTaskIds = new Set()) {
356
- if (scope.kind !== "full"
357
- || lifecycleHost === undefined
358
- || store.listDormantRuntimeOwners === undefined
359
- || store.markRuntimeOwnerStopped === undefined) {
358
+ if (lifecycleHost === undefined
359
+ || store.listDormantRuntimeOwners === undefined) {
360
360
  return;
361
361
  }
362
- const candidates = store.listDormantRuntimeOwners().filter((candidate) => (candidate.owner.scope !== "task"
363
- || !blockedTaskIds.has(candidate.owner.taskId)));
362
+ const selectedOwners = scope.kind === "full"
363
+ ? undefined
364
+ : new Set(selectedRuntimeLifecycleTargets(store, scope, blockedTaskIds)
365
+ .map((target) => runtimeOwnerIdentity(runtimeOwner(target))));
366
+ const candidates = store.listDormantRuntimeOwners().filter((candidate) => ((candidate.owner.scope !== "task"
367
+ || !blockedTaskIds.has(candidate.owner.taskId))
368
+ && (selectedOwners === undefined
369
+ || selectedOwners.has(runtimeOwnerIdentity(candidate.owner)))));
364
370
  if (candidates.length === 0)
365
371
  return;
366
372
  const owners = candidates.map((candidate) => candidate.owner);
@@ -393,17 +399,12 @@ async function reconcileDormantRuntimeOwners(store, delivery, lifecycleHost, sco
393
399
  for (const candidate of candidates) {
394
400
  if (byOwner.get(runtimeOwnerIdentity(candidate.owner))?.state
395
401
  === "stopped") {
396
- if (candidate.owner.scope === "task"
397
- && candidate.launchId !== undefined) {
402
+ if (candidate.launchId !== undefined) {
398
403
  // The exact launch-owned resources must settle through the durable
399
- // cleanup lane before its Session fact becomes stopped. The candidate
400
- // is passed back as the CAS fence so a concurrent Hook/launch cannot
401
- // redirect cleanup to a newer generation.
402
- store.enqueueRuntimeCleanup?.(candidate.owner, now, candidate);
403
- continue;
404
- }
405
- if (store.markRuntimeOwnerStopped(candidate, now)) {
406
- forgetPreparedRuntimeOwner(delivery, candidate.owner);
404
+ // cleanup lane before its Host fact is detached. The resumable Session
405
+ // remains active; the candidate is the CAS fence against a concurrent
406
+ // Hook or replacement launch.
407
+ store.enqueueRuntimeHostDetach?.(candidate.owner, now, candidate);
407
408
  }
408
409
  }
409
410
  }
@@ -421,20 +422,6 @@ function runtimeOwnerIdentity(owner) {
421
422
  ? `task\0${owner.taskId}\0${owner.roleName}`
422
423
  : `global\0${owner.roleName}`;
423
424
  }
424
- /**
425
- * Issue 04: reopens due in-place Provider retries on their original Native
426
- * Sessions before the active-run delivery pass, so the existing delivery
427
- * path re-pushes the exact same input in the same pass. A Run whose Session
428
- * is proven dead terminalizes with a replacement blocker instead.
429
- */
430
- function resolveDueProviderRetries(store, selection, now) {
431
- if (typeof store.resolveDueProviderRetries !== "function")
432
- return;
433
- const selectedTaskIds = selectedTaskIdsForBoundedPass(store, selection);
434
- if (selectedTaskIds?.size === 0)
435
- return;
436
- store.resolveDueProviderRetries(now, selectedTaskIds);
437
- }
438
425
  function selectedTaskIdsForBoundedPass(store, selection) {
439
426
  if (!selection.full) {
440
427
  if ((selection.blockedTaskIds?.size ?? 0) === 0)
@@ -1447,25 +1434,13 @@ export class FileTaskController {
1447
1434
  }
1448
1435
  if (this.#stopped)
1449
1436
  return;
1450
- const deadlines = [
1451
- ...this.store.listOpenInputRequests()
1452
- .flatMap((request) => request.policy.kind === "recommended"
1453
- ? [{
1454
- key: `task:${encodeURIComponent(request.taskId)}`,
1455
- at: Date.parse(request.policy.timeoutAt)
1456
- }]
1457
- : []),
1458
- // Issue 04 durable in-place retry timer: arm the Controller wake at the
1459
- // earliest dispatch/deadline wake. Scheduled retries re-push on their
1460
- // original Session; in-flight retries only wake at the episode deadline.
1461
- // The projection is durable, so a restart resumes the lineage.
1462
- ...(typeof this.store.listPendingProviderRetries === "function"
1463
- ? this.store.listPendingProviderRetries()
1464
- : []).map((retry) => ({
1465
- key: `role:${encodeURIComponent(retry.taskId)}/${encodeURIComponent(retry.roleName)}`,
1466
- at: Date.parse(retry.dueAt)
1467
- }))
1468
- ];
1437
+ const deadlines = this.store.listOpenInputRequests()
1438
+ .flatMap((request) => request.policy.kind === "recommended"
1439
+ ? [{
1440
+ key: `task:${encodeURIComponent(request.taskId)}`,
1441
+ at: Date.parse(request.policy.timeoutAt)
1442
+ }]
1443
+ : []);
1469
1444
  const nearest = nearestDeadlineBatch(deadlines);
1470
1445
  if (nearest === null)
1471
1446
  return;