diff --git a/src/secrets/runtime.integration.test.ts b/src/secrets/runtime.integration.test.ts new file mode 100644 index 00000000000..f39607cbe80 --- /dev/null +++ b/src/secrets/runtime.integration.test.ts @@ -0,0 +1,414 @@ +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { afterEach, describe, expect, it } from "vitest"; +import { ensureAuthProfileStore, type AuthProfileStore } from "../agents/auth-profiles.js"; +import { + clearConfigCache, + loadConfig, + type OpenClawConfig, + writeConfigFile, +} from "../config/config.js"; +import { withTempHome } from "../config/home-env.test-harness.js"; +import { + activateSecretsRuntimeSnapshot, + clearSecretsRuntimeSnapshot, + getActiveRuntimeWebToolsMetadata, + getActiveSecretsRuntimeSnapshot, + prepareSecretsRuntimeSnapshot, +} from "./runtime.js"; + +const OPENAI_ENV_KEY_REF = { source: "env", provider: "default", id: "OPENAI_API_KEY" } as const; +const allowInsecureTempSecretFile = process.platform === "win32"; + +function asConfig(value: unknown): OpenClawConfig { + return value as OpenClawConfig; +} + +function loadAuthStoreWithProfiles(profiles: AuthProfileStore["profiles"]): AuthProfileStore { + return { + version: 1, + profiles, + }; +} + +describe("secrets runtime snapshot integration", () => { + afterEach(() => { + clearSecretsRuntimeSnapshot(); + clearConfigCache(); + }); + + it("activates runtime snapshots for loadConfig and ensureAuthProfileStore", async () => { + const prepared = await prepareSecretsRuntimeSnapshot({ + config: asConfig({ + models: { + providers: { + openai: { + baseUrl: "https://api.openai.com/v1", + apiKey: { source: "env", provider: "default", id: "OPENAI_API_KEY" }, + models: [], + }, + }, + }, + }), + env: { OPENAI_API_KEY: "sk-runtime" }, + agentDirs: ["/tmp/openclaw-agent-main"], + loadAuthStore: () => + loadAuthStoreWithProfiles({ + "openai:default": { + type: "api_key", + provider: "openai", + keyRef: OPENAI_ENV_KEY_REF, + }, + }), + }); + + activateSecretsRuntimeSnapshot(prepared); + + expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-runtime"); + expect( + ensureAuthProfileStore("/tmp/openclaw-agent-main").profiles["openai:default"], + ).toMatchObject({ + type: "api_key", + key: "sk-runtime", + }); + }); + + it("keeps active secrets runtime snapshots resolved after config writes", async () => { + if (os.platform() === "win32") { + return; + } + await withTempHome("openclaw-secrets-runtime-write-", async (home) => { + const configDir = path.join(home, ".openclaw"); + const secretFile = path.join(configDir, "secrets.json"); + const agentDir = path.join(configDir, "agents", "main", "agent"); + const authStorePath = path.join(agentDir, "auth-profiles.json"); + await fs.mkdir(agentDir, { recursive: true }); + await fs.chmod(configDir, 0o700).catch(() => {}); + await fs.writeFile( + secretFile, + `${JSON.stringify({ providers: { openai: { apiKey: "sk-file-runtime" } } }, null, 2)}\n`, + { encoding: "utf8", mode: 0o600 }, + ); + await fs.writeFile( + authStorePath, + `${JSON.stringify( + { + version: 1, + profiles: { + "openai:default": { + type: "api_key", + provider: "openai", + keyRef: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, + }, + }, + }, + null, + 2, + )}\n`, + { encoding: "utf8", mode: 0o600 }, + ); + + const prepared = await prepareSecretsRuntimeSnapshot({ + config: asConfig({ + secrets: { + providers: { + default: { + source: "file", + path: secretFile, + mode: "json", + ...(allowInsecureTempSecretFile ? { allowInsecurePath: true } : {}), + }, + }, + }, + models: { + providers: { + openai: { + baseUrl: "https://api.openai.com/v1", + apiKey: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, + models: [], + }, + }, + }, + }), + agentDirs: [agentDir], + }); + + activateSecretsRuntimeSnapshot(prepared); + + expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-file-runtime"); + expect(ensureAuthProfileStore(agentDir).profiles["openai:default"]).toMatchObject({ + type: "api_key", + key: "sk-file-runtime", + }); + + await writeConfigFile({ + ...loadConfig(), + gateway: { auth: { mode: "token" } }, + }); + + expect(loadConfig().gateway?.auth).toEqual({ mode: "token" }); + expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-file-runtime"); + expect(ensureAuthProfileStore(agentDir).profiles["openai:default"]).toMatchObject({ + type: "api_key", + key: "sk-file-runtime", + }); + }); + }); + + it("keeps last-known-good runtime snapshot active when refresh fails after a write", async () => { + if (os.platform() === "win32") { + return; + } + await withTempHome("openclaw-secrets-runtime-refresh-fail-", async (home) => { + const configDir = path.join(home, ".openclaw"); + const secretFile = path.join(configDir, "secrets.json"); + const agentDir = path.join(configDir, "agents", "main", "agent"); + const authStorePath = path.join(agentDir, "auth-profiles.json"); + await fs.mkdir(agentDir, { recursive: true }); + await fs.chmod(configDir, 0o700).catch(() => {}); + await fs.writeFile( + secretFile, + `${JSON.stringify({ providers: { openai: { apiKey: "sk-file-runtime" } } }, null, 2)}\n`, + { encoding: "utf8", mode: 0o600 }, + ); + await fs.writeFile( + authStorePath, + `${JSON.stringify( + { + version: 1, + profiles: { + "openai:default": { + type: "api_key", + provider: "openai", + keyRef: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, + }, + }, + }, + null, + 2, + )}\n`, + { encoding: "utf8", mode: 0o600 }, + ); + + let loadAuthStoreCalls = 0; + const loadAuthStore = () => { + loadAuthStoreCalls += 1; + if (loadAuthStoreCalls > 1) { + throw new Error("simulated secrets runtime refresh failure"); + } + return loadAuthStoreWithProfiles({ + "openai:default": { + type: "api_key", + provider: "openai", + keyRef: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, + }, + }); + }; + + const prepared = await prepareSecretsRuntimeSnapshot({ + config: asConfig({ + secrets: { + providers: { + default: { + source: "file", + path: secretFile, + mode: "json", + ...(allowInsecureTempSecretFile ? { allowInsecurePath: true } : {}), + }, + }, + }, + models: { + providers: { + openai: { + baseUrl: "https://api.openai.com/v1", + apiKey: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, + models: [], + }, + }, + }, + }), + agentDirs: [agentDir], + loadAuthStore, + }); + + activateSecretsRuntimeSnapshot(prepared); + + await expect( + writeConfigFile({ + ...loadConfig(), + gateway: { auth: { mode: "token" } }, + }), + ).rejects.toThrow( + /runtime snapshot refresh failed: simulated secrets runtime refresh failure/i, + ); + + const activeAfterFailure = getActiveSecretsRuntimeSnapshot(); + expect(activeAfterFailure).not.toBeNull(); + expect(loadConfig().gateway?.auth).toBeUndefined(); + expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-file-runtime"); + expect(activeAfterFailure?.sourceConfig.models?.providers?.openai?.apiKey).toEqual({ + source: "file", + provider: "default", + id: "/providers/openai/apiKey", + }); + expect(ensureAuthProfileStore(agentDir).profiles["openai:default"]).toMatchObject({ + type: "api_key", + key: "sk-file-runtime", + }); + }); + }); + + it("keeps last-known-good web runtime snapshot when reload introduces unresolved active web refs", async () => { + await withTempHome("openclaw-secrets-runtime-web-reload-lkg-", async (home) => { + const prepared = await prepareSecretsRuntimeSnapshot({ + config: asConfig({ + tools: { + web: { + search: { + provider: "gemini", + gemini: { + apiKey: { source: "env", provider: "default", id: "WEB_SEARCH_GEMINI_API_KEY" }, + }, + }, + }, + }, + }), + env: { + WEB_SEARCH_GEMINI_API_KEY: "web-search-gemini-runtime-key", + }, + agentDirs: ["/tmp/openclaw-agent-main"], + loadAuthStore: () => ({ version: 1, profiles: {} }), + }); + + activateSecretsRuntimeSnapshot(prepared); + + await expect( + writeConfigFile({ + ...loadConfig(), + plugins: { + entries: { + google: { + config: { + webSearch: { + apiKey: { + source: "env", + provider: "default", + id: "MISSING_WEB_SEARCH_GEMINI_API_KEY", + }, + }, + }, + }, + }, + }, + tools: { + web: { + search: { + provider: "gemini", + gemini: { + apiKey: { + source: "env", + provider: "default", + id: "MISSING_WEB_SEARCH_GEMINI_API_KEY", + }, + }, + }, + }, + }, + }), + ).rejects.toThrow( + /runtime snapshot refresh failed: .*WEB_SEARCH_KEY_UNRESOLVED_NO_FALLBACK/i, + ); + + const activeAfterFailure = getActiveSecretsRuntimeSnapshot(); + expect(activeAfterFailure).not.toBeNull(); + expect(loadConfig().tools?.web?.search?.gemini?.apiKey).toBe("web-search-gemini-runtime-key"); + expect(activeAfterFailure?.sourceConfig.tools?.web?.search?.gemini?.apiKey).toEqual({ + source: "env", + provider: "default", + id: "WEB_SEARCH_GEMINI_API_KEY", + }); + expect(getActiveRuntimeWebToolsMetadata()?.search.selectedProvider).toBe("gemini"); + + const persistedConfig = JSON.parse( + await fs.readFile(path.join(home, ".openclaw", "openclaw.json"), "utf8"), + ) as OpenClawConfig; + const persistedGoogleWebSearchConfig = persistedConfig.plugins?.entries?.google?.config as + | { webSearch?: { apiKey?: unknown } } + | undefined; + expect(persistedGoogleWebSearchConfig?.webSearch?.apiKey).toEqual({ + source: "env", + provider: "default", + id: "MISSING_WEB_SEARCH_GEMINI_API_KEY", + }); + }); + }, 180_000); + + it("recomputes config-derived agent dirs when refreshing active secrets runtime snapshots", async () => { + await withTempHome("openclaw-secrets-runtime-agent-dirs-", async (home) => { + const mainAgentDir = path.join(home, ".openclaw", "agents", "main", "agent"); + const opsAgentDir = path.join(home, ".openclaw", "agents", "ops", "agent"); + await fs.mkdir(mainAgentDir, { recursive: true }); + await fs.mkdir(opsAgentDir, { recursive: true }); + await fs.writeFile( + path.join(mainAgentDir, "auth-profiles.json"), + `${JSON.stringify( + { + version: 1, + profiles: { + "openai:default": { + type: "api_key", + provider: "openai", + keyRef: { source: "env", provider: "default", id: "OPENAI_API_KEY" }, + }, + }, + }, + null, + 2, + )}\n`, + { encoding: "utf8", mode: 0o600 }, + ); + await fs.writeFile( + path.join(opsAgentDir, "auth-profiles.json"), + `${JSON.stringify( + { + version: 1, + profiles: { + "anthropic:ops": { + type: "api_key", + provider: "anthropic", + keyRef: { source: "env", provider: "default", id: "ANTHROPIC_API_KEY" }, + }, + }, + }, + null, + 2, + )}\n`, + { encoding: "utf8", mode: 0o600 }, + ); + + const prepared = await prepareSecretsRuntimeSnapshot({ + config: asConfig({}), + env: { + OPENAI_API_KEY: "sk-main-runtime", + ANTHROPIC_API_KEY: "sk-ops-runtime", + }, + }); + + activateSecretsRuntimeSnapshot(prepared); + expect(ensureAuthProfileStore(opsAgentDir).profiles["anthropic:ops"]).toBeUndefined(); + + await writeConfigFile({ + agents: { + list: [{ id: "ops", agentDir: opsAgentDir }], + }, + }); + + expect(ensureAuthProfileStore(opsAgentDir).profiles["anthropic:ops"]).toMatchObject({ + type: "api_key", + key: "sk-ops-runtime", + keyRef: { source: "env", provider: "default", id: "ANTHROPIC_API_KEY" }, + }); + }); + }); +}); diff --git a/src/secrets/runtime.test.ts b/src/secrets/runtime.test.ts index 92e942ab12f..b4f26f3e9a8 100644 --- a/src/secrets/runtime.test.ts +++ b/src/secrets/runtime.test.ts @@ -2,20 +2,13 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { ensureAuthProfileStore, type AuthProfileStore } from "../agents/auth-profiles.js"; -import { - clearConfigCache, - loadConfig, - type OpenClawConfig, - writeConfigFile, -} from "../config/config.js"; -import { withTempHome } from "../config/home-env.test-harness.js"; +import type { AuthProfileStore } from "../agents/auth-profiles.js"; +import { clearConfigCache, type OpenClawConfig } from "../config/config.js"; import type { PluginWebSearchProviderEntry } from "../plugins/types.js"; import { activateSecretsRuntimeSnapshot, clearSecretsRuntimeSnapshot, getActiveRuntimeWebToolsMetadata, - getActiveSecretsRuntimeSnapshot, prepareSecretsRuntimeSnapshot, } from "./runtime.js"; @@ -130,8 +123,6 @@ describe("secrets runtime snapshot", () => { resolvePluginWebSearchProvidersMock.mockReset(); }); - const allowInsecureTempSecretFile = process.platform === "win32"; - it("resolves env refs for config and auth profiles", async () => { const config = asConfig({ agents: { @@ -731,385 +722,6 @@ describe("secrets runtime snapshot", () => { } }); - it("activates runtime snapshots for loadConfig and ensureAuthProfileStore", async () => { - const prepared = await prepareSecretsRuntimeSnapshot({ - config: asConfig({ - models: { - providers: { - openai: { - baseUrl: "https://api.openai.com/v1", - apiKey: { source: "env", provider: "default", id: "OPENAI_API_KEY" }, - models: [], - }, - }, - }, - }), - env: { OPENAI_API_KEY: "sk-runtime" }, // pragma: allowlist secret - agentDirs: ["/tmp/openclaw-agent-main"], - loadAuthStore: () => - loadAuthStoreWithProfiles({ - "openai:default": { - type: "api_key", - provider: "openai", - keyRef: OPENAI_ENV_KEY_REF, - }, - }), - }); - - activateSecretsRuntimeSnapshot(prepared); - - expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-runtime"); - const store = ensureAuthProfileStore("/tmp/openclaw-agent-main"); - expect(store.profiles["openai:default"]).toMatchObject({ - type: "api_key", - key: "sk-runtime", - }); - }); - - it("keeps active secrets runtime snapshots resolved after config writes", async () => { - if (os.platform() === "win32") { - return; - } - await withTempHome("openclaw-secrets-runtime-write-", async (home) => { - const configDir = path.join(home, ".openclaw"); - const secretFile = path.join(configDir, "secrets.json"); - const agentDir = path.join(configDir, "agents", "main", "agent"); - const authStorePath = path.join(agentDir, "auth-profiles.json"); - await fs.mkdir(agentDir, { recursive: true }); - await fs.chmod(configDir, 0o700).catch(() => { - // best-effort on tmp dirs that already have secure perms - }); - await fs.writeFile( - secretFile, - `${JSON.stringify({ providers: { openai: { apiKey: "sk-file-runtime" } } }, null, 2)}\n`, // pragma: allowlist secret - { encoding: "utf8", mode: 0o600 }, - ); - await fs.writeFile( - authStorePath, - `${JSON.stringify( - { - version: 1, - profiles: { - "openai:default": { - type: "api_key", - provider: "openai", - keyRef: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, - }, - }, - }, - null, - 2, - )}\n`, - { encoding: "utf8", mode: 0o600 }, - ); - - const prepared = await prepareSecretsRuntimeSnapshot({ - config: asConfig({ - secrets: { - providers: { - default: { - source: "file", - path: secretFile, - mode: "json", - ...(allowInsecureTempSecretFile ? { allowInsecurePath: true } : {}), - }, - }, - }, - models: { - providers: { - openai: { - baseUrl: "https://api.openai.com/v1", - apiKey: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, - models: [], - }, - }, - }, - }), - agentDirs: [agentDir], - }); - - activateSecretsRuntimeSnapshot(prepared); - - expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-file-runtime"); - expect(ensureAuthProfileStore(agentDir).profiles["openai:default"]).toMatchObject({ - type: "api_key", - key: "sk-file-runtime", - }); - - await writeConfigFile({ - ...loadConfig(), - gateway: { auth: { mode: "token" } }, - }); - - expect(loadConfig().gateway?.auth).toEqual({ mode: "token" }); - expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-file-runtime"); - expect(ensureAuthProfileStore(agentDir).profiles["openai:default"]).toMatchObject({ - type: "api_key", - key: "sk-file-runtime", - }); - }); - }); - - it("keeps last-known-good runtime snapshot active when refresh fails after a write", async () => { - if (os.platform() === "win32") { - return; - } - await withTempHome("openclaw-secrets-runtime-refresh-fail-", async (home) => { - const configDir = path.join(home, ".openclaw"); - const secretFile = path.join(configDir, "secrets.json"); - const agentDir = path.join(configDir, "agents", "main", "agent"); - const authStorePath = path.join(agentDir, "auth-profiles.json"); - await fs.mkdir(agentDir, { recursive: true }); - await fs.chmod(configDir, 0o700).catch(() => { - // best-effort on tmp dirs that already have secure perms - }); - await fs.writeFile( - secretFile, - `${JSON.stringify({ providers: { openai: { apiKey: "sk-file-runtime" } } }, null, 2)}\n`, // pragma: allowlist secret - { encoding: "utf8", mode: 0o600 }, - ); - await fs.writeFile( - authStorePath, - `${JSON.stringify( - { - version: 1, - profiles: { - "openai:default": { - type: "api_key", - provider: "openai", - keyRef: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, - }, - }, - }, - null, - 2, - )}\n`, - { encoding: "utf8", mode: 0o600 }, - ); - - let loadAuthStoreCalls = 0; - const loadAuthStore = () => { - loadAuthStoreCalls += 1; - if (loadAuthStoreCalls > 1) { - throw new Error("simulated secrets runtime refresh failure"); - } - return loadAuthStoreWithProfiles({ - "openai:default": { - type: "api_key", - provider: "openai", - keyRef: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, - }, - }); - }; - - const prepared = await prepareSecretsRuntimeSnapshot({ - config: asConfig({ - secrets: { - providers: { - default: { - source: "file", - path: secretFile, - mode: "json", - ...(allowInsecureTempSecretFile ? { allowInsecurePath: true } : {}), - }, - }, - }, - models: { - providers: { - openai: { - baseUrl: "https://api.openai.com/v1", - apiKey: { source: "file", provider: "default", id: "/providers/openai/apiKey" }, - models: [], - }, - }, - }, - }), - agentDirs: [agentDir], - loadAuthStore, - }); - - activateSecretsRuntimeSnapshot(prepared); - - await expect( - writeConfigFile({ - ...loadConfig(), - gateway: { auth: { mode: "token" } }, - }), - ).rejects.toThrow( - /runtime snapshot refresh failed: simulated secrets runtime refresh failure/i, - ); - - const activeAfterFailure = getActiveSecretsRuntimeSnapshot(); - expect(activeAfterFailure).not.toBeNull(); - expect(loadConfig().gateway?.auth).toBeUndefined(); - expect(loadConfig().models?.providers?.openai?.apiKey).toBe("sk-file-runtime"); - expect(activeAfterFailure?.sourceConfig.models?.providers?.openai?.apiKey).toEqual({ - source: "file", - provider: "default", - id: "/providers/openai/apiKey", - }); - - const persistedStore = ensureAuthProfileStore(agentDir).profiles["openai:default"]; - expect(persistedStore).toMatchObject({ - type: "api_key", - key: "sk-file-runtime", - }); - }); - }); - - it("keeps last-known-good web runtime snapshot when reload introduces unresolved active web refs", async () => { - await withTempHome("openclaw-secrets-runtime-web-reload-lkg-", async (home) => { - const prepared = await prepareSecretsRuntimeSnapshot({ - config: asConfig({ - tools: { - web: { - search: { - provider: "gemini", - gemini: { - apiKey: { source: "env", provider: "default", id: "WEB_SEARCH_GEMINI_API_KEY" }, - }, - }, - }, - }, - }), - env: { - WEB_SEARCH_GEMINI_API_KEY: "web-search-gemini-runtime-key", // pragma: allowlist secret - }, - agentDirs: ["/tmp/openclaw-agent-main"], - loadAuthStore: () => ({ version: 1, profiles: {} }), - }); - - activateSecretsRuntimeSnapshot(prepared); - - await expect( - writeConfigFile({ - ...loadConfig(), - plugins: { - entries: { - google: { - config: { - webSearch: { - apiKey: { - source: "env", - provider: "default", - id: "MISSING_WEB_SEARCH_GEMINI_API_KEY", - }, - }, - }, - }, - }, - }, - tools: { - web: { - search: { - provider: "gemini", - gemini: { - apiKey: { - source: "env", - provider: "default", - id: "MISSING_WEB_SEARCH_GEMINI_API_KEY", - }, - }, - }, - }, - }, - }), - ).rejects.toThrow( - /runtime snapshot refresh failed: .*WEB_SEARCH_KEY_UNRESOLVED_NO_FALLBACK/i, - ); - - const activeAfterFailure = getActiveSecretsRuntimeSnapshot(); - expect(activeAfterFailure).not.toBeNull(); - expect(loadConfig().tools?.web?.search?.gemini?.apiKey).toBe("web-search-gemini-runtime-key"); - expect(activeAfterFailure?.sourceConfig.tools?.web?.search?.gemini?.apiKey).toEqual({ - source: "env", - provider: "default", - id: "WEB_SEARCH_GEMINI_API_KEY", - }); - expect(getActiveRuntimeWebToolsMetadata()?.search.selectedProvider).toBe("gemini"); - - const persistedConfig = JSON.parse( - await fs.readFile(path.join(home, ".openclaw", "openclaw.json"), "utf8"), - ) as OpenClawConfig; - const persistedGoogleWebSearchConfig = persistedConfig.plugins?.entries?.google?.config as - | { webSearch?: { apiKey?: unknown } } - | undefined; - expect(persistedGoogleWebSearchConfig?.webSearch?.apiKey).toEqual({ - source: "env", - provider: "default", - id: "MISSING_WEB_SEARCH_GEMINI_API_KEY", - }); - }); - }); - - it("recomputes config-derived agent dirs when refreshing active secrets runtime snapshots", async () => { - await withTempHome("openclaw-secrets-runtime-agent-dirs-", async (home) => { - const mainAgentDir = path.join(home, ".openclaw", "agents", "main", "agent"); - const opsAgentDir = path.join(home, ".openclaw", "agents", "ops", "agent"); - await fs.mkdir(mainAgentDir, { recursive: true }); - await fs.mkdir(opsAgentDir, { recursive: true }); - await fs.writeFile( - path.join(mainAgentDir, "auth-profiles.json"), - `${JSON.stringify( - { - version: 1, - profiles: { - "openai:default": { - type: "api_key", - provider: "openai", - keyRef: { source: "env", provider: "default", id: "OPENAI_API_KEY" }, - }, - }, - }, - null, - 2, - )}\n`, - { encoding: "utf8", mode: 0o600 }, - ); - await fs.writeFile( - path.join(opsAgentDir, "auth-profiles.json"), - `${JSON.stringify( - { - version: 1, - profiles: { - "anthropic:ops": { - type: "api_key", - provider: "anthropic", - keyRef: { source: "env", provider: "default", id: "ANTHROPIC_API_KEY" }, - }, - }, - }, - null, - 2, - )}\n`, - { encoding: "utf8", mode: 0o600 }, - ); - - const prepared = await prepareSecretsRuntimeSnapshot({ - config: asConfig({}), - env: { - OPENAI_API_KEY: "sk-main-runtime", // pragma: allowlist secret - ANTHROPIC_API_KEY: "sk-ops-runtime", // pragma: allowlist secret - }, - }); - - activateSecretsRuntimeSnapshot(prepared); - expect(ensureAuthProfileStore(opsAgentDir).profiles["anthropic:ops"]).toBeUndefined(); - - await writeConfigFile({ - agents: { - list: [{ id: "ops", agentDir: opsAgentDir }], - }, - }); - - expect(ensureAuthProfileStore(opsAgentDir).profiles["anthropic:ops"]).toMatchObject({ - type: "api_key", - key: "sk-ops-runtime", - keyRef: { source: "env", provider: "default", id: "ANTHROPIC_API_KEY" }, - }); - }); - }); - it("skips inactive-surface refs and emits diagnostics", async () => { const config = asConfig({ agents: { diff --git a/test/fixtures/test-parallel.behavior.json b/test/fixtures/test-parallel.behavior.json index 3f28709511f..f0585bd0249 100644 --- a/test/fixtures/test-parallel.behavior.json +++ b/test/fixtures/test-parallel.behavior.json @@ -31,6 +31,10 @@ "file": "src/secrets/runtime.test.ts", "reason": "Secrets runtime coverage retained the largest unit-fast heap spike in CI and is safer outside the shared lane." }, + { + "file": "src/secrets/runtime.integration.test.ts", + "reason": "Secrets runtime activation/write-through integration coverage is CPU-heavy and safer outside the shared unit-fast lane." + }, { "file": "src/memory/index.test.ts", "reason": "Memory index coverage retained nearly 1 GiB in unit-fast on Linux CI and is safer in its own fork."