@zq-silk/yui 0.13.9 → 0.14.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 (229) hide show
  1. package/ARCHITECTURE.md +69 -428
  2. package/README.md +108 -298
  3. package/dist/agent/managedRuntimeEnvironment.js +2 -2
  4. package/dist/cli/commandCatalog.js +39 -77
  5. package/dist/cli/interactionCandidates.js +4 -4
  6. package/dist/cli/interactionPolicy.js +7 -10
  7. package/dist/cli/invocationRouter.js +1 -1
  8. package/dist/cli/updateCommand.js +6 -27
  9. package/dist/cli/updateOrchestrator.js +63 -484
  10. package/dist/cli/updatePorts.js +15 -333
  11. package/dist/cli/upgradeCommand.js +8 -65
  12. package/dist/cli.js +57 -242
  13. package/dist/commands/configCommands.js +11 -62
  14. package/dist/commands/executionAuditCommands.js +23 -23
  15. package/dist/commands/globalRoleCommands.js +2 -7
  16. package/dist/commands/jobCommands.js +1 -4
  17. package/dist/commands/projectCommands.js +5 -5
  18. package/dist/commands/releaseCommands.js +3 -10
  19. package/dist/commands/resourcesCommands.js +2 -2
  20. package/dist/commands/sessionCommands.js +2 -2
  21. package/dist/commands/taskActor.js +31 -39
  22. package/dist/commands/taskChangeSetCommands.js +5 -12
  23. package/dist/commands/taskCommands.js +464 -1249
  24. package/dist/commands/taskContextCommand.js +35 -36
  25. package/dist/commands/taskExecutionCommands.js +33 -46
  26. package/dist/commands/taskInputCommands.js +20 -42
  27. package/dist/commands/taskNextActionCommand.js +9 -9
  28. package/dist/commands/taskOverviewCommand.js +56 -95
  29. package/dist/commands/taskRoleRuntimeStatus.js +77 -107
  30. package/dist/commands/taskUpstreamCommands.js +3 -3
  31. package/dist/commands/taskWorkspaceCommands.js +7 -79
  32. package/dist/commands/telemetryCommands.js +32 -124
  33. package/dist/commands/workflowCommands.js +3 -3
  34. package/dist/completion/fileCompletionManager.js +1 -1
  35. package/dist/config/configCatalog.js +4 -6
  36. package/dist/config/yuiConfig.js +6 -43
  37. package/dist/context/dispatchContext.js +14 -30
  38. package/dist/context/roleSessionContext.js +2 -2
  39. package/dist/context/sessionBootstrapManifest.js +2 -2
  40. package/dist/context/{runContextPack.js → turnContextPack.js} +58 -73
  41. package/dist/context/turnInputContract.js +204 -0
  42. package/dist/context/wakeNotification.js +2 -2
  43. package/dist/controller/agentRuntimeObserver.js +18 -18
  44. package/dist/controller/clientRuntime.js +13 -20
  45. package/dist/controller/controller.js +89 -116
  46. package/dist/controller/fileSchedulerStoreAdapter.js +511 -742
  47. package/dist/controller/jobControl.js +17 -17
  48. package/dist/controller/resourceInventory.js +6 -6
  49. package/dist/controller/resourceInventoryLinux.js +38 -59
  50. package/dist/controller/resourceInventoryRpc.js +3 -3
  51. package/dist/controller/resourceInventoryWorker.js +1 -1
  52. package/dist/controller/runtime.js +46 -53
  53. package/dist/controller/runtimeEventInbox.js +23 -31
  54. package/dist/controller/runtimeEventProcessor.js +15 -15
  55. package/dist/controller/{runtimeHookRunFence.js → runtimeHookTurnFence.js} +87 -81
  56. package/dist/controller/runtimeLaunchCoordinator.js +3 -3
  57. package/dist/controller/runtimeObservationHook.js +11 -8
  58. package/dist/controller/sessionNotify.js +11 -11
  59. package/dist/controller/structuredProviderObservation.js +89 -16
  60. package/dist/coordination/workMailbox.js +309 -579
  61. package/dist/coordination/workMailboxQueue.js +5 -6
  62. package/dist/core/controllerClient.js +1 -91
  63. package/dist/core/controllerServer.js +3 -6
  64. package/dist/doctor/doctor.js +51 -314
  65. package/dist/execution/candidateConvergence.js +3 -3
  66. package/dist/execution/executionGroup.js +32 -33
  67. package/dist/execution/executionHealth.js +36 -38
  68. package/dist/execution/resourceBroker.js +12 -12
  69. package/dist/executor/agentExecutor.js +30 -265
  70. package/dist/executor/effectiveLaunch.js +9 -19
  71. package/dist/executor/executorRegistry.js +43 -17
  72. package/dist/executor/fileRoleLaunchPlanner.js +56 -56
  73. package/dist/executor/launchPlan.js +3 -3
  74. package/dist/executor/workspacePreflightClassification.js +16 -16
  75. package/dist/grant/capabilityGrant.js +20 -25
  76. package/dist/input/inputRequest.js +12 -12
  77. package/dist/integration/changeSet.js +9 -13
  78. package/dist/integration/changeSetManifest.js +1 -1
  79. package/dist/integration/gitIntegrationService.js +2 -2
  80. package/dist/integration/integrationQueueService.js +5 -21
  81. package/dist/integration/overlapDiagnostics.js +2 -2
  82. package/dist/interaction/operatorPresentation.js +1 -1
  83. package/dist/job/jobRunner.js +1 -1
  84. package/dist/lifecycle/canonicalLifecycleEvent.js +25 -25
  85. package/dist/lifecycle/{exactRunTerminalization.js → exactTurnTerminalization.js} +116 -232
  86. package/dist/message/message.js +6 -6
  87. package/dist/observability/executionAudit.js +74 -86
  88. package/dist/observability/faultClassification.js +7 -24
  89. package/dist/observability/orchestrationMetrics.js +5 -5
  90. package/dist/observability/runtimeIdentity.js +34 -101
  91. package/dist/profile/agentProfile.js +1 -1
  92. package/dist/release/cliHomeReleaseFence.js +3 -3
  93. package/dist/release/releaseWorkflowEngine.js +6 -10
  94. package/dist/release/releaseWorkflowPorts.js +2 -2
  95. package/dist/release/workflowFileLock.js +1 -1
  96. package/dist/repository/checkoutSwap.js +1 -1
  97. package/dist/repository/gitWorkspace.js +0 -13
  98. package/dist/repository/project.js +1 -1
  99. package/dist/repository/projectMaintenanceLock.js +1 -2
  100. package/dist/repository/taskBaseFreshness.js +13 -13
  101. package/dist/repository/taskWorkspaceCoordinator.js +21 -25
  102. package/dist/repository/taskWorkspaceIdentity.js +8 -21
  103. package/dist/repository/taskWorkspacePreparer.js +63 -620
  104. package/dist/resources/autoResourceGc.js +3 -3
  105. package/dist/resources/liveReferences.js +1 -1
  106. package/dist/resources/resourceGc.js +1 -1
  107. package/dist/resources/sqliteResourceRegistry.js +1 -1
  108. package/dist/review/reviewDecision.js +7 -7
  109. package/dist/review/reviewFindingLedger.js +1 -1
  110. package/dist/review/reviewOutcomeClassifier.js +35 -50
  111. package/dist/review/reviewRound.js +14 -25
  112. package/dist/review/reviewerAvailability.js +4 -4
  113. package/dist/review/taskFinalReviewContractResolution.js +41 -0
  114. package/dist/role/role.js +6 -3
  115. package/dist/runtime/agentDriver.js +4 -0
  116. package/dist/runtime/agentHost.js +151 -36
  117. package/dist/runtime/builtinAgentDrivers.js +79 -2
  118. package/dist/runtime/codexAppServerRuntime.js +122 -0
  119. package/dist/runtime/continuationManager.js +3 -5
  120. package/dist/runtime/exactControlPlane.js +17 -42
  121. package/dist/runtime/firstProgressAdvisory.js +1 -1
  122. package/dist/runtime/index.js +2 -2
  123. package/dist/runtime/launchDiagnostics.js +2 -2
  124. package/dist/runtime/lifecycleReservation.js +4 -4
  125. package/dist/runtime/processExitObservation.js +1 -1
  126. package/dist/runtime/processExitOutbox.js +0 -32
  127. package/dist/runtime/promptEnvelope.js +9 -9
  128. package/dist/runtime/providerContinuation.js +2 -2
  129. package/dist/runtime/providerContinuationReconciliationService.js +2 -2
  130. package/dist/runtime/providerRuntimeIdentity.js +76 -24
  131. package/dist/runtime/recentTurnIds.js +38 -0
  132. package/dist/runtime/runtimeContinuationProjection.js +2 -2
  133. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  134. package/dist/runtime/runtimeObservation.js +58 -21
  135. package/dist/runtime/runtimeProjection.js +19 -27
  136. package/dist/runtime/sessionLaunchRequest.js +2 -2
  137. package/dist/runtime/structuredProviderHost.js +177 -12
  138. package/dist/runtime/tmuxAdapters.js +46 -11
  139. package/dist/scheduler/activeRoleTurnDelivery.js +245 -0
  140. package/dist/scheduler/leaderWakeupProcessor.js +147 -445
  141. package/dist/scheduler/operatorEvent.js +4 -6
  142. package/dist/scheduler/resourceQueueProjection.js +71 -0
  143. package/dist/scheduler/{roleRunLiveness.js → roleTurnLiveness.js} +24 -28
  144. package/dist/scheduler/{roleRunStall.js → roleTurnStall.js} +162 -247
  145. package/dist/scheduler/taskExecutionProjection.js +99 -99
  146. package/dist/scheduler/taskObservabilityProjection.js +10 -10
  147. package/dist/scheduler/taskWake.js +4 -4
  148. package/dist/scheduler/wakeReason.js +6 -10
  149. package/dist/scheduler/wakeupQueue.js +0 -9
  150. package/dist/setup/setupCommand.js +2 -2
  151. package/dist/storage/currentTaskStore.js +46 -0
  152. package/dist/storage/persistenceWorker.js +1 -1
  153. package/dist/storage/sqliteSchema.js +81 -485
  154. package/dist/storage/sqliteStore.js +206 -365
  155. package/dist/storage/storageSchema.js +1 -15
  156. package/dist/storage/storageVersions.js +8 -9
  157. package/dist/storage/storeRpc.js +10 -34
  158. package/dist/storage/taskStore.js +63 -3415
  159. package/dist/storage/upgrade/recordVersions.js +55 -149
  160. package/dist/storage/upgrade/upgradeOrchestrator.js +89 -1752
  161. package/dist/task/completionReadiness.js +5 -5
  162. package/dist/task/deliveryGuard.js +10 -10
  163. package/dist/task/nextAction.js +74 -77
  164. package/dist/task/task.js +2 -4
  165. package/dist/task/taskRecordReference.js +3 -3
  166. package/dist/task/taskRecordRetirement.js +1 -1
  167. package/dist/telemetry/sqliteTelemetryStore.js +53 -53
  168. package/dist/telemetry/telemetryConfig.js +14 -14
  169. package/dist/telemetry/telemetryWiring.js +8 -14
  170. package/dist/turn/turn.js +356 -0
  171. package/dist/{run/runIdentity.js → turn/turnIdentity.js} +4 -4
  172. package/dist/verification/gateArtifactStore.js +2 -2
  173. package/dist/web/assets/client/app.js +1 -1
  174. package/dist/web/assets/client/components.js +29 -54
  175. package/dist/web/assets/client/i18n.js +17 -37
  176. package/dist/web/assets/client/view.js +37 -37
  177. package/dist/web/assets/shell.js +1 -1
  178. package/dist/web/assets/styles/cards.js +5 -5
  179. package/dist/web/assets/styles/widgets.js +1 -2
  180. package/dist/web/webSnapshot.js +65 -60
  181. package/dist/workItem/workItem.js +11 -11
  182. package/dist/workspace/workItemChangeSetManager.js +1 -1
  183. package/docs/task-local-identity.md +5 -5
  184. package/i18n/README.zh-CN.md +41 -54
  185. package/package.json +1 -1
  186. package/skills/yui-leader/SKILL.md +85 -83
  187. package/skills/yui-operator/SKILL.md +16 -16
  188. package/skills/yui-reviewer/SKILL.md +10 -10
  189. package/skills/yui-runtime/SKILL.md +17 -18
  190. package/skills/yui-worker/SKILL.md +16 -18
  191. package/dist/context/runContextContract.js +0 -162
  192. package/dist/executor/turnCompletion.js +0 -126
  193. package/dist/review/taskFinalReviewContractEvent.js +0 -1
  194. package/dist/review/taskFinalReviewContractRebind.js +0 -367
  195. package/dist/run/agentRun.js +0 -356
  196. package/dist/run/rejectedYieldAttempt.js +0 -221
  197. package/dist/run/runControlRequest.js +0 -50
  198. package/dist/run/yieldReceipt.js +0 -65
  199. package/dist/runtime/turnCompletion.js +0 -3
  200. package/dist/scheduler/actionability.js +0 -323
  201. package/dist/scheduler/activeRoleRunDelivery.js +0 -868
  202. package/dist/scheduler/activeTaskProgress.js +0 -126
  203. package/dist/storage/compatibleTaskStore.js +0 -248
  204. package/dist/storage/migration/baseline.js +0 -78
  205. package/dist/storage/migration/classifier.js +0 -51
  206. package/dist/storage/migration/compatibleCodec.js +0 -53
  207. package/dist/storage/migration/engine.js +0 -147
  208. package/dist/storage/migration/index.js +0 -33
  209. package/dist/storage/migration/planner.js +0 -154
  210. package/dist/storage/migration/productionRegistry.js +0 -3931
  211. package/dist/storage/migration/registry.js +0 -169
  212. package/dist/storage/migration/report.js +0 -54
  213. package/dist/storage/migration/types.js +0 -31
  214. package/dist/storage/upgrade/homeClassification.js +0 -353
  215. package/dist/storage/upgrade/homeMigrationTarget.js +0 -595
  216. package/dist/storage/upgrade/migrationReceipt.js +0 -67
  217. package/dist/storage/upgrade/offlineUpgradeInventory.js +0 -453
  218. package/dist/storage/upgrade/productionMigrationRegistry.js +0 -6
  219. package/dist/storage/upgrade/pseudoLayoutRepair.js +0 -241
  220. package/dist/storage/upgrade/recordVersionScan.js +0 -176
  221. package/dist/storage/upgrade/sqliteFileSet.js +0 -50
  222. package/dist/storage/upgrade/sqliteMigrationTarget.js +0 -375
  223. package/dist/storage/upgrade/sqliteRecordMigrationTarget.js +0 -305
  224. package/dist/storage/upgrade/sqliteStateMigration.js +0 -918
  225. package/dist/storage/upgrade/switchProgress.js +0 -80
  226. package/dist/storage/upgrade/upgradeReceipt.js +0 -161
  227. package/dist/storage/upgradeCoordination.js +0 -187
  228. package/dist/storage/upgradeFence.js +0 -366
  229. package/dist/telemetry/telemetryCompaction.js +0 -252
@@ -98,14 +98,14 @@ function collectTaskStatuses(store) {
98
98
  return statuses;
99
99
  }
100
100
  /**
101
- * Workspace paths claimed by active durable Jobs. An active AgentRun still
101
+ * Workspace paths claimed by active durable Jobs. An active Turn still
102
102
  * holds its workspace even after the managed workspace record is gone, so
103
- * those paths stay protected until the Run finishes.
103
+ * those paths stay protected until the Turn finishes.
104
104
  */
105
105
  function collectActiveWorkspaceOwnerPaths(store) {
106
106
  const paths = [];
107
107
  for (const task of store.listTasks()) {
108
- for (const run of store.listAgentRuns(task.id)) {
108
+ for (const run of store.listTurns(task.id)) {
109
109
  if (run.status !== "active")
110
110
  continue;
111
111
  const workspace = run.workspace;
@@ -145,7 +145,7 @@ export async function scanLiveReferences(input) {
145
145
  }
146
146
  }
147
147
  }
148
- // 6. Active durable workspace owners (e.g. an active AgentRun launch).
148
+ // 6. Active durable workspace owners (e.g. an active Turn launch).
149
149
  const activeOwners = input.ports?.activeWorkspaceOwners !== undefined
150
150
  ? input.ports.activeWorkspaceOwners()
151
151
  : [];
@@ -125,7 +125,7 @@ function classifyDiscoveredResources(discovered, registry, scan, input, home) {
125
125
  }
126
126
  /**
127
127
  * Collect active workspace owner path fragments from durable state.
128
- * These protect resources that an active Session, Job, or AgentRun still
128
+ * These protect resources that an active Session, Job, or Turn still
129
129
  * references even when the Task itself is terminal.
130
130
  */
131
131
  function collectActiveWorkspaceOwners(input) {
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * The registry is GC's own state: it is not part of the aggregate and never
10
10
  * participates in aggregate versioning. The `resource_registry` table is
11
- * created by schema migration 8.
11
+ * created by the current SQLite baseline.
12
12
  */
13
13
  import { existsSync } from "node:fs";
14
14
  import { join } from "node:path";
@@ -3,7 +3,7 @@ import { isAcceptedTaskReviewBaseline } from "./reviewAcceptance.js";
3
3
  import { projectReviewerAvailability } from "./reviewerAvailability.js";
4
4
  /** Read-only facts for Leader judgment; this projection never blocks an action. */
5
5
  export function projectReviewDecision(input) {
6
- const { store, task, roles, runs, rounds, reviewConfig, currentCandidate } = input;
6
+ const { store, task, roles, turns, rounds, reviewConfig, currentCandidate } = input;
7
7
  const taskRounds = rounds.filter((round) => (round.scope ?? "work-item") === "task");
8
8
  const accepted = [...taskRounds]
9
9
  .filter((round) => isAcceptedTaskReviewBaseline(store, round))
@@ -20,15 +20,15 @@ export function projectReviewDecision(input) {
20
20
  const activeReviews = taskRounds
21
21
  .filter((round) => (round.status === "pending" || round.status === "running"))
22
22
  .map((round) => {
23
- const activeRun = runs.find((run) => (run.status === "active" && run.reviewRoundId === round.id));
24
- const workspaceRoot = round.workspace?.root ?? activeRun?.workspace?.root;
23
+ const activeTurn = turns.find((turn) => (turn.status === "active" && turn.reviewRoundId === round.id));
24
+ const workspaceRoot = round.workspace?.root ?? activeTurn?.workspace?.root;
25
25
  return {
26
26
  reviewRoundId: round.id,
27
27
  reviewerRoleName: round.reviewerRoleName,
28
28
  mode: round.deltaRecheck === undefined ? "full" : "delta-recheck",
29
29
  status: round.status,
30
- ...(activeRun === undefined ? {} : { activeRunId: activeRun.id }),
31
- startedAt: activeRun?.createdAt ?? round.createdAt,
30
+ ...(activeTurn === undefined ? {} : { activeTurnId: activeTurn.id }),
31
+ startedAt: activeTurn?.createdAt ?? round.createdAt,
32
32
  frozenCandidate: round.taskCandidate ?? null,
33
33
  candidateRelation: candidateRelation(round.taskCandidate ?? null, currentCandidate),
34
34
  ...(workspaceRoot === undefined ? {} : { workspaceRoot })
@@ -62,9 +62,9 @@ export function projectReviewDecision(input) {
62
62
  reviewerRoleName,
63
63
  status: "busy",
64
64
  phase: availability.phase,
65
- ...(availability.activeRunId === undefined
65
+ ...(availability.activeTurnId === undefined
66
66
  ? {}
67
- : { activeRunId: availability.activeRunId }),
67
+ : { activeTurnId: availability.activeTurnId }),
68
68
  ...(availability.activeReviewRoundId === undefined
69
69
  ? {}
70
70
  : { activeReviewRoundId: availability.activeReviewRoundId }),
@@ -505,7 +505,7 @@ export function buildTaskFinalReviewFindingContext(store, taskId, candidate) {
505
505
  ledgerContext = renderFindingLedgerContext(summarizeFindingLedger(store, taskId));
506
506
  }
507
507
  catch {
508
- ledgerContext = "Finding ledger: unavailable (SQLite backend required; run `yui update` to migrate this Home).";
508
+ ledgerContext = "Finding ledger: unavailable (a current SQLite Home is required).";
509
509
  }
510
510
  const lines = [
511
511
  "Review convergence context:",
@@ -1,27 +1,25 @@
1
- import { matchYieldReceipt } from "../run/yieldReceipt.js";
2
1
  import { isTaskRecordRetired, operationalTaskRecords } from "../task/taskRecordRetirement.js";
3
2
  const INFRA_SIGNATURES = [
4
3
  { kind: "session-not-stopped", pattern: /session must be stopped before workspace migration/iu },
5
- { kind: "run-start", pattern: /role run could not start|could not start (?:the )?(?:reviewer|role) run/iu },
4
+ { kind: "turn-start", pattern: /role turn could not start|could not start (?:the )?(?:reviewer|role) turn/iu },
6
5
  { kind: "storage-lock", pattern: /\.state\.lock|state lock|lock timeout|storage lock/iu },
7
6
  { kind: "tmux-exit", pattern: /tmux[^\n]{0,80}(?:exited|exit|died|vanished)|pane (?:exited|died)/iu },
8
- { kind: "yield-timeout", pattern: /yield timeout|controller yield timeout|yield timed out/iu },
9
- { kind: "run-identity", pattern: /wrong run id|unknown run id|run id (?:is )?(?:invalid|unknown|mismatch)/iu },
7
+ { kind: "turn-identity", pattern: /wrong turn id|unknown turn id|turn id (?:is )?(?:invalid|unknown|mismatch)/iu },
10
8
  { kind: "policy", pattern: /cyber_?policy|policy denial|permission denied by policy/iu },
11
9
  { kind: "baseline-contamination", pattern: /cross[-\s]?baseline|baseline pollution|contaminated baseline|wrong base sha/iu },
12
- { kind: "context-load", pattern: /(?:run )?(?:context|context pack) load (?:failed|unavailable|unauthorized|stale|mismatched|malformed)/iu },
10
+ { kind: "context-load", pattern: /(?:turn )?(?:context|context pack) load (?:failed|unavailable|unauthorized|stale|mismatched|malformed)/iu },
13
11
  { kind: "workspace-binding", pattern: /workspace is not the durable owner|workspace-binding failure/iu }
14
12
  ];
15
13
  /** Classify one terminal Round without rewriting it. */
16
14
  export function classifyReviewRoundOutcome(round, evidence) {
17
15
  if (round.status !== "completed" && round.status !== "failed")
18
16
  return null;
19
- if (evidence !== undefined && round.reviewerRunId !== undefined
20
- && isTaskRecordRetired(evidence.listEvents(round.taskId), "agent-run", round.reviewerRunId)) {
17
+ if (evidence !== undefined && round.reviewerTurnId !== undefined
18
+ && isTaskRecordRetired(evidence.listEvents(round.taskId), "turn", round.reviewerTurnId)) {
21
19
  return {
22
20
  kind: "non-semantic",
23
- infraKind: "run-identity",
24
- reason: `Reviewer Run ${round.reviewerRunId} was retired from operational evidence.`
21
+ infraKind: "turn-identity",
22
+ reason: `Reviewer Turn ${round.reviewerTurnId} was retired from operational evidence.`
25
23
  };
26
24
  }
27
25
  const infraKind = classifyInfraKind(`${round.summary ?? ""}\n${round.report ?? ""}`);
@@ -46,7 +44,7 @@ export function classifyReviewRoundOutcome(round, evidence) {
46
44
  return {
47
45
  kind: "ambiguous",
48
46
  infraKind,
49
- reason: "Completed Round claims an infrastructure failure but corroborating Run/Event evidence was not supplied."
47
+ reason: "Completed Round claims an infrastructure failure but corroborating Turn/Event evidence was not supplied."
50
48
  };
51
49
  }
52
50
  const corroborationFailure = completedInfrastructureCorroborationFailure(round, evidence);
@@ -54,7 +52,7 @@ export function classifyReviewRoundOutcome(round, evidence) {
54
52
  ? {
55
53
  kind: "non-semantic",
56
54
  infraKind,
57
- reason: "Completed Round and yielded Run agree on an explicit pre-review infrastructure failure."
55
+ reason: "Completed Round and Turn agree on an explicit pre-review infrastructure failure."
58
56
  }
59
57
  : {
60
58
  kind: "ambiguous",
@@ -90,17 +88,17 @@ function failedRoundSemanticEvidence(round, evidence) {
90
88
  || (lane.result?.evidence ?? []).length > 0
91
89
  || lane.result?.evidenceCommit !== undefined
92
90
  || lane.result?.gitSnapshot !== undefined
93
- || lane.status === "yielded"
94
91
  || lane.status === "completed"));
95
92
  if (semanticLane !== undefined)
96
93
  return `Reviewer Lane ${semanticLane.id} delivered semantic evidence.`;
97
94
  if (evidence !== undefined) {
98
95
  const events = evidence.listEvents(round.taskId);
99
- const reviewRun = operationalTaskRecords(evidence.listAgentRuns(round.taskId), events, "agent-run").find((run) => (run.purpose === "review"
96
+ const reviewRun = operationalTaskRecords(evidence.listTurns(round.taskId), events, "turn").find((run) => (run.purpose === "review"
100
97
  && run.reviewRoundId === round.id
101
- && (run.status === "yielded" || runtimeFailureSummaryHasReviewerOutput(run.summary ?? ""))));
98
+ && (run.status === "completed"
99
+ || runtimeFailureSummaryHasReviewerOutput(run.result?.output ?? ""))));
102
100
  if (reviewRun !== undefined)
103
- return `Reviewer Run ${reviewRun.id} records Reviewer output.`;
101
+ return `Reviewer Turn ${reviewRun.id} records Reviewer output.`;
104
102
  const finding = evidence.listReviewFindings(round.taskId).find((entry) => (entry.firstReviewRoundId === round.id || entry.lastReviewRoundId === round.id));
105
103
  if (finding !== undefined)
106
104
  return `Review finding ${finding.id} references the Round.`;
@@ -140,7 +138,7 @@ function completedInfrastructureCorroborationFailure(round, store) {
140
138
  || lane.result?.gitSnapshot !== undefined) {
141
139
  return `Reviewer Lane ${lane.id} delivered semantic evidence.`;
142
140
  }
143
- if (lane.status === "yielded" || lane.status === "completed") {
141
+ if (lane.status === "completed") {
144
142
  if (lane.result === undefined
145
143
  || lane.result.summary !== round.summary
146
144
  || lane.result.report !== round.report
@@ -153,36 +151,23 @@ function completedInfrastructureCorroborationFailure(round, store) {
153
151
  }
154
152
  }
155
153
  const allEvents = store.listEvents(round.taskId);
156
- const runs = operationalTaskRecords(store.listAgentRuns(round.taskId), allEvents, "agent-run").filter((run) => (run.purpose === "review" && run.reviewRoundId === round.id));
154
+ const runs = operationalTaskRecords(store.listTurns(round.taskId), allEvents, "turn").filter((run) => (run.purpose === "review" && run.reviewRoundId === round.id));
157
155
  const active = runs.find(({ status }) => status === "active");
158
156
  if (active !== undefined)
159
- return `Reviewer Run ${active.id} is still active.`;
160
- const output = runs.find((run) => (run.status === "failed" && runtimeFailureSummaryHasReviewerOutput(run.summary ?? "")));
157
+ return `Reviewer Turn ${active.id} is still active.`;
158
+ const output = runs.find((run) => (run.status === "failed" && runtimeFailureSummaryHasReviewerOutput(run.result?.output ?? "")));
161
159
  if (output !== undefined)
162
- return `Reviewer Run ${output.id} records Reviewer output.`;
163
- const yielded = runs.filter(({ status }) => status === "yielded");
164
- if (round.reviewerRunId === undefined
165
- || yielded.length !== 1
166
- || yielded[0].id !== round.reviewerRunId) {
167
- return "Completed Round lacks one exact yielded Reviewer Run.";
168
- }
169
- const run = yielded[0];
160
+ return `Reviewer Turn ${output.id} records Reviewer output.`;
161
+ const completed = runs.filter(({ status }) => status === "completed");
162
+ if (round.reviewerTurnId === undefined
163
+ || completed.length !== 1
164
+ || completed[0].id !== round.reviewerTurnId) {
165
+ return "Completed Round lacks one exact completed Reviewer Turn.";
166
+ }
167
+ const run = completed[0];
170
168
  if (run.roleName !== round.reviewerRoleName
171
- || run.summary !== round.summary
172
- || run.yieldReceipt === undefined) {
173
- return `Reviewer Run ${run.id} does not match the non-semantic Round receipt.`;
174
- }
175
- const receiptMatch = matchYieldReceipt(run.yieldReceipt, {
176
- status: "yielded",
177
- summary: round.summary ?? "",
178
- reviewResult: {
179
- report: round.report ?? "",
180
- checks: round.checks ?? [],
181
- evidenceCommit: round.reviewBaseCommit
182
- }
183
- });
184
- if (receiptMatch?.kind !== "replayed") {
185
- return `Reviewer Run ${run.id} yield receipt does not cover the Round outcome.`;
169
+ || run.result?.output !== round.summary) {
170
+ return `Reviewer Turn ${run.id} does not match the non-semantic Round result.`;
186
171
  }
187
172
  const finding = store.listReviewFindings(round.taskId).find((entry) => (entry.firstReviewRoundId === round.id || entry.lastReviewRoundId === round.id));
188
173
  if (finding !== undefined)
@@ -204,12 +189,12 @@ function explicitCompletedReviewInfrastructureFailure(summary, round) {
204
189
  if (exactCompletedReviewInfrastructureFailureReport(summary))
205
190
  return true;
206
191
  const report = summary.trim();
207
- if (report === `Role Run workspace is not the durable owner: ${round.taskId}/${round.reviewerRoleName}.`
208
- || (round.reviewerRunId !== undefined
209
- && report === `Review Run workspace is not the durable owner: ${round.reviewerRunId}.`)) {
192
+ if (report === `Role Turn workspace is not the durable owner: ${round.taskId}/${round.reviewerRoleName}.`
193
+ || (round.reviewerTurnId !== undefined
194
+ && report === `Review Turn workspace is not the durable owner: ${round.reviewerTurnId}.`)) {
210
195
  return true;
211
196
  }
212
- return /^(?:Run )?(?:Context|Context Pack) load (?:failed|unavailable|unauthorized|stale|mismatched|malformed)(?:: (?:failure|mismatch|unavailable|unauthorized|stale|mismatched|malformed))?\.?$/iu
197
+ return /^(?:Turn )?(?:Context|Context Pack) load (?:failed|unavailable|unauthorized|stale|mismatched|malformed)(?:: (?:failure|mismatch|unavailable|unauthorized|stale|mismatched|malformed))?\.?$/iu
213
198
  .test(report);
214
199
  }
215
200
  function exactCompletedReviewInfrastructureFailureReport(summary) {
@@ -217,9 +202,9 @@ function exactCompletedReviewInfrastructureFailureReport(summary) {
217
202
  const envelope = [
218
203
  /^# Review result: (?:context-load|workspace-binding) failure$/u,
219
204
  /^$/u,
220
- /^The assigned Run context could not be safely matched to this native session, so no candidate review was performed\.$/u,
205
+ /^The assigned Turn context could not be safely matched to this native session, so no candidate review was performed\.$/u,
221
206
  /^$/u,
222
- /^- Run: `[^`\r\n]+`$/u,
207
+ /^- Turn: `[^`\r\n]+`$/u,
223
208
  /^- ReviewRound: `[^`\r\n]+`$/u,
224
209
  /^- Review base commit: `[0-9a-f]{40}`$/u,
225
210
  /^- Frozen target: `[^`\r\n]+`$/u,
@@ -236,14 +221,14 @@ function exactCompletedReviewInfrastructureFailureReport(summary) {
236
221
  /^$/u,
237
222
  /^## Checks actually run$/u,
238
223
  /^$/u,
239
- /^- Exact Context API load: passed for Task\/Run\/Role\/purpose\/subject\/snapshot\/adapter\.$/u,
224
+ /^- Exact Context API load: passed for Task\/Turn\/Role\/purpose\/subject\/snapshot\/adapter\.$/u,
240
225
  /^- Workspace binding verification: failed\.$/u,
241
226
  /^- Candidate build\/tests\/package checks: not run\.$/u,
242
227
  /^- Real-provider E2E: not run and not authorized\.$/u,
243
228
  /^$/u,
244
229
  /^## Required next action$/u,
245
230
  /^$/u,
246
- /^Attach the native Reviewer session to the exact workspace recorded by the Context Pack, or issue a fresh internally consistent Review Run\/Context Pack\. Then perform the complete bounded Task-final review at the frozen head\.$/u
231
+ /^Attach the native Reviewer session to the exact workspace recorded by the Context Pack, or issue a fresh internally consistent Review Turn\/Context Pack\. Then perform the complete bounded Task-final review at the frozen head\.$/u
247
232
  ];
248
233
  return lines.length === envelope.length
249
234
  && envelope.every((pattern, index) => pattern.test(lines[index]));
@@ -78,7 +78,7 @@ export function attachReviewRoundWorkspace(round, workspace) {
78
78
  }
79
79
  return validateReviewRound({ ...round, workspace });
80
80
  }
81
- export function startReviewRound(round, reviewerRunId) {
81
+ export function startReviewRound(round, reviewerTurnId) {
82
82
  validateReviewRound(round);
83
83
  if (round.status !== "pending") {
84
84
  throw new Error(`ReviewRound cannot start from ${round.status}: ${round.id}.`);
@@ -88,7 +88,7 @@ export function startReviewRound(round, reviewerRunId) {
88
88
  }
89
89
  return validateReviewRound({
90
90
  ...round,
91
- reviewerRunId: requireIdentity(reviewerRunId, "Reviewer Run id"),
91
+ reviewerTurnId: requireIdentity(reviewerTurnId, "Reviewer Turn id"),
92
92
  status: "running"
93
93
  });
94
94
  }
@@ -134,7 +134,7 @@ export function finishReviewRound(round, status, summary, now, result = {}) {
134
134
  }
135
135
  /**
136
136
  * Issue 06: retry a failed Task-final execution attempt under the same semantic
137
- * Round identity. AgentRun history remains the attempt trail; the Round itself
137
+ * Round identity. Turn history remains the attempt trail; the Round itself
138
138
  * returns to pending so infrastructure retries do not manufacture a new
139
139
  * semantic ReviewRound or duplicate findings.
140
140
  */
@@ -153,7 +153,6 @@ export function retryTaskReviewRound(round, requestedBy, executionLaneId) {
153
153
  schemaVersion: round.schemaVersion,
154
154
  id: round.id,
155
155
  taskId: round.taskId,
156
- ...(round.legacyAnchor === undefined ? {} : { legacyAnchor: round.legacyAnchor }),
157
156
  reviewerRoleName: round.reviewerRoleName,
158
157
  reviewBaseCommit: round.reviewBaseCommit,
159
158
  scope: "task",
@@ -177,7 +176,7 @@ export function retryTaskReviewRound(round, requestedBy, executionLaneId) {
177
176
  deletedLines: round.deltaRecheck.deletedLines
178
177
  })
179
178
  }),
180
- // Keep the historical attempt Group and Lane addressable from AgentRun
179
+ // Keep the historical attempt Group and Lane addressable from Turn
181
180
  // history while resetting the Lane for another dispatch attempt.
182
181
  ...(retryExecutionGroup === undefined ? {} : { executionGroup: retryExecutionGroup }),
183
182
  requestedBy: validateReviewRequestSource(requestedBy),
@@ -187,15 +186,15 @@ export function retryTaskReviewRound(round, requestedBy, executionLaneId) {
187
186
  });
188
187
  }
189
188
  /** Keep a running panel Round active while retrying only its exact failed Lane. */
190
- export function retryRunningReviewExecutionLane(round, executionLaneId, runId, now) {
189
+ export function retryRunningReviewExecutionLane(round, executionLaneId, turnId, now) {
191
190
  validateReviewRound(round);
192
191
  if (round.status !== "running" || round.executionGroup === undefined) {
193
192
  throw new Error(`ReviewRound ${round.id} has no running ExecutionGroup.`);
194
193
  }
195
194
  const lane = round.executionGroup.lanes.find(({ id }) => id === executionLaneId);
196
- if (lane === undefined || lane.status !== "failed" || lane.runId !== runId) {
195
+ if (lane === undefined || lane.status !== "failed" || lane.turnId !== turnId) {
197
196
  throw new Error(`Review retry does not target the current failed Lane attempt: `
198
- + `${round.executionGroup.id}/${executionLaneId}/${runId}.`);
197
+ + `${round.executionGroup.id}/${executionLaneId}/${turnId}.`);
199
198
  }
200
199
  return updateReviewExecutionGroup(round, retryReviewExecutionGroup(round, executionLaneId, now));
201
200
  }
@@ -219,7 +218,7 @@ function retryReviewExecutionGroup(round, executionLaneId, retryAt) {
219
218
  });
220
219
  }
221
220
  /** Accepts the Reviewer's complete report and extracts only optional known evidence. */
222
- export function parseReviewYieldReport(value) {
221
+ export function parseReviewResultReport(value) {
223
222
  const report = requireText(value, "Review report");
224
223
  let parsed;
225
224
  try {
@@ -372,15 +371,6 @@ export function validateReviewRound(round) {
372
371
  if (round.workItemId !== undefined || round.candidateId !== undefined) {
373
372
  throw new Error(`Task ReviewRound cannot use a WorkItem Candidate anchor: ${round.id}.`);
374
373
  }
375
- if (round.legacyAnchor !== undefined) {
376
- validateTaskRecordReference({
377
- taskId: round.taskId,
378
- localId: round.legacyAnchor.workItemId
379
- }, "workItem");
380
- if (!/^candidate-[1-9]\d*$/.test(round.legacyAnchor.candidateId)) {
381
- throw new Error(`Legacy Candidate local id is invalid: ${round.legacyAnchor.candidateId}.`);
382
- }
383
- }
384
374
  if (round.taskCandidate === undefined) {
385
375
  throw new Error(`Task ReviewRound requires a frozen Task candidate: ${round.id}.`);
386
376
  }
@@ -407,8 +397,7 @@ export function validateReviewRound(round) {
407
397
  throw new Error(`Candidate local id is invalid: ${round.candidateId}.`);
408
398
  }
409
399
  if (round.taskCandidate !== undefined
410
- || round.taskFinalReviewContract !== undefined
411
- || round.legacyAnchor !== undefined) {
400
+ || round.taskFinalReviewContract !== undefined) {
412
401
  throw new Error(`WorkItem ReviewRound cannot carry Task-final metadata: ${round.id}.`);
413
402
  }
414
403
  }
@@ -424,11 +413,11 @@ export function validateReviewRound(round) {
424
413
  }
425
414
  validateDeltaRecheckRecord(round.deltaRecheck);
426
415
  }
427
- if (round.reviewerRunId !== undefined) {
416
+ if (round.reviewerTurnId !== undefined) {
428
417
  validateTaskRecordReference({
429
418
  taskId: round.taskId,
430
- localId: round.reviewerRunId
431
- }, "agentRun");
419
+ localId: round.reviewerTurnId
420
+ }, "turn");
432
421
  }
433
422
  if (round.workspace !== undefined)
434
423
  validateReviewWorkspace(round, round.workspace);
@@ -456,8 +445,8 @@ export function validateReviewRound(round) {
456
445
  throw new Error("An active ReviewRound cannot have terminal metadata.");
457
446
  }
458
447
  if (round.status === "running"
459
- && (round.reviewerRunId === undefined || round.workspace === undefined)) {
460
- throw new Error("A running ReviewRound requires a Reviewer Run and workspace.");
448
+ && (round.reviewerTurnId === undefined || round.workspace === undefined)) {
449
+ throw new Error("A running ReviewRound requires a Reviewer Turn and workspace.");
461
450
  }
462
451
  if (round.workspaceDisposition !== undefined) {
463
452
  if (!terminal || round.workspace === undefined) {
@@ -2,14 +2,14 @@ import { nextPendingBatch, mailboxHasWork } from "../coordination/workMailbox.js
2
2
  import { runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
3
3
  /** One authoritative read-only projection for a Task Reviewer Role slot. */
4
4
  export function projectReviewerAvailability(store, taskId, reviewerRoleName) {
5
- const active = store.getActiveAgentRun(taskId, reviewerRoleName)
6
- ?? store.listAgentRuns(taskId).find((run) => (run.roleName === reviewerRoleName && run.status === "active"));
5
+ const active = store.getActiveTurn(taskId, reviewerRoleName)
6
+ ?? store.listTurns(taskId).find((run) => (run.roleName === reviewerRoleName && run.status === "active"));
7
7
  if (active !== null && active !== undefined) {
8
8
  return {
9
9
  kind: "busy",
10
10
  reviewerRoleName,
11
- phase: "active-run",
12
- activeRunId: active.id,
11
+ phase: "active-turn",
12
+ activeTurnId: active.id,
13
13
  ...(active.reviewRoundId === undefined
14
14
  ? {}
15
15
  : { activeReviewRoundId: active.reviewRoundId }),
@@ -0,0 +1,41 @@
1
+ import { requireIdentity } from "../domain/validation.js";
2
+ import { sameTaskFinalReviewContract, validateTaskFinalReviewContract } from "./taskFinalReviewContract.js";
3
+ /**
4
+ * Resolve the one Task-final Review contract recorded by current Candidate and
5
+ * ReviewRound evidence. The contract is immutable once established; all later
6
+ * observations must match it exactly.
7
+ */
8
+ export function resolveRecordedTaskFinalReviewContract(taskId, workItems, reviewRounds) {
9
+ const normalizedTaskId = requireIdentity(taskId, "Task final-review contract Task id");
10
+ const observations = [
11
+ ...workItems.flatMap((item) => item.candidates.flatMap((candidate) => (candidate.taskFinalReviewContract === undefined
12
+ ? []
13
+ : [{
14
+ contract: candidate.taskFinalReviewContract,
15
+ source: `Candidate ${item.id}/${candidate.id}`
16
+ }]))),
17
+ ...reviewRounds.flatMap((round) => ((round.scope ?? "work-item") !== "task"
18
+ || round.taskFinalReviewContract === undefined
19
+ ? []
20
+ : [{
21
+ contract: round.taskFinalReviewContract,
22
+ source: `ReviewRound ${round.id}`
23
+ }]))
24
+ ];
25
+ if (observations.length === 0)
26
+ return undefined;
27
+ const effective = validateTaskFinalReviewContract(observations[0].contract);
28
+ if (effective.taskId !== normalizedTaskId) {
29
+ throw new Error(`${observations[0].source} carries a final-review contract for another Task.`);
30
+ }
31
+ for (const observation of observations.slice(1)) {
32
+ const contract = validateTaskFinalReviewContract(observation.contract);
33
+ if (contract.taskId !== normalizedTaskId) {
34
+ throw new Error(`${observation.source} carries a final-review contract for another Task.`);
35
+ }
36
+ if (!sameTaskFinalReviewContract(contract, effective)) {
37
+ throw new Error(`${observation.source} conflicts with the Task final-review contract.`);
38
+ }
39
+ }
40
+ return Object.freeze({ effective });
41
+ }
package/dist/role/role.js CHANGED
@@ -93,7 +93,7 @@ export function switchActiveRoleAgent(role, sessions, targetAgentId, runtime, no
93
93
  : updateGlobalRole(role, { activeAgentId: normalizedTarget }, now);
94
94
  // A running process keeps its immutable effective identity. The desired
95
95
  // switch becomes visible only when the next launch is planned.
96
- const updatedSessions = runtime.activeRun || runtime.nativeProcessRunning
96
+ const updatedSessions = runtime.activeTurn || runtime.nativeProcessRunning
97
97
  ? sessions
98
98
  : {
99
99
  ...sessions,
@@ -126,8 +126,11 @@ export function unbindRoleAgent(role, sessions, agentId, now) {
126
126
  const taskSessions = sessions.owner.scope === "task"
127
127
  ? sessions
128
128
  : null;
129
- if (taskSessions?.inFlight?.agentId === normalizedAgentId) {
130
- throw new Error(`Cannot unbind Role Agent with an active Run: ${normalizedAgentId}.`);
129
+ if (taskSessions?.providerBinding?.turn !== null
130
+ && taskSessions?.providerBinding?.turn !== undefined
131
+ && taskSessions.activeAgentId === normalizedAgentId
132
+ && ["submitting", "accepted", "running"].includes(taskSessions.providerBinding.turn.status)) {
133
+ throw new Error(`Cannot unbind Role Agent with an active Turn: ${normalizedAgentId}.`);
131
134
  }
132
135
  const targetSession = sessions.sessions[normalizedAgentId];
133
136
  if (targetSession !== undefined && targetSession.status === "active") {
@@ -92,6 +92,9 @@ export function validateAgentDriverCapabilities(input) {
92
92
  if (!["exact", "partial", "unavailable"].includes(observation.turnLifecycle)) {
93
93
  throw new Error("Agent Driver turn lifecycle capability is invalid.");
94
94
  }
95
+ if (!["exact", "partial", "unavailable"].includes(observation.goalLifecycle)) {
96
+ throw new Error("Agent Driver Goal lifecycle capability is invalid.");
97
+ }
95
98
  if (!USAGE_MODES.includes(observation.usage)) {
96
99
  throw new Error("Agent Driver usage capability is invalid.");
97
100
  }
@@ -163,6 +166,7 @@ export function validateAgentDriverCapabilities(input) {
163
166
  preInputReadiness: observation.preInputReadiness,
164
167
  promptAcceptance: observation.promptAcceptance,
165
168
  turnLifecycle: observation.turnLifecycle,
169
+ goalLifecycle: observation.goalLifecycle,
166
170
  operations: Object.freeze(uniqueMembers(observation.operations, OPERATIONS, "Agent Driver operation")),
167
171
  waiting: Object.freeze(uniqueMembers(observation.waiting, WAIT_REASONS, "Agent Driver wait reason")),
168
172
  usage: observation.usage,