@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.
- package/ARCHITECTURE.md +69 -428
- package/README.md +108 -298
- package/dist/agent/managedRuntimeEnvironment.js +2 -2
- package/dist/cli/commandCatalog.js +39 -77
- package/dist/cli/interactionCandidates.js +4 -4
- package/dist/cli/interactionPolicy.js +7 -10
- package/dist/cli/invocationRouter.js +1 -1
- package/dist/cli/updateCommand.js +6 -27
- package/dist/cli/updateOrchestrator.js +63 -484
- package/dist/cli/updatePorts.js +15 -333
- package/dist/cli/upgradeCommand.js +8 -65
- package/dist/cli.js +57 -242
- package/dist/commands/configCommands.js +11 -62
- package/dist/commands/executionAuditCommands.js +23 -23
- package/dist/commands/globalRoleCommands.js +2 -7
- package/dist/commands/jobCommands.js +1 -4
- package/dist/commands/projectCommands.js +5 -5
- package/dist/commands/releaseCommands.js +3 -10
- package/dist/commands/resourcesCommands.js +2 -2
- package/dist/commands/sessionCommands.js +2 -2
- package/dist/commands/taskActor.js +31 -39
- package/dist/commands/taskChangeSetCommands.js +5 -12
- package/dist/commands/taskCommands.js +464 -1249
- package/dist/commands/taskContextCommand.js +35 -36
- package/dist/commands/taskExecutionCommands.js +33 -46
- package/dist/commands/taskInputCommands.js +20 -42
- package/dist/commands/taskNextActionCommand.js +9 -9
- package/dist/commands/taskOverviewCommand.js +56 -95
- package/dist/commands/taskRoleRuntimeStatus.js +77 -107
- package/dist/commands/taskUpstreamCommands.js +3 -3
- package/dist/commands/taskWorkspaceCommands.js +7 -79
- package/dist/commands/telemetryCommands.js +32 -124
- package/dist/commands/workflowCommands.js +3 -3
- package/dist/completion/fileCompletionManager.js +1 -1
- package/dist/config/configCatalog.js +4 -6
- package/dist/config/yuiConfig.js +6 -43
- package/dist/context/dispatchContext.js +14 -30
- package/dist/context/roleSessionContext.js +2 -2
- package/dist/context/sessionBootstrapManifest.js +2 -2
- package/dist/context/{runContextPack.js → turnContextPack.js} +58 -73
- package/dist/context/turnInputContract.js +204 -0
- package/dist/context/wakeNotification.js +2 -2
- package/dist/controller/agentRuntimeObserver.js +18 -18
- package/dist/controller/clientRuntime.js +13 -20
- package/dist/controller/controller.js +89 -116
- package/dist/controller/fileSchedulerStoreAdapter.js +511 -742
- package/dist/controller/jobControl.js +17 -17
- package/dist/controller/resourceInventory.js +6 -6
- package/dist/controller/resourceInventoryLinux.js +38 -59
- package/dist/controller/resourceInventoryRpc.js +3 -3
- package/dist/controller/resourceInventoryWorker.js +1 -1
- package/dist/controller/runtime.js +46 -53
- package/dist/controller/runtimeEventInbox.js +23 -31
- package/dist/controller/runtimeEventProcessor.js +15 -15
- package/dist/controller/{runtimeHookRunFence.js → runtimeHookTurnFence.js} +87 -81
- package/dist/controller/runtimeLaunchCoordinator.js +3 -3
- package/dist/controller/runtimeObservationHook.js +11 -8
- package/dist/controller/sessionNotify.js +11 -11
- package/dist/controller/structuredProviderObservation.js +89 -16
- package/dist/coordination/workMailbox.js +309 -579
- package/dist/coordination/workMailboxQueue.js +5 -6
- package/dist/core/controllerClient.js +1 -91
- package/dist/core/controllerServer.js +3 -6
- package/dist/doctor/doctor.js +51 -314
- package/dist/execution/candidateConvergence.js +3 -3
- package/dist/execution/executionGroup.js +32 -33
- package/dist/execution/executionHealth.js +36 -38
- package/dist/execution/resourceBroker.js +12 -12
- package/dist/executor/agentExecutor.js +30 -265
- package/dist/executor/effectiveLaunch.js +9 -19
- package/dist/executor/executorRegistry.js +43 -17
- package/dist/executor/fileRoleLaunchPlanner.js +56 -56
- package/dist/executor/launchPlan.js +3 -3
- package/dist/executor/workspacePreflightClassification.js +16 -16
- package/dist/grant/capabilityGrant.js +20 -25
- package/dist/input/inputRequest.js +12 -12
- package/dist/integration/changeSet.js +9 -13
- package/dist/integration/changeSetManifest.js +1 -1
- package/dist/integration/gitIntegrationService.js +2 -2
- package/dist/integration/integrationQueueService.js +5 -21
- package/dist/integration/overlapDiagnostics.js +2 -2
- package/dist/interaction/operatorPresentation.js +1 -1
- package/dist/job/jobRunner.js +1 -1
- package/dist/lifecycle/canonicalLifecycleEvent.js +25 -25
- package/dist/lifecycle/{exactRunTerminalization.js → exactTurnTerminalization.js} +116 -232
- package/dist/message/message.js +6 -6
- package/dist/observability/executionAudit.js +74 -86
- package/dist/observability/faultClassification.js +7 -24
- package/dist/observability/orchestrationMetrics.js +5 -5
- package/dist/observability/runtimeIdentity.js +34 -101
- package/dist/profile/agentProfile.js +1 -1
- package/dist/release/cliHomeReleaseFence.js +3 -3
- package/dist/release/releaseWorkflowEngine.js +6 -10
- package/dist/release/releaseWorkflowPorts.js +2 -2
- package/dist/release/workflowFileLock.js +1 -1
- package/dist/repository/checkoutSwap.js +1 -1
- package/dist/repository/gitWorkspace.js +0 -13
- package/dist/repository/project.js +1 -1
- package/dist/repository/projectMaintenanceLock.js +1 -2
- package/dist/repository/taskBaseFreshness.js +13 -13
- package/dist/repository/taskWorkspaceCoordinator.js +21 -25
- package/dist/repository/taskWorkspaceIdentity.js +8 -21
- package/dist/repository/taskWorkspacePreparer.js +63 -620
- package/dist/resources/autoResourceGc.js +3 -3
- package/dist/resources/liveReferences.js +1 -1
- package/dist/resources/resourceGc.js +1 -1
- package/dist/resources/sqliteResourceRegistry.js +1 -1
- package/dist/review/reviewDecision.js +7 -7
- package/dist/review/reviewFindingLedger.js +1 -1
- package/dist/review/reviewOutcomeClassifier.js +35 -50
- package/dist/review/reviewRound.js +14 -25
- package/dist/review/reviewerAvailability.js +4 -4
- package/dist/review/taskFinalReviewContractResolution.js +41 -0
- package/dist/role/role.js +6 -3
- package/dist/runtime/agentDriver.js +4 -0
- package/dist/runtime/agentHost.js +151 -36
- package/dist/runtime/builtinAgentDrivers.js +79 -2
- package/dist/runtime/codexAppServerRuntime.js +122 -0
- package/dist/runtime/continuationManager.js +3 -5
- package/dist/runtime/exactControlPlane.js +17 -42
- package/dist/runtime/firstProgressAdvisory.js +1 -1
- package/dist/runtime/index.js +2 -2
- package/dist/runtime/launchDiagnostics.js +2 -2
- package/dist/runtime/lifecycleReservation.js +4 -4
- package/dist/runtime/processExitObservation.js +1 -1
- package/dist/runtime/processExitOutbox.js +0 -32
- package/dist/runtime/promptEnvelope.js +9 -9
- package/dist/runtime/providerContinuation.js +2 -2
- package/dist/runtime/providerContinuationReconciliationService.js +2 -2
- package/dist/runtime/providerRuntimeIdentity.js +76 -24
- package/dist/runtime/recentTurnIds.js +38 -0
- package/dist/runtime/runtimeContinuationProjection.js +2 -2
- package/dist/runtime/runtimeHealthPolicy.js +1 -1
- package/dist/runtime/runtimeObservation.js +58 -21
- package/dist/runtime/runtimeProjection.js +19 -27
- package/dist/runtime/sessionLaunchRequest.js +2 -2
- package/dist/runtime/structuredProviderHost.js +177 -12
- package/dist/runtime/tmuxAdapters.js +46 -11
- package/dist/scheduler/activeRoleTurnDelivery.js +245 -0
- package/dist/scheduler/leaderWakeupProcessor.js +147 -445
- package/dist/scheduler/operatorEvent.js +4 -6
- package/dist/scheduler/resourceQueueProjection.js +71 -0
- package/dist/scheduler/{roleRunLiveness.js → roleTurnLiveness.js} +24 -28
- package/dist/scheduler/{roleRunStall.js → roleTurnStall.js} +162 -247
- package/dist/scheduler/taskExecutionProjection.js +99 -99
- package/dist/scheduler/taskObservabilityProjection.js +10 -10
- package/dist/scheduler/taskWake.js +4 -4
- package/dist/scheduler/wakeReason.js +6 -10
- package/dist/scheduler/wakeupQueue.js +0 -9
- package/dist/setup/setupCommand.js +2 -2
- package/dist/storage/currentTaskStore.js +46 -0
- package/dist/storage/persistenceWorker.js +1 -1
- package/dist/storage/sqliteSchema.js +81 -485
- package/dist/storage/sqliteStore.js +206 -365
- package/dist/storage/storageSchema.js +1 -15
- package/dist/storage/storageVersions.js +8 -9
- package/dist/storage/storeRpc.js +10 -34
- package/dist/storage/taskStore.js +63 -3415
- package/dist/storage/upgrade/recordVersions.js +55 -149
- package/dist/storage/upgrade/upgradeOrchestrator.js +89 -1752
- package/dist/task/completionReadiness.js +5 -5
- package/dist/task/deliveryGuard.js +10 -10
- package/dist/task/nextAction.js +74 -77
- package/dist/task/task.js +2 -4
- package/dist/task/taskRecordReference.js +3 -3
- package/dist/task/taskRecordRetirement.js +1 -1
- package/dist/telemetry/sqliteTelemetryStore.js +53 -53
- package/dist/telemetry/telemetryConfig.js +14 -14
- package/dist/telemetry/telemetryWiring.js +8 -14
- package/dist/turn/turn.js +356 -0
- package/dist/{run/runIdentity.js → turn/turnIdentity.js} +4 -4
- package/dist/verification/gateArtifactStore.js +2 -2
- package/dist/web/assets/client/app.js +1 -1
- package/dist/web/assets/client/components.js +29 -54
- package/dist/web/assets/client/i18n.js +17 -37
- package/dist/web/assets/client/view.js +37 -37
- package/dist/web/assets/shell.js +1 -1
- package/dist/web/assets/styles/cards.js +5 -5
- package/dist/web/assets/styles/widgets.js +1 -2
- package/dist/web/webSnapshot.js +65 -60
- package/dist/workItem/workItem.js +11 -11
- package/dist/workspace/workItemChangeSetManager.js +1 -1
- package/docs/task-local-identity.md +5 -5
- package/i18n/README.zh-CN.md +41 -54
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +85 -83
- package/skills/yui-operator/SKILL.md +16 -16
- package/skills/yui-reviewer/SKILL.md +10 -10
- package/skills/yui-runtime/SKILL.md +17 -18
- package/skills/yui-worker/SKILL.md +16 -18
- package/dist/context/runContextContract.js +0 -162
- package/dist/executor/turnCompletion.js +0 -126
- package/dist/review/taskFinalReviewContractEvent.js +0 -1
- package/dist/review/taskFinalReviewContractRebind.js +0 -367
- package/dist/run/agentRun.js +0 -356
- package/dist/run/rejectedYieldAttempt.js +0 -221
- package/dist/run/runControlRequest.js +0 -50
- package/dist/run/yieldReceipt.js +0 -65
- package/dist/runtime/turnCompletion.js +0 -3
- package/dist/scheduler/actionability.js +0 -323
- package/dist/scheduler/activeRoleRunDelivery.js +0 -868
- package/dist/scheduler/activeTaskProgress.js +0 -126
- package/dist/storage/compatibleTaskStore.js +0 -248
- package/dist/storage/migration/baseline.js +0 -78
- package/dist/storage/migration/classifier.js +0 -51
- package/dist/storage/migration/compatibleCodec.js +0 -53
- package/dist/storage/migration/engine.js +0 -147
- package/dist/storage/migration/index.js +0 -33
- package/dist/storage/migration/planner.js +0 -154
- package/dist/storage/migration/productionRegistry.js +0 -3931
- package/dist/storage/migration/registry.js +0 -169
- package/dist/storage/migration/report.js +0 -54
- package/dist/storage/migration/types.js +0 -31
- package/dist/storage/upgrade/homeClassification.js +0 -353
- package/dist/storage/upgrade/homeMigrationTarget.js +0 -595
- package/dist/storage/upgrade/migrationReceipt.js +0 -67
- package/dist/storage/upgrade/offlineUpgradeInventory.js +0 -453
- package/dist/storage/upgrade/productionMigrationRegistry.js +0 -6
- package/dist/storage/upgrade/pseudoLayoutRepair.js +0 -241
- package/dist/storage/upgrade/recordVersionScan.js +0 -176
- package/dist/storage/upgrade/sqliteFileSet.js +0 -50
- package/dist/storage/upgrade/sqliteMigrationTarget.js +0 -375
- package/dist/storage/upgrade/sqliteRecordMigrationTarget.js +0 -305
- package/dist/storage/upgrade/sqliteStateMigration.js +0 -918
- package/dist/storage/upgrade/switchProgress.js +0 -80
- package/dist/storage/upgrade/upgradeReceipt.js +0 -161
- package/dist/storage/upgradeCoordination.js +0 -187
- package/dist/storage/upgradeFence.js +0 -366
- package/dist/telemetry/telemetryCompaction.js +0 -252
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { enqueueWork } from "../coordination/workMailboxQueue.js";
|
|
2
2
|
import { createTaskEvent } from "../event/taskEvent.js";
|
|
3
|
+
import { queueLeaderWakeup } from "./wakeupQueue.js";
|
|
3
4
|
export const LEADER_ATTENTION_REQUIRED_EVENT = "leader.attention-required";
|
|
4
5
|
/** The sole Task-event boundary into the global Operator mailbox. */
|
|
5
6
|
export function enqueueOperatorEvent(store, event, reason, now) {
|
|
@@ -7,9 +8,7 @@ export function enqueueOperatorEvent(store, event, reason, now) {
|
|
|
7
8
|
{ type: "event", taskId: event.taskId, id: event.id }
|
|
8
9
|
], {
|
|
9
10
|
source: "task-event",
|
|
10
|
-
dedupeKey: `operator-event:${event.taskId}:${event.id}
|
|
11
|
-
deliveryMode: "followup",
|
|
12
|
-
lane: "normal"
|
|
11
|
+
dedupeKey: `operator-event:${event.taskId}:${event.id}`
|
|
13
12
|
});
|
|
14
13
|
}
|
|
15
14
|
/** Routes one Role fact to its supervisor without exposing Provider details to Operator code. */
|
|
@@ -20,10 +19,9 @@ export function routeRoleEvent(store, event, roleName, reason, now) {
|
|
|
20
19
|
}
|
|
21
20
|
enqueueWork(store, { kind: "role", taskId: event.taskId, roleName: "leader" }, reason, now, [{ type: "event", taskId: event.taskId, id: event.id }], {
|
|
22
21
|
source: "task-event",
|
|
23
|
-
dedupeKey: `leader-event:${event.taskId}:${event.id}
|
|
24
|
-
deliveryMode: "followup",
|
|
25
|
-
lane: "normal"
|
|
22
|
+
dedupeKey: `leader-event:${event.taskId}:${event.id}`
|
|
26
23
|
});
|
|
24
|
+
queueLeaderWakeup(store, event.taskId, reason, now);
|
|
27
25
|
}
|
|
28
26
|
/** Records the semantic boundary used when a Leader can no longer continue. */
|
|
29
27
|
export function recordLeaderAttentionRequired(store, input) {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { currentWorkItemExecutionGroup } from "../workItem/workItem.js";
|
|
2
|
+
import { executionStageSpendClosed, observedExecutionResourceUsage, projectExecutionStageResources } from "../execution/resourceBroker.js";
|
|
3
|
+
/** Exact durable Broker queue used by resource admission. */
|
|
4
|
+
export function projectQueuedResourceLaneIdentities(store, now) {
|
|
5
|
+
return store.listActiveTaskIds().flatMap((taskId) => {
|
|
6
|
+
const taskTurns = store.listTurns(taskId);
|
|
7
|
+
const taskEvents = store.listEvents(taskId);
|
|
8
|
+
const workItemLanes = store.listWorkItems(taskId).flatMap((item) => {
|
|
9
|
+
if (item.status !== "running")
|
|
10
|
+
return [];
|
|
11
|
+
const group = currentWorkItemExecutionGroup(item);
|
|
12
|
+
if (group === undefined || group.resolution !== undefined)
|
|
13
|
+
return [];
|
|
14
|
+
if (group.stage !== undefined) {
|
|
15
|
+
const resources = projectExecutionStageResources({
|
|
16
|
+
group,
|
|
17
|
+
stageGroups: item.executionGroups,
|
|
18
|
+
usage: observedExecutionResourceUsage({
|
|
19
|
+
group,
|
|
20
|
+
stageGroups: item.executionGroups,
|
|
21
|
+
turns: taskTurns,
|
|
22
|
+
events: taskEvents
|
|
23
|
+
}),
|
|
24
|
+
now
|
|
25
|
+
});
|
|
26
|
+
if (executionStageSpendClosed(resources))
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return group.lanes.flatMap((lane) => {
|
|
30
|
+
if (lane.status !== "pending"
|
|
31
|
+
|| lane.effective === undefined
|
|
32
|
+
|| lane.turnId !== undefined)
|
|
33
|
+
return [];
|
|
34
|
+
return [{
|
|
35
|
+
taskId,
|
|
36
|
+
workItemId: item.id,
|
|
37
|
+
executionGroupId: group.id,
|
|
38
|
+
executionLaneId: lane.id,
|
|
39
|
+
providerId: lane.effective.adapterId,
|
|
40
|
+
agentId: lane.effective.agentId,
|
|
41
|
+
...(lane.effective.model === undefined ? {} : { model: lane.effective.model }),
|
|
42
|
+
requestedAt: lane.updatedAt
|
|
43
|
+
}];
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
const reviewLanes = store.listReviewRounds(taskId).flatMap((round) => {
|
|
47
|
+
if (round.status !== "pending" && round.status !== "running")
|
|
48
|
+
return [];
|
|
49
|
+
const group = round.executionGroup;
|
|
50
|
+
if (group === undefined || group.resolution !== undefined)
|
|
51
|
+
return [];
|
|
52
|
+
return group.lanes.flatMap((lane) => {
|
|
53
|
+
if (lane.status !== "pending"
|
|
54
|
+
|| lane.effective === undefined
|
|
55
|
+
|| lane.turnId !== undefined)
|
|
56
|
+
return [];
|
|
57
|
+
return [{
|
|
58
|
+
taskId,
|
|
59
|
+
...(round.workItemId === undefined ? {} : { workItemId: round.workItemId }),
|
|
60
|
+
executionGroupId: group.id,
|
|
61
|
+
executionLaneId: lane.id,
|
|
62
|
+
providerId: lane.effective.adapterId,
|
|
63
|
+
agentId: lane.effective.agentId,
|
|
64
|
+
...(lane.effective.model === undefined ? {} : { model: lane.effective.model }),
|
|
65
|
+
requestedAt: lane.updatedAt
|
|
66
|
+
}];
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
return [...workItemLanes, ...reviewLanes];
|
|
70
|
+
});
|
|
71
|
+
}
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import { selectedSchedulerRoles, selectedActiveSchedulerTasks } from "./ports.js";
|
|
2
2
|
import { formatTaskRecordReference } from "../task/taskRecordReference.js";
|
|
3
|
-
import {
|
|
3
|
+
import { currentRoleTurnProgressAt, DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS } from "./roleTurnStall.js";
|
|
4
4
|
/**
|
|
5
|
-
* Lightweight liveness only.
|
|
6
|
-
*
|
|
7
|
-
* deliveredAt is absent; pane/process loss is therefore runtime-health
|
|
8
|
-
* evidence, not an application-level outcome. The Run stays active so native
|
|
5
|
+
* Lightweight liveness only. Pane/process loss is runtime-health evidence,
|
|
6
|
+
* not an application-level outcome. The Turn stays active so native
|
|
9
7
|
* child work or another observer can still contribute facts, while the stall
|
|
10
8
|
* path raises bounded attention independently.
|
|
11
9
|
* Process liveness is only a recovery signal. An absent pane/Host never proves
|
|
12
|
-
* that the native Session or
|
|
13
|
-
* native identity when possible, otherwise preserve the active
|
|
10
|
+
* that the native Session or Turn ended; recover the same generation and
|
|
11
|
+
* native identity when possible, otherwise preserve the active Turn.
|
|
14
12
|
*/
|
|
15
|
-
export async function
|
|
13
|
+
export async function reconcileExitedRoleTurns(store, delivery, now, selection, excludedTurnRefs = new Set(), liveStatuses, resourceEvidence, targetedInventory = selection !== undefined && !selection.full) {
|
|
16
14
|
const failed = [];
|
|
17
15
|
const candidates = selectedActiveSchedulerTasks(store, selection).flatMap((task) => (selectedSchedulerRoles(store, task.id, selection).flatMap((role) => {
|
|
18
|
-
const run = store.
|
|
16
|
+
const run = store.getActiveTurn(task.id, role.name);
|
|
19
17
|
if (run === null)
|
|
20
18
|
return [];
|
|
21
19
|
const session = store.getRoleSession(task.id, role.name, run.effective.agentId);
|
|
@@ -29,8 +27,8 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
29
27
|
roleName: role.name,
|
|
30
28
|
agentId: run.effective.agentId,
|
|
31
29
|
adapterId: run.effective.adapterId,
|
|
32
|
-
|
|
33
|
-
progressAt: run.
|
|
30
|
+
turnId: run.id,
|
|
31
|
+
progressAt: run.createdAt,
|
|
34
32
|
...(session?.launchId === undefined ? {} : { launchId: session.launchId }),
|
|
35
33
|
...(session?.nativeSessionId === undefined
|
|
36
34
|
? {}
|
|
@@ -40,10 +38,9 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
40
38
|
})));
|
|
41
39
|
if (candidates.length === 0)
|
|
42
40
|
return failed;
|
|
43
|
-
const eligible = candidates.filter(({ task, run }) => (!
|
|
44
|
-
&& run.pushedAt === undefined));
|
|
41
|
+
const eligible = candidates.filter(({ task, run }) => (!excludedTurnRefs.has(formatTaskRecordReference(task.id, run.id, "turn"))));
|
|
45
42
|
// Full reconciliation builds one complete provider inventory for every
|
|
46
|
-
// active
|
|
43
|
+
// active Turn, including delivery-uncertain and completion-pending Turns.
|
|
47
44
|
// The stall phase reuses that snapshot so one full pass never probes the
|
|
48
45
|
// same pane twice. When targetedInventory is true, a dirty pass instead
|
|
49
46
|
// uses exact probes below; stall reconciliation intentionally does not run
|
|
@@ -60,10 +57,10 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
60
57
|
? [{
|
|
61
58
|
taskId: task.id,
|
|
62
59
|
roleName: role.name,
|
|
63
|
-
|
|
60
|
+
turnId: run.id,
|
|
64
61
|
agentId: run.effective.agentId,
|
|
65
62
|
adapterId: run.effective.adapterId,
|
|
66
|
-
progressAt:
|
|
63
|
+
progressAt: currentRoleTurnProgressAt(store, task.id, role.name, run).progressAt,
|
|
67
64
|
...(session?.nativeSessionId === undefined
|
|
68
65
|
? {}
|
|
69
66
|
: { nativeSessionId: session.nativeSessionId }),
|
|
@@ -79,7 +76,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
79
76
|
for (const [key, resource] of batchSnapshot.resources) {
|
|
80
77
|
const candidate = candidates.find(({ task, role }) => (`${task.id}\0${role.name}` === key));
|
|
81
78
|
if (candidate !== undefined) {
|
|
82
|
-
// Keep only the exact
|
|
79
|
+
// Keep only the exact Turn key. A task/role or bare-Turn fallback can
|
|
83
80
|
// bridge an asynchronous sample from a prior generation.
|
|
84
81
|
resourceEvidence.set(`${key}\0${candidate.run.id}`, resource);
|
|
85
82
|
}
|
|
@@ -96,7 +93,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
96
93
|
store.saveRoleHostExitObservation?.({
|
|
97
94
|
taskId: task.id,
|
|
98
95
|
roleName: role.name,
|
|
99
|
-
|
|
96
|
+
turnId: run.id,
|
|
100
97
|
...(session?.launchId === undefined ? {} : { launchId: session.launchId }),
|
|
101
98
|
...(session?.nativeSessionId === undefined
|
|
102
99
|
? {}
|
|
@@ -113,7 +110,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
113
110
|
delivery.forgetPrepared?.({
|
|
114
111
|
taskId: task.id,
|
|
115
112
|
roleName: role.name,
|
|
116
|
-
|
|
113
|
+
turnId: run.id
|
|
117
114
|
});
|
|
118
115
|
const recovered = await delivery.prepareRoleSession({
|
|
119
116
|
taskId: task.id,
|
|
@@ -124,16 +121,16 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
124
121
|
workspace: run.effective.workspace.root,
|
|
125
122
|
...(run.workspace === undefined ? {} : { managedWorkspace: run.workspace }),
|
|
126
123
|
mode: "resume",
|
|
127
|
-
|
|
124
|
+
turnId: run.id,
|
|
128
125
|
nativeSessionId: session.nativeSessionId,
|
|
129
126
|
...(session.launchId === undefined
|
|
130
127
|
? {}
|
|
131
128
|
: { hostActivationId: session.launchId })
|
|
132
129
|
});
|
|
133
|
-
store.
|
|
130
|
+
store.saveRoleTurnPrepared({
|
|
134
131
|
task,
|
|
135
132
|
role,
|
|
136
|
-
run,
|
|
133
|
+
turn: run,
|
|
137
134
|
session: recovered.session ?? session,
|
|
138
135
|
...(recovered.launchId === undefined ? {} : { launchId: recovered.launchId }),
|
|
139
136
|
now
|
|
@@ -142,7 +139,7 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
142
139
|
}
|
|
143
140
|
catch {
|
|
144
141
|
// Absence plus an inconclusive local recovery attempt is still not a
|
|
145
|
-
// native Session death proof. Keep the exact
|
|
142
|
+
// native Session death proof. Keep the exact Turn active for the next
|
|
146
143
|
// bounded recovery pass and expose the blocked axis separately.
|
|
147
144
|
store.queueTaskProgress(task.id, "host-missing-native-resume-pending", now);
|
|
148
145
|
}
|
|
@@ -201,11 +198,10 @@ function exactBatchInventory(batch, candidates) {
|
|
|
201
198
|
function isResourceCandidate(task, run, now) {
|
|
202
199
|
if (task.status !== "active"
|
|
203
200
|
|| task.executionGate.state !== "enabled"
|
|
204
|
-
|| run.status !== "active"
|
|
205
|
-
|| run.deliveredAt === undefined) {
|
|
201
|
+
|| run.status !== "active") {
|
|
206
202
|
return false;
|
|
207
203
|
}
|
|
208
|
-
const
|
|
209
|
-
return Number.isFinite(
|
|
210
|
-
&& now.getTime() -
|
|
204
|
+
const createdAt = Date.parse(run.createdAt);
|
|
205
|
+
return Number.isFinite(createdAt)
|
|
206
|
+
&& now.getTime() - createdAt >= DEFAULT_WORKFLOW_STALL_CANDIDATE_AGE_MS;
|
|
211
207
|
}
|