@zq-silk/yui 0.6.13 → 0.6.14

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 (90) hide show
  1. package/README.md +34 -5
  2. package/dist/cli/commandCatalog.js +173 -57
  3. package/dist/cli/helpRenderer.js +3 -1
  4. package/dist/cli.js +99 -11
  5. package/dist/commands/configCommands.js +521 -171
  6. package/dist/commands/deliveryGuardPreflight.js +2 -2
  7. package/dist/commands/executionAuditCommands.js +56 -3
  8. package/dist/commands/projectCommands.js +504 -2
  9. package/dist/commands/releaseCommands.js +0 -1
  10. package/dist/commands/taskActor.js +17 -0
  11. package/dist/commands/taskBaseCommands.js +29 -0
  12. package/dist/commands/taskCommands.js +577 -126
  13. package/dist/commands/taskContextCommand.js +36 -2
  14. package/dist/commands/taskNextActionCommand.js +48 -3
  15. package/dist/commands/taskPublicationCommands.js +319 -0
  16. package/dist/commands/taskRoleRuntimeStatus.js +83 -59
  17. package/dist/commands/telemetryCommands.js +14 -13
  18. package/dist/config/yuiConfig.js +161 -8
  19. package/dist/context/sessionContextBudget.js +68 -0
  20. package/dist/context/wakeNotification.js +65 -0
  21. package/dist/controller/clientRuntime.js +2 -1
  22. package/dist/controller/ephemeralResourceReaper.js +2 -1
  23. package/dist/controller/fileSchedulerStoreAdapter.js +183 -16
  24. package/dist/controller/jobSupervisor.js +5 -4
  25. package/dist/controller/resourceCleanupLinux.js +6 -6
  26. package/dist/controller/resourceInventoryLinux.js +3 -3
  27. package/dist/controller/runtime.js +88 -10
  28. package/dist/controller/updateReconciliation.js +4 -3
  29. package/dist/doctor/doctor.js +26 -7
  30. package/dist/executor/agentConfigurationCatalog.js +18 -0
  31. package/dist/executor/fileRoleLaunchPlanner.js +3 -3
  32. package/dist/lifecycle/contextBudgetRollover.js +81 -0
  33. package/dist/lifecycle/exactRunTerminalization.js +11 -1
  34. package/dist/lifecycle/providerErrorClass.js +33 -12
  35. package/dist/observability/executionAudit.js +214 -6
  36. package/dist/output/table.js +18 -0
  37. package/dist/repository/gitWorkspace.js +92 -0
  38. package/dist/repository/project.js +218 -4
  39. package/dist/repository/taskBaseFreshness.js +318 -0
  40. package/dist/repository/taskWorkspacePreparer.js +16 -2
  41. package/dist/review/deltaRecheck.js +232 -0
  42. package/dist/review/reviewConfig.js +31 -0
  43. package/dist/review/reviewFindingLedger.js +5 -1
  44. package/dist/review/reviewRound.js +156 -1
  45. package/dist/run/providerRetry.js +21 -3
  46. package/dist/run/providerRetryConfig.js +13 -60
  47. package/dist/run/recoveryProjection.js +199 -0
  48. package/dist/runtime/builtinAgentDrivers.js +3 -0
  49. package/dist/runtime/builtinTranscriptUsage.js +76 -32
  50. package/dist/runtime/continuationManager.js +17 -0
  51. package/dist/runtime/index.js +2 -0
  52. package/dist/runtime/launchDiagnostics.js +154 -0
  53. package/dist/runtime/lifecycleReservation.js +13 -0
  54. package/dist/runtime/providerContinuation.js +38 -0
  55. package/dist/runtime/providerContinuationReconciliationService.js +1 -0
  56. package/dist/runtime/providerErrorCodes.js +278 -0
  57. package/dist/runtime/runtimeHealthPolicy.js +20 -0
  58. package/dist/runtime/runtimeObservation.js +1 -0
  59. package/dist/runtime/runtimeProjection.js +115 -23
  60. package/dist/runtime/tmuxAdapters.js +242 -48
  61. package/dist/scheduler/activeRoleRunDelivery.js +139 -3
  62. package/dist/scheduler/activeTaskProgress.js +4 -3
  63. package/dist/scheduler/leaderWakeupProcessor.js +105 -15
  64. package/dist/scheduler/roleRunLiveness.js +2 -1
  65. package/dist/scheduler/roleRunStall.js +3 -2
  66. package/dist/scheduler/taskWake.js +72 -0
  67. package/dist/scheduler/wakeReason.js +64 -0
  68. package/dist/scheduler/wakeupQueue.js +2 -1
  69. package/dist/setup/setupCommand.js +1 -1
  70. package/dist/storage/migration/productionRegistry.js +325 -1
  71. package/dist/storage/sqliteSchema.js +61 -2
  72. package/dist/storage/sqliteStore.js +129 -2
  73. package/dist/storage/storeRpc.js +1 -0
  74. package/dist/storage/taskStore.js +262 -5
  75. package/dist/storage/upgrade/recordVersions.js +6 -1
  76. package/dist/storage/upgrade/sqliteStateMigration.js +22 -2
  77. package/dist/task/completionReadiness.js +282 -0
  78. package/dist/task/publicationReference.js +123 -0
  79. package/dist/task/taskRecordReference.js +3 -1
  80. package/dist/telemetry/telemetryConfig.js +23 -18
  81. package/dist/telemetry/telemetryWiring.js +8 -8
  82. package/dist/tmux/tmuxManager.js +50 -9
  83. package/dist/web/assets/client/i18n.js +4 -0
  84. package/dist/web/assets/client/view.js +18 -0
  85. package/dist/web/webSnapshot.js +100 -10
  86. package/i18n/README.zh-CN.md +5 -5
  87. package/package.json +1 -1
  88. package/skills/yui-leader/SKILL.md +49 -10
  89. package/skills/yui-operator/SKILL.md +13 -3
  90. package/skills/yui-worker/SKILL.md +8 -0
package/dist/cli.js CHANGED
@@ -16,6 +16,7 @@ import { resolveOperatorWizardArguments } from "./cli/operatorWizard.js";
16
16
  import { runUpdateCommand } from "./cli/updateCommand.js";
17
17
  import { runUpgradeCommand } from "./cli/upgradeCommand.js";
18
18
  import { formatTimestamp } from "./output/timePresentation.js";
19
+ import { resolveTmuxBin } from "./config/yuiConfig.js";
19
20
  import { renderAgentConfigurationCatalog } from "./output/agentConfigurationPresentation.js";
20
21
  import { nativeAgentEnvironmentNames } from "./agent/launchEnvironment.js";
21
22
  import { runAgentCommand } from "./commands/agentCommands.js";
@@ -45,6 +46,8 @@ import { createReleaseWorkflowPorts } from "./release/releaseWorkflowPorts.js";
45
46
  import { readRuntimeIdentity } from "./release/runtimeRelease.js";
46
47
  import { renderReleaseActivateResult, renderReleaseInstallResult, renderReleaseList, runReleaseActivate, runReleaseInstall, runReleaseList } from "./commands/releaseCommands.js";
47
48
  import { reconcileTaskRemoteBaselines } from "./commands/taskCompletionGate.js";
49
+ import { runTaskBaseStatusCommand } from "./commands/taskBaseCommands.js";
50
+ import { assertTaskBaseFreshnessForCompletion, inspectTaskBaseFreshness } from "./repository/taskBaseFreshness.js";
48
51
  import { FileCompletionManager, resolveCliIdentity } from "./completion/fileCompletionManager.js";
49
52
  import { assertFileTaskControllerStorageCompatible, ensureFileTaskController, FileTaskWorkflowRuntime, refreshRunningFileTaskControllerConfiguration, refreshRunningFileTaskControllerEnvironment, restartFileTaskController, stopFileTaskController } from "./controller/clientRuntime.js";
50
53
  import { callController, ControllerClientError } from "./core/controllerClient.js";
@@ -77,6 +80,9 @@ import { YUI_VERSION, yuiVersionIdentity } from "./version.js";
77
80
  import { YUI_CONTROL_PLANE_DESCRIPTOR, YUI_TASK_RUNTIME_DESCRIPTOR, assertExactControlPlanePreflight, assertExactTaskRuntimeEnvironment, assertExactTaskRuntimeState, exactControlPlaneDigest, extractExactControlArgument, parseExactControlPlaneDescriptor } from "./runtime/exactControlPlane.js";
78
81
  import { builtinAgentDriverRegistry } from "./runtime/builtinAgentDrivers.js";
79
82
  import { createTaskFinalReviewContract, extractTaskFinalReviewRequest } from "./review/taskFinalReviewContract.js";
83
+ import { assessDeltaRecheck } from "./review/deltaRecheck.js";
84
+ import { deltaRecheckEnabled } from "./review/reviewConfig.js";
85
+ import { NodeGitWorkspace } from "./repository/gitWorkspace.js";
80
86
  import { currentWorkItemExecutionGroup, workItemExecutionGroupById } from "./workItem/workItem.js";
81
87
  const VERSION = YUI_VERSION;
82
88
  const exactControlInvocation = extractExactControlArgument(process.argv.slice(2));
@@ -283,7 +289,7 @@ export async function main() {
283
289
  }
284
290
  const options = parseSessionReconcileOptions(args.slice(2));
285
291
  const store = openCompatibleFileTaskStore(home);
286
- const tmux = new TmuxManager(process.env.YUI_TMUX_BIN ?? "tmux", new NodeCommandExecutor(), { yuiHome: home });
292
+ const tmux = new TmuxManager(resolveTmuxBin(store.getConfig().tmuxBin), new NodeCommandExecutor(), { yuiHome: home });
287
293
  const reconciliation = new SessionOwnerReconciliation({
288
294
  home,
289
295
  store,
@@ -488,12 +494,12 @@ export async function main() {
488
494
  }
489
495
  await preflightAgentConfigurationMutation(resolved, store, catalogs);
490
496
  const executor = new NodeCommandExecutor();
491
- const tmux = new TmuxManager(process.env.YUI_TMUX_BIN ?? "tmux", executor, {
497
+ const tmux = new TmuxManager(resolveTmuxBin(store.getConfig().tmuxBin), executor, {
492
498
  yuiHome: home,
493
499
  terminalInput: process.stdin,
494
500
  onWarning: (message) => process.stderr.write(`Warning: ${message}\n`)
495
501
  });
496
- const schedulerStore = new FileSchedulerStoreAdapter(store, openSchedulerTelemetry(home, process.env));
502
+ const schedulerStore = new FileSchedulerStoreAdapter(store, openSchedulerTelemetry(home, store.getConfig()));
497
503
  const planner = new FileRoleLaunchPlanner(home, store, { environment: process.env });
498
504
  const workspacePreparer = new FileTaskWorkspacePreparer(home, store);
499
505
  const runtime = new FileTaskWorkflowRuntime(home, store, schedulerStore, planner, tmux, workspacePreparer, {
@@ -510,7 +516,7 @@ export async function main() {
510
516
  const options = parseWebCommandOptions(resolved.slice(1));
511
517
  const terminal = new TmuxWebTerminalService({
512
518
  yuiHome: home,
513
- tmuxBin: process.env.YUI_TMUX_BIN ?? "tmux",
519
+ tmuxBin: resolveTmuxBin(store.getConfig().tmuxBin),
514
520
  tmux,
515
521
  prepareGlobalRole: (roleName) => runtime.prepareGlobalRoleEnter(roleName),
516
522
  environment: process.env,
@@ -591,18 +597,18 @@ export async function main() {
591
597
  }
592
598
  if (resolved[0] === "config") {
593
599
  const configArgs = resolved.slice(1);
594
- const output = runConfigCommand(configArgs, store);
600
+ const result = runConfigCommand(configArgs, store);
595
601
  if (configArgs[0] === "set"
596
- && configArgs[1] === "--reconciliation-interval-seconds") {
602
+ && configArgs[1] === "reconciliation-interval-seconds") {
597
603
  const refresh = await refreshRunningFileTaskControllerConfiguration(home, { environment: process.env });
598
- emit(withControllerRefreshWarning(output, refresh, "Controller configuration"));
604
+ emit(withControllerRefreshWarning(result.output, refresh, "Controller configuration"));
599
605
  return;
600
606
  }
601
- emit(output);
607
+ emit(result.output, false, result.data);
602
608
  return;
603
609
  }
604
610
  if (resolved[0] === "project") {
605
- const result = await runProjectCommand(resolved.slice(1), store);
611
+ const result = await runProjectCommand(resolved.slice(1), store, { environment: process.env });
606
612
  emit(result.output, false, result.data);
607
613
  return;
608
614
  }
@@ -915,9 +921,15 @@ export async function main() {
915
921
  }
916
922
  }
917
923
  let completionSummary;
924
+ if (resolved[1] === "base" && resolved[2] === "status") {
925
+ const result = await runTaskBaseStatusCommand(resolved.slice(3), store);
926
+ emit(result.output, false, result.data);
927
+ return;
928
+ }
918
929
  if (resolved[1] === "complete" && resolved[2] !== undefined) {
919
930
  const completionRequest = parseTaskCompletionRequest(resolved.slice(2));
920
931
  completionSummary = completionRequest.summary;
932
+ const refreshRemote = resolved.includes("--refresh-remote");
921
933
  const completion = preflightTaskCompletion(resolved[2], store, {
922
934
  environment: process.env,
923
935
  ...(taskFinalReviewContract === undefined
@@ -925,7 +937,17 @@ export async function main() {
925
937
  : { taskFinalReviewContract })
926
938
  });
927
939
  if (!completion.completed && !completion.activeTaskReview) {
928
- await reconcileTaskRemoteBaselines(resolved[2], store, home, { environment: process.env, jobPort: createControllerIntegrationJobPort(home, { environment: process.env, store }) });
940
+ const freshness = await inspectTaskBaseFreshness(resolved[2], store, {
941
+ refresh: refreshRemote
942
+ });
943
+ for (const warning of assertTaskBaseFreshnessForCompletion(freshness)) {
944
+ process.stderr.write(`Warning: ${warning}\n`);
945
+ }
946
+ // Keep completion offline by default. An explicit refresh is the only
947
+ // path that may fetch and reconcile a moved remote baseline.
948
+ if (refreshRemote) {
949
+ await reconcileTaskRemoteBaselines(resolved[2], store, home, { environment: process.env, jobPort: createControllerIntegrationJobPort(home, { environment: process.env, store }) });
950
+ }
929
951
  }
930
952
  }
931
953
  let candidateMaterialization;
@@ -943,6 +965,7 @@ export async function main() {
943
965
  : candidateMaterialization.snapshot;
944
966
  const directTaskMainSnapshot = await directTaskMainSnapshotForTaskCommand(resolved, store, workspacePreparer, process.env, taskFinalReviewContract);
945
967
  const actualTaskReviewCandidate = await actualTaskReviewCandidateForTaskCommand(resolved, store, workspacePreparer, process.env, taskFinalReviewContract);
968
+ const deltaRecheckPreflight = await deltaRecheckPreflightForTaskCommand(resolved.slice(1), store, actualTaskReviewCandidate);
946
969
  const reviewWorkspaceResult = await reviewWorkspaceResultForTaskCommand(resolved, store, workspacePreparer, process.env);
947
970
  const executionLaneGitSnapshot = await executionLaneGitSnapshotForTaskCommand(resolved, store, workspacePreparer, process.env);
948
971
  const laneSnapshotPreflight = executionLaneGitSnapshot === undefined
@@ -967,6 +990,9 @@ export async function main() {
967
990
  ...(actualTaskReviewCandidate === undefined
968
991
  ? {}
969
992
  : { actualTaskReviewCandidate }),
993
+ ...(deltaRecheckPreflight === undefined
994
+ ? {}
995
+ : { deltaRecheckPreflight }),
970
996
  ...(reviewWorkspaceResult === undefined ? {} : { reviewWorkspaceResult }),
971
997
  ...(laneSnapshotPreflight === undefined ? {} : { executionLaneGitSnapshot: laneSnapshotPreflight }),
972
998
  ...(taskRetirementProof === undefined ? {} : { taskRetirementProof })
@@ -1019,7 +1045,11 @@ export async function main() {
1019
1045
  ...(freshTaskCandidate === undefined
1020
1046
  ? {}
1021
1047
  : { actualTaskReviewCandidate: freshTaskCandidate }),
1022
- ...(executionLaneWorkspaces === undefined ? {} : { executionLaneWorkspaces })
1048
+ ...(executionLaneWorkspaces === undefined ? {} : { executionLaneWorkspaces }),
1049
+ ...(storedRound?.deltaRecheck === undefined
1050
+ || deltaRecheckPreflight === undefined
1051
+ ? {}
1052
+ : { deltaRecheckDiff: deltaRecheckPreflight.diffByProject })
1023
1053
  });
1024
1054
  reviewOutput = `Review queued as ${requestedRound.id} (${run.id})\n`;
1025
1055
  reviewData = {
@@ -1628,6 +1658,64 @@ async function snapshotActualTaskReviewCandidate(taskId, store, preparer) {
1628
1658
  + `${error instanceof Error ? error.message : String(error)}`);
1629
1659
  }
1630
1660
  }
1661
+ /**
1662
+ * Issue 07: computes the delta-recheck assessment for `task review request
1663
+ * --delta-recheck`. Runs only for that exact command; every other command
1664
+ * returns undefined. The assessment's deterministic gates (contiguous base,
1665
+ * attempt thresholds, evidence-file overlap) fail closed here; the Reviewer
1666
+ * still owns the semantic equivalence decision.
1667
+ */
1668
+ async function deltaRecheckPreflightForTaskCommand(args, store, actualTaskReviewCandidate) {
1669
+ if (args[0] !== "task" || args[1] !== "review" || args[2] !== "request") {
1670
+ return undefined;
1671
+ }
1672
+ if (!args.includes("--delta-recheck"))
1673
+ return undefined;
1674
+ const taskId = args[3];
1675
+ if (taskId === undefined)
1676
+ return undefined;
1677
+ const task = store.getTask(taskId);
1678
+ if (task === null || task.status !== "active")
1679
+ return undefined;
1680
+ const config = store.getReviewConfig();
1681
+ if (!deltaRecheckEnabled(config)) {
1682
+ throw usageError("Delta-recheck is not enabled for this Project's review policy. "
1683
+ + "Set `yui config set review --role <role> --trigger final --delta-recheck enabled` "
1684
+ + "or request a full Review.");
1685
+ }
1686
+ const reviewConfig = config;
1687
+ if (actualTaskReviewCandidate === undefined)
1688
+ return undefined;
1689
+ // The previous Round is the latest completed Task-final Round that accepted
1690
+ // a head (a full Review or an equivalent-and-accepted delta). A
1691
+ // non-accepted delta cannot be the base for a new delta.
1692
+ const previous = [...store.listReviewRounds(task.id)]
1693
+ .filter((round) => ((round.scope ?? "work-item") === "task"
1694
+ && round.status === "completed"
1695
+ && (round.deltaRecheck === undefined
1696
+ || round.deltaRecheck.disposition === "equivalent-and-accepted")))
1697
+ .sort((left, right) => left.id.localeCompare(right.id, undefined, { numeric: true }))
1698
+ .at(-1);
1699
+ if (previous === undefined) {
1700
+ throw usageError("Delta-recheck requires a previous completed Task-final Review that accepted a head.");
1701
+ }
1702
+ const projectId = actualTaskReviewCandidate.projects[0].projectId;
1703
+ const project = store.getProject(projectId);
1704
+ if (project === null) {
1705
+ throw usageError(`Delta-recheck Project not found: ${projectId}.`);
1706
+ }
1707
+ const assessment = await assessDeltaRecheck({
1708
+ repositoryPath: project.path,
1709
+ previousRound: previous,
1710
+ candidate: actualTaskReviewCandidate,
1711
+ git: new NodeGitWorkspace(),
1712
+ config: reviewConfig
1713
+ });
1714
+ if (assessment.kind === "ineligible") {
1715
+ throw usageError(`Delta-recheck is not allowed: ${assessment.reason} Request a full Review instead.`);
1716
+ }
1717
+ return assessment.preflight;
1718
+ }
1631
1719
  async function reviewWorkspaceResultForTaskCommand(args, store, preparer, environment) {
1632
1720
  if (args[0] !== "task" || args[1] !== "run" || args[2] !== "yield"
1633
1721
  || args[3] === undefined)