Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/source-architecture-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"src/lib/runner.ts": 89,
"src/lib/security/redact.ts": 51,
"src/lib/state/onboard-session.ts": 34,
"src/lib/state/registry.ts": 102,
"src/lib/state/registry.ts": 99,
"src/lib/state/state-root.ts": 23,
"src/lib/subprocess-env.ts": 23,
"src/lib/validation.ts": 25
Expand Down
9 changes: 5 additions & 4 deletions src/lib/actions/sandbox/rebuild-flow-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ import {
type TrustedLocalBaseImageOverride,
} from "../../sandbox-base-image";
import * as shields from "../../shields";
import * as registry from "../../state/registry";
import type { SandboxEntry } from "../../state/registry";
import { load as loadRegistry } from "../../state/registry/persistence";
import * as sandboxState from "../../state/sandbox";
import * as userManagedFilesProbe from "../../state/user-managed-files-probe";
import {
Expand All @@ -49,11 +50,11 @@ import {
} from "./gateway-state";
import { openRebuildShieldsWindow, type RebuildShieldsWindow } from "./rebuild-shields";

export type RebuildSandboxEntry = registry.SandboxEntry & { agents?: unknown[] };
export type RebuildSandboxEntry = SandboxEntry & { agents?: unknown[] };

export type RebuildLiveState = {
staleRecovery: boolean;
staleRegistrySnapshot: ReturnType<typeof registry.load> | null;
staleRegistrySnapshot: ReturnType<typeof loadRegistry> | null;
};

export type RebuildAgentBaseImageOptions = {
Expand Down Expand Up @@ -224,7 +225,7 @@ export async function resolveRebuildLiveState(
);
return {
staleRecovery: true,
staleRegistrySnapshot: JSON.parse(JSON.stringify(registry.load())),
staleRegistrySnapshot: JSON.parse(JSON.stringify(loadRegistry())),
};
}

Expand Down
13 changes: 7 additions & 6 deletions src/lib/actions/sandbox/rebuild-gateway-drift.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as openshellRuntime from "../../adapters/openshell/runtime";
import * as gatewayRuntime from "../../gateway-runtime-action";
import * as dockerDriverRecovery from "../../onboard/docker-driver-sandbox-recovery";
import * as registry from "../../state/registry";
import * as registryPersistence from "../../state/registry/persistence";
import { type RebuildSandboxEntry, resolveRebuildLiveState } from "./rebuild-flow-helpers";
import {
checkRebuildGatewaySchemaPreflight,
Expand Down Expand Up @@ -84,7 +85,7 @@ describe("rebuild gateway drift preflight", () => {
.spyOn(dockerDriverRecovery, "recoverDockerDriverSandbox")
.mockReturnValue({ recovered: false, via: null });
vi.spyOn(registry, "getSandbox").mockReturnValue(makeSandboxEntry() as never);
vi.spyOn(registry, "load").mockReturnValue({
vi.spyOn(registryPersistence, "load").mockReturnValue({
sandboxes: { alpha: makeSandboxEntry() },
} as never);
errorSpy = vi.spyOn(console, "error").mockImplementation(() => undefined);
Expand Down Expand Up @@ -138,7 +139,7 @@ describe("rebuild gateway drift preflight", () => {
const entry = makeSandboxEntry(recordedGateway, recordedPort);
const registrySnapshot = { sandboxes: { alpha: entry } };
vi.mocked(registry.getSandbox).mockReturnValue(entry as never);
vi.mocked(registry.load).mockReturnValue(registrySnapshot as never);
vi.mocked(registryPersistence.load).mockReturnValue(registrySnapshot as never);
captureOpenshellSpy
.mockReturnValueOnce({ status: 0, output: "" })
.mockReturnValueOnce({ status: 1, output: "Error: × Not Found: sandbox not found" });
Expand All @@ -165,7 +166,7 @@ describe("rebuild gateway drift preflight", () => {
expect.anything(),
);
expect(recoverDockerDriverSandboxSpy).toHaveBeenCalledWith("alpha");
expect(registry.load).toHaveBeenCalledOnce();
expect(registryPersistence.load).toHaveBeenCalledOnce();
expect(logSpy.mock.calls.flat().join("\n")).toContain("absent from the live OpenShell gateway");
expect(behaviorLog.mock.calls.flat().join("\n")).toContain("Stale-sandbox recovery");
});
Expand All @@ -180,7 +181,7 @@ describe("rebuild gateway drift preflight", () => {
const entry = makeSandboxEntry(gatewayName, gatewayPort);
const registrySnapshot = { sandboxes: { alpha: entry } };
vi.mocked(registry.getSandbox).mockReturnValue(entry as never);
vi.mocked(registry.load).mockReturnValue(registrySnapshot as never);
vi.mocked(registryPersistence.load).mockReturnValue(registrySnapshot as never);
captureOpenshellSpy
.mockReturnValueOnce({
status: 1,
Expand Down Expand Up @@ -220,7 +221,7 @@ describe("rebuild gateway drift preflight", () => {
);
expect(getNamedGatewayLifecycleStateSpy).not.toHaveBeenCalled();
expect(recoverDockerDriverSandboxSpy).toHaveBeenCalledWith("alpha");
expect(registry.load).toHaveBeenCalledOnce();
expect(registryPersistence.load).toHaveBeenCalledOnce();
expect(logSpy.mock.calls.flat().join("\n")).toContain("absent from the live OpenShell gateway");
expect(behaviorLog.mock.calls.flat().join("\n")).toContain("Stale-sandbox recovery");
});
Expand All @@ -245,7 +246,7 @@ describe("rebuild gateway drift preflight", () => {
expect(captureOpenshellSpy).toHaveBeenCalledWith(["sandbox", "list"]);
expect(getNamedGatewayLifecycleStateSpy).not.toHaveBeenCalled();
expect(recoverDockerDriverSandboxSpy).not.toHaveBeenCalled();
expect(registry.load).not.toHaveBeenCalled();
expect(registryPersistence.load).not.toHaveBeenCalled();
expect(errorSpy.mock.calls.flat().join("\n")).toContain("Failed to query running sandboxes");
});
});
4 changes: 2 additions & 2 deletions src/lib/actions/sandbox/rebuild-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { hydrateCredentialEnv } from "../../onboard/credential-env";
import { DOCKER_GPU_PATCH_NETWORK_ENV } from "../../onboard/docker-gpu-patch";
import { withMcpLifecycleLock } from "../../state/mcp-lifecycle-lock";
import * as onboardSession from "../../state/onboard-session";
import * as registry from "../../state/registry";
import { load as loadRegistry } from "../../state/registry/persistence";
import { normalizeRebuildTargetPolicyPresets, runRebuildBackupPhase } from "./rebuild-backup-phase";
import { buildRefreshMutableOpenClawConfigHashCommand } from "./rebuild-config-hash";
import { DCODE_AGENT_NAME } from "./rebuild-dcode-target";
Expand Down Expand Up @@ -126,7 +126,7 @@ async function rebuildSandboxUnlocked(
try {
if (blockRebuildOnPendingBaselineTransition(sandboxEntry, sandboxName, bail)) return;
let recoveryRegistrySnapshot = preparedBackupRecovery
? JSON.parse(JSON.stringify(registry.load()))
? JSON.parse(JSON.stringify(loadRegistry()))
: liveState.staleRegistrySnapshot;
const registryRollback = createRebuildRegistryRollback({
sandboxName,
Expand Down
9 changes: 5 additions & 4 deletions src/lib/actions/sandbox/rebuild-prepared-recovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import { isDeepStrictEqual } from "node:util";

import { RD as _RD, R } from "../../cli/terminal-style";
import * as registry from "../../state/registry";
import type { SandboxRegistry } from "../../state/registry";
import { load as loadRegistry } from "../../state/registry/persistence";
import * as sandboxState from "../../state/sandbox";
import type { RebuildBail } from "./rebuild-credential-preflight";
import type { RebuildSandboxEntry } from "./rebuild-flow-helpers";
Expand Down Expand Up @@ -89,16 +90,16 @@ export function revalidatePreparedRecoveryBeforeDelete(
sandboxName: string,
initialEntry: RebuildSandboxEntry,
candidate: sandboxState.RebuildManifest | null,
registrySnapshot: registry.SandboxRegistry | null,
registrySnapshot: SandboxRegistry | null,
allowLegacyManagedImageRecovery: boolean,
bail: RebuildBail,
): {
manifest: sandboxState.RebuildManifest | null;
registrySnapshot: registry.SandboxRegistry | null;
registrySnapshot: SandboxRegistry | null;
} {
if (!candidate) return { manifest: null, registrySnapshot };

const refreshedRegistrySnapshot = registry.load();
const refreshedRegistrySnapshot = loadRegistry();
const currentEntry = refreshedRegistrySnapshot.sandboxes[sandboxName];
if (!currentEntry) {
return failPreparedRecoveryPreDelete(
Expand Down
Loading
Loading