From 1f9ab948e8d7795bca0da83f438faaea4785b79b Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Wed, 15 Jul 2026 17:24:32 -0700 Subject: [PATCH] test(codex): model codex config/batchWrite faithfully on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The grant-lane stub simulated codex by calling Orca's upsertHookTrustEntries, which writes both separator variants for a Windows key (a fallback-lane compat shim real codex never does) — fabricating duplicate tables and whitespace the RPC path never produces, so the byte-stable and no-duplicate assertions failed on win32. Replace it with a single-variant, blank-line-separated writer that matches the real 0.144.x binary's output. --- .../codex/hook-service-trust-grant.test.ts | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/codex/hook-service-trust-grant.test.ts b/src/main/codex/hook-service-trust-grant.test.ts index c308fde1cc0..20ffe6b245b 100644 --- a/src/main/codex/hook-service-trust-grant.test.ts +++ b/src/main/codex/hook-service-trust-grant.test.ts @@ -3,12 +3,14 @@ import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'nod import { tmpdir } from 'node:os' import type * as Os from 'node:os' import { join } from 'node:path' +import { existsSync } from 'node:fs' import { wrapPosixHookCommand } from '../agent-hooks/installer-utils' import { + computeTrustKey, computeTrustedHash, + escapeTomlString, parseTrustKey, readHookTrustEntries, - upsertHookTrustEntries, type CodexTrustEntry } from './config-toml-trust' import { codexAppServerCapabilityCache } from './codex-app-server-capability-cache' @@ -70,6 +72,32 @@ afterEach(() => { vi.clearAllMocks() }) +// Why: model codex's own config/batchWrite — exactly one +// `[hooks.state.""]` table per reported key, keyed verbatim, blank-line +// separated (the shape the real 0.144.x binary writes). Orca's +// upsertHookTrustEntries writes BOTH separator variants for a Windows key (a +// fallback-lane compat shim real codex never does), which would fabricate +// duplicate tables on win32 that the RPC path never produces. +function writeCodexLikeTrust(configPath: string, entries: CodexTrustEntry[]): void { + let content = existsSync(configPath) ? readFileSync(configPath, 'utf-8') : '' + if (!/^\[hooks\.state\][ \t]*$/m.test(content)) { + const separator = content.length === 0 ? '' : content.endsWith('\n') ? '' : '\n' + content += `${separator}[hooks.state]\n` + } + for (const entry of entries) { + const header = `[hooks.state."${escapeTomlString(computeTrustKey(entry))}"]` + // Why: replace any existing table for this exact key so re-grants upgrade + // in place instead of duplicating (mirrors codex's upsert merge strategy). + const existingBlock = new RegExp( + `(?:\\n)?${header.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n(?:[^[\\n].*\\n?|\\n)*`, + 'g' + ) + content = content.replace(existingBlock, '') + content += `${content.endsWith('\n') ? '' : '\n'}\n${header}\ntrusted_hash = "${escapeTomlString(entry.trustedHash!)}"\n` + } + writeFileSync(configPath, content) +} + function installCodexLikeGrantRunner(): ReturnType { const codexHash = (key: string): string => `sha256:codex-${parseTrustKey(key)?.eventLabel ?? 'unknown'}` @@ -84,7 +112,7 @@ function installCodexLikeGrantRunner(): ReturnType { trustedHash: codexHash(key) } }) - upsertHookTrustEntries(join(codexHome!, 'config.toml'), entries) + writeCodexLikeTrust(join(codexHome!, 'config.toml'), entries) return { outcome: 'granted' as const, wroteTrust: true,