Skip to content

Commit 0454985

Browse files
committed
fix: simplify stale deep-scan configuration cleanup
1 parent b958c82 commit 0454985

2 files changed

Lines changed: 38 additions & 134 deletions

File tree

sdk/typescript/src/api.ts

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
readFile,
88
realpath,
99
rm,
10-
stat,
1110
writeFile,
1211
} from "node:fs/promises";
1312
import { randomUUID } from "node:crypto";
@@ -1433,35 +1432,7 @@ async function prepareDeepScanConfig(
14331432
const hasOverrides = Object.keys(overrides).length > 0;
14341433
if (existing === undefined && !hasOverrides) {
14351434
if (destination !== source) {
1436-
const identity = async (path: string) => {
1437-
try {
1438-
return await stat(path);
1439-
} catch (error) {
1440-
if (isRecord(error) && error["code"] === "ENOENT") return null;
1441-
throw error;
1442-
}
1443-
};
1444-
const sameIdentity = (
1445-
first: Awaited<ReturnType<typeof identity>>,
1446-
second: Awaited<ReturnType<typeof identity>>,
1447-
): boolean =>
1448-
first !== null &&
1449-
second !== null &&
1450-
first.dev === second.dev &&
1451-
first.ino === second.ino;
1452-
const [sourceIdentity, destinationIdentity] = await Promise.all([
1453-
identity(source),
1454-
identity(destination),
1455-
]);
1456-
if (!sameIdentity(sourceIdentity, destinationIdentity)) {
1457-
const [sourceDirectory, destinationDirectory] = await Promise.all([
1458-
identity(dirname(source)),
1459-
identity(dirname(destination)),
1460-
]);
1461-
if (!sameIdentity(sourceDirectory, destinationDirectory)) {
1462-
await rm(destination, { force: true });
1463-
}
1464-
}
1435+
await rm(destination, { force: true });
14651436
}
14661437
return;
14671438
}

sdk/typescript/tests-ts/api.test.ts

Lines changed: 37 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
copyFile,
33
cp,
4-
link,
54
mkdir,
65
mkdtemp,
76
readFile,
@@ -1833,7 +1832,7 @@ describe("CodexSecurity orchestration", () => {
18331832
? []
18341833
: [
18351834
"without deep settings and a dangling runtime link",
1836-
"without deep settings and a hard-linked dangling runtime link",
1835+
"without deep settings and a cyclic runtime link",
18371836
]),
18381837
])(
18391838
"clears stale runtime deep-scan configuration when ambient settings are %s",
@@ -1890,13 +1889,10 @@ describe("CodexSecurity orchestration", () => {
18901889
await rm(runtimeConfig);
18911890
await symlink(escapedConfig, runtimeConfig);
18921891
} else if (
1893-
ambientState ===
1894-
"without deep settings and a hard-linked dangling runtime link"
1892+
ambientState === "without deep settings and a cyclic runtime link"
18951893
) {
1896-
await rm(ambientConfig);
1897-
await symlink(escapedConfig, ambientConfig);
18981894
await rm(runtimeConfig);
1899-
execFileSync("ln", ["-P", ambientConfig, runtimeConfig]);
1895+
await symlink(runtimeConfig, runtimeConfig);
19001896
}
19011897

19021898
await expect(client.run(repository, { mode: "deep" })).rejects.toThrow(
@@ -1905,15 +1901,6 @@ describe("CodexSecurity orchestration", () => {
19051901
await expect(fsPromises.lstat(runtimeConfig)).rejects.toMatchObject({
19061902
code: "ENOENT",
19071903
});
1908-
if (
1909-
ambientState ===
1910-
"without deep settings and a hard-linked dangling runtime link"
1911-
) {
1912-
expect((await fsPromises.lstat(ambientConfig)).isSymbolicLink()).toBe(
1913-
true,
1914-
);
1915-
await rm(ambientConfig);
1916-
}
19171904

19181905
await writeFile(ambientConfig, "[deep_scan]\nworkers = 7\n");
19191906
await expect(client.run(repository, { mode: "deep" })).rejects.toThrow(
@@ -1925,97 +1912,43 @@ describe("CodexSecurity orchestration", () => {
19251912
},
19261913
);
19271914

1928-
test.each([
1929-
"the same path",
1930-
"a symlink alias",
1931-
"a shared configuration directory",
1932-
"a shared file identity",
1933-
...(process.platform === "win32"
1934-
? []
1935-
: ["a shared configuration file", "a shared dangling configuration"]),
1936-
])(
1937-
"preserves ambient configuration when the deep-scan runtime shares it through %s",
1938-
async (configurationAlias) => {
1939-
const root = await temporaryDirectory();
1940-
const repository = join(root, "repository");
1941-
const codexHome = join(root, "codex-home");
1942-
const ambientHome =
1943-
configurationAlias !== "the same path"
1944-
? join(root, "ambient-home-link")
1945-
: codexHome;
1946-
const scanDir = join(root, "scan");
1947-
const configPath = join(codexHome, "codex-security", "config.toml");
1948-
const originalConfiguration = "[other]\nenabled = true\n";
1949-
await mkdir(repository);
1950-
await mkdir(join(codexHome, "codex-security"), { recursive: true });
1951-
if (configurationAlias === "a shared dangling configuration") {
1952-
await symlink(join(root, "missing-config.toml"), configPath);
1953-
} else {
1954-
await writeFile(configPath, originalConfiguration);
1955-
}
1956-
if (configurationAlias === "a symlink alias") {
1957-
await symlink(
1958-
codexHome,
1959-
ambientHome,
1960-
process.platform === "win32" ? "junction" : "dir",
1961-
);
1962-
} else if (
1963-
configurationAlias === "a shared configuration directory" ||
1964-
configurationAlias === "a shared dangling configuration"
1965-
) {
1966-
await mkdir(ambientHome);
1967-
await symlink(
1968-
join(codexHome, "codex-security"),
1969-
join(ambientHome, "codex-security"),
1970-
process.platform === "win32" ? "junction" : "dir",
1971-
);
1972-
} else if (configurationAlias === "a shared configuration file") {
1973-
await mkdir(join(ambientHome, "codex-security"), { recursive: true });
1974-
await symlink(
1975-
configPath,
1976-
join(ambientHome, "codex-security", "config.toml"),
1977-
);
1978-
} else if (configurationAlias === "a shared file identity") {
1979-
await mkdir(join(ambientHome, "codex-security"), { recursive: true });
1980-
await link(
1981-
configPath,
1982-
join(ambientHome, "codex-security", "config.toml"),
1983-
);
1984-
}
1985-
await mkdir(scanDir, { mode: 0o700 });
1915+
test("preserves ambient configuration when the deep-scan runtime uses the same home", async () => {
1916+
const root = await temporaryDirectory();
1917+
const repository = join(root, "repository");
1918+
const codexHome = join(root, "codex-home");
1919+
const scanDir = join(root, "scan");
1920+
const configPath = join(codexHome, "codex-security", "config.toml");
1921+
const originalConfiguration = "[other]\nenabled = true\n";
1922+
await mkdir(repository);
1923+
await mkdir(join(codexHome, "codex-security"), { recursive: true });
1924+
await writeFile(configPath, originalConfiguration);
1925+
await mkdir(scanDir, { mode: 0o700 });
19861926

1987-
const client = new TestClient(
1988-
{},
1989-
{
1990-
environment: { CODEX_HOME: ambientHome },
1991-
prepareRuntime: async () => preparedRuntime(codexHome),
1992-
resolvePluginPython: async () => "/managed/python",
1993-
prepareOutputDir: async () => scanDir,
1994-
repositoryRevision: async () => "deadbeef",
1995-
createCodex: () => ({
1996-
startThread: () => ({
1997-
id: null,
1998-
async runStreamed() {
1999-
throw new Error("deep scan settings captured");
2000-
},
2001-
}),
1927+
const client = new TestClient(
1928+
{},
1929+
{
1930+
environment: { CODEX_HOME: codexHome },
1931+
prepareRuntime: async () => preparedRuntime(codexHome),
1932+
resolvePluginPython: async () => "/managed/python",
1933+
prepareOutputDir: async () => scanDir,
1934+
repositoryRevision: async () => "deadbeef",
1935+
createCodex: () => ({
1936+
startThread: () => ({
1937+
id: null,
1938+
async runStreamed() {
1939+
throw new Error("deep scan settings captured");
1940+
},
20021941
}),
2003-
},
2004-
);
1942+
}),
1943+
},
1944+
);
20051945

2006-
await expect(client.run(repository, { mode: "deep" })).rejects.toThrow(
2007-
"deep scan settings captured",
2008-
);
2009-
if (configurationAlias === "a shared dangling configuration") {
2010-
expect((await fsPromises.lstat(configPath)).isSymbolicLink()).toBe(
2011-
true,
2012-
);
2013-
} else {
2014-
expect(await readFile(configPath, "utf8")).toBe(originalConfiguration);
2015-
}
2016-
await client.close();
2017-
},
2018-
);
1946+
await expect(client.run(repository, { mode: "deep" })).rejects.toThrow(
1947+
"deep scan settings captured",
1948+
);
1949+
expect(await readFile(configPath, "utf8")).toBe(originalConfiguration);
1950+
await client.close();
1951+
});
20191952

20201953
test("rejects a scan registration without an authoritative target contract", async () => {
20211954
const root = await temporaryDirectory();

0 commit comments

Comments
 (0)