@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
package/dist/doctor/doctor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { accessSync, constants, existsSync, lstatSync
|
|
1
|
+
import { accessSync, constants, existsSync, lstatSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join } from "node:path";
|
|
3
3
|
import Database from "better-sqlite3";
|
|
4
4
|
import { configuredAgentToDefinition, resolveAgentEnvironment } from "../agent/agent.js";
|
|
@@ -10,16 +10,11 @@ import { resolveEffectiveLaunch } from "../executor/effectiveLaunch.js";
|
|
|
10
10
|
import { compileRoleSessionContext } from "../context/roleSessionContext.js";
|
|
11
11
|
import { usageError } from "../errors/cliError.js";
|
|
12
12
|
import { defaultTableWidth, renderTable } from "../output/table.js";
|
|
13
|
-
import { resolveYuiHome
|
|
14
|
-
import {
|
|
13
|
+
import { resolveYuiHome } from "../storage/taskStore.js";
|
|
14
|
+
import { CURRENT_DATABASE_FILENAME, openCurrentTaskStore } from "../storage/currentTaskStore.js";
|
|
15
15
|
import { inspectStorageSchema } from "../storage/storageSchema.js";
|
|
16
|
-
import { resolveTaskStoreBackendForHome } from "../storage/sqliteStore.js";
|
|
17
16
|
import { resolveStoreWorkerEnabledForHome } from "../storage/storeRpc.js";
|
|
18
|
-
import { classifyHome } from "../storage/upgrade/homeClassification.js";
|
|
19
17
|
import { resolveTmuxBin } from "../config/yuiConfig.js";
|
|
20
|
-
import { readMigrationReceipt } from "../storage/upgrade/migrationReceipt.js";
|
|
21
|
-
import { latestStorageVersionState } from "../storage/upgrade/recordVersions.js";
|
|
22
|
-
import { COMMITTED_DATABASE_FILENAME } from "../storage/upgrade/sqliteStateMigration.js";
|
|
23
18
|
import { CommandExecutionError } from "../tmux/commandExecutor.js";
|
|
24
19
|
import { EPHEMERAL_DOMAIN_GRACE_MS, readEphemeralDomainIdentity, readLinuxProcessStartIdentity } from "../controller/domainIdentity.js";
|
|
25
20
|
/**
|
|
@@ -47,8 +42,8 @@ export function summarizeStorageHealth(checks) {
|
|
|
47
42
|
return { healthy: blocking.length === 0, blocking };
|
|
48
43
|
}
|
|
49
44
|
/** Build the full machine-readable doctor report (checks + storage health). */
|
|
50
|
-
export function buildDoctorReport(env, executor
|
|
51
|
-
const inspection = inspectDoctor(env, executor
|
|
45
|
+
export function buildDoctorReport(env, executor) {
|
|
46
|
+
const inspection = inspectDoctor(env, executor);
|
|
52
47
|
const home = resolveYuiHome(env);
|
|
53
48
|
return {
|
|
54
49
|
checks: inspection.checks,
|
|
@@ -70,8 +65,8 @@ function inspectStorageDetails(home, env) {
|
|
|
70
65
|
const logicalLayout = schema.status === "current" || schema.status === "unsupported"
|
|
71
66
|
? schema.currentLayoutVersion
|
|
72
67
|
: null;
|
|
73
|
-
const authoritativeBackend =
|
|
74
|
-
const dbPath = join(home,
|
|
68
|
+
const authoritativeBackend = "sqlite";
|
|
69
|
+
const dbPath = join(home, CURRENT_DATABASE_FILENAME);
|
|
75
70
|
const databasePath = existsSync(dbPath) ? dbPath : null;
|
|
76
71
|
let journalMode = null;
|
|
77
72
|
let lastCommittedRevision = null;
|
|
@@ -92,44 +87,34 @@ function inspectStorageDetails(home, env) {
|
|
|
92
87
|
// Leave both null; the storage state check surfaces the corruption.
|
|
93
88
|
}
|
|
94
89
|
}
|
|
95
|
-
else {
|
|
96
|
-
try {
|
|
97
|
-
const state = JSON.parse(readFileSync(join(home, STORAGE_STATE_FILE), "utf8"));
|
|
98
|
-
lastCommittedRevision = typeof state.revision === "number" ? state.revision : null;
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
lastCommittedRevision = null;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
90
|
return {
|
|
105
91
|
logicalLayout,
|
|
106
92
|
authoritativeBackend,
|
|
107
93
|
databasePath,
|
|
108
94
|
journalMode,
|
|
109
95
|
workerEnabled: resolveStoreWorkerEnabledForHome(home, env),
|
|
110
|
-
migrationReceipt: readMigrationReceipt(home),
|
|
111
96
|
lastCommittedRevision
|
|
112
97
|
};
|
|
113
98
|
}
|
|
114
|
-
/** Runs the read-only
|
|
115
|
-
export function runDoctorCommand(args, env, executor
|
|
99
|
+
/** Runs the read-only current-storage diagnostics used by `yui doctor`. */
|
|
100
|
+
export function runDoctorCommand(args, env, executor) {
|
|
116
101
|
if (args.length !== 0)
|
|
117
102
|
throw usageError("Doctor usage: yui doctor");
|
|
118
|
-
const inspection = inspectDoctor(env, executor
|
|
103
|
+
const inspection = inspectDoctor(env, executor);
|
|
119
104
|
return renderDoctor(inspection.checks, inspection.review);
|
|
120
105
|
}
|
|
121
|
-
export function getDoctorChecks(env, executor
|
|
122
|
-
return inspectDoctor(env, executor
|
|
106
|
+
export function getDoctorChecks(env, executor) {
|
|
107
|
+
return inspectDoctor(env, executor).checks;
|
|
123
108
|
}
|
|
124
|
-
function inspectDoctor(env, executor
|
|
109
|
+
function inspectDoctor(env, executor) {
|
|
125
110
|
const home = resolveYuiHome(env);
|
|
126
111
|
const homeCheck = checkHome(home);
|
|
127
112
|
const schema = readSchema(home);
|
|
128
|
-
const compatibility = inspectCompatibility(home, homeCheck, schema
|
|
129
|
-
const schemaCheck = checkSchema(schema
|
|
113
|
+
const compatibility = inspectCompatibility(home, homeCheck, schema);
|
|
114
|
+
const schemaCheck = checkSchema(schema);
|
|
130
115
|
const storage = inspectState(home, homeCheck, schema, compatibility);
|
|
131
116
|
const domain = checkEphemeralDomain(home);
|
|
132
|
-
const durableConfig = readDurableConfigSafely(home
|
|
117
|
+
const durableConfig = readDurableConfigSafely(home);
|
|
133
118
|
const toolChecks = [
|
|
134
119
|
checkExecutable("git", durableConfig.gitBin, ["--version"], executor),
|
|
135
120
|
checkExecutable("tmux", durableConfig.tmuxBin, ["-V"], executor)
|
|
@@ -223,7 +208,7 @@ function readSchema(home) {
|
|
|
223
208
|
return { status: "read-error", detail: errorMessage(error) };
|
|
224
209
|
}
|
|
225
210
|
}
|
|
226
|
-
function checkSchema(state
|
|
211
|
+
function checkSchema(state) {
|
|
227
212
|
switch (state.status) {
|
|
228
213
|
case "uninitialized":
|
|
229
214
|
return { name: "storage schema", status: "missing", detail: "run yui setup" };
|
|
@@ -234,16 +219,6 @@ function checkSchema(state, compatibility) {
|
|
|
234
219
|
detail: `current=${state.currentVersion} latest=${state.latestVersion}`
|
|
235
220
|
};
|
|
236
221
|
case "unsupported":
|
|
237
|
-
if ((compatibility.storageStatus === "compatible-old"
|
|
238
|
-
|| compatibility.storageStatus === "needs-storage-repair")
|
|
239
|
-
&& compatibility.check.status === "ok") {
|
|
240
|
-
return {
|
|
241
|
-
name: "storage schema",
|
|
242
|
-
status: "ok",
|
|
243
|
-
detail: `current=${state.currentVersion} latest=${state.latestVersion} `
|
|
244
|
-
+ `direction=${state.direction}; ${compatibility.storageStatus} validated`
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
222
|
return {
|
|
248
223
|
name: "storage schema",
|
|
249
224
|
status: "unsupported",
|
|
@@ -255,17 +230,8 @@ function checkSchema(state, compatibility) {
|
|
|
255
230
|
return { name: "storage schema", status: "invalid", detail: state.detail };
|
|
256
231
|
}
|
|
257
232
|
}
|
|
258
|
-
/**
|
|
259
|
-
|
|
260
|
-
* NEEDS_NEW_VERSION / CORRUPTED. This complements the raw "storage schema" check
|
|
261
|
-
* with the migration framework's verdict, so a user sees whether a Home can be
|
|
262
|
-
* used as-is, upgraded with `yui upgrade`, needs a newer release, or is damaged.
|
|
263
|
-
* Doctor uses the same explicit production registry as `yui upgrade`; tests
|
|
264
|
-
* may inject a synthetic registry so the same classification and validation
|
|
265
|
-
* path proves compatible-old behavior. Missing paths fail closed, and
|
|
266
|
-
* CORRUPTED is reserved for structural or reference failure.
|
|
267
|
-
*/
|
|
268
|
-
function inspectCompatibility(home, homeCheck, schema, storageOptions) {
|
|
233
|
+
/** Diagnose admission to the exact current storage contract without repair. */
|
|
234
|
+
function inspectCompatibility(home, homeCheck, schema) {
|
|
269
235
|
const name = "storage compatibility";
|
|
270
236
|
if (homeCheck.status !== "ok") {
|
|
271
237
|
return { check: { name, status: homeCheck.status, detail: homeCheck.detail } };
|
|
@@ -276,110 +242,30 @@ function inspectCompatibility(home, homeCheck, schema, storageOptions) {
|
|
|
276
242
|
if (schema.status === "read-error") {
|
|
277
243
|
return { check: { name, status: "invalid", detail: schema.detail } };
|
|
278
244
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
try {
|
|
282
|
-
resolvedStorageOptions = {
|
|
283
|
-
registry: storageOptions.registry ?? createProductionStorageRegistry(),
|
|
284
|
-
latest: storageOptions.latest ?? latestStorageVersionState()
|
|
285
|
-
};
|
|
286
|
-
classification = classifyHome({
|
|
287
|
-
home,
|
|
288
|
-
registry: resolvedStorageOptions.registry,
|
|
289
|
-
latest: resolvedStorageOptions.latest
|
|
290
|
-
});
|
|
245
|
+
if (schema.status === "invalid") {
|
|
246
|
+
return { check: { name, status: "invalid", detail: schema.detail } };
|
|
291
247
|
}
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
catch (error) {
|
|
305
|
-
return {
|
|
306
|
-
storageStatus,
|
|
307
|
-
storageOptions: resolvedStorageOptions,
|
|
308
|
-
check: {
|
|
309
|
-
name,
|
|
310
|
-
status: "invalid",
|
|
311
|
-
detail: `unsupported ${storageStatus} shape: ${errorMessage(error)}`
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
}
|
|
248
|
+
if (schema.status === "unsupported") {
|
|
249
|
+
return {
|
|
250
|
+
storageStatus: "unsupported",
|
|
251
|
+
check: {
|
|
252
|
+
name,
|
|
253
|
+
status: "unsupported",
|
|
254
|
+
detail: `unsupported contract: ${schema.incompatibleComponent} is ${schema.direction} `
|
|
255
|
+
+ `(current=${schema.currentVersion}, required=${schema.latestVersion}). `
|
|
256
|
+
+ "Preserve this Home and initialize a new Home."
|
|
257
|
+
}
|
|
258
|
+
};
|
|
315
259
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
return {
|
|
324
|
-
storageStatus,
|
|
325
|
-
storageOptions: resolvedStorageOptions,
|
|
326
|
-
check: { name, status: "ok", detail: `current (USABLE) ${versions}` }
|
|
327
|
-
};
|
|
328
|
-
case "compatible-old":
|
|
329
|
-
return {
|
|
330
|
-
storageStatus,
|
|
331
|
-
storageOptions: resolvedStorageOptions,
|
|
332
|
-
check: {
|
|
333
|
-
name,
|
|
334
|
-
status: "ok",
|
|
335
|
-
detail: `compatible-old (COMPATIBLE) ${versions}; ordinary commands are supported`
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
case "migration-required":
|
|
339
|
-
return {
|
|
340
|
-
storageStatus,
|
|
341
|
-
storageOptions: resolvedStorageOptions,
|
|
342
|
-
check: {
|
|
343
|
-
name,
|
|
344
|
-
status: "ok",
|
|
345
|
-
detail: `migration-required (MIGRATABLE) ${versions}; run yui update when Sessions are clear`
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
case "needs-storage-repair":
|
|
349
|
-
return {
|
|
350
|
-
storageStatus,
|
|
351
|
-
storageOptions: resolvedStorageOptions,
|
|
352
|
-
check: {
|
|
353
|
-
name,
|
|
354
|
-
// Diagnostic mode (Issue 01 rollout step 1): the Home is readable
|
|
355
|
-
// and usable, but the manifest claims layout 7 without a yui.db.
|
|
356
|
-
// Surface the repair need in the detail while keeping the Home
|
|
357
|
-
// healthy so ordinary commands keep working.
|
|
358
|
-
status: "ok",
|
|
359
|
-
detail: `needs-storage-repair (NEEDS_STORAGE_REPAIR) ${versions}; `
|
|
360
|
-
+ "the manifest claims layout 7 but yui.db is missing. Run `yui upgrade` to rebuild it from state.json."
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
case "unsupported": {
|
|
364
|
-
const unsupported = classification.classification;
|
|
365
|
-
return {
|
|
366
|
-
storageStatus,
|
|
367
|
-
storageOptions: resolvedStorageOptions,
|
|
368
|
-
check: unsupported.verdict === "CORRUPTED"
|
|
369
|
-
? {
|
|
370
|
-
name,
|
|
371
|
-
status: "invalid",
|
|
372
|
-
detail: `unsupported (CORRUPTED): ${unsupported.detail}`
|
|
373
|
-
}
|
|
374
|
-
: {
|
|
375
|
-
name,
|
|
376
|
-
status: "unsupported",
|
|
377
|
-
detail: `unsupported (NEEDS_NEW_VERSION) ${versions}${incompatible}; ` +
|
|
378
|
-
`${unsupported.blocker.reason}`
|
|
379
|
-
}
|
|
380
|
-
};
|
|
260
|
+
return {
|
|
261
|
+
storageStatus: "current",
|
|
262
|
+
check: {
|
|
263
|
+
name,
|
|
264
|
+
status: "ok",
|
|
265
|
+
detail: `current layout=${schema.currentLayoutVersion}/${schema.latestLayoutVersion} `
|
|
266
|
+
+ `aggregate=${schema.currentAggregateSchemaVersion}/${schema.latestAggregateSchemaVersion}`
|
|
381
267
|
}
|
|
382
|
-
}
|
|
268
|
+
};
|
|
383
269
|
}
|
|
384
270
|
function inspectState(home, homeCheck, schema, compatibility) {
|
|
385
271
|
if (homeCheck.status !== "ok") {
|
|
@@ -392,42 +278,18 @@ function inspectState(home, homeCheck, schema, compatibility) {
|
|
|
392
278
|
return blockedStorage("invalid", schema.detail);
|
|
393
279
|
if (schema.status === "read-error")
|
|
394
280
|
return blockedStorage("invalid", schema.detail);
|
|
395
|
-
|
|
396
|
-
// the compatibility check surfaces the repair need, but the store itself is
|
|
397
|
-
// readable, so the state and review checks must still run (Issue 01).
|
|
398
|
-
if (compatibility.check.status !== "ok"
|
|
399
|
-
&& compatibility.storageStatus !== "needs-storage-repair") {
|
|
281
|
+
if (compatibility.check.status !== "ok") {
|
|
400
282
|
return blockedStorage(compatibility.check.status, storageBlockerDetail(compatibility.check));
|
|
401
283
|
}
|
|
402
|
-
if (compatibility.storageStatus !== "current"
|
|
403
|
-
&& compatibility.storageStatus !== "compatible-old"
|
|
404
|
-
&& compatibility.storageStatus !== "needs-storage-repair") {
|
|
284
|
+
if (compatibility.storageStatus !== "current") {
|
|
405
285
|
return blockedStorage("unsupported", compatibility.check.detail);
|
|
406
286
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
const statePath = join(home, STORAGE_STATE_FILE);
|
|
411
|
-
// A repaired layout-7 Home archived state.json; yui.db is the authoritative
|
|
412
|
-
// backend then, so the state.json gate is skipped (Issue 01).
|
|
413
|
-
const sqliteAuthoritative = !existsSync(statePath)
|
|
414
|
-
&& existsSync(join(home, COMMITTED_DATABASE_FILENAME));
|
|
415
|
-
if (!sqliteAuthoritative) {
|
|
416
|
-
if (!existsSync(statePath))
|
|
417
|
-
return blockedStorage("missing", "run yui setup");
|
|
418
|
-
try {
|
|
419
|
-
const metadata = lstatSync(statePath);
|
|
420
|
-
if (!metadata.isFile() || metadata.isSymbolicLink()) {
|
|
421
|
-
return blockedStorage("invalid", `${STORAGE_STATE_FILE} must be a regular file.`);
|
|
422
|
-
}
|
|
423
|
-
accessSync(statePath, constants.R_OK);
|
|
424
|
-
}
|
|
425
|
-
catch (error) {
|
|
426
|
-
return blockedStorage("invalid", errorMessage(error));
|
|
427
|
-
}
|
|
287
|
+
const databasePath = join(home, CURRENT_DATABASE_FILENAME);
|
|
288
|
+
if (!existsSync(databasePath)) {
|
|
289
|
+
return blockedStorage("invalid", "Current storage is incomplete: yui.db is missing.");
|
|
428
290
|
}
|
|
429
291
|
try {
|
|
430
|
-
const store =
|
|
292
|
+
const store = openCurrentTaskStore(home);
|
|
431
293
|
const config = store.getConfig();
|
|
432
294
|
const agents = store.listConfiguredAgents();
|
|
433
295
|
const tasks = store.listTasks();
|
|
@@ -437,12 +299,12 @@ function inspectState(home, homeCheck, schema, compatibility) {
|
|
|
437
299
|
check: {
|
|
438
300
|
name: "storage state",
|
|
439
301
|
status: "ok",
|
|
440
|
-
detail:
|
|
302
|
+
detail: `yui.db readable agents=${agents.length} tasks=${tasks.length} roles=${roleCount} globalRoles=${globalRoles.length} defaultAgent=${config.defaultAgent ?? "none"}`
|
|
441
303
|
},
|
|
442
304
|
agents,
|
|
443
305
|
review: {
|
|
444
306
|
storageReady: true,
|
|
445
|
-
storageDetail:
|
|
307
|
+
storageDetail: "yui.db is readable",
|
|
446
308
|
...(config.review === undefined ? {} : { policy: config.review }),
|
|
447
309
|
...(config.review === undefined
|
|
448
310
|
? {}
|
|
@@ -465,7 +327,7 @@ function inspectState(home, homeCheck, schema, compatibility) {
|
|
|
465
327
|
function storageBlockerDetail(check) {
|
|
466
328
|
const corruptionPrefix = "unsupported (CORRUPTED): ";
|
|
467
329
|
return check.status === "invalid" && check.detail.startsWith(corruptionPrefix)
|
|
468
|
-
? `Invalid
|
|
330
|
+
? `Invalid storage: ${check.detail.slice(corruptionPrefix.length)}`
|
|
469
331
|
: check.detail;
|
|
470
332
|
}
|
|
471
333
|
function blockedStorage(status, detail) {
|
|
@@ -480,11 +342,6 @@ function blockedStorage(status, detail) {
|
|
|
480
342
|
}
|
|
481
343
|
function inspectReview(source, agentChecks, environment) {
|
|
482
344
|
if (!source.storageReady) {
|
|
483
|
-
const raw = source.home === undefined
|
|
484
|
-
? null
|
|
485
|
-
: inspectRawReview(source.home, source.storageDetail);
|
|
486
|
-
if (raw !== null)
|
|
487
|
-
return raw;
|
|
488
345
|
return {
|
|
489
346
|
report: {
|
|
490
347
|
status: "misconfigured",
|
|
@@ -623,126 +480,6 @@ function inspectReview(source, agentChecks, environment) {
|
|
|
623
480
|
checks
|
|
624
481
|
};
|
|
625
482
|
}
|
|
626
|
-
/**
|
|
627
|
-
* Preserve a bounded Reviewer diagnosis when another malformed record prevents
|
|
628
|
-
* FileTaskStore from opening. This is read-only evidence, never a compatibility
|
|
629
|
-
* path: the storage check remains invalid and the review projection cannot be
|
|
630
|
-
* reported as ready from unvalidated bytes.
|
|
631
|
-
*/
|
|
632
|
-
function inspectRawReview(home, storageDetail) {
|
|
633
|
-
try {
|
|
634
|
-
const parsed = JSON.parse(readFileSync(join(home, STORAGE_STATE_FILE), "utf8"));
|
|
635
|
-
if (!isRecord(parsed) || !isRecord(parsed.config))
|
|
636
|
-
return null;
|
|
637
|
-
const rawPolicy = parsed.config.review;
|
|
638
|
-
if (!isRecord(rawPolicy)
|
|
639
|
-
|| typeof rawPolicy.roleName !== "string"
|
|
640
|
-
|| typeof rawPolicy.trigger !== "string") {
|
|
641
|
-
return {
|
|
642
|
-
report: {
|
|
643
|
-
status: "misconfigured",
|
|
644
|
-
providerNative: "unverified",
|
|
645
|
-
detail: `Storage state is invalid; Review policy is unavailable: ${storageDetail}`
|
|
646
|
-
},
|
|
647
|
-
checks: [{
|
|
648
|
-
name: "review policy",
|
|
649
|
-
status: "invalid",
|
|
650
|
-
detail: `storage state invalid: ${storageDetail}`
|
|
651
|
-
}]
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
const policy = {
|
|
655
|
-
roleName: rawPolicy.roleName,
|
|
656
|
-
trigger: rawPolicy.trigger
|
|
657
|
-
};
|
|
658
|
-
const roles = isRecord(parsed.globalRoles) ? parsed.globalRoles : {};
|
|
659
|
-
const roleValue = roles[policy.roleName];
|
|
660
|
-
if (!isRecord(roleValue)) {
|
|
661
|
-
return rawReviewMisconfigured(policy, storageDetail, [{
|
|
662
|
-
name: "review policy",
|
|
663
|
-
status: "ok",
|
|
664
|
-
detail: `role=${policy.roleName} trigger=${policy.trigger}`
|
|
665
|
-
}, {
|
|
666
|
-
name: "reviewer role",
|
|
667
|
-
status: "missing",
|
|
668
|
-
detail: `Global Role not found: ${policy.roleName}.`
|
|
669
|
-
}]);
|
|
670
|
-
}
|
|
671
|
-
const roleName = typeof roleValue.name === "string" ? roleValue.name : policy.roleName;
|
|
672
|
-
const activeAgentId = typeof roleValue.activeAgentId === "string"
|
|
673
|
-
? roleValue.activeAgentId
|
|
674
|
-
: "";
|
|
675
|
-
const checks = [{
|
|
676
|
-
name: "review policy",
|
|
677
|
-
status: "ok",
|
|
678
|
-
detail: `role=${policy.roleName} trigger=${policy.trigger}`
|
|
679
|
-
}, {
|
|
680
|
-
name: "reviewer role",
|
|
681
|
-
status: "ok",
|
|
682
|
-
detail: `name=${roleName} activeAgent=${activeAgentId || "missing"}`
|
|
683
|
-
}];
|
|
684
|
-
const bindings = isRecord(roleValue.agentBindings) ? roleValue.agentBindings : {};
|
|
685
|
-
const bindingValue = activeAgentId.length === 0 ? undefined : bindings[activeAgentId];
|
|
686
|
-
if (!isRecord(bindingValue)) {
|
|
687
|
-
checks.push({
|
|
688
|
-
name: "reviewer binding",
|
|
689
|
-
status: "missing",
|
|
690
|
-
detail: `active Agent binding is missing: ${activeAgentId || "unknown"}.`
|
|
691
|
-
});
|
|
692
|
-
return rawReviewMisconfigured(policy, storageDetail, checks, roleName, activeAgentId || undefined);
|
|
693
|
-
}
|
|
694
|
-
const bindingAgentId = typeof bindingValue.agentId === "string"
|
|
695
|
-
? bindingValue.agentId
|
|
696
|
-
: activeAgentId;
|
|
697
|
-
const adapterId = typeof bindingValue.adapterId === "string"
|
|
698
|
-
? bindingValue.adapterId
|
|
699
|
-
: "unknown";
|
|
700
|
-
checks.push({
|
|
701
|
-
name: "reviewer binding",
|
|
702
|
-
status: "ok",
|
|
703
|
-
detail: `agent=${bindingAgentId} adapter=${adapterId}`
|
|
704
|
-
});
|
|
705
|
-
const configuredAgents = isRecord(parsed.configuredAgents)
|
|
706
|
-
? parsed.configuredAgents
|
|
707
|
-
: {};
|
|
708
|
-
const agentValue = configuredAgents[bindingAgentId];
|
|
709
|
-
if (!isRecord(agentValue)) {
|
|
710
|
-
checks.push({
|
|
711
|
-
name: "reviewer agent",
|
|
712
|
-
status: "missing",
|
|
713
|
-
detail: `Configured Agent not found: ${bindingAgentId}.`
|
|
714
|
-
});
|
|
715
|
-
return rawReviewMisconfigured(policy, storageDetail, checks, roleName, bindingAgentId, adapterId);
|
|
716
|
-
}
|
|
717
|
-
checks.push({
|
|
718
|
-
name: "reviewer agent",
|
|
719
|
-
status: "invalid",
|
|
720
|
-
detail: `Storage state is invalid; configured Agent ${bindingAgentId} cannot be validated.`
|
|
721
|
-
});
|
|
722
|
-
return rawReviewMisconfigured(policy, storageDetail, checks, roleName, bindingAgentId, adapterId, typeof agentValue.command === "string" ? agentValue.command : undefined);
|
|
723
|
-
}
|
|
724
|
-
catch {
|
|
725
|
-
return null;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
function rawReviewMisconfigured(policy, storageDetail, checks, roleName, activeAgentId, adapterId, command) {
|
|
729
|
-
return {
|
|
730
|
-
report: {
|
|
731
|
-
status: "misconfigured",
|
|
732
|
-
policy,
|
|
733
|
-
...(roleName === undefined ? {} : { roleName }),
|
|
734
|
-
...(activeAgentId === undefined ? {} : { activeAgentId }),
|
|
735
|
-
...(adapterId === undefined ? {} : { adapterId }),
|
|
736
|
-
...(command === undefined ? {} : { command }),
|
|
737
|
-
providerNative: "unverified",
|
|
738
|
-
detail: `Storage state is invalid; ${checks.at(-1)?.detail ?? storageDetail}`
|
|
739
|
-
},
|
|
740
|
-
checks
|
|
741
|
-
};
|
|
742
|
-
}
|
|
743
|
-
function isRecord(value) {
|
|
744
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
745
|
-
}
|
|
746
483
|
function reviewMisconfigured(policy, checks, detail, role, activeAgentId, adapterId, command) {
|
|
747
484
|
return {
|
|
748
485
|
report: {
|
|
@@ -983,9 +720,9 @@ function errorMessage(error) {
|
|
|
983
720
|
* Read the durable config for executable paths. Falls back to defaults when
|
|
984
721
|
* the Home store cannot be opened (the doctor must still run on broken Homes).
|
|
985
722
|
*/
|
|
986
|
-
function readDurableConfigSafely(home
|
|
723
|
+
function readDurableConfigSafely(home) {
|
|
987
724
|
try {
|
|
988
|
-
const store =
|
|
725
|
+
const store = openCurrentTaskStore(home);
|
|
989
726
|
const config = store.getConfig();
|
|
990
727
|
return {
|
|
991
728
|
tmuxBin: resolveTmuxBin(config.tmuxBin),
|
|
@@ -12,7 +12,7 @@ export function candidateConvergenceDirective(stage) {
|
|
|
12
12
|
const parentRefs = stage.parentResults.map(parentResultRef);
|
|
13
13
|
const common = [
|
|
14
14
|
"Candidate convergence contract v1 is active.",
|
|
15
|
-
"
|
|
15
|
+
"Return one JSON object. Keep summary/checks/findings/evidence at the top level and add convergence={schemaVersion:1,stage,artifactType,parentResultRefs,...}.",
|
|
16
16
|
`convergence.stage must be ${stage.stage}; parentResultRefs must equal ${JSON.stringify(parentRefs)} in this order.`,
|
|
17
17
|
"artifactType is research, architecture, or code and must stay unchanged across the round.",
|
|
18
18
|
"Use only frozen parent result references; never replay sibling transcripts. Direct sources, executable checks, and frozen artifacts outrank derived analysis or vote counts."
|
|
@@ -236,7 +236,7 @@ export function candidateConvergenceEvidenceSufficient(workItem, group, selected
|
|
|
236
236
|
|| (stage.stage !== "verify" && stage.stage !== "resolve")
|
|
237
237
|
|| selectedLaneIds.length === 0)
|
|
238
238
|
return false;
|
|
239
|
-
const usable = group.lanes.filter(({ status }) =>
|
|
239
|
+
const usable = group.lanes.filter(({ status }) => status === "completed");
|
|
240
240
|
if (selectedLaneIds.some((laneId) => !usable.some(({ id }) => id === laneId)))
|
|
241
241
|
return false;
|
|
242
242
|
// Cost policy may never hide contradictory evidence that has already
|
|
@@ -320,7 +320,7 @@ function usableCandidateConvergenceEnvelopes(group) {
|
|
|
320
320
|
const stage = group.stage;
|
|
321
321
|
if (stage?.convergence === undefined)
|
|
322
322
|
return [];
|
|
323
|
-
const usable = group.lanes.filter(({ status, result }) => (
|
|
323
|
+
const usable = group.lanes.filter(({ status, result }) => (status === "completed" && result !== undefined));
|
|
324
324
|
try {
|
|
325
325
|
return usable.map(({ result }) => validateCandidateConvergenceReport(result, stage.stage, stage.parentResults));
|
|
326
326
|
}
|