From 39119f43bb69ea656e0ff410ca0b551082d7c37b Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Fri, 23 Oct 2026 19:18:33 +0900 Subject: [PATCH 1/8] Bind separate-prefix Windows Node/npm for read-only plan under the launcher arch anchor --- docs-site/src/content/docs/reference/cli.md | 8 +- .../src/content/docs/reference/cli/agents.md | 10 +- src/codex/cli-windows-plan-provenance.ts | 19 +++- structure/codex-cli-update.md | 18 +-- .../codex-cli-windows-plan.test.ts | 105 ++++++++++++------ 5 files changed, 108 insertions(+), 52 deletions(-) diff --git a/docs-site/src/content/docs/reference/cli.md b/docs-site/src/content/docs/reference/cli.md index 8bc2ef7316..e2b65fc3fc 100644 --- a/docs-site/src/content/docs/reference/cli.md +++ b/docs-site/src/content/docs/reference/cli.md @@ -153,8 +153,10 @@ The JSON report exposes `candidateAvailable`, `candidateVersion`, `candidateSour Inspecting the configured candidate requires a trusted published-launcher context; a direct Bun/source launch has no such proof, ignores ambient and persisted candidate state, and may report `candidate_unavailable` on POSIX or `windows_inspection_deferred` on Windows. Windows x64 also supports -a proof-captured absolute standard npm `codex.cmd` with prefix-local Node/npm and a verified in-prefix -platform backing. It uses reparse-refusing held handles; other Windows layouts remain deferred or unmanaged. +a proof-captured absolute standard npm `codex.cmd` with a held-bound Node/npm toolchain — prefix-local +when present, otherwise the captured-PATH pair anchored to the launcher architecture — and a verified +in-prefix platform backing. It uses reparse-refusing held handles; other Windows layouts remain deferred +or unmanaged. The command does not install or repair software, execute Codex or npm, control a running process, or write configuration/cache state. @@ -164,7 +166,7 @@ exact version and SHA-512 integrity, and refuses active sessions or incomplete p Registry queries use isolated temporary npm configuration, cache and logs with best-effort cleanup. No software is installed and no process is signalled. A supported Windows installation can produce a deterministic read-only plan with `applicable: false` and `refusal: windows_apply_disabled`. -PATH-only selection, separate-prefix Node and OpenCodex autostart wrappers remain deferred. +PATH-only selection and OpenCodex autostart wrappers remain deferred. See [planning details](/reference/cli/agents/#read-only-codex-cli-update-plan). For a reviewed POSIX non-shim npm-global plan, `ocx system codex-cli-update apply --plan-id --yes` diff --git a/docs-site/src/content/docs/reference/cli/agents.md b/docs-site/src/content/docs/reference/cli/agents.md index 622c59d181..8af4f6a651 100644 --- a/docs-site/src/content/docs/reference/cli/agents.md +++ b/docs-site/src/content/docs/reference/cli/agents.md @@ -1164,8 +1164,9 @@ can then establish `managed: true` when it proves ownership and, if a candidate and `selectionAttested`. Inspecting the configured candidate requires a trusted published-launcher context; a direct Bun/source launch has no such proof, ignores ambient and persisted candidate state, and may report `candidate_unavailable` on POSIX. On Windows x64, a proof-captured absolute standard npm `codex.cmd` -can be managed when held local handles bind its package, prefix-local Node/npm and the first in-prefix -platform backing. Other Windows layouts remain deferred or unmanaged. Windows never consults persisted state, so a run +can be managed when held local handles bind its package, a held-bound Node/npm toolchain — prefix-local +when present, otherwise the captured-PATH pair anchored to the launcher architecture — and the first +in-prefix platform backing. Other Windows layouts remain deferred or unmanaged. Windows never consults persisted state, so a run with no captured environment candidate reports `windows_inspection_deferred` rather than `candidate_unavailable`: the command cannot observe whether a Codex CLI is installed, so it reports the deferral instead of asserting that no candidate exists. The command does not execute Codex or a package manager, repair a shim, @@ -1183,8 +1184,9 @@ ocx system codex-cli-update plan --channel latest --json Run through the published Node launcher with the intended `CODEX_CLI_PATH` in the shell environment. The plan requires an attested npm-global installation and a linked package manifest version. -Windows supports only an explicit absolute standard npm `codex.cmd` with prefix-local Node/npm; -PATH-only selection, separate-prefix Node, OpenCodex autostart wrappers and global/vendor fallback stay deferred. +Windows supports only an explicit absolute standard npm `codex.cmd` with a held-bound Node/npm toolchain — +prefix-local when present, otherwise the captured-PATH pair anchored to the launcher architecture; +PATH-only selection, OpenCodex autostart wrappers and global/vendor fallback stay deferred. It queries the official npm registry for an exact version, SHA-512 integrity and same-origin tarball, using the launcher's captured PATH and isolated temporary npm configuration, cache and logs. Proxy settings and `NODE_EXTRA_CA_CERTS` remain supported; cleanup is best-effort. No Codex command runs. diff --git a/src/codex/cli-windows-plan-provenance.ts b/src/codex/cli-windows-plan-provenance.ts index 0f7b5d5c05..9c0b0d9dd0 100644 --- a/src/codex/cli-windows-plan-provenance.ts +++ b/src/codex/cli-windows-plan-provenance.ts @@ -48,9 +48,14 @@ function peArch(bytes: Uint8Array): "x64" | "arm64" | null { /** * Read-only supported subset: a proof-captured absolute standard npm cmd-shim - * override, its global-prefix package, prefix-local Node/npm, and the prefix-local - * optional backing. PATH-only Node selection remains refused until the snapshot - * proves the target cmd-shim's cwd and search policy. + * override, its global-prefix package, a held-bound Node/npm toolchain, and the + * in-prefix optional backing. When the prefix has no node.exe, the toolchain is + * the npm pair the captured PATH resolves — the updater's own metadata vehicle, + * never a claim about which interpreter a later codex.cmd invocation resolves: + * the shim's bare `node` falls through to the ambient invocation working + * directory, which no launcher snapshot can prove. A separate toolchain + * therefore also requires the launcher arch anchor, keeping the backing lane + * tied to the selection instead of to an arbitrary PATH hit. */ export async function inspectWindowsCodexCliPlanInstall( deps: CodexCliInstallProvenanceDeps, fallback: CodexCliInstallReport, excluded: (path: string) => boolean, @@ -75,7 +80,11 @@ export async function inspectWindowsCodexCliPlanInstall( const npmCli = derivation.input.npmCli; const npmRoot = win32.dirname(win32.dirname(npmCli)); const pathNode = !sameWindowsPath(node, localNodePath); - if (pathNode) return fallback; + // A prefix-local node.exe is provably the shim's own interpreter; a PATH-resolved + // separate toolchain is bound as the updater's metadata vehicle only. Without the + // launcher arch the toolchain's arch cannot be tied to the selection at all, so a + // separate toolchain stays refused rather than claim an unanchored backing lane. + if (pathNode && !deps.arch) return fallback; const root = win32.join(prefix, "node_modules", "@openai", "codex"); const manifest = win32.join(root, "package.json"); const npmManifest = win32.join(npmRoot, "package.json"); @@ -137,7 +146,7 @@ export async function inspectWindowsCodexCliPlanInstall( const backing = json(files.get(backingManifest)!); if (!backing || "exports" in backing || ![pkg, "@openai/codex"].includes(String(backing.name)) || ![main.version, `${main.version}-win32-${arch}`].includes(String(backing.version))) return fallback; - const content = hash(JSON.stringify(["windows-npm-read-only-plan-v2", arch, prefix, candidate, node, npmCli, + const content = hash(JSON.stringify(["windows-npm-read-only-plan-v3", arch, prefix, candidate, node, npmCli, ...final.files.map(file => [file.path, file.identity, file.digest])])); const report: CodexCliInstallReport = Object.freeze({ ...fallback, managed: true, selectionAttested: true, provenance: "npm-global", reason: "managed_npm_global", packageVersion: main.version, diff --git a/structure/codex-cli-update.md b/structure/codex-cli-update.md index 122a743bdb..843ecd6317 100644 --- a/structure/codex-cli-update.md +++ b/structure/codex-cli-update.md @@ -60,13 +60,15 @@ an existing Codex session. Windows enumeration/installation limits remain unchan `src/codex/cli-windows-plan-provenance.ts` admits only a proof-captured, drive-absolute `CODEX_CLI_PATH` naming the exact standard npm `codex.cmd` grammar. The global npm -package prefix comes from the shim directory and its `node_modules` tree. This plan -currently requires prefix-local `node.exe` and npm. Derivation may propose a PATH Node only -when the local Node probe proves `not-found`; a refused/reparse probe never counts as absent. -The production plan still refuses that external candidate: a standard npm cmd-shim runs bare -`node` when its local Node is absent, and CMD can prefer the invocation working directory. -The proof-bound launcher snapshot has PATH/PATHEXT but no target-shim invocation -cwd/search-result evidence, so a separate Node cannot be selected safely yet. The production runtime resolver confirms the explicit Codex override's +package prefix comes from the shim directory and its `node_modules` tree. A prefix-local +`node.exe` and npm bind as the shim's own interpreter toolchain. When the local probe +proves `not-found`, the captured PATH's Node/npm pair binds instead as the updater's +metadata toolchain; a refused or reparse probe never counts as absent, and a separate +toolchain without the launcher arch anchor stays refused because its arch could not be +tied to the selection at all. The bound Node is never claimed to be the interpreter a +later `codex.cmd` invocation resolves: the shim's bare `node` falls through to the +ambient invocation working directory — CMD prefers the current directory over PATH — +and no launcher snapshot can carry that per-invocation property. The production runtime resolver confirms the explicit Codex override's priority without saved-state reads or probes. A PE header binds Node's architecture; the package manifest/bin, npm manifest/bin, Node and the first in-prefix platform package plus native backing are observed together. Backing lookup follows the @@ -78,7 +80,7 @@ to 256 KiB and Node to 128 MiB. The native backing uses the same finite 1 GiB The native reader bounds aggregate requests to that backing plus 128 MiB Node and twelve 1 MiB text requests; hash-only bytes are never buffered whole. -PATH-only or separate-prefix Node selection, autostart wrappers, global/vendor fallback, +PATH-only candidate selection, autostart wrappers, global/vendor fallback, app/Store/MSIX bundles and version-manager ownership remain unverified and unmanaged. The explicit `attest` report stays observation-only. Only the production plan predicate creates private plan evidence; copying a public report cannot enable Windows planning. diff --git a/tests/codex-integration/codex-cli-windows-plan.test.ts b/tests/codex-integration/codex-cli-windows-plan.test.ts index 5f96068276..600b802ca2 100644 --- a/tests/codex-integration/codex-cli-windows-plan.test.ts +++ b/tests/codex-integration/codex-cli-windows-plan.test.ts @@ -155,29 +155,67 @@ native("a selected override changing during observation refuses the original pre }); native("npm toolchain drift after inspection refuses metadata without executing the replacement", async () => { - const f = fixture(); let queries = 0; - const plan = await createCodexCliUpdatePlan({ inspectionDeps: f.deps, inspect: async deps => { - const report = await inspectCodexCliInstall(deps); expect(report.managed).toBe(true); - writeFileSync(join(f.npmRoot, "bin", "npm-cli.js"), "throw new Error('replacement');"); - return report; - }, resolveTarget: () => { queries++; throw new Error("must not query changed toolchain"); } }); - expect(queries).toBe(0); expect(plan.refusal).toBe("target_unresolved"); + for (const f of [fixture(), fixture(true)]) { + let queries = 0; + const plan = await createCodexCliUpdatePlan({ inspectionDeps: f.deps, inspect: async deps => { + const report = await inspectCodexCliInstall(deps); expect(report.managed).toBe(true); + writeFileSync(join(f.npmRoot, "bin", "npm-cli.js"), "throw new Error('replacement');"); + return report; + }, resolveTarget: () => { queries++; throw new Error("must not query changed toolchain"); } }); + expect(queries).toBe(0); expect(plan.refusal).toBe("target_unresolved"); + } }); -native("a separate PATH Node is refused without proof of the target cmd-shim's search result", async () => { +native("a separate PATH Node/npm toolchain binds for read-only planning under the launcher arch anchor", async () => { const f = fixture(true); expect((await inspectCodexCliInstall({ ...f.deps, selectionAttested: false })).managed).toBe(false); const report = await inspectCodexCliInstall(f.deps); + expect(report).toMatchObject({ managed: true, selectionAttested: true, provenance: "npm-global", + reason: "managed_npm_global", packageVersion: "1.2.3" }); + expect(report.installContentDigest).toMatch(/^[a-f0-9]{64}$/); + expect((await inspectCodexCliInstall(f.deps)).installContentDigest).toBe(report.installContentDigest); + expect(JSON.stringify(report)).not.toContain(f.root); + + const deps = { inspectionDeps: f.deps, + resolveTarget: () => ({ kind: "resolved" as const, version: "1.2.4", integrity: "sha512-" + Buffer.alloc(64, 1).toString("base64") }), + scanProcesses: () => ({ kind: "observed" as const, processes: [] }) }; + const first = await createCodexCliUpdatePlan(deps); + expect(first).toMatchObject({ managed: true, applicable: false, refusal: "windows_apply_disabled", + installedVersion: "1.2.3", targetVersion: "1.2.4" }); + expect(first.planId).toMatch(/^[a-f0-9]{32}$/); + expect((await createCodexCliUpdatePlan(deps)).planId).toBe(first.planId); + expect(JSON.stringify(first)).not.toContain(f.root); +}); + +native("a separate PATH Node without the launcher arch anchor stays refused", async () => { + const f = fixture(true); + const report = await inspectCodexCliInstall({ ...f.deps, arch: undefined }); expect(report).toMatchObject({ managed: false, installContentDigest: null }); let targetQueries = 0; - const plan = await createCodexCliUpdatePlan({ inspectionDeps: f.deps, - resolveTarget: () => { targetQueries++; throw new Error("unproven Node must not query registry"); } }); + const plan = await createCodexCliUpdatePlan({ inspectionDeps: { ...f.deps, arch: undefined }, + resolveTarget: () => { targetQueries++; throw new Error("unanchored Node must not query registry"); } }); expect(targetQueries).toBe(0); expect(plan.managed).toBe(false); expect(plan.refusal).toBe("windows_inspection_deferred"); expect(JSON.stringify(plan)).not.toContain(f.root); }); +native("a separate PATH Node whose PE arch disagrees with the launcher anchor stays refused", async () => { + const f = fixture(true); + const report = await inspectCodexCliInstall({ ...f.deps, arch: "arm64" as const }); + expect(report).toMatchObject({ managed: false, installContentDigest: null }); +}); + +native("a separate PATH Node without its adjacent npm-cli.js stays deferred", async () => { + const f = fixture(true); + removeTreeWithRetry(f.npmRoot); + const report = await inspectCodexCliInstall(f.deps); + expect(report).toMatchObject({ managed: false, installContentDigest: null }); + const plan = await createCodexCliUpdatePlan({ inspectionDeps: f.deps }); + expect(plan.managed).toBe(false); + expect(plan.refusal).toBe("windows_inspection_deferred"); +}); + native("synthetic CMD lookup selects a current-directory node.cmd ahead of PATH", () => { const root = mkdtempSync(join(tmpdir(), "ocx-cmd-search-")); roots.push(root); const current = join(root, "current"); const pathDir = join(root, "path"); @@ -230,26 +268,29 @@ native("actual CLI handler reaches production inspector and plan from the proof- }); native("published Node CLI uses the production inspector and observed toolchain for read-only metadata", () => { - const f = fixture(); const hostNode = Bun.which("node"); expect(hostNode).not.toBeNull(); - const node = join(f.toolchainPrefix, "node.exe"); copyFileSync(hostNode!, node); - const integrity = "sha512-" + Buffer.alloc(64, 1).toString("base64"); - const main = { name: "@openai/codex", version: "1.2.4", optionalDependencies: { "@openai/codex-win32-x64": "1.2.4" }, - dist: { integrity, tarball: "https://registry.npmjs.org/@openai/codex/-/codex-1.2.4.tgz" } }; - const backing = { name: "@openai/codex-win32-x64", version: "1.2.4", dist: { integrity, - tarball: "https://registry.npmjs.org/@openai/codex-win32-x64/-/codex-win32-x64-1.2.4.tgz" } }; - // Controlled registry protocol fixture; no real npm installation or network request. - writeFileSync(join(f.npmRoot, "bin", "npm-cli.js"), - `const spec = process.argv[3]; console.log(JSON.stringify(spec.startsWith('@openai/codex-win32-x64@') ? ${JSON.stringify(backing)} : ${JSON.stringify(main)}));`); - const run = spawnSync(node, [repoPath("bin", "ocx.mjs"), "system", "codex-cli-update", "plan", "--json"], { - cwd: repoRoot(), encoding: "utf8", windowsHide: true, timeout: 45_000, - env: { ...process.env, CODEX_CLI_PATH: f.deps.env.CODEX_CLI_PATH, OPENCODEX_HOME: f.deps.configDir, - OPENCODEX_BUN_PATH: process.execPath, OCX_NO_DESKTOP_HANDOFF: "1" }, - }); - expect(run.error).toBeUndefined(); expect(run.status).toBe(0); - const plan = JSON.parse(run.stdout); - expect(plan.managed).toBe(true); expect(plan.targetVersion).toBe("1.2.4"); - expect(plan.targetIntegrity).toBe(integrity); - expect(plan.applicable).toBe(false); - expect(["blocked_active_session", "blocked_process_state_unknown", "windows_apply_disabled"]).toContain(plan.refusal); - expect(JSON.stringify(plan)).not.toContain(f.root); + const hostNode = Bun.which("node"); expect(hostNode).not.toBeNull(); + for (const f of [fixture(), fixture(true)]) { + const node = join(f.toolchainPrefix, "node.exe"); copyFileSync(hostNode!, node); + const integrity = "sha512-" + Buffer.alloc(64, 1).toString("base64"); + const main = { name: "@openai/codex", version: "1.2.4", optionalDependencies: { "@openai/codex-win32-x64": "1.2.4" }, + dist: { integrity, tarball: "https://registry.npmjs.org/@openai/codex/-/codex-1.2.4.tgz" } }; + const backing = { name: "@openai/codex-win32-x64", version: "1.2.4", dist: { integrity, + tarball: "https://registry.npmjs.org/@openai/codex-win32-x64/-/codex-win32-x64-1.2.4.tgz" } }; + // Controlled registry protocol fixture; no real npm installation or network request. + writeFileSync(join(f.npmRoot, "bin", "npm-cli.js"), + `const spec = process.argv[3]; console.log(JSON.stringify(spec.startsWith('@openai/codex-win32-x64@') ? ${JSON.stringify(backing)} : ${JSON.stringify(main)}));`); + const run = spawnSync(node, [repoPath("bin", "ocx.mjs"), "system", "codex-cli-update", "plan", "--json"], { + cwd: repoRoot(), encoding: "utf8", windowsHide: true, timeout: 45_000, + env: { ...process.env, PATH: f.toolchainPrefix + ";" + process.env.PATH, + CODEX_CLI_PATH: f.deps.env.CODEX_CLI_PATH, OPENCODEX_HOME: f.deps.configDir, + OPENCODEX_BUN_PATH: process.execPath, OCX_NO_DESKTOP_HANDOFF: "1" }, + }); + expect(run.error).toBeUndefined(); expect(run.status).toBe(0); + const plan = JSON.parse(run.stdout); + expect(plan.managed).toBe(true); expect(plan.targetVersion).toBe("1.2.4"); + expect(plan.targetIntegrity).toBe(integrity); + expect(plan.applicable).toBe(false); + expect(["blocked_active_session", "blocked_process_state_unknown", "windows_apply_disabled"]).toContain(plan.refusal); + expect(JSON.stringify(plan)).not.toContain(f.root); + } }, 60_000); From 88f8d21b0b7e99d82523f97da84183cd221c1bdd Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Fri, 23 Oct 2026 19:26:00 +0900 Subject: [PATCH 2/8] Document that managed Windows layouts bind a metadata toolchain, not the shim interpreter --- docs-site/src/content/docs/reference/cli.md | 4 +++- docs-site/src/content/docs/reference/cli/agents.md | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs-site/src/content/docs/reference/cli.md b/docs-site/src/content/docs/reference/cli.md index e2b65fc3fc..9486f97540 100644 --- a/docs-site/src/content/docs/reference/cli.md +++ b/docs-site/src/content/docs/reference/cli.md @@ -156,7 +156,9 @@ a direct Bun/source launch has no such proof, ignores ambient and persisted cand a proof-captured absolute standard npm `codex.cmd` with a held-bound Node/npm toolchain — prefix-local when present, otherwise the captured-PATH pair anchored to the launcher architecture — and a verified in-prefix platform backing. It uses reparse-refusing held handles; other Windows layouts remain deferred -or unmanaged. +or unmanaged. A `managed` Windows result classifies the observed installation layout only: the bound Node/npm +is the updater's read-only metadata toolchain, never a claim about which interpreter a later `codex.cmd` +invocation resolves, and planning stays read-only with apply disabled. The command does not install or repair software, execute Codex or npm, control a running process, or write configuration/cache state. diff --git a/docs-site/src/content/docs/reference/cli/agents.md b/docs-site/src/content/docs/reference/cli/agents.md index 8af4f6a651..614a9ecf7f 100644 --- a/docs-site/src/content/docs/reference/cli/agents.md +++ b/docs-site/src/content/docs/reference/cli/agents.md @@ -1166,7 +1166,10 @@ a direct Bun/source launch has no such proof, ignores ambient and persisted cand `candidate_unavailable` on POSIX. On Windows x64, a proof-captured absolute standard npm `codex.cmd` can be managed when held local handles bind its package, a held-bound Node/npm toolchain — prefix-local when present, otherwise the captured-PATH pair anchored to the launcher architecture — and the first -in-prefix platform backing. Other Windows layouts remain deferred or unmanaged. Windows never consults persisted state, so a run +in-prefix platform backing. Other Windows layouts remain deferred or unmanaged. A `managed` Windows result classifies +the observed installation layout only: the bound Node/npm is the updater's read-only metadata toolchain, never a claim +about which interpreter a later `codex.cmd` invocation resolves, and planning stays read-only with apply disabled. +Windows never consults persisted state, so a run with no captured environment candidate reports `windows_inspection_deferred` rather than `candidate_unavailable`: the command cannot observe whether a Codex CLI is installed, so it reports the deferral instead of asserting that no candidate exists. The command does not execute Codex or a package manager, repair a shim, From fe46d32401e7a99be0c6c8461c2a469458d0f8be Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 24 Oct 2026 15:27:10 +0900 Subject: [PATCH 3/8] docs(cli): align localized Windows codex-cli-update toolchain contract Align the seven locale summaries (fr, ja, ko, ru, tr, zh-cn, zh-tw) in cli.md and cli/agents.md with the English contract: the held-bound Node/npm toolchain is prefix-local when present, otherwise the captured-PATH pair anchored to the launcher architecture; a managed Windows result classifies the observed installation layout only and does not guarantee which interpreter a later codex.cmd resolves; PATH-only selection, OpenCodex autostart wrappers, and global/vendor fallback stay deferred with apply disabled. --- docs-site/src/content/docs/fr/reference/cli.md | 2 +- docs-site/src/content/docs/fr/reference/cli/agents.md | 2 +- docs-site/src/content/docs/ja/reference/cli.md | 2 +- docs-site/src/content/docs/ja/reference/cli/agents.md | 2 +- docs-site/src/content/docs/ko/reference/cli.md | 2 +- docs-site/src/content/docs/ko/reference/cli/agents.md | 2 +- docs-site/src/content/docs/ru/reference/cli.md | 2 +- docs-site/src/content/docs/ru/reference/cli/agents.md | 2 +- docs-site/src/content/docs/tr/reference/cli.md | 2 +- docs-site/src/content/docs/tr/reference/cli/agents.md | 2 +- docs-site/src/content/docs/zh-cn/reference/cli.md | 2 +- docs-site/src/content/docs/zh-cn/reference/cli/agents.md | 2 +- docs-site/src/content/docs/zh-tw/reference/cli.md | 2 +- docs-site/src/content/docs/zh-tw/reference/cli/agents.md | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs-site/src/content/docs/fr/reference/cli.md b/docs-site/src/content/docs/fr/reference/cli.md index 015a3e3aaf..b2b8edace1 100644 --- a/docs-site/src/content/docs/fr/reference/cli.md +++ b/docs-site/src/content/docs/fr/reference/cli.md @@ -17,7 +17,7 @@ Exécutez `ocx help` (ou `ocx --help` / `ocx -h`) pour afficher l’aide génér Les commandes de gestion communiquent avec l’API de gestion du proxy actif. Elles s’appuient sur le port d’exécution enregistré et sur des contrôles d’identité, plutôt que sur un second chemin de configuration. Un proxy arrêté ou inaccessible est représenté par une réponse HTTP 503 et entraîne un code de sortie CLI non nul. Les commandes explicitement documentées comme des opérations de configuration hors ligne peuvent, quant à elles, valider et modifier le fichier de configuration sans proxy actif. -`check` ne consulte aucun registre et n’exécute pas Codex. Sur POSIX, `selectionAttested` peut être `true` si le résolveur choisit le même chemin canonique que le candidat d’environnement capturé par le lanceur publié. Un manifeste npm-global lié peut alors établir `managed: true` s’il prouve la propriété et, lorsqu’une version candidate est signalée, si elle correspond à celle du manifeste ; les candidats persistants restent non attestés. Windows x64 prend aussi en charge un `codex.cmd` npm standard absolu lié à la preuve, avec Node/npm locaux au préfixe et une plateforme de support vérifiée dans le préfixe, en utilisant des handles maintenus qui refusent la réanalyse. Les autres dispositions Windows restent différées ou non gérées. Une exécution directe via Bun ou les sources n’a pas de preuve du lanceur. `plan` consulte le registre officiel avec une configuration, un cache et des journaux npm temporaires isolés, et refuse les sessions actives ou une observation incomplète des processus. Il n’installe rien et n’envoie aucun signal. Une installation Windows prise en charge peut produire un plan en lecture seule déterministe avec `applicable: false` et `refusal: windows_apply_disabled` ; la sélection par PATH seul, un Node de préfixe distinct et les wrappers de démarrage automatique OpenCodex restent différés. Voir [les commandes et motifs de refus complets (en anglais)](/reference/cli/agents/#read-only-codex-cli-update-plan). +`check` ne consulte aucun registre et n’exécute pas Codex. Sur POSIX, `selectionAttested` peut être `true` si le résolveur choisit le même chemin canonique que le candidat d’environnement capturé par le lanceur publié. Un manifeste npm-global lié peut alors établir `managed: true` s’il prouve la propriété et, lorsqu’une version candidate est signalée, si elle correspond à celle du manifeste ; les candidats persistants restent non attestés. Windows x64 prend aussi en charge un `codex.cmd` npm standard absolu lié à la preuve, avec une chaîne d’outils Node/npm liée par les handles — locale au préfixe quand elle est présente, sinon la paire PATH capturée ancrée à l’architecture du lanceur — et une plateforme de support vérifiée dans le préfixe, en utilisant des handles maintenus qui refusent la réanalyse. Les autres dispositions Windows restent différées ou non gérées. Un résultat `managed` Windows ne décrit que la disposition d’installation observée : le Node/npm lié est la chaîne d’outils de métadonnées en lecture seule de l’outil de mise à jour, et non une garantie sur l’interpréteur qu’une invocation ultérieure de `codex.cmd` résoudra. Une exécution directe via Bun ou les sources n’a pas de preuve du lanceur. `plan` consulte le registre officiel avec une configuration, un cache et des journaux npm temporaires isolés, et refuse les sessions actives ou une observation incomplète des processus. Il n’installe rien et n’envoie aucun signal. Une installation Windows prise en charge peut produire un plan en lecture seule déterministe avec `applicable: false` et `refusal: windows_apply_disabled` ; la sélection par PATH seul, les wrappers de démarrage automatique OpenCodex et les replis global/vendor restent différés. Voir [les commandes et motifs de refus complets (en anglais)](/reference/cli/agents/#read-only-codex-cli-update-plan). Pour observer une installation Windows x64, consultez [`attest`](/fr/reference/cli/agents/). Sans chemins explicites, la commande observe le candidat sélectionné identifié par l’instantané du lanceur lié à la preuve ; aucune autorité de mise à jour ni sélection du runtime n’est attestée. diff --git a/docs-site/src/content/docs/fr/reference/cli/agents.md b/docs-site/src/content/docs/fr/reference/cli/agents.md index e788fa47bb..05c0fba25d 100644 --- a/docs-site/src/content/docs/fr/reference/cli/agents.md +++ b/docs-site/src/content/docs/fr/reference/cli/agents.md @@ -287,7 +287,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` ne consulte aucun registre et n’exécute pas Codex. Sur POSIX, `selectionAttested` peut être `true` si le résolveur choisit le même chemin canonique que le candidat d’environnement capturé par le lanceur publié. Un manifeste npm-global lié peut alors établir `managed: true` s’il prouve la propriété et, lorsqu’une version candidate est signalée, si elle correspond à celle du manifeste ; les candidats persistants restent non attestés. Windows x64 prend aussi en charge un `codex.cmd` npm standard absolu lié à la preuve, avec Node/npm locaux au préfixe et une plateforme de support vérifiée dans le préfixe, en utilisant des handles maintenus qui refusent la réanalyse. Les autres dispositions Windows restent différées ou non gérées. Une exécution directe via Bun ou les sources n’a pas de preuve du lanceur. `plan` consulte le registre officiel avec une configuration, un cache et des journaux npm temporaires isolés, et refuse les sessions actives ou une observation incomplète des processus. Il n’installe rien et n’envoie aucun signal. Une installation Windows prise en charge peut produire un plan en lecture seule déterministe avec `applicable: false` et `refusal: windows_apply_disabled` ; la sélection par PATH seul, un Node de préfixe distinct et les wrappers de démarrage automatique OpenCodex restent différés. Voir [les commandes et motifs de refus complets (en anglais)](/reference/cli/agents/#read-only-codex-cli-update-plan). +`check` ne consulte aucun registre et n’exécute pas Codex. Sur POSIX, `selectionAttested` peut être `true` si le résolveur choisit le même chemin canonique que le candidat d’environnement capturé par le lanceur publié. Un manifeste npm-global lié peut alors établir `managed: true` s’il prouve la propriété et, lorsqu’une version candidate est signalée, si elle correspond à celle du manifeste ; les candidats persistants restent non attestés. Windows x64 prend aussi en charge un `codex.cmd` npm standard absolu lié à la preuve, avec une chaîne d’outils Node/npm liée par les handles — locale au préfixe quand elle est présente, sinon la paire PATH capturée ancrée à l’architecture du lanceur — et une plateforme de support vérifiée dans le préfixe, en utilisant des handles maintenus qui refusent la réanalyse. Les autres dispositions Windows restent différées ou non gérées. Un résultat `managed` Windows ne décrit que la disposition d’installation observée : le Node/npm lié est la chaîne d’outils de métadonnées en lecture seule de l’outil de mise à jour, et non une garantie sur l’interpréteur qu’une invocation ultérieure de `codex.cmd` résoudra. Une exécution directe via Bun ou les sources n’a pas de preuve du lanceur. `plan` consulte le registre officiel avec une configuration, un cache et des journaux npm temporaires isolés, et refuse les sessions actives ou une observation incomplète des processus. Il n’installe rien et n’envoie aucun signal. Une installation Windows prise en charge peut produire un plan en lecture seule déterministe avec `applicable: false` et `refusal: windows_apply_disabled` ; la sélection par PATH seul, les wrappers de démarrage automatique OpenCodex et les replis global/vendor restent différés. Voir [les commandes et motifs de refus complets (en anglais)](/reference/cli/agents/#read-only-codex-cli-update-plan). Sous Windows, une commande simple capturée comme `CODEX_CLI_PATH=codex`, un chemin distant ou un chemin de périphérique produit plutôt `candidate_path_unavailable`. Le candidat a été capturé, mais son chemin ne convient pas à cette inspection. diff --git a/docs-site/src/content/docs/ja/reference/cli.md b/docs-site/src/content/docs/ja/reference/cli.md index 4762c9a1fa..2be6fe58d1 100644 --- a/docs-site/src/content/docs/ja/reference/cli.md +++ b/docs-site/src/content/docs/ja/reference/cli.md @@ -20,7 +20,7 @@ opencodex CLI は `ocx` です。最初のコマンド名でディスパッチ 管理コマンドは、2 番目の構成パスを維持するのではなく、記録されたランタイム ポートと ID チェックを使用して、稼働中のプロキシの管理 API をラウンドトリップします。停止したプロキシまたは到達不能なプロキシは HTTP 503 として表され、ゼロ以外の CLI 終了が生成されます。オフライン構成操作として明示的に文書化されているコマンドは、代わりに、稼働中のプロキシを使用せずに設定ファイルを検証および編集できます。 -`check` はレジストリへの問い合わせも Codex の実行も行いません。POSIX では、公開ランチャーが記録した環境候補とランタイムリゾルバーが選ぶ正規パスが一致すると `selectionAttested: true` になり、リンクされた npm-global パッケージのマニフェストで所有権を確認でき、候補バージョンが報告されている場合はそれがマニフェストのバージョンと一致するときに `managed: true` になります。永続化された候補は認証されません。Windows x64 は、証明にバインドされた絶対パスの標準 npm `codex.cmd` とプレフィックスローカルの Node/npm、検証済みのインプレフィックスプラットフォームバッキングもサポートし、リパースを拒否する保持ハンドルを使用します。他の Windows レイアウトは引き続き延期または非管理です。Bun やソースからの直接実行にはランチャーの証明がありません。`plan` は分離した一時 npm 設定・キャッシュ・ログで公式レジストリに問い合わせ、実行中のセッションや不完全なプロセス観測を拒否します。インストールやプロセスへのシグナル送信は行いません。サポートされている Windows インストールは `applicable: false` と `refusal: windows_apply_disabled` を持つ決定論的な読み取り専用 plan を生成でき、PATH のみの選択・別プレフィックスの Node・OpenCodex 自動起動ラッパーは引き続き延期されます。[コマンドと拒否理由の詳細(英語)](/reference/cli/agents/#read-only-codex-cli-update-plan)を参照してください。 +`check` はレジストリへの問い合わせも Codex の実行も行いません。POSIX では、公開ランチャーが記録した環境候補とランタイムリゾルバーが選ぶ正規パスが一致すると `selectionAttested: true` になり、リンクされた npm-global パッケージのマニフェストで所有権を確認でき、候補バージョンが報告されている場合はそれがマニフェストのバージョンと一致するときに `managed: true` になります。永続化された候補は認証されません。Windows x64 は、証明にバインドされた絶対パスの標準 npm `codex.cmd` と保持ハンドルにバインドされた Node/npm ツールチェーン(存在する場合はプレフィックスローカル、存在しないことが確認された場合はランチャーアーキテクチャにアンカーされたキャプチャ済み PATH ペア)、検証済みのインプレフィックスプラットフォームバッキングもサポートし、リパースを拒否する保持ハンドルを使用します。他の Windows レイアウトは引き続き延期または非管理です。Windows の `managed` 結果は観測されたインストールレイアウトのみを分類し、バインドされた Node/npm はアップデーターの読み取り専用メタデータツールチェーンであって、後の `codex.cmd` 呼び出しがどのインタープリターを解決するかを保証するものではありません。Bun やソースからの直接実行にはランチャーの証明がありません。`plan` は分離した一時 npm 設定・キャッシュ・ログで公式レジストリに問い合わせ、実行中のセッションや不完全なプロセス観測を拒否します。インストールやプロセスへのシグナル送信は行いません。サポートされている Windows インストールは `applicable: false` と `refusal: windows_apply_disabled` を持つ決定論的な読み取り専用 plan を生成でき、PATH のみの選択・OpenCodex 自動起動ラッパー・global/vendor フォールバックは引き続き延期されます。[コマンドと拒否理由の詳細(英語)](/reference/cli/agents/#read-only-codex-cli-update-plan)を参照してください。 Windows x64 インストールの観測は [`attest` コマンド](/ja/reference/cli/agents/)を参照してください。明示パスを省略すると、証明にバインドされたランチャースナップショットが特定した選択候補を観測します。更新権限やランタイム選択は証明しません。 diff --git a/docs-site/src/content/docs/ja/reference/cli/agents.md b/docs-site/src/content/docs/ja/reference/cli/agents.md index fa91fed772..9a23067b60 100644 --- a/docs-site/src/content/docs/ja/reference/cli/agents.md +++ b/docs-site/src/content/docs/ja/reference/cli/agents.md @@ -218,7 +218,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` はレジストリへの問い合わせも Codex の実行も行いません。POSIX では、公開ランチャーが記録した環境候補とランタイムリゾルバーが選ぶ正規パスが一致すると `selectionAttested: true` になり、リンクされた npm-global パッケージのマニフェストで所有権を確認でき、候補バージョンが報告されている場合はそれがマニフェストのバージョンと一致するときに `managed: true` になります。永続化された候補は認証されません。Windows x64 は、証明にバインドされた絶対パスの標準 npm `codex.cmd` とプレフィックスローカルの Node/npm、検証済みのインプレフィックスプラットフォームバッキングもサポートし、リパースを拒否する保持ハンドルを使用します。他の Windows レイアウトは引き続き延期または非管理です。Bun やソースからの直接実行にはランチャーの証明がありません。`plan` は分離した一時 npm 設定・キャッシュ・ログで公式レジストリに問い合わせ、実行中のセッションや不完全なプロセス観測を拒否します。インストールやプロセスへのシグナル送信は行いません。サポートされている Windows インストールは `applicable: false` と `refusal: windows_apply_disabled` を持つ決定論的な読み取り専用 plan を生成でき、PATH のみの選択・別プレフィックスの Node・OpenCodex 自動起動ラッパーは引き続き延期されます。[コマンドと拒否理由の詳細(英語)](/reference/cli/agents/#read-only-codex-cli-update-plan)を参照してください。 +`check` はレジストリへの問い合わせも Codex の実行も行いません。POSIX では、公開ランチャーが記録した環境候補とランタイムリゾルバーが選ぶ正規パスが一致すると `selectionAttested: true` になり、リンクされた npm-global パッケージのマニフェストで所有権を確認でき、候補バージョンが報告されている場合はそれがマニフェストのバージョンと一致するときに `managed: true` になります。永続化された候補は認証されません。Windows x64 は、証明にバインドされた絶対パスの標準 npm `codex.cmd` と保持ハンドルにバインドされた Node/npm ツールチェーン(存在する場合はプレフィックスローカル、存在しないことが確認された場合はランチャーアーキテクチャにアンカーされたキャプチャ済み PATH ペア)、検証済みのインプレフィックスプラットフォームバッキングもサポートし、リパースを拒否する保持ハンドルを使用します。他の Windows レイアウトは引き続き延期または非管理です。Windows の `managed` 結果は観測されたインストールレイアウトのみを分類し、バインドされた Node/npm はアップデーターの読み取り専用メタデータツールチェーンであって、後の `codex.cmd` 呼び出しがどのインタープリターを解決するかを保証するものではありません。Bun やソースからの直接実行にはランチャーの証明がありません。`plan` は分離した一時 npm 設定・キャッシュ・ログで公式レジストリに問い合わせ、実行中のセッションや不完全なプロセス観測を拒否します。インストールやプロセスへのシグナル送信は行いません。サポートされている Windows インストールは `applicable: false` と `refusal: windows_apply_disabled` を持つ決定論的な読み取り専用 plan を生成でき、PATH のみの選択・OpenCodex 自動起動ラッパー・global/vendor フォールバックは引き続き延期されます。[コマンドと拒否理由の詳細(英語)](/reference/cli/agents/#read-only-codex-cli-update-plan)を参照してください。 Windows で `CODEX_CLI_PATH=codex` のような単純なコマンド名、リモートパス、デバイスパスが候補としてキャプチャされた場合は、`candidate_path_unavailable` を報告します。候補は取得されていますが、そのパスはこの検査の対象になりません。 diff --git a/docs-site/src/content/docs/ko/reference/cli.md b/docs-site/src/content/docs/ko/reference/cli.md index 9b02fb11fc..124b2050da 100644 --- a/docs-site/src/content/docs/ko/reference/cli.md +++ b/docs-site/src/content/docs/ko/reference/cli.md @@ -17,7 +17,7 @@ opencodex CLI는 `ocx`입니다. 첫 번째 명령 이름으로 분기하며, `s 관리 명령은 기록된 런타임 포트와 신원 검사를 사용해 살아 있는 프록시의 management API와 왕복 통신하며, 두 번째 설정 경로를 따로 두지 않습니다. 멈췄거나 닿을 수 없는 프록시는 HTTP 503으로 표시되며 CLI는 0이 아닌 종료 코드를 반환합니다. 명시적으로 오프라인 설정 작업으로 문서화된 명령은 라이브 프록시 없이 설정 파일을 검증하고 수정할 수 있습니다. -`check`는 레지스트리를 조회하거나 Codex를 실행하지 않습니다. POSIX에서는 배포 런처가 캡처한 환경 후보와 런타임 리졸버가 선택한 정규 경로가 같으면 `selectionAttested: true`가 될 수 있습니다. 연결된 npm-global 패키지 매니페스트가 소유권을 증명하고, 후보 버전이 보고된 경우 그 버전이 매니페스트 버전과 일치하면 `managed: true`가 될 수 있으며 저장된 후보는 인증되지 않습니다. Windows x64는 증명에 바인딩된 절대 표준 npm `codex.cmd`와 프리픽스 로컬 Node/npm, 검증된 인프리픽스 플랫폼 백킹도 지원하며 reparse를 거부하는 보유 핸들을 사용합니다. 다른 Windows 레이아웃은 계속 연기되거나 관리되지 않습니다. 직접 Bun/소스 실행은 런처 증거가 없어 후보를 신뢰하지 않습니다. `plan`은 격리된 임시 npm 설정·캐시·로그로 공식 레지스트리를 조회하고 활성 세션이나 불완전한 프로세스 관측을 거절합니다. 설치하거나 프로세스에 신호를 보내지 않습니다. 지원되는 Windows 설치는 `applicable: false`와 `refusal: windows_apply_disabled`를 가진 결정적 읽기 전용 plan을 생성할 수 있으며 PATH 전용 선택·분리된 프리픽스 Node·OpenCodex 자동 시작 래퍼는 계속 연기됩니다. [명령과 거절 사유의 전체 설명(영문)](/reference/cli/agents/#read-only-codex-cli-update-plan)을 참고하세요. +`check`는 레지스트리를 조회하거나 Codex를 실행하지 않습니다. POSIX에서는 배포 런처가 캡처한 환경 후보와 런타임 리졸버가 선택한 정규 경로가 같으면 `selectionAttested: true`가 될 수 있습니다. 연결된 npm-global 패키지 매니페스트가 소유권을 증명하고, 후보 버전이 보고된 경우 그 버전이 매니페스트 버전과 일치하면 `managed: true`가 될 수 있으며 저장된 후보는 인증되지 않습니다. Windows x64는 증명에 바인딩된 절대 표준 npm `codex.cmd`와 보유 핸들로 바인딩된 Node/npm 도구체인(있으면 프리픽스 로컬, 없다고 확인되면 런처 아키텍처에 고정된 캡처된 PATH 쌍), 검증된 인프리픽스 플랫폼 백킹도 지원하며 reparse를 거부하는 보유 핸들을 사용합니다. 다른 Windows 레이아웃은 계속 연기되거나 관리되지 않습니다. Windows의 `managed` 결과는 관측된 설치 레이아웃만 분류하며, 바인딩된 Node/npm은 업데이터의 읽기 전용 메타데이터 도구체인일 뿐 이후 `codex.cmd` 호출이 어떤 인터프리터를 해석할지를 보증하지 않습니다. 직접 Bun/소스 실행은 런처 증거가 없어 후보를 신뢰하지 않습니다. `plan`은 격리된 임시 npm 설정·캐시·로그로 공식 레지스트리를 조회하고 활성 세션이나 불완전한 프로세스 관측을 거절합니다. 설치하거나 프로세스에 신호를 보내지 않습니다. 지원되는 Windows 설치는 `applicable: false`와 `refusal: windows_apply_disabled`를 가진 결정적 읽기 전용 plan을 생성할 수 있으며 PATH 전용 선택·OpenCodex 자동 시작 래퍼·global/vendor 폴백은 계속 연기됩니다. [명령과 거절 사유의 전체 설명(영문)](/reference/cli/agents/#read-only-codex-cli-update-plan)을 참고하세요. Windows x64 설치 관측은 [`attest` 명령](/ko/reference/cli/agents/)을 참조하세요. 명시적 경로 없이 증명에 바인딩된 런처 스냅샷이 식별한 선택 후보를 관측하며, 업데이트 권한이나 런타임 선택을 증명하지 않습니다. diff --git a/docs-site/src/content/docs/ko/reference/cli/agents.md b/docs-site/src/content/docs/ko/reference/cli/agents.md index 8fc893a989..5f672ae539 100644 --- a/docs-site/src/content/docs/ko/reference/cli/agents.md +++ b/docs-site/src/content/docs/ko/reference/cli/agents.md @@ -256,7 +256,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check`는 레지스트리를 조회하거나 Codex를 실행하지 않습니다. POSIX에서는 배포 런처가 캡처한 환경 후보와 런타임 리졸버가 선택한 정규 경로가 같으면 `selectionAttested: true`가 될 수 있습니다. 연결된 npm-global 패키지 매니페스트가 소유권을 증명하고, 후보 버전이 보고된 경우 그 버전이 매니페스트 버전과 일치하면 `managed: true`가 될 수 있으며 저장된 후보는 인증되지 않습니다. Windows x64는 증명에 바인딩된 절대 표준 npm `codex.cmd`와 프리픽스 로컬 Node/npm, 검증된 인프리픽스 플랫폼 백킹도 지원하며 reparse를 거부하는 보유 핸들을 사용합니다. 다른 Windows 레이아웃은 계속 연기되거나 관리되지 않습니다. 직접 Bun/소스 실행은 런처 증거가 없어 후보를 신뢰하지 않습니다. `plan`은 격리된 임시 npm 설정·캐시·로그로 공식 레지스트리를 조회하고 활성 세션이나 불완전한 프로세스 관측을 거절합니다. 설치하거나 프로세스에 신호를 보내지 않습니다. 지원되는 Windows 설치는 `applicable: false`와 `refusal: windows_apply_disabled`를 가진 결정적 읽기 전용 plan을 생성할 수 있으며 PATH 전용 선택·분리된 프리픽스 Node·OpenCodex 자동 시작 래퍼는 계속 연기됩니다. [명령과 거절 사유의 전체 설명(영문)](/reference/cli/agents/#read-only-codex-cli-update-plan)을 참고하세요. +`check`는 레지스트리를 조회하거나 Codex를 실행하지 않습니다. POSIX에서는 배포 런처가 캡처한 환경 후보와 런타임 리졸버가 선택한 정규 경로가 같으면 `selectionAttested: true`가 될 수 있습니다. 연결된 npm-global 패키지 매니페스트가 소유권을 증명하고, 후보 버전이 보고된 경우 그 버전이 매니페스트 버전과 일치하면 `managed: true`가 될 수 있으며 저장된 후보는 인증되지 않습니다. Windows x64는 증명에 바인딩된 절대 표준 npm `codex.cmd`와 보유 핸들로 바인딩된 Node/npm 도구체인(있으면 프리픽스 로컬, 없다고 확인되면 런처 아키텍처에 고정된 캡처된 PATH 쌍), 검증된 인프리픽스 플랫폼 백킹도 지원하며 reparse를 거부하는 보유 핸들을 사용합니다. 다른 Windows 레이아웃은 계속 연기되거나 관리되지 않습니다. Windows의 `managed` 결과는 관측된 설치 레이아웃만 분류하며, 바인딩된 Node/npm은 업데이터의 읽기 전용 메타데이터 도구체인일 뿐 이후 `codex.cmd` 호출이 어떤 인터프리터를 해석할지를 보증하지 않습니다. 직접 Bun/소스 실행은 런처 증거가 없어 후보를 신뢰하지 않습니다. `plan`은 격리된 임시 npm 설정·캐시·로그로 공식 레지스트리를 조회하고 활성 세션이나 불완전한 프로세스 관측을 거절합니다. 설치하거나 프로세스에 신호를 보내지 않습니다. 지원되는 Windows 설치는 `applicable: false`와 `refusal: windows_apply_disabled`를 가진 결정적 읽기 전용 plan을 생성할 수 있으며 PATH 전용 선택·OpenCodex 자동 시작 래퍼·global/vendor 폴백은 계속 연기됩니다. [명령과 거절 사유의 전체 설명(영문)](/reference/cli/agents/#read-only-codex-cli-update-plan)을 참고하세요. Windows에서 `CODEX_CLI_PATH=codex` 같은 단순 명령 이름이나 원격 경로·장치 경로가 후보로 캡처되면 `candidate_path_unavailable`을 보고합니다. 후보는 캡처됐지만 해당 경로가 이 검사 대상에 적합하지 않은 경우입니다. diff --git a/docs-site/src/content/docs/ru/reference/cli.md b/docs-site/src/content/docs/ru/reference/cli.md index aca2b049ee..37272642e1 100644 --- a/docs-site/src/content/docs/ru/reference/cli.md +++ b/docs-site/src/content/docs/ru/reference/cli.md @@ -31,7 +31,7 @@ runtime port и проверку identity, а не поддерживая вто явно документированные как offline-операции с конфигурацией, вместо этого могут валидировать и редактировать файл конфигурации без живого прокси. -`check` не обращается к реестру и не запускает Codex. В POSIX `selectionAttested` может быть `true`, если разрешитель выбирает тот же канонический путь, что и кандидат окружения, зафиксированный опубликованным средством запуска. Связанный манифест npm-global может подтвердить `managed: true`, если он доказывает владение и, когда версия кандидата сообщается, она совпадает с версией манифеста; сохранённые кандидаты остаются неаттестованными. Windows x64 также поддерживает привязанный к доказательству абсолютный стандартный npm `codex.cmd` с локальными для префикса Node/npm и проверенной внутрипрефиксной платформенной подложкой, используя удерживаемые дескрипторы, отклоняющие reparse. Остальные раскладки Windows остаются отложенными или неуправляемыми. Прямой запуск через Bun или исходный код не даёт доказательства средства запуска. `plan` обращается к официальному реестру с изолированными временными настройками, кешем и журналами npm, отказывая при активных сессиях или неполном наблюдении процессов. Он ничего не устанавливает и не посылает сигналы. Поддерживаемая установка Windows может создать детерминированный план только для чтения с `applicable: false` и `refusal: windows_apply_disabled`; выбор только по PATH, Node из отдельного префикса и обёртки автозапуска OpenCodex остаются отложенными. См. [полное описание команд и причин отказа (англ.)](/reference/cli/agents/#read-only-codex-cli-update-plan). +`check` не обращается к реестру и не запускает Codex. В POSIX `selectionAttested` может быть `true`, если разрешитель выбирает тот же канонический путь, что и кандидат окружения, зафиксированный опубликованным средством запуска. Связанный манифест npm-global может подтвердить `managed: true`, если он доказывает владение и, когда версия кандидата сообщается, она совпадает с версией манифеста; сохранённые кандидаты остаются неаттестованными. Windows x64 также поддерживает привязанный к доказательству абсолютный стандартный npm `codex.cmd` с цепочкой инструментов Node/npm — локальной для префикса при её наличии, иначе парой из захваченного PATH, привязанной к архитектуре средства запуска, — и проверенной внутрипрефиксной платформенной подложкой, используя удерживаемые дескрипторы, отклоняющие reparse. Остальные раскладки Windows остаются отложенными или неуправляемыми. Результат `managed` в Windows классифицирует только наблюдаемую раскладку установки: привязанные Node/npm — это цепочка инструментов метаданных средства обновления, доступная только для чтения, а не гарантия того, какой интерпретатор разрешит последующий вызов `codex.cmd`. Прямой запуск через Bun или исходный код не даёт доказательства средства запуска. `plan` обращается к официальному реестру с изолированными временными настройками, кешем и журналами npm, отказывая при активных сессиях или неполном наблюдении процессов. Он ничего не устанавливает и не посылает сигналы. Поддерживаемая установка Windows может создать детерминированный план только для чтения с `applicable: false` и `refusal: windows_apply_disabled`; выбор только по PATH, обёртки автозапуска OpenCodex и откат к global/vendor остаются отложенными. См. [полное описание команд и причин отказа (англ.)](/reference/cli/agents/#read-only-codex-cli-update-plan). Для наблюдения установки Windows x64 см. [`attest`](/ru/reference/cli/agents/). Без явных путей команда наблюдает выбранного кандидата, определённого привязанным к доказательству снимком средства запуска; полномочия на обновление и выбор runtime не подтверждаются. diff --git a/docs-site/src/content/docs/ru/reference/cli/agents.md b/docs-site/src/content/docs/ru/reference/cli/agents.md index 1656aca847..8d4a389d3b 100644 --- a/docs-site/src/content/docs/ru/reference/cli/agents.md +++ b/docs-site/src/content/docs/ru/reference/cli/agents.md @@ -270,7 +270,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` не обращается к реестру и не запускает Codex. В POSIX `selectionAttested` может быть `true`, если разрешитель выбирает тот же канонический путь, что и кандидат окружения, зафиксированный опубликованным средством запуска. Связанный манифест npm-global может подтвердить `managed: true`, если он доказывает владение и, когда версия кандидата сообщается, она совпадает с версией манифеста; сохранённые кандидаты остаются неаттестованными. Windows x64 также поддерживает привязанный к доказательству абсолютный стандартный npm `codex.cmd` с локальными для префикса Node/npm и проверенной внутрипрефиксной платформенной подложкой, используя удерживаемые дескрипторы, отклоняющие reparse. Остальные раскладки Windows остаются отложенными или неуправляемыми. Прямой запуск через Bun или исходный код не даёт доказательства средства запуска. `plan` обращается к официальному реестру с изолированными временными настройками, кешем и журналами npm, отказывая при активных сессиях или неполном наблюдении процессов. Он ничего не устанавливает и не посылает сигналы. Поддерживаемая установка Windows может создать детерминированный план только для чтения с `applicable: false` и `refusal: windows_apply_disabled`; выбор только по PATH, Node из отдельного префикса и обёртки автозапуска OpenCodex остаются отложенными. См. [полное описание команд и причин отказа (англ.)](/reference/cli/agents/#read-only-codex-cli-update-plan). +`check` не обращается к реестру и не запускает Codex. В POSIX `selectionAttested` может быть `true`, если разрешитель выбирает тот же канонический путь, что и кандидат окружения, зафиксированный опубликованным средством запуска. Связанный манифест npm-global может подтвердить `managed: true`, если он доказывает владение и, когда версия кандидата сообщается, она совпадает с версией манифеста; сохранённые кандидаты остаются неаттестованными. Windows x64 также поддерживает привязанный к доказательству абсолютный стандартный npm `codex.cmd` с цепочкой инструментов Node/npm — локальной для префикса при её наличии, иначе парой из захваченного PATH, привязанной к архитектуре средства запуска, — и проверенной внутрипрефиксной платформенной подложкой, используя удерживаемые дескрипторы, отклоняющие reparse. Остальные раскладки Windows остаются отложенными или неуправляемыми. Результат `managed` в Windows классифицирует только наблюдаемую раскладку установки: привязанные Node/npm — это цепочка инструментов метаданных средства обновления, доступная только для чтения, а не гарантия того, какой интерпретатор разрешит последующий вызов `codex.cmd`. Прямой запуск через Bun или исходный код не даёт доказательства средства запуска. `plan` обращается к официальному реестру с изолированными временными настройками, кешем и журналами npm, отказывая при активных сессиях или неполном наблюдении процессов. Он ничего не устанавливает и не посылает сигналы. Поддерживаемая установка Windows может создать детерминированный план только для чтения с `applicable: false` и `refusal: windows_apply_disabled`; выбор только по PATH, обёртки автозапуска OpenCodex и откат к global/vendor остаются отложенными. См. [полное описание команд и причин отказа (англ.)](/reference/cli/agents/#read-only-codex-cli-update-plan). В Windows захваченная команда без полного пути, например `CODEX_CLI_PATH=codex`, удалённый путь или путь устройства возвращает `candidate_path_unavailable`. Кандидат захвачен, но его путь не подходит для этой проверки. diff --git a/docs-site/src/content/docs/tr/reference/cli.md b/docs-site/src/content/docs/tr/reference/cli.md index 9422b3821d..f9f7e7cbe8 100644 --- a/docs-site/src/content/docs/tr/reference/cli.md +++ b/docs-site/src/content/docs/tr/reference/cli.md @@ -36,7 +36,7 @@ yönetim API'sine gidiş-dönüş yapar. Durdurulmuş veya erişilemeyen bir pro yapılandırma işlemleri olarak açıkça belgelenen komutlar, bunun yerine canlı bir proxy olmadan yapılandırma dosyasını doğrulayabilir ve düzenleyebilir. -`check` kayıt defterini sorgulamaz ve Codex’i çalıştırmaz. POSIX üzerinde çözümleyicinin seçtiği kanonik yol, yayımlanmış başlatıcının yakaladığı ortam adayıyla aynıysa `selectionAttested: true` olabilir. Bağlantılı npm-global paket bildirimi sahipliği doğrularsa ve aday sürüm bildirildiyse bu sürüm bildirimdeki sürümle eşleşirse `managed: true` olabilir; kalıcı adaylar doğrulanmaz. Windows x64 ayrıca kanıta bağlı mutlak standart npm `codex.cmd` ile önek-yerel Node/npm ve önek içinde doğrulanmış platform desteğini destekler; yeniden ayrıştırmayı reddeden tutulan tanıtıcılar kullanır. Diğer Windows düzenleri ertelenmiş veya yönetimsiz kalır. Doğrudan Bun/kaynak çalıştırması başlatıcı kanıtı sağlamaz. `plan`, yalıtılmış geçici npm yapılandırması, önbelleği ve günlükleriyle resmî kayıt defterini sorgular; etkin oturumları veya eksik süreç gözlemini reddeder. Yazılım kurmaz ve süreçlere sinyal göndermez. Desteklenen bir Windows kurulumu `applicable: false` ve `refusal: windows_apply_disabled` ile belirleyici bir salt okunur plan üretebilir; yalnızca PATH seçimi, ayrı önekli Node ve OpenCodex otomatik başlatma sarmalayıcıları ertelenmiş kalır. [Komutların ve ret nedenlerinin tam açıklamasına (İngilizce)](/reference/cli/agents/#read-only-codex-cli-update-plan) bakın. +`check` kayıt defterini sorgulamaz ve Codex’i çalıştırmaz. POSIX üzerinde çözümleyicinin seçtiği kanonik yol, yayımlanmış başlatıcının yakaladığı ortam adayıyla aynıysa `selectionAttested: true` olabilir. Bağlantılı npm-global paket bildirimi sahipliği doğrularsa ve aday sürüm bildirildiyse bu sürüm bildirimdeki sürümle eşleşirse `managed: true` olabilir; kalıcı adaylar doğrulanmaz. Windows x64 ayrıca kanıta bağlı mutlak standart npm `codex.cmd` ile tutulan tanıtıcılara bağlı bir Node/npm araç zincirini (varsa önek-yerel, yokluğu doğrulanırsa başlatıcı mimarisine bağlanmış yakalanan PATH çifti) ve önek içinde doğrulanmış platform desteğini destekler; yeniden ayrıştırmayı reddeden tutulan tanıtıcılar kullanır. Diğer Windows düzenleri ertelenmiş veya yönetimsiz kalır. Windows'taki bir `managed` sonucu yalnızca gözlemlenen kurulum düzenini sınıflandırır: bağlı Node/npm, güncelleyicinin salt okunur meta veri araç zinciridir ve sonraki bir `codex.cmd` çağrısının hangi yorumlayıcıyı çözeceğine dair bir güvence değildir. Doğrudan Bun/kaynak çalıştırması başlatıcı kanıtı sağlamaz. `plan`, yalıtılmış geçici npm yapılandırması, önbelleği ve günlükleriyle resmî kayıt defterini sorgular; etkin oturumları veya eksik süreç gözlemini reddeder. Yazılım kurmaz ve süreçlere sinyal göndermez. Desteklenen bir Windows kurulumu `applicable: false` ve `refusal: windows_apply_disabled` ile belirleyici bir salt okunur plan üretebilir; yalnızca PATH seçimi, OpenCodex otomatik başlatma sarmalayıcıları ve global/vendor geri dönüşü ertelenmiş kalır. [Komutların ve ret nedenlerinin tam açıklamasına (İngilizce)](/reference/cli/agents/#read-only-codex-cli-update-plan) bakın. Windows x64 kurulum gözlemi için [`attest`](/tr/reference/cli/agents/) komutuna bakın. Açık yollar verilmezse komut, kanıta bağlı başlatıcı anlık görüntüsünün belirlediği seçili adayı gözlemler; güncelleme yetkisi veya çalışma zamanı seçimi doğrulanmaz. diff --git a/docs-site/src/content/docs/tr/reference/cli/agents.md b/docs-site/src/content/docs/tr/reference/cli/agents.md index 6a52461ec5..b27dbabfd2 100644 --- a/docs-site/src/content/docs/tr/reference/cli/agents.md +++ b/docs-site/src/content/docs/tr/reference/cli/agents.md @@ -322,7 +322,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` kayıt defterini sorgulamaz ve Codex’i çalıştırmaz. POSIX üzerinde çözümleyicinin seçtiği kanonik yol, yayımlanmış başlatıcının yakaladığı ortam adayıyla aynıysa `selectionAttested: true` olabilir. Bağlantılı npm-global paket bildirimi sahipliği doğrularsa ve aday sürüm bildirildiyse bu sürüm bildirimdeki sürümle eşleşirse `managed: true` olabilir; kalıcı adaylar doğrulanmaz. Windows x64 ayrıca kanıta bağlı mutlak standart npm `codex.cmd` ile önek-yerel Node/npm ve önek içinde doğrulanmış platform desteğini destekler; yeniden ayrıştırmayı reddeden tutulan tanıtıcılar kullanır. Diğer Windows düzenleri ertelenmiş veya yönetimsiz kalır. Doğrudan Bun/kaynak çalıştırması başlatıcı kanıtı sağlamaz. `plan`, yalıtılmış geçici npm yapılandırması, önbelleği ve günlükleriyle resmî kayıt defterini sorgular; etkin oturumları veya eksik süreç gözlemini reddeder. Yazılım kurmaz ve süreçlere sinyal göndermez. Desteklenen bir Windows kurulumu `applicable: false` ve `refusal: windows_apply_disabled` ile belirleyici bir salt okunur plan üretebilir; yalnızca PATH seçimi, ayrı önekli Node ve OpenCodex otomatik başlatma sarmalayıcıları ertelenmiş kalır. [Komutların ve ret nedenlerinin tam açıklamasına (İngilizce)](/reference/cli/agents/#read-only-codex-cli-update-plan) bakın. +`check` kayıt defterini sorgulamaz ve Codex’i çalıştırmaz. POSIX üzerinde çözümleyicinin seçtiği kanonik yol, yayımlanmış başlatıcının yakaladığı ortam adayıyla aynıysa `selectionAttested: true` olabilir. Bağlantılı npm-global paket bildirimi sahipliği doğrularsa ve aday sürüm bildirildiyse bu sürüm bildirimdeki sürümle eşleşirse `managed: true` olabilir; kalıcı adaylar doğrulanmaz. Windows x64 ayrıca kanıta bağlı mutlak standart npm `codex.cmd` ile tutulan tanıtıcılara bağlı bir Node/npm araç zincirini (varsa önek-yerel, yokluğu doğrulanırsa başlatıcı mimarisine bağlanmış yakalanan PATH çifti) ve önek içinde doğrulanmış platform desteğini destekler; yeniden ayrıştırmayı reddeden tutulan tanıtıcılar kullanır. Diğer Windows düzenleri ertelenmiş veya yönetimsiz kalır. Windows'taki bir `managed` sonucu yalnızca gözlemlenen kurulum düzenini sınıflandırır: bağlı Node/npm, güncelleyicinin salt okunur meta veri araç zinciridir ve sonraki bir `codex.cmd` çağrısının hangi yorumlayıcıyı çözeceğine dair bir güvence değildir. Doğrudan Bun/kaynak çalıştırması başlatıcı kanıtı sağlamaz. `plan`, yalıtılmış geçici npm yapılandırması, önbelleği ve günlükleriyle resmî kayıt defterini sorgular; etkin oturumları veya eksik süreç gözlemini reddeder. Yazılım kurmaz ve süreçlere sinyal göndermez. Desteklenen bir Windows kurulumu `applicable: false` ve `refusal: windows_apply_disabled` ile belirleyici bir salt okunur plan üretebilir; yalnızca PATH seçimi, OpenCodex otomatik başlatma sarmalayıcıları ve global/vendor geri dönüşü ertelenmiş kalır. [Komutların ve ret nedenlerinin tam açıklamasına (İngilizce)](/reference/cli/agents/#read-only-codex-cli-update-plan) bakın. Windows üzerinde `CODEX_CLI_PATH=codex` gibi yalın bir komut, uzak yol veya aygıt yolu aday olarak yakalanırsa `candidate_path_unavailable` bildirilir. Aday yakalanmıştır; ancak yolu bu inceleme için uygun değildir. diff --git a/docs-site/src/content/docs/zh-cn/reference/cli.md b/docs-site/src/content/docs/zh-cn/reference/cli.md index 80e9204f39..e5e615b1fb 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli.md @@ -17,7 +17,7 @@ opencodex 的 CLI 是 `ocx`。它会根据第一个命令名进行分发;文 管理命令会通过实时代理的管理 API 往返调用,使用记录下来的运行时端口和身份检查,而不是维护第二条配置路径。已停止或不可达的代理会被表示为 HTTP 503,并导致 CLI 以非零状态退出。明确标注为离线配置操作的命令,则可以在没有实时代理的情况下验证并编辑配置文件。 -`check` 不查询注册表,也不运行 Codex。在 POSIX 上,当已发布启动器捕获的环境候选项与运行时解析器选择的规范路径一致时,`selectionAttested` 可以为 `true`;如果关联的 npm-global 软件包清单证明了所有权,`managed` 可以为 `true`。持久化候选项仍不获认证。Windows x64 还支持经证明绑定的绝对路径标准 npm `codex.cmd`,以及前缀本地 Node/npm 和已验证的前缀内平台支持组件,并使用拒绝重解析的持有句柄。其他 Windows 布局仍然推迟或不受管理。直接通过 Bun 或源码运行时没有启动器证明。`plan` 使用隔离的临时 npm 配置、缓存和日志查询官方注册表,并拒绝活动会话或不完整的进程观测。它不安装软件,也不向进程发送信号。受支持的 Windows 安装可以生成 `applicable: false` 且 `refusal: windows_apply_disabled` 的确定性只读 plan;仅 PATH 选择、独立前缀的 Node 和 OpenCodex 自启动包装器仍然推迟。请参阅[完整命令和拒绝原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 +`check` 不查询注册表,也不运行 Codex。在 POSIX 上,当已发布启动器捕获的环境候选项与运行时解析器选择的规范路径一致时,`selectionAttested` 可以为 `true`;如果关联的 npm-global 软件包清单证明了所有权,`managed` 可以为 `true`。持久化候选项仍不获认证。Windows x64 还支持经证明绑定的绝对路径标准 npm `codex.cmd`,以及由持有句柄绑定的 Node/npm 工具链(存在时为前缀本地,确认不存在时为锚定到启动器架构的已捕获 PATH 对)和已验证的前缀内平台支持组件,并使用拒绝重解析的持有句柄。其他 Windows 布局仍然推迟或不受管理。Windows 的 `managed` 结果仅对观察到的安装布局进行分类:绑定的 Node/npm 是更新器的只读元数据工具链,并不保证后续 `codex.cmd` 调用将解析到哪个解释器。直接通过 Bun 或源码运行时没有启动器证明。`plan` 使用隔离的临时 npm 配置、缓存和日志查询官方注册表,并拒绝活动会话或不完整的进程观测。它不安装软件,也不向进程发送信号。受支持的 Windows 安装可以生成 `applicable: false` 且 `refusal: windows_apply_disabled` 的确定性只读 plan;仅 PATH 选择、OpenCodex 自启动包装器和 global/vendor 回退仍然推迟。请参阅[完整命令和拒绝原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 有关 Windows x64 安装观察,请参阅 [`attest` 命令](/zh-cn/reference/cli/agents/)。未提供显式路径时,该命令观察由受证明约束的启动器快照识别出的已选候选项;它不授予更新权限,也不证明运行时选择。 diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md index 868a1553d6..20116370b8 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md @@ -222,7 +222,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` 不查询注册表,也不运行 Codex。在 POSIX 上,当已发布启动器捕获的环境候选项与运行时解析器选择的规范路径一致时,`selectionAttested` 可以为 `true`;如果关联的 npm-global 软件包清单证明了所有权,`managed` 可以为 `true`。持久化候选项仍不获认证。Windows x64 还支持经证明绑定的绝对路径标准 npm `codex.cmd`,以及前缀本地 Node/npm 和已验证的前缀内平台支持组件,并使用拒绝重解析的持有句柄。其他 Windows 布局仍然推迟或不受管理。直接通过 Bun 或源码运行时没有启动器证明。`plan` 使用隔离的临时 npm 配置、缓存和日志查询官方注册表,并拒绝活动会话或不完整的进程观测。它不安装软件,也不向进程发送信号。受支持的 Windows 安装可以生成 `applicable: false` 且 `refusal: windows_apply_disabled` 的确定性只读 plan;仅 PATH 选择、独立前缀的 Node 和 OpenCodex 自启动包装器仍然推迟。请参阅[完整命令和拒绝原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 +`check` 不查询注册表,也不运行 Codex。在 POSIX 上,当已发布启动器捕获的环境候选项与运行时解析器选择的规范路径一致时,`selectionAttested` 可以为 `true`;如果关联的 npm-global 软件包清单证明了所有权,`managed` 可以为 `true`。持久化候选项仍不获认证。Windows x64 还支持经证明绑定的绝对路径标准 npm `codex.cmd`,以及由持有句柄绑定的 Node/npm 工具链(存在时为前缀本地,确认不存在时为锚定到启动器架构的已捕获 PATH 对)和已验证的前缀内平台支持组件,并使用拒绝重解析的持有句柄。其他 Windows 布局仍然推迟或不受管理。Windows 的 `managed` 结果仅对观察到的安装布局进行分类:绑定的 Node/npm 是更新器的只读元数据工具链,并不保证后续 `codex.cmd` 调用将解析到哪个解释器。直接通过 Bun 或源码运行时没有启动器证明。`plan` 使用隔离的临时 npm 配置、缓存和日志查询官方注册表,并拒绝活动会话或不完整的进程观测。它不安装软件,也不向进程发送信号。受支持的 Windows 安装可以生成 `applicable: false` 且 `refusal: windows_apply_disabled` 的确定性只读 plan;仅 PATH 选择、OpenCodex 自启动包装器和 global/vendor 回退仍然推迟。请参阅[完整命令和拒绝原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 在 Windows 上,如果捕获到 `CODEX_CLI_PATH=codex` 这样的裸命令、远程路径或设备路径,则报告 `candidate_path_unavailable`。这些情况下候选项已被捕获,但其路径不适用于此检查。 diff --git a/docs-site/src/content/docs/zh-tw/reference/cli.md b/docs-site/src/content/docs/zh-tw/reference/cli.md index ad1e14b503..94db6894e2 100644 --- a/docs-site/src/content/docs/zh-tw/reference/cli.md +++ b/docs-site/src/content/docs/zh-tw/reference/cli.md @@ -28,7 +28,7 @@ opencodex 的命令列工具是 `ocx`。它依第一個命令名稱分派,有 設定路徑。停止或無法連線的代理以 HTTP 503 呈現,並產生非零的 CLI 離開碼。明確記載為 離線設定操作的命令,可以在沒有執行中代理的情況下驗證與編輯設定檔。 -`check` 不查詢註冊表,也不執行 Codex。在 POSIX 上,當已發布啟動器擷取的環境候選項與執行階段解析器選擇的正規路徑相同時,`selectionAttested` 可以為 `true`;若關聯的 npm-global 套件資訊清單證明了所有權,`managed` 可以為 `true`。持久化候選項仍不獲認證。Windows x64 也支援經證明繫結的絕對路徑標準 npm `codex.cmd`,以及前綴本機 Node/npm 和已驗證的前綴內平台支援元件,並使用拒絕重新剖析的持有控制代碼。其他 Windows 配置仍然延後或不受管理。直接透過 Bun 或原始碼執行時沒有啟動器證明。`plan` 使用隔離的暫存 npm 設定、快取和日誌查詢官方註冊表,並拒絕活動工作階段或不完整的程序觀測。它不安裝軟體,也不向程序傳送訊號。受支援的 Windows 安裝可產生 `applicable: false` 且 `refusal: windows_apply_disabled` 的確定性唯讀 plan;僅 PATH 選取、獨立前綴的 Node 和 OpenCodex 自動啟動包裝器仍然延後。請參閱[完整命令與拒絕原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 +`check` 不查詢註冊表,也不執行 Codex。在 POSIX 上,當已發布啟動器擷取的環境候選項與執行階段解析器選擇的正規路徑相同時,`selectionAttested` 可以為 `true`;若關聯的 npm-global 套件資訊清單證明了所有權,`managed` 可以為 `true`。持久化候選項仍不獲認證。Windows x64 也支援經證明繫結的絕對路徑標準 npm `codex.cmd`,以及由持有控制代碼繫結的 Node/npm 工具鏈(存在時為前綴本機,確認不存在時為錨定到啟動器架構的已擷取 PATH 配對)和已驗證的前綴內平台支援元件,並使用拒絕重新剖析的持有控制代碼。其他 Windows 配置仍然延後或不受管理。Windows 的 `managed` 結果僅對觀測到的安裝配置進行分類:繫結的 Node/npm 是更新器的唯讀中繼資料工具鏈,並不保證後續 `codex.cmd` 呼叫將解析到哪個直譯器。直接透過 Bun 或原始碼執行時沒有啟動器證明。`plan` 使用隔離的暫存 npm 設定、快取和日誌查詢官方註冊表,並拒絕活動工作階段或不完整的程序觀測。它不安裝軟體,也不向程序傳送訊號。受支援的 Windows 安裝可產生 `applicable: false` 且 `refusal: windows_apply_disabled` 的確定性唯讀 plan;僅 PATH 選取、OpenCodex 自動啟動包裝器和 global/vendor 後援仍然延後。請參閱[完整命令與拒絕原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 觀測 Windows x64 安裝的方式請參閱 [`attest` 命令](/zh-tw/reference/cli/agents/)。未提供明確路徑時,該命令會觀測由受證明約束的啟動器快照識別出的已選候選項;它不授予更新權限,也不證明執行階段選擇。 diff --git a/docs-site/src/content/docs/zh-tw/reference/cli/agents.md b/docs-site/src/content/docs/zh-tw/reference/cli/agents.md index 5ab8a27cde..5b97e68f4b 100644 --- a/docs-site/src/content/docs/zh-tw/reference/cli/agents.md +++ b/docs-site/src/content/docs/zh-tw/reference/cli/agents.md @@ -223,7 +223,7 @@ ocx system settings --stream-mode eager-relay ocx system codex-cli-update check --json ``` -`check` 不查詢註冊表,也不執行 Codex。在 POSIX 上,當已發布啟動器擷取的環境候選項與執行階段解析器選擇的正規路徑相同時,`selectionAttested` 可以為 `true`;若關聯的 npm-global 套件資訊清單證明了所有權,`managed` 可以為 `true`。持久化候選項仍不獲認證。Windows x64 也支援經證明繫結的絕對路徑標準 npm `codex.cmd`,以及前綴本機 Node/npm 和已驗證的前綴內平台支援元件,並使用拒絕重新剖析的持有控制代碼。其他 Windows 配置仍然延後或不受管理。直接透過 Bun 或原始碼執行時沒有啟動器證明。`plan` 使用隔離的暫存 npm 設定、快取和日誌查詢官方註冊表,並拒絕活動工作階段或不完整的程序觀測。它不安裝軟體,也不向程序傳送訊號。受支援的 Windows 安裝可產生 `applicable: false` 且 `refusal: windows_apply_disabled` 的確定性唯讀 plan;僅 PATH 選取、獨立前綴的 Node 和 OpenCodex 自動啟動包裝器仍然延後。請參閱[完整命令與拒絕原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 +`check` 不查詢註冊表,也不執行 Codex。在 POSIX 上,當已發布啟動器擷取的環境候選項與執行階段解析器選擇的正規路徑相同時,`selectionAttested` 可以為 `true`;若關聯的 npm-global 套件資訊清單證明了所有權,`managed` 可以為 `true`。持久化候選項仍不獲認證。Windows x64 也支援經證明繫結的絕對路徑標準 npm `codex.cmd`,以及由持有控制代碼繫結的 Node/npm 工具鏈(存在時為前綴本機,確認不存在時為錨定到啟動器架構的已擷取 PATH 配對)和已驗證的前綴內平台支援元件,並使用拒絕重新剖析的持有控制代碼。其他 Windows 配置仍然延後或不受管理。Windows 的 `managed` 結果僅對觀測到的安裝配置進行分類:繫結的 Node/npm 是更新器的唯讀中繼資料工具鏈,並不保證後續 `codex.cmd` 呼叫將解析到哪個直譯器。直接透過 Bun 或原始碼執行時沒有啟動器證明。`plan` 使用隔離的暫存 npm 設定、快取和日誌查詢官方註冊表,並拒絕活動工作階段或不完整的程序觀測。它不安裝軟體,也不向程序傳送訊號。受支援的 Windows 安裝可產生 `applicable: false` 且 `refusal: windows_apply_disabled` 的確定性唯讀 plan;僅 PATH 選取、OpenCodex 自動啟動包裝器和 global/vendor 後援仍然延後。請參閱[完整命令與拒絕原因(英文)](/reference/cli/agents/#read-only-codex-cli-update-plan)。 在 Windows 上,如果擷取到 `CODEX_CLI_PATH=codex` 這類單純命令名稱、遠端路徑或裝置路徑,則回報 `candidate_path_unavailable`。這些情況已有擷取的候選項,但其路徑不適用於此檢查。 From 695ec0c86b9904e6823805e624c7b620c6c74be1 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sun, 25 Oct 2026 08:09:38 +0900 Subject: [PATCH 4/8] test: cover separate Windows toolchain planning in workers --- .../codex-cli-windows-plan.test.ts | 58 ++++++++++++++++++- .../helpers/cli-windows-plan-drift-worker.ts | 34 +++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 tests/helpers/cli-windows-plan-drift-worker.ts diff --git a/tests/codex-integration/codex-cli-windows-plan.test.ts b/tests/codex-integration/codex-cli-windows-plan.test.ts index 1666400b24..1e86c90925 100644 --- a/tests/codex-integration/codex-cli-windows-plan.test.ts +++ b/tests/codex-integration/codex-cli-windows-plan.test.ts @@ -1,6 +1,6 @@ import { afterEach, expect, test } from "bun:test"; import { spawnSync } from "node:child_process"; -import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, renameSync, symlinkSync, truncateSync, writeFileSync } from "node:fs"; +import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, symlinkSync, truncateSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { inspectCodexCliInstall, MAX_NATIVE_BACKING_BYTES } from "../../src/codex/cli-install-provenance"; @@ -379,6 +379,62 @@ native("a fresh production Worker rebuilds private Windows plan evidence before } }, 60_000); +function separateWorkerFixture() { + const f = fixture(true), hostNode = Bun.which("node"); expect(hostNode).not.toBeNull(); + copyFileSync(hostNode!, join(f.toolchainPrefix, "node.exe")); + expect(existsSync(join(f.prefix, "node.exe"))).toBe(false); + const marker = join(f.root, "metadata-ran"), integrity = "sha512-" + Buffer.alloc(64, 1).toString("base64"); + const main = { name: "@openai/codex", version: "1.2.4", optionalDependencies: { "@openai/codex-win32-x64": "1.2.4" }, + dist: { integrity, tarball: "https://registry.npmjs.org/@openai/codex/-/codex-1.2.4.tgz" } }; + const backing = { name: "@openai/codex-win32-x64", version: "1.2.4", dist: { integrity, + tarball: "https://registry.npmjs.org/@openai/codex-win32-x64/-/codex-win32-x64-1.2.4.tgz" } }; + writeFileSync(join(f.npmRoot, "bin", "npm-cli.js"), + `require('node:fs').appendFileSync(${JSON.stringify(marker)}, 'metadata\\n'); const spec = process.argv[3]; console.log(JSON.stringify(spec.startsWith('@openai/codex-win32-x64@') ? ${JSON.stringify(backing)} : ${JSON.stringify(main)}));`); + return { ...f, marker, integrity }; +} + +async function separateWorkerPlan(f: ReturnType, arch: "x64" | "arm64" | null, drift = false) { + let starts = 0, closed = false; + const plan = await runCodexCliUpdatePlanInWorker({ + snapshot: { codexCliPath: f.deps.env.CODEX_CLI_PATH, path: f.toolchainPrefix, pathExt: ".EXE;.CMD", + home: f.root, nodePath: null, managerRoots: {}, transportEnv: {}, configDir: f.deps.configDir, arch }, + spawnWorkerFn: (url, key) => { + expect(key).toBe("cli-update-worker"); starts++; + // Drift needs a test-only injection seam; the positive and arch refusals use the production entry. + const worker = new Worker(drift ? repoPath("tests", "helpers", "cli-windows-plan-drift-worker.ts") : url, { type: "module" }); + liveWorkerRoots.add(f.root); + worker.addEventListener("close", () => { closed = true; liveWorkerRoots.delete(f.root); }, { once: true }); + return worker; + }, + }); + // afterEach retains the root if dispatch/test timeout occurs without real close. + expect(starts).toBe(1); expect(closed).toBe(true); + return plan; +} + +native("a fresh production Worker binds a separate Node/npm metadata vehicle with the launcher arch", async () => { + const f = separateWorkerFixture(), plan = await separateWorkerPlan(f, "x64"); + expect(plan).toMatchObject({ managed: true, installedVersion: "1.2.3", targetVersion: "1.2.4", + targetIntegrity: f.integrity, applicable: false }); + expect(plan.installContentDigest).toMatch(/^[a-f0-9]{64}$/); + expect(["blocked_active_session", "blocked_process_state_unknown", "windows_apply_disabled"]).toContain(plan.refusal); + expect(readFileSync(f.marker, "utf8")).toContain("metadata"); + expect(JSON.stringify(plan)).not.toContain(f.root); +}, 60_000); + +native("fresh Worker realms refuse missing or mismatched arch and reject post-inspection npm drift before metadata", async () => { + for (const mode of ["missing", "mismatch", "drift"] as const) { + const f = separateWorkerFixture(); + const plan = await separateWorkerPlan(f, mode === "missing" ? null : mode === "mismatch" ? "arm64" : "x64", mode === "drift"); + expect(plan).toMatchObject({ managed: mode === "drift", applicable: false, targetVersion: null, + refusal: mode === "drift" ? "target_unresolved" : "windows_inspection_deferred" }); + if (mode === "drift") expect(plan.installContentDigest).toMatch(/^[a-f0-9]{64}$/); + else expect(plan.installContentDigest).toBeNull(); + expect(existsSync(f.marker)).toBe(false); + expect(JSON.stringify(plan)).not.toContain(f.root); + } +}, 60_000); + native("published Node CLI uses the production inspector and observed toolchain for read-only metadata", () => { const hostNode = Bun.which("node"); expect(hostNode).not.toBeNull(); for (const f of [fixture(), fixture(true)]) { diff --git a/tests/helpers/cli-windows-plan-drift-worker.ts b/tests/helpers/cli-windows-plan-drift-worker.ts new file mode 100644 index 0000000000..2ec60a37bb --- /dev/null +++ b/tests/helpers/cli-windows-plan-drift-worker.ts @@ -0,0 +1,34 @@ +/** Test-only post-inspection drift seam; this is NOT the production Worker entry. */ +import { writeFileSync } from "node:fs"; +import { join } from "node:path"; +import { inspectCodexCliInstall } from "../../src/codex/cli-install-provenance"; +import { codexCliUpdateInspectionDepsFromSnapshot } from "../../src/codex/cli-update-inspection-context"; +import { createCodexCliUpdatePlan } from "../../src/codex/cli-update-plan"; +import type { CodexCliUpdateWorkerRunMessage } from "../../src/codex/cli-update-worker"; + +declare const self: Worker; +if (typeof Bun !== "undefined" && Bun.isMainThread === false) { + let ran = false; + self.onmessage = async ({ data }: MessageEvent) => { + if (ran || data.type !== "run" || data.operation !== "plan") return; + ran = true; + try { + const snapshot = data.snapshot; + if (!snapshot?.path || !snapshot.home) throw new Error("fixture_snapshot_missing"); + const plan = await createCodexCliUpdatePlan({ + inspectionDeps: codexCliUpdateInspectionDepsFromSnapshot(snapshot), + inspect: async deps => { + const report = await inspectCodexCliInstall(deps); + if (!report.managed || !report.installContentDigest) throw new Error("fixture_inspection_missing"); + // Same realm/report/private evidence; only the previously observed npm bytes change. + writeFileSync(join(snapshot.path!, "node_modules", "npm", "bin", "npm-cli.js"), + `require('node:fs').writeFileSync(${JSON.stringify(join(snapshot.home!, "metadata-ran"))}, 'unexpected'); process.exit(97);`); + return report; + }, + }); + self.postMessage({ type: "done", requestId: data.requestId, jobId: data.jobId, operation: "plan", plan }); + } catch { + self.postMessage({ type: "error", requestId: data.requestId, jobId: data.jobId, message: "fixture_worker_failed" }); + } finally { self.onmessage = null; } + }; +} From ba22f168585ef282dd7734e8eb1b480e34035ac6 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sun, 25 Oct 2026 08:43:21 +0900 Subject: [PATCH 5/8] test: avoid executable copies for pre-metadata arch refusals --- .../codex-integration/codex-cli-windows-plan.test.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/codex-integration/codex-cli-windows-plan.test.ts b/tests/codex-integration/codex-cli-windows-plan.test.ts index 1e86c90925..d61472af54 100644 --- a/tests/codex-integration/codex-cli-windows-plan.test.ts +++ b/tests/codex-integration/codex-cli-windows-plan.test.ts @@ -379,9 +379,12 @@ native("a fresh production Worker rebuilds private Windows plan evidence before } }, 60_000); -function separateWorkerFixture() { - const f = fixture(true), hostNode = Bun.which("node"); expect(hostNode).not.toBeNull(); - copyFileSync(hostNode!, join(f.toolchainPrefix, "node.exe")); +function separateWorkerFixture(copyExecutable = true) { + const f = fixture(true); + if (copyExecutable) { + const hostNode = Bun.which("node"); expect(hostNode).not.toBeNull(); + copyFileSync(hostNode!, join(f.toolchainPrefix, "node.exe")); + } expect(existsSync(join(f.prefix, "node.exe"))).toBe(false); const marker = join(f.root, "metadata-ran"), integrity = "sha512-" + Buffer.alloc(64, 1).toString("base64"); const main = { name: "@openai/codex", version: "1.2.4", optionalDependencies: { "@openai/codex-win32-x64": "1.2.4" }, @@ -424,7 +427,7 @@ native("a fresh production Worker binds a separate Node/npm metadata vehicle wit native("fresh Worker realms refuse missing or mismatched arch and reject post-inspection npm drift before metadata", async () => { for (const mode of ["missing", "mismatch", "drift"] as const) { - const f = separateWorkerFixture(); + const f = separateWorkerFixture(mode === "drift"); const plan = await separateWorkerPlan(f, mode === "missing" ? null : mode === "mismatch" ? "arm64" : "x64", mode === "drift"); expect(plan).toMatchObject({ managed: mode === "drift", applicable: false, targetVersion: null, refusal: mode === "drift" ? "target_unresolved" : "windows_inspection_deferred" }); From 22cdbaac425425e69e9266666b7521d431c5af4d Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sun, 25 Oct 2026 08:52:16 +0900 Subject: [PATCH 6/8] test: give each Windows CLI layout an independent case --- .../codex-cli-windows-plan.test.ts | 61 +++++++++++-------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/tests/codex-integration/codex-cli-windows-plan.test.ts b/tests/codex-integration/codex-cli-windows-plan.test.ts index d61472af54..e0dc738e72 100644 --- a/tests/codex-integration/codex-cli-windows-plan.test.ts +++ b/tests/codex-integration/codex-cli-windows-plan.test.ts @@ -438,30 +438,43 @@ native("fresh Worker realms refuse missing or mismatched arch and reject post-in } }, 60_000); -native("published Node CLI uses the production inspector and observed toolchain for read-only metadata", () => { +function checkPublishedNodeCliPlan(separateNodeToolchain: boolean) { + const started = performance.now(); const hostNode = Bun.which("node"); expect(hostNode).not.toBeNull(); - for (const f of [fixture(), fixture(true)]) { - const node = join(f.toolchainPrefix, "node.exe"); copyFileSync(hostNode!, node); - const integrity = "sha512-" + Buffer.alloc(64, 1).toString("base64"); - const main = { name: "@openai/codex", version: "1.2.4", optionalDependencies: { "@openai/codex-win32-x64": "1.2.4" }, - dist: { integrity, tarball: "https://registry.npmjs.org/@openai/codex/-/codex-1.2.4.tgz" } }; - const backing = { name: "@openai/codex-win32-x64", version: "1.2.4", dist: { integrity, - tarball: "https://registry.npmjs.org/@openai/codex-win32-x64/-/codex-win32-x64-1.2.4.tgz" } }; - // Controlled registry protocol fixture; no real npm installation or network request. - writeFileSync(join(f.npmRoot, "bin", "npm-cli.js"), - `const spec = process.argv[3]; console.log(JSON.stringify(spec.startsWith('@openai/codex-win32-x64@') ? ${JSON.stringify(backing)} : ${JSON.stringify(main)}));`); - const run = spawnSync(node, [repoPath("bin", "ocx.mjs"), "system", "codex-cli-update", "plan", "--json"], { - cwd: repoRoot(), encoding: "utf8", windowsHide: true, timeout: 45_000, - env: { ...process.env, PATH: f.toolchainPrefix + ";" + process.env.PATH, - CODEX_CLI_PATH: f.deps.env.CODEX_CLI_PATH, OPENCODEX_HOME: f.deps.configDir, - OPENCODEX_BUN_PATH: process.execPath, OCX_NO_DESKTOP_HANDOFF: "1" }, - }); - expect(run.error).toBeUndefined(); expect(run.status).toBe(0); - const plan = JSON.parse(run.stdout); - expect(plan.managed).toBe(true); expect(plan.targetVersion).toBe("1.2.4"); - expect(plan.targetIntegrity).toBe(integrity); - expect(plan.applicable).toBe(false); - expect(["blocked_active_session", "blocked_process_state_unknown", "windows_apply_disabled"]).toContain(plan.refusal); - expect(JSON.stringify(plan)).not.toContain(f.root); + const f = fixture(separateNodeToolchain); + const node = join(f.toolchainPrefix, "node.exe"); copyFileSync(hostNode!, node); + const integrity = "sha512-" + Buffer.alloc(64, 1).toString("base64"); + const main = { name: "@openai/codex", version: "1.2.4", optionalDependencies: { "@openai/codex-win32-x64": "1.2.4" }, + dist: { integrity, tarball: "https://registry.npmjs.org/@openai/codex/-/codex-1.2.4.tgz" } }; + const backing = { name: "@openai/codex-win32-x64", version: "1.2.4", dist: { integrity, + tarball: "https://registry.npmjs.org/@openai/codex-win32-x64/-/codex-win32-x64-1.2.4.tgz" } }; + // Controlled registry protocol fixture; no real npm installation or network request. + writeFileSync(join(f.npmRoot, "bin", "npm-cli.js"), + `const spec = process.argv[3]; console.log(JSON.stringify(spec.startsWith('@openai/codex-win32-x64@') ? ${JSON.stringify(backing)} : ${JSON.stringify(main)}));`); + const run = spawnSync(node, [repoPath("bin", "ocx.mjs"), "system", "codex-cli-update", "plan", "--json"], { + cwd: repoRoot(), encoding: "utf8", windowsHide: true, timeout: 45_000, + env: { ...process.env, PATH: f.toolchainPrefix + ";" + process.env.PATH, + CODEX_CLI_PATH: f.deps.env.CODEX_CLI_PATH, OPENCODEX_HOME: f.deps.configDir, + OPENCODEX_BUN_PATH: process.execPath, OCX_NO_DESKTOP_HANDOFF: "1" }, + }); + if (run.error || run.status !== 0) { + console.error(JSON.stringify({ layout: separateNodeToolchain ? "separate-PATH" : "prefix-local", + elapsedMs: Math.round(performance.now() - started), status: run.status, signal: run.signal, + errorCode: (run.error as NodeJS.ErrnoException | undefined)?.code ?? null })); } + expect(run.error).toBeUndefined(); expect(run.status).toBe(0); + const plan = JSON.parse(run.stdout); + expect(plan.managed).toBe(true); expect(plan.targetVersion).toBe("1.2.4"); + expect(plan.targetIntegrity).toBe(integrity); + expect(plan.applicable).toBe(false); + expect(["blocked_active_session", "blocked_process_state_unknown", "windows_apply_disabled"]).toContain(plan.refusal); + expect(JSON.stringify(plan)).not.toContain(f.root); +} + +native("published Node CLI plans with the production inspector and prefix-local toolchain", () => { + checkPublishedNodeCliPlan(false); +}, 60_000); + +native("published Node CLI plans with the production inspector and separate PATH toolchain", () => { + checkPublishedNodeCliPlan(true); }, 60_000); From b9fe203709a2ed4321e5b54064f60619b3bdcb86 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sun, 25 Oct 2026 08:55:09 +0900 Subject: [PATCH 7/8] test: retain fixtures for unsettled Windows CLI children --- tests/codex-integration/codex-cli-windows-plan.test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/codex-integration/codex-cli-windows-plan.test.ts b/tests/codex-integration/codex-cli-windows-plan.test.ts index e0dc738e72..9aa558ee9a 100644 --- a/tests/codex-integration/codex-cli-windows-plan.test.ts +++ b/tests/codex-integration/codex-cli-windows-plan.test.ts @@ -24,8 +24,8 @@ afterEach(() => { setWindowsInstallationFilesOpenedForTests(); setWindowsInstallationFilesReadForTests(); for (const root of roots.splice(0)) { - // A test timeout does not cancel its async body. Keep even that body's - // fixture owned until a real Worker close, never remove beneath native I/O. + // A test timeout does not cancel its async body. Retain fixtures until a real + // Worker close, or external reconciliation of an unsettled CLI process tree. if (liveWorkerRoots.has(root)) { roots.push(root); continue; } removeTreeWithRetry(root); } @@ -457,7 +457,9 @@ function checkPublishedNodeCliPlan(separateNodeToolchain: boolean) { CODEX_CLI_PATH: f.deps.env.CODEX_CLI_PATH, OPENCODEX_HOME: f.deps.configDir, OPENCODEX_BUN_PATH: process.execPath, OCX_NO_DESKTOP_HANDOFF: "1" }, }); - if (run.error || run.status !== 0) { + if (run.error || run.status !== 0 || run.signal) { + // A failed synchronous result does not prove Node/Bun descendants have exited. + liveWorkerRoots.add(f.root); console.error(JSON.stringify({ layout: separateNodeToolchain ? "separate-PATH" : "prefix-local", elapsedMs: Math.round(performance.now() - started), status: run.status, signal: run.signal, errorCode: (run.error as NodeJS.ErrnoException | undefined)?.code ?? null })); From 9004861a3b61644b6f1bace8296f4db224ba3276 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sun, 25 Oct 2026 08:59:50 +0900 Subject: [PATCH 8/8] test: track unsettled CLI and plan-worker fixture producers --- .../codex-cli-windows-plan.test.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/codex-integration/codex-cli-windows-plan.test.ts b/tests/codex-integration/codex-cli-windows-plan.test.ts index 9aa558ee9a..129c9b521f 100644 --- a/tests/codex-integration/codex-cli-windows-plan.test.ts +++ b/tests/codex-integration/codex-cli-windows-plan.test.ts @@ -15,6 +15,7 @@ import { removeTreeWithRetry } from "../helpers/remove-tree"; import { repoPath, repoRoot } from "../helpers/repo-root"; import { handleCodexCliUpdateCommand } from "../../src/cli/codex-cli-update"; import { initializeNodeLauncherContext, NODE_LAUNCH_CONTEXT_ENV, NODE_LAUNCH_PROOF_PREFIX } from "../../src/cli/launcher-context"; +import { trackBackgroundWork } from "../../src/lib/background-work"; const native = process.platform === "win32" && process.arch === "x64" ? test : test.skip; const roots: string[] = []; @@ -359,7 +360,11 @@ native("a fresh production Worker rebuilds private Windows plan evidence before // Pin this integration to current source, not a leftover generated bundle. worker = new Worker(url, { type: "module" }); liveWorkerRoots.add(f.root); - worker.addEventListener("close", () => { closed = true; liveWorkerRoots.delete(f.root); }, { once: true }); + const actualClose = Promise.withResolvers(); + void trackBackgroundWork("windows-plan-fixture-worker-close", actualClose.promise); + worker.addEventListener("close", () => { + closed = true; liveWorkerRoots.delete(f.root); actualClose.resolve(); + }, { once: true }); return worker; }, }); @@ -406,7 +411,11 @@ async function separateWorkerPlan(f: ReturnType, a // Drift needs a test-only injection seam; the positive and arch refusals use the production entry. const worker = new Worker(drift ? repoPath("tests", "helpers", "cli-windows-plan-drift-worker.ts") : url, { type: "module" }); liveWorkerRoots.add(f.root); - worker.addEventListener("close", () => { closed = true; liveWorkerRoots.delete(f.root); }, { once: true }); + const actualClose = Promise.withResolvers(); + void trackBackgroundWork("windows-plan-fixture-worker-close", actualClose.promise); + worker.addEventListener("close", () => { + closed = true; liveWorkerRoots.delete(f.root); actualClose.resolve(); + }, { once: true }); return worker; }, }); @@ -460,6 +469,8 @@ function checkPublishedNodeCliPlan(separateNodeToolchain: boolean) { if (run.error || run.status !== 0 || run.signal) { // A failed synchronous result does not prove Node/Bun descendants have exited. liveWorkerRoots.add(f.root); + // Keep the preload's ancestor sandbox too; only external ownership checks can release it. + void trackBackgroundWork("windows-plan-fixture-cli-unsettled", new Promise(() => {})); console.error(JSON.stringify({ layout: separateNodeToolchain ? "separate-PATH" : "prefix-local", elapsedMs: Math.round(performance.now() - started), status: run.status, signal: run.signal, errorCode: (run.error as NodeJS.ErrnoException | undefined)?.code ?? null }));