@zq-silk/yui 0.15.11 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +11 -6
- package/ARCHITECTURE.zh-CN.md +8 -4
- package/README.md +13 -5
- package/dist/agentRun/agentRun.js +3 -0
- package/dist/artifacts/artifactCommitLock.js +16 -55
- package/dist/artifacts/taskArtifactRepository.js +3 -3
- package/dist/cli/agentConfigurationPicker.js +1 -1
- package/dist/cli/commandCatalog.js +92 -48
- package/dist/cli/completion.js +18 -18
- package/dist/cli/completionWizard.js +1 -1
- package/dist/cli/dynamicCompletion.js +1 -1
- package/dist/cli/interactionPolicy.js +11 -3
- package/dist/cli/invocationAuthority.js +64 -0
- package/dist/cli/managedDiagnostics.js +2 -2
- package/dist/cli/parseRepeatable.js +35 -0
- package/dist/cli/updatePorts.js +26 -5
- package/dist/cli.js +1303 -1235
- package/dist/commands/agentCommands.js +4 -4
- package/dist/commands/capabilityCommands.js +1 -1
- package/dist/commands/configCommands.js +6 -57
- package/dist/commands/configOverview.js +2 -2
- package/dist/commands/durableJobCommands.js +12 -6
- package/dist/commands/executionAuditCommands.js +10 -0
- package/dist/commands/globalRoleCommands.js +78 -29
- package/dist/commands/grantCommands.js +0 -3
- package/dist/commands/jobCommands.js +1 -4
- package/dist/commands/operatorCommands.js +3 -3
- package/dist/commands/projectCommands.js +45 -25
- package/dist/commands/resourcesCommands.js +10 -40
- package/dist/commands/roleConfiguration.js +2 -6
- package/dist/commands/taskActivationCommands.js +4 -8
- package/dist/commands/taskAgentCapabilities.js +9 -0
- package/dist/commands/taskCommandSupport.js +155 -0
- package/dist/commands/taskCommandTypes.js +1 -0
- package/dist/commands/taskCommands.js +355 -732
- package/dist/commands/taskCompletionGate.js +1 -1
- package/dist/commands/taskExecutionCommands.js +1 -1
- package/dist/commands/taskFactCommands.js +325 -0
- package/dist/commands/taskInputCommands.js +12 -42
- package/dist/commands/taskIntegrationCommands.js +20 -58
- package/dist/commands/taskNextActionCommand.js +7 -6
- package/dist/commands/taskPublicationAdoptCommand.js +127 -0
- package/dist/commands/taskPublicationCommands.js +12 -3
- package/dist/commands/taskPublicationVerifyCommand.js +24 -40
- package/dist/commands/taskRemoteDeliveryCommand.js +5 -86
- package/dist/commands/taskUpstreamCommands.js +19 -8
- package/dist/commands/workflowCommands.js +6 -1
- package/dist/completion/completionInstaller.js +26 -26
- package/dist/completion/completionState.js +26 -26
- package/dist/completion/fileCompletionManager.js +6 -11
- package/dist/config/configCatalog.js +0 -2
- package/dist/config/timeZone.js +14 -0
- package/dist/config/yuiConfig.js +0 -29
- package/dist/context/runContextPack.js +5 -3
- package/dist/context/taskCatalog.js +185 -0
- package/dist/context/taskContext.js +152 -151
- package/dist/context/wakeRunReferences.js +11 -0
- package/dist/controller/agentCapabilities.js +58 -0
- package/dist/controller/agentRuntimeObserver.js +6 -11
- package/dist/controller/clientRuntime.js +22 -14
- package/dist/controller/controller.js +20 -24
- package/dist/controller/fileSchedulerStoreAdapter.js +191 -225
- package/dist/controller/globalInputDelivery.js +13 -0
- package/dist/controller/jobClient.js +4 -4
- package/dist/controller/jobControl.js +60 -25
- package/dist/controller/jobSupervisor.js +4 -4
- package/dist/controller/providerRetryAdmission.js +100 -0
- package/dist/controller/providerRetryDelivery.js +218 -0
- package/dist/controller/runtime.js +85 -43
- package/dist/controller/runtimeEventProcessor.js +0 -5
- package/dist/controller/sessionOwnerReconciliation.js +5 -0
- package/dist/controller/taskAgentError.js +35 -0
- package/dist/coordination/workMailboxQueue.js +2 -24
- package/dist/core/controllerClient.js +2 -2
- package/dist/core/fileLockOwner.js +74 -0
- package/dist/decision/decision.js +17 -0
- package/dist/doctor/doctor.js +18 -9
- package/dist/event/taskEvent.js +12 -0
- package/dist/execution/workItemExecutionProjection.js +2 -2
- package/dist/executor/agentCapabilityConfig.js +43 -0
- package/dist/executor/agentConfigurationCatalog.js +49 -11
- package/dist/executor/agentExecutor.js +5 -8
- package/dist/executor/fileRoleLaunchPlanner.js +11 -53
- package/dist/executor/taskAgentCapabilities.js +64 -0
- package/dist/integration/deliveryObligation.js +1 -69
- package/dist/integration/gitIntegrationService.js +79 -90
- package/dist/integration/integrationAttempt.js +3 -14
- package/dist/integration/integrationSourceApplication.js +4 -12
- package/dist/integration/manifestTags.js +2 -2
- package/dist/job/durableJob.js +4 -25
- package/dist/job/jobAssignmentScope.js +22 -0
- package/dist/job/jobOperation.js +16 -0
- package/dist/job/jobRunner.js +2 -1
- package/dist/job/stepDirectory.js +15 -0
- package/dist/kernel/builtinCapabilities.js +15 -11
- package/dist/kernel/kernelPorts.js +1 -17
- package/dist/lifecycle/exactRunTerminalization.js +5 -10
- package/dist/message/globalProviderRetry.js +15 -0
- package/dist/message/inputControlResolution.js +3 -4
- package/dist/message/message.js +17 -20
- package/dist/message/messageContinuation.js +1 -1
- package/dist/milestone/milestone.js +11 -0
- package/dist/observability/executionAudit.js +19 -0
- package/dist/observability/orchestrationMetrics.js +24 -1
- package/dist/observability/runtimeIdentity.js +1 -17
- package/dist/output/agentConfigurationPresentation.js +2 -0
- package/dist/output/timePresentation.js +1 -14
- package/dist/plugins/pluginService.js +12 -4
- package/dist/release/releaseWorkflowPorts.js +45 -96
- package/dist/release/runtimeRelease.js +9 -15
- package/dist/repository/gitWorkspace.js +371 -105
- package/dist/repository/projectMaintenanceLock.js +98 -82
- package/dist/repository/taskBaseFreshness.js +1 -1
- package/dist/repository/taskWorkspaceCoordinator.js +82 -144
- package/dist/repository/taskWorkspacePreparer.js +113 -47
- package/dist/repository/workspaceCleanupInspection.js +187 -0
- package/dist/resources/autoResourceGc.js +4 -77
- package/dist/resources/liveReferences.js +7 -54
- package/dist/resources/resourceDiscovery.js +5 -118
- package/dist/resources/resourceGc.js +233 -181
- package/dist/resources/resourceRegistrar.js +5 -4
- package/dist/resources/resourceRegistry.js +3 -37
- package/dist/resources/resourceRegistryStore.js +13 -36
- package/dist/resources/sqliteResourceRegistry.js +43 -26
- package/dist/review/deltaRecheck.js +1 -1
- package/dist/review/reviewAcceptance.js +1 -1
- package/dist/review/reviewDecision.js +1 -1
- package/dist/review/reviewRound.js +8 -7
- package/dist/review/taskFinalReviewContractResolution.js +1 -1
- package/dist/runtime/acpProtocol.js +4 -51
- package/dist/runtime/acpSession.js +10 -75
- package/dist/runtime/acpSessionConfiguration.js +1 -8
- package/dist/runtime/agentEndpoint.js +3 -2
- package/dist/runtime/agentError.js +5 -3
- package/dist/runtime/agentFailureContext.js +43 -0
- package/dist/runtime/agentHost.js +42 -25
- package/dist/runtime/builtinAgentErrorMappers.js +91 -0
- package/dist/runtime/codexAppServerRuntime.js +34 -3
- package/dist/runtime/codexInteractiveHost.js +2 -2
- package/dist/runtime/index.js +0 -1
- package/dist/runtime/managedCaller.js +21 -1
- package/dist/runtime/providerControl.js +5 -1
- package/dist/runtime/providerErrors.js +38 -0
- package/dist/runtime/providerRetry.js +198 -0
- package/dist/runtime/providerRuntimeIdentity.js +28 -2
- package/dist/runtime/runtimeObservation.js +0 -5
- package/dist/runtime/runtimeSessionCandidate.js +2 -3
- package/dist/runtime/sessionOwnerIdentity.js +1 -1
- package/dist/runtime/sessionTokenMetrics.js +15 -5
- package/dist/runtime/structuredProviderHost.js +10 -43
- package/dist/runtime/taskUsageMetrics.js +275 -0
- package/dist/runtime/tmuxAdapters.js +6 -8
- package/dist/scheduler/activeRoleRunDelivery.js +19 -7
- package/dist/scheduler/leaderWakeupProcessor.js +24 -6
- package/dist/scheduler/operatorEvent.js +12 -20
- package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
- package/dist/scheduler/ports.js +5 -8
- package/dist/scheduler/roleRunLiveness.js +4 -4
- package/dist/scheduler/roleRunStall.js +16 -23
- package/dist/scheduler/taskExecutionProjection.js +49 -36
- package/dist/scheduler/taskObservabilityProjection.js +6 -45
- package/dist/scheduler/taskWake.js +5 -10
- package/dist/scheduler/wakeReason.js +2 -0
- package/dist/scheduler/wakeupQueue.js +2 -4
- package/dist/setup/setupCommand.js +1 -1
- package/dist/storage/contextRecords.js +106 -0
- package/dist/storage/currentTaskStore.js +1 -1
- package/dist/storage/homeLayout.js +13 -17
- package/dist/storage/migrations/agentFailureContext.js +22 -0
- package/dist/storage/migrations/currentInputContract.js +86 -0
- package/dist/storage/migrations/currentRuntimeContract.js +228 -0
- package/dist/storage/migrations/historicalVerificationPlan.js +35 -0
- package/dist/storage/migrations/integrationContinuation.js +5 -4
- package/dist/storage/migrations/narrowAgentFailureContext.js +65 -0
- package/dist/storage/migrations/notificationOnlyWakes.js +74 -0
- package/dist/storage/migrations/verificationPlanV1.js +162 -0
- package/dist/storage/migrations/verificationPolicy.js +74 -0
- package/dist/storage/migrations/workItemHistory.js +46 -0
- package/dist/storage/persistenceWorker.js +12 -4
- package/dist/storage/recordValidation.js +87 -0
- package/dist/storage/sqliteSchema.js +173 -1
- package/dist/storage/sqliteStore.js +172 -161
- package/dist/storage/storageSchema.js +2 -14
- package/dist/storage/storageVersions.js +1 -1
- package/dist/storage/storeRpc.js +16 -7
- package/dist/storage/taskCatalog.js +123 -0
- package/dist/storage/taskStore.js +5 -7
- package/dist/storage/upgrade/upgradeOrchestrator.js +25 -37
- package/dist/task/archiveDiagnostics.js +1 -0
- package/dist/task/archivePreflight.js +124 -0
- package/dist/task/completionReadiness.js +5 -24
- package/dist/task/draftPlan.js +0 -53
- package/dist/task/nextAction.js +7 -13
- package/dist/task/publicationAdoption.js +56 -0
- package/dist/task/publicationReference.js +10 -0
- package/dist/task/remoteDelivery.js +31 -16
- package/dist/task/remoteDeliveryService.js +89 -0
- package/dist/task/taskActivation.js +2 -25
- package/dist/task/taskActivationService.js +0 -2
- package/dist/task/taskRecordReference.js +0 -1
- package/dist/task/taskSubmission.js +3 -14
- package/dist/telemetry/sqliteTelemetryBatch.js +29 -0
- package/dist/telemetry/sqliteTelemetryStore.js +49 -49
- package/dist/telemetry/telemetryWiring.js +4 -3
- package/dist/tmux/tmuxManager.js +29 -20
- package/dist/verification/gateArtifact.js +15 -24
- package/dist/verification/gateArtifactStore.js +14 -7
- package/dist/verification/verificationGateService.js +29 -88
- package/dist/verification/verificationPlan.js +27 -72
- package/dist/web/assets/client/app.js +92 -17
- package/dist/web/assets/client/components.js +55 -13
- package/dist/web/assets/client/i18n.js +72 -4
- package/dist/web/assets/client/taskSurface.js +6 -5
- package/dist/web/assets/client/view.js +35 -7
- package/dist/web/assets/shell.js +6 -0
- package/dist/web/assets/styles/layout.js +7 -0
- package/dist/web/webServer.js +12 -3
- package/dist/web/webSnapshot.js +14 -85
- package/dist/web/webTaskSurface.js +17 -46
- package/dist/workItem/workItem.js +1 -12
- package/dist/workspace/cleanupInspection.js +63 -0
- package/dist/workspace/workItemChangeSetManager.js +110 -50
- package/docs/agent-result-consumption.md +4 -0
- package/docs/agent-result-consumption.zh-CN.md +3 -0
- package/docs/agent-runtime-drivers.md +7 -0
- package/docs/agent-runtime-drivers.zh-CN.md +5 -0
- package/docs/architecture/README.md +2 -0
- package/docs/architecture/README.zh-CN.md +3 -1
- package/docs/architecture/capabilities-and-resources.md +42 -5
- package/docs/architecture/capabilities-and-resources.zh-CN.md +33 -3
- package/docs/managed-turn-and-session-runtime.md +121 -1
- package/docs/managed-turn-and-session-runtime.zh-CN.md +96 -2
- package/docs/observability/README.md +62 -0
- package/docs/observability/README.zh-CN.md +47 -0
- package/docs/plugin-sdk.md +4 -2
- package/docs/project-refresh.md +77 -0
- package/docs/project-refresh.zh-CN.md +59 -0
- package/docs/provider-retry.md +70 -0
- package/docs/provider-runtime.md +3 -1
- package/docs/provider-runtime.zh-CN.md +4 -2
- package/docs/release-workflow.md +190 -7
- package/docs/release-workflow.zh-CN.md +139 -5
- package/docs/roles-and-configuration.md +29 -0
- package/docs/roles-and-configuration.zh-CN.md +21 -0
- package/docs/sqlite-control-plane-design.md +16 -3
- package/docs/sqlite-control-plane-design.zh-CN.md +13 -2
- package/docs/task-dag-semantics.md +3 -3
- package/docs/task-dag-semantics.zh-CN.md +2 -2
- package/docs/task-delivery.md +223 -17
- package/docs/task-delivery.zh-CN.md +171 -14
- package/docs/task-discovery.md +101 -0
- package/docs/task-discovery.zh-CN.md +85 -0
- package/docs/testing/verification-levels.md +161 -9
- package/docs/testing/verification-levels.zh-CN.md +116 -9
- package/i18n/README.zh-CN.md +13 -7
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +5 -0
- package/skills/yui-leader/references/execution.md +3 -2
- package/skills/yui-leader/references/integration.md +9 -5
- package/skills/yui-leader/references/planning.md +9 -3
- package/skills/yui-operator/SKILL.md +24 -8
- package/skills/yui-reviewer/SKILL.md +4 -0
- package/skills/yui-runtime/SKILL.md +17 -2
- package/skills/yui-runtime/references/publication.md +26 -4
- package/skills/yui-runtime/references/recovery.md +71 -0
- package/dist/agent/agentRegistry.js +0 -10
- package/dist/agentRun/runIdentity.js +0 -22
- package/dist/commands/deliveryGuardPreflight.js +0 -30
- package/dist/commands/taskIntegrationQueueCommands.js +0 -226
- package/dist/commands/taskOverviewCommand.js +0 -376
- package/dist/completion/completionWizard.js +0 -125
- package/dist/context/dispatchContext.js +0 -110
- package/dist/context/wakeNotification.js +0 -144
- package/dist/integration/integrationCheckEvidenceReuse.js +0 -53
- package/dist/integration/integrationQueueEntry.js +0 -191
- package/dist/integration/integrationQueueService.js +0 -810
- package/dist/release/fakeReleasePorts.js +0 -55
- package/dist/runtime/sessionOwnerRegistry.js +0 -137
- package/dist/task/deliveryGuard.js +0 -226
- /package/dist/{commands/taskActor.js → task/taskAuthority.js} +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export function readHistoricalVerificationPlan(raw) {
|
|
2
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
3
|
+
throw new Error("VerificationPlan must be an object.");
|
|
4
|
+
}
|
|
5
|
+
const record = raw;
|
|
6
|
+
if (record.kind !== "verification-plan")
|
|
7
|
+
throw new Error('VerificationPlan kind must be "verification-plan".');
|
|
8
|
+
if ((record.schemaVersion ?? 1) !== 1)
|
|
9
|
+
throw new Error("VerificationPlan schemaVersion must be 1.");
|
|
10
|
+
const mode = record.mode ?? "record";
|
|
11
|
+
if (mode !== "record" && mode !== "reuse" && mode !== "enforce") {
|
|
12
|
+
throw new Error(`VerificationPlan mode is invalid: ${String(mode)}.`);
|
|
13
|
+
}
|
|
14
|
+
const plan = {
|
|
15
|
+
schemaVersion: 1, kind: "verification-plan",
|
|
16
|
+
id: identity(record.id, "VerificationPlan id"),
|
|
17
|
+
version: text(record.version, "VerificationPlan version"),
|
|
18
|
+
mode,
|
|
19
|
+
toolchain: toolchain(record.toolchain),
|
|
20
|
+
bootstrap: steps(record.bootstrap, "bootstrap"),
|
|
21
|
+
l1: { categories: categories(record.l1) },
|
|
22
|
+
l2: { steps: steps(record.l2?.steps, "l2") },
|
|
23
|
+
...(record.l3 === undefined ? {} : {
|
|
24
|
+
l3: { steps: steps(record.l3?.steps, "l3") }
|
|
25
|
+
}),
|
|
26
|
+
...(record.excludedRealResourceChecks === undefined ? {} : {
|
|
27
|
+
excludedRealResourceChecks: textList(record.excludedRealResourceChecks, "VerificationPlan excludedRealResourceChecks")
|
|
28
|
+
}),
|
|
29
|
+
...(record.artifactTtlDays === undefined ? {} : {
|
|
30
|
+
artifactTtlDays: positive(Number(record.artifactTtlDays), "VerificationPlan artifactTtlDays")
|
|
31
|
+
})
|
|
32
|
+
};
|
|
33
|
+
if (plan.l2.steps.length === 0)
|
|
34
|
+
throw new Error("VerificationPlan l2 requires at least one step.");
|
|
35
|
+
return plan;
|
|
36
|
+
}
|
|
37
|
+
export function resolveHistoricalVerificationPlan(project) {
|
|
38
|
+
let found;
|
|
39
|
+
for (const entry of project.knowledge) {
|
|
40
|
+
if (entry.status !== "active")
|
|
41
|
+
continue;
|
|
42
|
+
let parsed;
|
|
43
|
+
try {
|
|
44
|
+
parsed = JSON.parse(entry.body);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (typeof parsed !== "object" || parsed === null
|
|
50
|
+
|| parsed.kind !== "verification-plan")
|
|
51
|
+
continue;
|
|
52
|
+
const plan = readHistoricalVerificationPlan(parsed);
|
|
53
|
+
if (found !== undefined)
|
|
54
|
+
throw new Error(`Project ${project.id} declares multiple VerificationPlans; only one is allowed.`);
|
|
55
|
+
found = plan;
|
|
56
|
+
}
|
|
57
|
+
return found;
|
|
58
|
+
}
|
|
59
|
+
function toolchain(raw) {
|
|
60
|
+
if (raw === undefined)
|
|
61
|
+
return Object.freeze({});
|
|
62
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
63
|
+
throw new Error("VerificationPlan toolchain must be an object.");
|
|
64
|
+
const record = raw;
|
|
65
|
+
return {
|
|
66
|
+
...(record.node === undefined ? {} : { node: text(record.node, "VerificationPlan toolchain node") }),
|
|
67
|
+
...(record.npm === undefined ? {} : { npm: text(record.npm, "VerificationPlan toolchain npm") }),
|
|
68
|
+
...(record.platform === undefined ? {} : { platform: text(record.platform, "VerificationPlan toolchain platform") })
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function steps(raw, label) {
|
|
72
|
+
if (!Array.isArray(raw))
|
|
73
|
+
throw new Error(`VerificationPlan ${label} steps must be an array.`);
|
|
74
|
+
const names = new Set();
|
|
75
|
+
return Object.freeze(raw.map(entry => {
|
|
76
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
77
|
+
throw new Error(`VerificationPlan ${label} step must be an object.`);
|
|
78
|
+
const record = entry;
|
|
79
|
+
const name = identity(record.name, `VerificationPlan ${label} step name`);
|
|
80
|
+
if (names.has(name))
|
|
81
|
+
throw new Error(`VerificationPlan ${label} step names must be unique: ${name}.`);
|
|
82
|
+
names.add(name);
|
|
83
|
+
if (!Array.isArray(record.argv) || record.argv.length === 0) {
|
|
84
|
+
throw new Error(`VerificationPlan ${label} step ${name} requires a non-empty argv.`);
|
|
85
|
+
}
|
|
86
|
+
const step = {
|
|
87
|
+
name, argv: Object.freeze(record.argv.map(value => text(value, `VerificationPlan ${label} step ${name} argv`))),
|
|
88
|
+
...(record.cwd === undefined ? {} : { cwd: text(record.cwd, `VerificationPlan ${label} step ${name} cwd`) }),
|
|
89
|
+
...(record.env === undefined ? {} : { env: stepEnv(record.env, `${label} step ${name}`) }),
|
|
90
|
+
...(record.shell === undefined ? {} : { shell: record.shell === true })
|
|
91
|
+
};
|
|
92
|
+
if (step.cwd?.startsWith("/"))
|
|
93
|
+
throw new Error(`VerificationPlan ${label} step ${name} cwd must be workspace-relative.`);
|
|
94
|
+
return step;
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
function stepEnv(raw, label) {
|
|
98
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
99
|
+
throw new Error(`VerificationPlan ${label} env must be a map.`);
|
|
100
|
+
const env = {};
|
|
101
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
102
|
+
if (typeof value !== "string")
|
|
103
|
+
throw new Error(`VerificationPlan ${label} env values must be strings: ${key}.`);
|
|
104
|
+
env[identity(key, `VerificationPlan ${label} env key`)] = value;
|
|
105
|
+
}
|
|
106
|
+
return Object.freeze(env);
|
|
107
|
+
}
|
|
108
|
+
function categories(raw) {
|
|
109
|
+
if (raw === undefined)
|
|
110
|
+
return Object.freeze([]);
|
|
111
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
112
|
+
throw new Error("VerificationPlan l1 must be an object.");
|
|
113
|
+
const values = raw.categories;
|
|
114
|
+
if (!Array.isArray(values))
|
|
115
|
+
throw new Error("VerificationPlan l1 categories must be an array.");
|
|
116
|
+
const ids = new Set();
|
|
117
|
+
return Object.freeze(values.map(entry => {
|
|
118
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
119
|
+
throw new Error("VerificationPlan l1 category must be an object.");
|
|
120
|
+
const record = entry;
|
|
121
|
+
const id = identity(record.id, "VerificationPlan l1 category id");
|
|
122
|
+
if (ids.has(id))
|
|
123
|
+
throw new Error(`VerificationPlan l1 category ids must be unique: ${id}.`);
|
|
124
|
+
ids.add(id);
|
|
125
|
+
return Object.freeze({
|
|
126
|
+
id, paths: textList(record.paths, `VerificationPlan l1 category ${id} paths`),
|
|
127
|
+
checks: steps(record.checks, `l1 ${id}`)
|
|
128
|
+
});
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
function textList(raw, label) {
|
|
132
|
+
if (!Array.isArray(raw))
|
|
133
|
+
throw new Error(`${label} must be an array.`);
|
|
134
|
+
const seen = new Set();
|
|
135
|
+
return Object.freeze(raw.map(value => {
|
|
136
|
+
const next = text(value, label);
|
|
137
|
+
if (seen.has(next))
|
|
138
|
+
throw new Error(`${label} must be unique: ${next}.`);
|
|
139
|
+
seen.add(next);
|
|
140
|
+
return next;
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
function text(value, label) {
|
|
144
|
+
if (typeof value !== "string" || value.includes("\0"))
|
|
145
|
+
throw new Error(`${label} is invalid.`);
|
|
146
|
+
const normalized = value.trim();
|
|
147
|
+
if (normalized.length === 0)
|
|
148
|
+
throw new Error(`${label} is required.`);
|
|
149
|
+
return normalized;
|
|
150
|
+
}
|
|
151
|
+
function identity(value, label) {
|
|
152
|
+
const normalized = text(value, label);
|
|
153
|
+
if ([".", "..", "__proto__", "prototype", "constructor"].includes(normalized) || /[\/\\\0]/u.test(normalized)) {
|
|
154
|
+
throw new Error(`${label} is invalid.`);
|
|
155
|
+
}
|
|
156
|
+
return normalized;
|
|
157
|
+
}
|
|
158
|
+
function positive(value, label) {
|
|
159
|
+
if (!Number.isSafeInteger(value) || value < 1)
|
|
160
|
+
throw new Error(`${label} must be a positive integer.`);
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { resolveHistoricalVerificationPlan } from "./verificationPlanV1.js";
|
|
2
|
+
/** Read-only: an admitted old gate keeps its original plan identity until it
|
|
3
|
+
* settles. The cutover never relabels a running Job or replays its checks. */
|
|
4
|
+
export function preflightVerificationPolicy(db) {
|
|
5
|
+
const active = db.prepare(`SELECT task_id, integration_id FROM integration_attempts
|
|
6
|
+
WHERE status IN ('running','validating')
|
|
7
|
+
AND json_type(payload,'$.gatePlanDigest') IS NOT NULL LIMIT 1`)
|
|
8
|
+
.get();
|
|
9
|
+
if (active !== undefined) {
|
|
10
|
+
throw new Error(`Verification policy cutover requires the admitted gate to settle: ${active.task_id}/${active.integration_id}. Preserve its Job and continue it with the current release before upgrading.`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Frozen 32→33 policy cutover. Only declared configuration representations
|
|
14
|
+
* change; old execution artifacts/Job results and their logs remain evidence. */
|
|
15
|
+
export function migrateVerificationPolicy(db) {
|
|
16
|
+
preflightVerificationPolicy(db);
|
|
17
|
+
const configRow = db.prepare("SELECT payload FROM config WHERE id=1").get();
|
|
18
|
+
if (configRow !== undefined) {
|
|
19
|
+
const config = JSON.parse(configRow.payload);
|
|
20
|
+
const mode = config.leaderNextActionMode;
|
|
21
|
+
const budget = config.leaderSemanticBudgetRuns;
|
|
22
|
+
if ((mode != null && (typeof mode !== "string"
|
|
23
|
+
|| !["", "display", "warn", "enforce"].includes(mode.trim().toLowerCase())))
|
|
24
|
+
|| (budget != null && (!Number.isSafeInteger(budget) || budget < 1 || budget > 20))) {
|
|
25
|
+
throw new Error("Invalid retired Leader policy; preserve the config for diagnosis.");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const projects = db.prepare("SELECT id,payload FROM projects").all();
|
|
29
|
+
const saveProject = db.prepare("UPDATE projects SET payload=? WHERE id=?");
|
|
30
|
+
for (const row of projects) {
|
|
31
|
+
const project = JSON.parse(row.payload);
|
|
32
|
+
// This frozen reader preserves validation and duplicate-plan rejection.
|
|
33
|
+
resolveHistoricalVerificationPlan(project);
|
|
34
|
+
let changed = false;
|
|
35
|
+
const knowledge = project.knowledge.map(entry => {
|
|
36
|
+
if (entry.status !== "active")
|
|
37
|
+
return entry;
|
|
38
|
+
let value;
|
|
39
|
+
try {
|
|
40
|
+
value = JSON.parse(entry.body);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return entry;
|
|
44
|
+
}
|
|
45
|
+
if (typeof value !== "object" || value === null
|
|
46
|
+
|| value.kind !== "verification-plan")
|
|
47
|
+
return entry;
|
|
48
|
+
const { mode: _mode, ...plan } = value;
|
|
49
|
+
changed = true;
|
|
50
|
+
return { ...entry, body: JSON.stringify({ ...plan, schemaVersion: 1 }) };
|
|
51
|
+
});
|
|
52
|
+
if (changed)
|
|
53
|
+
saveProject.run(JSON.stringify({ ...project, knowledge }), row.id);
|
|
54
|
+
}
|
|
55
|
+
const invalidRerun = db.prepare(`SELECT task_id,integration_id FROM integration_attempts
|
|
56
|
+
WHERE json_type(payload,'$.rerunChecks') IS NOT NULL
|
|
57
|
+
AND json_type(payload,'$.rerunChecks') NOT IN ('true','false') LIMIT 1`).get();
|
|
58
|
+
if (invalidRerun !== undefined)
|
|
59
|
+
throw new Error("Invalid Integration check execution intent; preserve the record.");
|
|
60
|
+
const artifacts = db.prepare(`SELECT key,payload FROM gate_artifacts
|
|
61
|
+
WHERE json_type(payload,'$.potentialReuseCount') IS NOT NULL`).all();
|
|
62
|
+
for (const artifact of artifacts) {
|
|
63
|
+
const count = JSON.parse(artifact.payload).potentialReuseCount;
|
|
64
|
+
if (!Number.isSafeInteger(count) || count < 0) {
|
|
65
|
+
throw new Error(`Invalid historical verification counter: ${artifact.key}. Preserve the artifact for diagnosis.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
db.exec(`
|
|
69
|
+
UPDATE config SET payload=json_remove(payload,'$.leaderNextActionMode','$.leaderSemanticBudgetRuns');
|
|
70
|
+
UPDATE integration_attempts SET payload=json_set(payload,'$.rerunChecks',json('false'))
|
|
71
|
+
WHERE json_type(payload,'$.rerunChecks') IS NULL;
|
|
72
|
+
UPDATE gate_artifacts SET payload=json_remove(payload,'$.potentialReuseCount');
|
|
73
|
+
`);
|
|
74
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Frozen 31→32 transform: obsolete execution-shaped diagnostics are audit
|
|
2
|
+
* records, not another representation of current WorkItem state. */
|
|
3
|
+
export function migrateWorkItemHistory(db) {
|
|
4
|
+
const rows = db.prepare(`SELECT task_id, work_item_id, payload FROM work_items
|
|
5
|
+
WHERE json_type(payload, '$.historicalState') IS NOT NULL
|
|
6
|
+
ORDER BY task_id, work_item_id`).all();
|
|
7
|
+
for (const row of rows) {
|
|
8
|
+
const value = JSON.parse(row.payload);
|
|
9
|
+
const history = value.historicalState;
|
|
10
|
+
if (value.taskId !== row.task_id || value.id !== row.work_item_id
|
|
11
|
+
|| history === null || typeof history !== "object" || Array.isArray(history)
|
|
12
|
+
|| !["pending", "running", "awaiting_acceptance", "completed", "failed", "retired"].includes(history.status)
|
|
13
|
+
|| (history.outcome !== undefined && !text(history.outcome))
|
|
14
|
+
|| (history.endedAt !== undefined
|
|
15
|
+
&& (!text(history.endedAt) || !Number.isFinite(Date.parse(history.endedAt))))) {
|
|
16
|
+
throw new Error(`Invalid historical WorkItem execution state: ${row.task_id}/${row.work_item_id}. Preserve it for diagnosis.`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const highWater = db.prepare(`SELECT max(
|
|
20
|
+
coalesce((SELECT high_water FROM id_sequences WHERE task_id = ? AND kind = 'event'), 0),
|
|
21
|
+
coalesce((SELECT max(CAST(substr(event_id, 7) AS INTEGER)) FROM events WHERE task_id = ?), 0)
|
|
22
|
+
) AS value`);
|
|
23
|
+
const saveEvent = db.prepare("INSERT INTO events(task_id,event_id,type,occurred_at,payload) VALUES(?,?,?,?,?)");
|
|
24
|
+
const saveCounter = db.prepare(`INSERT INTO id_sequences(task_id,kind,high_water) VALUES(?,'event',?)
|
|
25
|
+
ON CONFLICT(task_id,kind) DO UPDATE SET high_water=max(high_water,excluded.high_water)`);
|
|
26
|
+
const removeHistoricalState = db.prepare(`UPDATE work_items SET payload=json_remove(payload,'$.historicalState')
|
|
27
|
+
WHERE task_id=? AND work_item_id=?`);
|
|
28
|
+
const counters = new Map();
|
|
29
|
+
const at = new Date().toISOString();
|
|
30
|
+
for (const row of rows) {
|
|
31
|
+
const sequence = (counters.get(row.task_id)
|
|
32
|
+
?? highWater.get(row.task_id, row.task_id).value) + 1;
|
|
33
|
+
counters.set(row.task_id, sequence);
|
|
34
|
+
const event = {
|
|
35
|
+
schemaVersion: 2, id: `event-${sequence}`, taskId: row.task_id,
|
|
36
|
+
type: "work-item.execution-state-retired", createdAt: at,
|
|
37
|
+
payload: { workItemId: row.work_item_id, record: row.payload, disposition: "audit-only" }
|
|
38
|
+
};
|
|
39
|
+
saveEvent.run(row.task_id, event.id, event.type, at, JSON.stringify(event));
|
|
40
|
+
saveCounter.run(row.task_id, sequence);
|
|
41
|
+
removeHistoricalState.run(row.task_id, row.work_item_id);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function text(value) {
|
|
45
|
+
return typeof value === "string" && value.trim().length > 0 && !value.includes("\0");
|
|
46
|
+
}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The worker owns the {@link SqliteTaskStore} connection: one writer connection
|
|
5
5
|
* (single-writer, `BEGIN IMMEDIATE`) plus a small read pool (separate WAL
|
|
6
|
-
* connections
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* connections for reads). Observer folds and telemetry ingestion use this
|
|
7
|
+
* worker; the Controller's synchronous scheduler still has its own connection
|
|
8
|
+
* to the same WAL database. This is an execution boundary, not another Store.
|
|
9
9
|
*
|
|
10
10
|
* The port handshake, dispatch, cancellation observation, and error
|
|
11
11
|
* serialization are provided by the shared `core/boundedRpc` worker host
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
* - `observer` ..... a controller observer method hosted by the worker (the
|
|
23
23
|
* `FileSchedulerStoreAdapter` folds run here, off the main
|
|
24
24
|
* event loop).
|
|
25
|
+
* - `telemetry` .... bounded diagnostic batch, using existing row keys and
|
|
26
|
+
* triggers without Task revision or outbox writes.
|
|
25
27
|
* - `expectedRevision` enforces the global revision CAS in the same txn
|
|
26
28
|
* (§5.3); a mismatch fails with `StorageConflictError`.
|
|
27
29
|
*
|
|
@@ -141,6 +143,7 @@ runRpcWorker({
|
|
|
141
143
|
case "call":
|
|
142
144
|
case "transaction":
|
|
143
145
|
case "observer":
|
|
146
|
+
case "telemetry":
|
|
144
147
|
return "request";
|
|
145
148
|
}
|
|
146
149
|
},
|
|
@@ -149,6 +152,7 @@ runRpcWorker({
|
|
|
149
152
|
case "call":
|
|
150
153
|
case "transaction":
|
|
151
154
|
case "observer":
|
|
155
|
+
case "telemetry":
|
|
152
156
|
case "cancel":
|
|
153
157
|
return request.requestId;
|
|
154
158
|
case "init":
|
|
@@ -157,7 +161,7 @@ runRpcWorker({
|
|
|
157
161
|
}
|
|
158
162
|
},
|
|
159
163
|
init: (request) => handleInit(request),
|
|
160
|
-
handle: (request) => {
|
|
164
|
+
handle: async (request) => {
|
|
161
165
|
switch (request.kind) {
|
|
162
166
|
case "call":
|
|
163
167
|
return handleCall(request);
|
|
@@ -165,6 +169,10 @@ runRpcWorker({
|
|
|
165
169
|
return handleTransaction(request);
|
|
166
170
|
case "observer":
|
|
167
171
|
return handleObserver(request);
|
|
172
|
+
case "telemetry":
|
|
173
|
+
if (state.writer === undefined)
|
|
174
|
+
throw new Error("Worker not initialized.");
|
|
175
|
+
return state.writer.flushTelemetry(request.entries, request.runCap);
|
|
168
176
|
case "init":
|
|
169
177
|
case "cancel":
|
|
170
178
|
case "shutdown":
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { validateConfiguredAgent } from "../agent/agent.js";
|
|
2
|
+
import { validateRun } from "../agentRun/agentRun.js";
|
|
3
|
+
import { validateContextSnapshot } from "../context/contextSnapshot.js";
|
|
4
|
+
import { validateDecision } from "../decision/decision.js";
|
|
5
|
+
import { validateTaskEvent } from "../event/taskEvent.js";
|
|
6
|
+
import { validateRoleSessionSet } from "../executor/agentExecutor.js";
|
|
7
|
+
import { validateInputRequest } from "../input/inputRequest.js";
|
|
8
|
+
import { validateChangeSet } from "../integration/changeSet.js";
|
|
9
|
+
import { validateIntegrationAttempt } from "../integration/integrationAttempt.js";
|
|
10
|
+
import { validateDurableJob } from "../job/durableJob.js";
|
|
11
|
+
import { validateGlobalRoleMessage, validateTaskMessage } from "../message/message.js";
|
|
12
|
+
import { validateMilestone } from "../milestone/milestone.js";
|
|
13
|
+
import { validatePluginIntent } from "../plugins/pluginIntent.js";
|
|
14
|
+
import { validatePluginValidation } from "../plugins/pluginPackage.js";
|
|
15
|
+
import { validateAgentProfile } from "../profile/agentProfile.js";
|
|
16
|
+
import { validateProject } from "../repository/project.js";
|
|
17
|
+
import { validateEnvironmentPreparation, validateLocalResource } from "../resources/projectResource.js";
|
|
18
|
+
import { validateReviewRound } from "../review/reviewRound.js";
|
|
19
|
+
import { validateGlobalRole, validateTaskRole } from "../role/role.js";
|
|
20
|
+
import { createSessionOwnerIdentity } from "../runtime/sessionOwnerIdentity.js";
|
|
21
|
+
import { validateTaskWake } from "../scheduler/taskWake.js";
|
|
22
|
+
import { validateTask } from "../task/task.js";
|
|
23
|
+
import { validateGateArtifact } from "../verification/gateArtifact.js";
|
|
24
|
+
import { validateWorkItem } from "../workItem/workItem.js";
|
|
25
|
+
import { validateManagedWorkspace } from "../worktree/managedWorkspace.js";
|
|
26
|
+
import { StorageRecordError, storedCapabilityGrant, storedPublicationReference, storedReleaseWorkflow } from "./taskStore.js";
|
|
27
|
+
const check = (validate) => record => { validate(record); };
|
|
28
|
+
/** One current domain contract for saves, reads and explicit Home diagnostics.
|
|
29
|
+
* Protocol-specific metadata/outbox/telemetry have their own readers. This is
|
|
30
|
+
* validation only: historical formats belong exclusively to migrations. */
|
|
31
|
+
const validators = {
|
|
32
|
+
task_records: check(validateTask),
|
|
33
|
+
work_items: check(validateWorkItem),
|
|
34
|
+
configured_agents: check(validateConfiguredAgent),
|
|
35
|
+
agent_profiles: check(validateAgentProfile),
|
|
36
|
+
projects: check(validateProject),
|
|
37
|
+
task_roles: check(validateTaskRole),
|
|
38
|
+
global_roles: check(validateGlobalRole),
|
|
39
|
+
role_session_sets: check(validateRoleSessionSet),
|
|
40
|
+
global_role_session_sets: check(validateRoleSessionSet),
|
|
41
|
+
messages: check(validateTaskMessage),
|
|
42
|
+
global_role_messages: check(validateGlobalRoleMessage),
|
|
43
|
+
turns: check(validateRun),
|
|
44
|
+
review_rounds: check(validateReviewRound),
|
|
45
|
+
change_sets: check(validateChangeSet),
|
|
46
|
+
integration_attempts: check(validateIntegrationAttempt),
|
|
47
|
+
durable_jobs: check(validateDurableJob),
|
|
48
|
+
context_snapshots: check(validateContextSnapshot),
|
|
49
|
+
managed_workspaces: check(validateManagedWorkspace),
|
|
50
|
+
input_requests: check(validateInputRequest),
|
|
51
|
+
decisions: check(validateDecision),
|
|
52
|
+
milestones: check(validateMilestone),
|
|
53
|
+
events: check(validateTaskEvent),
|
|
54
|
+
task_wakes: check(validateTaskWake),
|
|
55
|
+
gate_artifacts: check(validateGateArtifact),
|
|
56
|
+
capability_grants: check(storedCapabilityGrant),
|
|
57
|
+
release_workflows: check(storedReleaseWorkflow),
|
|
58
|
+
publication_references: check(storedPublicationReference),
|
|
59
|
+
local_resources: check(validateLocalResource),
|
|
60
|
+
environment_preparations: check(validateEnvironmentPreparation),
|
|
61
|
+
plugin_intents: check(validatePluginIntent),
|
|
62
|
+
plugin_validations: check(validatePluginValidation),
|
|
63
|
+
session_owners: check((record) => {
|
|
64
|
+
if (record.schemaVersion !== 2 || record.kind !== "yui-session-owner" || Object.hasOwn(record, "launchId")) {
|
|
65
|
+
throw new Error("Session owner identity is invalid.");
|
|
66
|
+
}
|
|
67
|
+
createSessionOwnerIdentity({ ...record, recordedAt: new Date(record.recordedAt) });
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
export const STORED_RECORD_TABLES = Object.freeze(Object.keys(validators));
|
|
71
|
+
export function validateStoredRecord(table, record) {
|
|
72
|
+
if (!Object.hasOwn(validators, table))
|
|
73
|
+
return;
|
|
74
|
+
try {
|
|
75
|
+
if (record === null || typeof record !== "object" || Array.isArray(record)) {
|
|
76
|
+
throw new Error("Record must be an object.");
|
|
77
|
+
}
|
|
78
|
+
validators[table](record);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
const fields = record !== null && typeof record === "object" ? record : {};
|
|
82
|
+
const identity = [fields.taskId, fields.id ?? fields.name ?? fields.pluginId]
|
|
83
|
+
.filter((value) => typeof value === "string")
|
|
84
|
+
.map(value => JSON.stringify(value.slice(0, 160))).join("/");
|
|
85
|
+
throw new StorageRecordError(`Invalid ${table} record${identity ? ` ${identity}` : ""}: ${error instanceof Error ? error.message : String(error)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -25,6 +25,13 @@ import { REMOVE_RUNTIME_GENERATION_SQL, removeRuntimeGenerationRecords } from ".
|
|
|
25
25
|
import { migrateAgentRunContract } from "./migrations/agentRunContract.js";
|
|
26
26
|
import { migrateArtifactsToGit } from "./migrations/artifactsToGit.js";
|
|
27
27
|
import { migrateIntegrationContinuation } from "./migrations/integrationContinuation.js";
|
|
28
|
+
import { migrateNotificationOnlyWakes } from "./migrations/notificationOnlyWakes.js";
|
|
29
|
+
import { migrateWorkItemHistory } from "./migrations/workItemHistory.js";
|
|
30
|
+
import { migrateVerificationPolicy } from "./migrations/verificationPolicy.js";
|
|
31
|
+
import { migrateCurrentInputContract } from "./migrations/currentInputContract.js";
|
|
32
|
+
import { CURRENT_RUNTIME_CONTRACT_SQL, migrateCurrentRuntimeContract } from "./migrations/currentRuntimeContract.js";
|
|
33
|
+
import { migrateAgentFailureContext } from "./migrations/agentFailureContext.js";
|
|
34
|
+
import { migrateNarrowAgentFailureContext } from "./migrations/narrowAgentFailureContext.js";
|
|
28
35
|
import { UNIFY_HOME_LAYOUT_SQL, migrateUnifyHomeLayout } from "./migrations/unifyHomeLayout.js";
|
|
29
36
|
import { COLLAPSE_WORKTREE_LAYOUT_SQL, migrateCollapseWorktreeLayout } from "./migrations/collapseWorktreeLayout.js";
|
|
30
37
|
import { CURRENT_STORAGE_VERSION, MIN_SUPPORTED_STORAGE_VERSION } from "./storageVersions.js";
|
|
@@ -1264,6 +1271,171 @@ UPDATE review_rounds SET payload = json_set(payload, '$.executionGroup.lanes', j
|
|
|
1264
1271
|
// The data/filesystem transform is the substantive step; the SQL is inert.
|
|
1265
1272
|
sql: COLLAPSE_WORKTREE_LAYOUT_SQL,
|
|
1266
1273
|
migrateData: migrateCollapseWorktreeLayout
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
version: 26,
|
|
1277
|
+
name: "publication-candidate-adoption",
|
|
1278
|
+
introducedIn: "0.15.12",
|
|
1279
|
+
// Add optional Publication.headCommit (the observed PR/MR source head) and
|
|
1280
|
+
// publication.candidate-adopted events binding publicationId, completionEventId,
|
|
1281
|
+
// projectId, acceptedCommit/localCommit, acceptedTree/candidateTree, diffDigest,
|
|
1282
|
+
// acceptance and by, optionally integrationId/integrationDigest. Derived
|
|
1283
|
+
// task.archived mergeCoverage may also be uncovered or unverified.
|
|
1284
|
+
// No stored delivery index and no inferred adoption or verification:
|
|
1285
|
+
// valid old Publication, completion and archive payloads remain byte-identical.
|
|
1286
|
+
sql: "SELECT 1; -- fixed acceptance-to-publication evidence; preserve all historical facts"
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
version: 27,
|
|
1290
|
+
name: "bounded-provider-input-retry",
|
|
1291
|
+
introducedIn: "0.16.0",
|
|
1292
|
+
// Optional owned input/recovery records on the existing Provider binding;
|
|
1293
|
+
// positive Driver transient evidence on StandardAgentError. No historical
|
|
1294
|
+
// failures are scanned, scheduled, reclassified or replayed by upgrading.
|
|
1295
|
+
sql: `
|
|
1296
|
+
-- ProviderTurn.input/retrySupported/failure; ProviderRuntimeBinding.retry/retryHistory/retryDisabled;
|
|
1297
|
+
-- optional error retryable and retryAfterMs facts. Index existing records only.
|
|
1298
|
+
CREATE INDEX idx_task_provider_retry ON role_session_sets(
|
|
1299
|
+
json_extract(payload, '$.providerBinding.retry.status')
|
|
1300
|
+
) WHERE json_extract(payload, '$.providerBinding.retry.status') IN ('waiting', 'in-flight');
|
|
1301
|
+
CREATE INDEX idx_global_provider_retry ON global_role_session_sets(
|
|
1302
|
+
json_extract(payload, '$.providerBinding.retry.status')
|
|
1303
|
+
) WHERE json_extract(payload, '$.providerBinding.retry.status') IN ('waiting', 'in-flight');
|
|
1304
|
+
`
|
|
1305
|
+
},
|
|
1306
|
+
{
|
|
1307
|
+
version: 28,
|
|
1308
|
+
name: "current-contract-only-dispatch",
|
|
1309
|
+
introducedIn: "0.16.0",
|
|
1310
|
+
// Freeze the one valid earlier singleton dispatch shape here, not in the
|
|
1311
|
+
// normal runtime. Preserve the full input batch and sequence; only replace
|
|
1312
|
+
// its transport dedupe identity. Merged/ambiguous batches, processing
|
|
1313
|
+
// claims, original Messages, results and external-effect evidence remain
|
|
1314
|
+
// untouched. This step does not accept, replay or complete any execution.
|
|
1315
|
+
sql: `
|
|
1316
|
+
UPDATE mailboxes
|
|
1317
|
+
SET pending = json_set(pending,
|
|
1318
|
+
'$.sources', json_array('turn-dispatch'),
|
|
1319
|
+
'$.dedupeKeys', json_array('role-turn:' || task_id || ':' || role_name || ':' ||
|
|
1320
|
+
(SELECT json_extract(value, '$.id') FROM json_each(mailboxes.pending, '$.refs')
|
|
1321
|
+
WHERE json_extract(value, '$.type') = 'run'
|
|
1322
|
+
AND json_extract(value, '$.taskId') = mailboxes.task_id)))
|
|
1323
|
+
WHERE target_kind = 'role' AND role_name <> 'leader' AND pending IS NOT NULL
|
|
1324
|
+
AND json_extract(pending, '$.requestCount') = 1
|
|
1325
|
+
AND json_array_length(pending, '$.sources') = 1
|
|
1326
|
+
AND json_extract(pending, '$.sources[0]') = 'yui'
|
|
1327
|
+
AND EXISTS (SELECT 1 FROM json_each(mailboxes.pending, '$.reasons')
|
|
1328
|
+
WHERE value IN ('turn-dispatched', 'turn-retried', 'review-requested',
|
|
1329
|
+
'workitem-synthesis-ready', 'review-synthesis-ready'))
|
|
1330
|
+
AND (SELECT count(*) FROM json_each(mailboxes.pending, '$.refs')
|
|
1331
|
+
WHERE json_extract(value, '$.type') = 'run') = 1
|
|
1332
|
+
AND EXISTS (SELECT 1 FROM json_each(mailboxes.pending, '$.refs')
|
|
1333
|
+
WHERE json_extract(value, '$.type') = 'run'
|
|
1334
|
+
AND json_extract(value, '$.taskId') = mailboxes.task_id);
|
|
1335
|
+
`
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
version: 29,
|
|
1339
|
+
name: "agent-ordered-atomic-integration",
|
|
1340
|
+
introducedIn: "0.16.0",
|
|
1341
|
+
// Retire the scheduler, not its user's intent. Freeze each complete queue
|
|
1342
|
+
// payload in ordinary Task history before dropping the active table.
|
|
1343
|
+
// Existing Integrations, Jobs and WorkItem delivery evidence remain exact;
|
|
1344
|
+
// no entry is interpreted as committed or automatically replayed.
|
|
1345
|
+
sql: `
|
|
1346
|
+
CREATE TEMP TABLE retired_integration_queue AS
|
|
1347
|
+
SELECT q.*,
|
|
1348
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now') AS retired_at,
|
|
1349
|
+
max(
|
|
1350
|
+
coalesce((SELECT high_water FROM id_sequences
|
|
1351
|
+
WHERE task_id = q.task_id AND kind = 'event'), 0),
|
|
1352
|
+
coalesce((SELECT max(CAST(substr(event_id, 7) AS INTEGER)) FROM events
|
|
1353
|
+
WHERE task_id = q.task_id), 0)
|
|
1354
|
+
) + row_number() OVER (
|
|
1355
|
+
PARTITION BY q.task_id ORDER BY q.created_at,
|
|
1356
|
+
CAST(substr(q.queue_id, length('integration-queue-') + 1) AS INTEGER)
|
|
1357
|
+
) AS event_sequence
|
|
1358
|
+
FROM integration_queue AS q;
|
|
1359
|
+
|
|
1360
|
+
INSERT INTO events(task_id, event_id, type, occurred_at, payload)
|
|
1361
|
+
SELECT task_id, 'event-' || event_sequence, 'integration.queue-retired', retired_at,
|
|
1362
|
+
json_object(
|
|
1363
|
+
'schemaVersion', 2, 'id', 'event-' || event_sequence, 'taskId', task_id,
|
|
1364
|
+
'type', 'integration.queue-retired', 'createdAt', retired_at,
|
|
1365
|
+
'payload', json_object('queueId', queue_id, 'record', payload,
|
|
1366
|
+
'disposition', 'retired-without-replay')
|
|
1367
|
+
)
|
|
1368
|
+
FROM retired_integration_queue;
|
|
1369
|
+
|
|
1370
|
+
INSERT INTO id_sequences(task_id, kind, high_water)
|
|
1371
|
+
SELECT task_id, 'event', max(event_sequence)
|
|
1372
|
+
FROM retired_integration_queue GROUP BY task_id
|
|
1373
|
+
ON CONFLICT(task_id, kind) DO UPDATE SET high_water = excluded.high_water;
|
|
1374
|
+
|
|
1375
|
+
DROP TABLE retired_integration_queue;
|
|
1376
|
+
DROP TABLE integration_queue;
|
|
1377
|
+
DELETE FROM id_sequences WHERE kind = 'integrationQueue';
|
|
1378
|
+
`
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
version: 30,
|
|
1382
|
+
name: "notification-only-wakes",
|
|
1383
|
+
introducedIn: "0.16.0",
|
|
1384
|
+
sql: "SELECT 1; -- Retire Run-linked wakes as audit events; notification schema 2; explicit Global providerBinding",
|
|
1385
|
+
migrateData: migrateNotificationOnlyWakes
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
version: 31,
|
|
1389
|
+
name: "explicit-review-scope",
|
|
1390
|
+
introducedIn: "0.16.0",
|
|
1391
|
+
sql: `
|
|
1392
|
+
UPDATE review_rounds
|
|
1393
|
+
SET payload = json_set(payload, '$.scope', 'work-item')
|
|
1394
|
+
WHERE json_type(payload, '$.scope') IS NULL
|
|
1395
|
+
OR json_type(payload, '$.scope') = 'null';
|
|
1396
|
+
`
|
|
1397
|
+
},
|
|
1398
|
+
{
|
|
1399
|
+
version: 32,
|
|
1400
|
+
name: "work-item-history-as-events",
|
|
1401
|
+
introducedIn: "0.16.0",
|
|
1402
|
+
sql: "SELECT 1; -- Archive original WorkItem payloads before removing historicalState",
|
|
1403
|
+
migrateData: migrateWorkItemHistory
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
version: 33,
|
|
1407
|
+
name: "advisory-and-verification-policy",
|
|
1408
|
+
introducedIn: "0.16.0",
|
|
1409
|
+
sql: "SELECT 1; -- Retire rollout modes/shadow metrics; explicit rerun intent; verification proof v3",
|
|
1410
|
+
migrateData: migrateVerificationPolicy
|
|
1411
|
+
},
|
|
1412
|
+
{
|
|
1413
|
+
version: 34,
|
|
1414
|
+
name: "current-input-contract",
|
|
1415
|
+
introducedIn: "0.16.0",
|
|
1416
|
+
sql: "SELECT 1; -- Archive retired Message wake policies and activation origin gates",
|
|
1417
|
+
migrateData: migrateCurrentInputContract
|
|
1418
|
+
},
|
|
1419
|
+
{
|
|
1420
|
+
version: 35,
|
|
1421
|
+
name: "current-verification-and-owner-contract",
|
|
1422
|
+
introducedIn: "0.16.0",
|
|
1423
|
+
sql: CURRENT_RUNTIME_CONTRACT_SQL,
|
|
1424
|
+
migrateData: migrateCurrentRuntimeContract
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
version: 36,
|
|
1428
|
+
name: "agent-failure-configuration-context",
|
|
1429
|
+
introducedIn: "0.16.0",
|
|
1430
|
+
sql: "SELECT 1; -- Preserve historical errors; absent original launch configuration is explicitly unavailable",
|
|
1431
|
+
migrateData: migrateAgentFailureContext
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
version: 37,
|
|
1435
|
+
name: "narrow-agent-failure-context",
|
|
1436
|
+
introducedIn: "0.16.0",
|
|
1437
|
+
sql: "SELECT 1; -- Archive full v36 failure snapshots; retain only native metadata selectors",
|
|
1438
|
+
migrateData: migrateNarrowAgentFailureContext
|
|
1267
1439
|
}
|
|
1268
1440
|
]);
|
|
1269
1441
|
for (let index = 0; index < MIGRATIONS.length; index += 1) {
|
|
@@ -1540,6 +1712,7 @@ export function migrateSqliteSchema(db, options) {
|
|
|
1540
1712
|
}
|
|
1541
1713
|
/** The names of every table the schema creates (for tests/introspection). */
|
|
1542
1714
|
export const SQLITE_SCHEMA_TABLES = [
|
|
1715
|
+
"storage_migration_archive",
|
|
1543
1716
|
"plugin_intents",
|
|
1544
1717
|
"plugin_validations",
|
|
1545
1718
|
"local_resources",
|
|
@@ -1558,7 +1731,6 @@ export const SQLITE_SCHEMA_TABLES = [
|
|
|
1558
1731
|
"managed_workspaces",
|
|
1559
1732
|
"id_sequences",
|
|
1560
1733
|
"coordination_locks",
|
|
1561
|
-
"integration_queue",
|
|
1562
1734
|
"durable_jobs",
|
|
1563
1735
|
"outbox",
|
|
1564
1736
|
"mailboxes",
|