@@ -21,6 +21,7 @@ import {
2121} from "node:fs" ;
2222import { tmpdir } from "node:os" ;
2323import { join , relative , resolve } from "node:path" ;
24+ import { pathToFileURL } from "node:url" ;
2425
2526import {
2627 canonicalizeCodexHome ,
@@ -296,7 +297,62 @@ afterEach(async () => {
296297 while ( roots . length ) await roots . pop ( ) ! . cleanup ( ) ;
297298} ) ;
298299
300+ type WindowsProbeResult = { variant : string ; stage : string ; exit : number | null ; elapsedMs : number ; stdoutPresent : boolean ; stderrPresent : boolean ; killed : boolean } ;
301+
302+ async function diagnoseWindowsFixtureEnvironment ( fx : Fixture ) : Promise < void > {
303+ const strict = fx . env ( ) ;
304+ // These children execute only fixed OS identity/compiler probes, never the
305+ // CLI, profiles, network requests, or application credential readers.
306+ const inherited = { ...process . env , ...strict } ;
307+ const groups : Record < string , RegExp > = {
308+ powershell : / ^ ( P S M o d u l e P a t h | P S E x e c u t i o n P o l i c y P r e f e r e n c e ) $ / i,
309+ programLocations : / ^ ( P r o g r a m F i l e s (?: \( x 8 6 \) ) ? | P r o g r a m W 6 4 3 2 | C o m m o n P r o g r a m F i l e s (?: \( x 8 6 \) ) ? | C o m m o n P r o g r a m W 6 4 3 2 | P r o g r a m D a t a | A L L U S E R S P R O F I L E ) $ / i,
310+ system : / ^ ( S y s t e m D r i v e | O S | P R O C E S S O R _ A R C H I T E C T U R E | P R O C E S S O R _ A R C H I T E W 6 4 3 2 | P R O C E S S O R _ I D E N T I F I E R | P R O C E S S O R _ L E V E L | P R O C E S S O R _ R E V I S I O N | N U M B E R _ O F _ P R O C E S S O R S | C O M P U T E R N A M E | L O G O N S E R V E R | P U B L I C | H O M E D R I V E | H O M E P A T H ) $ / i,
311+ } ;
312+ const expressions = {
313+ sid : "$ErrorActionPreference='Stop'; $null=[System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value" ,
314+ compiler : "$ErrorActionPreference='Stop'; Add-Type -TypeDefinition 'public static class CcxProbe { public static int Value() { return 1; } }'; $null=[CcxProbe]::Value()" ,
315+ } ;
316+ const results : WindowsProbeResult [ ] = [ ] ;
317+ const probe = async ( variant : string , stage : string , env : Record < string , string | undefined > ) : Promise < WindowsProbeResult > => {
318+ const command = stage === "resolver"
319+ ? [ process . execPath , "--eval" , [
320+ `const { resolveEffectiveUserIdentity, resolveCodexCoordinatorDatabasePath } = await import(${ JSON . stringify ( pathToFileURL ( resolve ( repoRoot , "src/codex/user-identity.ts" ) ) . href ) } );` ,
321+ "try { resolveCodexCoordinatorDatabasePath(resolveEffectiveUserIdentity(), process.env.CODEX_HOME); } catch { process.exitCode = 1; }" ,
322+ ] . join ( "\n" ) ]
323+ : [ "powershell.exe" , "-NoLogo" , "-NoProfile" , "-NonInteractive" , "-EncodedCommand" , Buffer . from ( expressions [ stage as keyof typeof expressions ] , "utf16le" ) . toString ( "base64" ) ] ;
324+ const started = Date . now ( ) ;
325+ const child = Bun . spawn ( command , { cwd : fx . root , env, stdout : "pipe" , stderr : "pipe" } ) ;
326+ fx . children . push ( child ) ;
327+ let killed = false ;
328+ const timer = setTimeout ( ( ) => { killed = true ; child . kill ( ) ; } , stage === "resolver" ? 25_000 : 12_000 ) ;
329+ try {
330+ const [ exit , stdout , stderr ] = await Promise . all ( [ child . exited , new Response ( child . stdout ) . text ( ) , new Response ( child . stderr ) . text ( ) ] ) ;
331+ const result = { variant, stage, exit, elapsedMs : Date . now ( ) - started , stdoutPresent : ! ! stdout , stderrPresent : ! ! stderr , killed } ;
332+ results . push ( result ) ;
333+ return result ;
334+ } finally {
335+ clearTimeout ( timer ) ;
336+ }
337+ } ;
338+ for ( const stage of [ "sid" , "compiler" , "resolver" ] ) {
339+ const baseline = await probe ( "strict" , stage , strict ) ;
340+ const contrast = await probe ( "inherited" , stage , inherited ) ;
341+ if ( baseline . exit !== 0 && contrast . exit === 0 ) {
342+ for ( const [ name , pattern ] of Object . entries ( groups ) ) {
343+ const group = Object . fromEntries ( Object . entries ( process . env ) . filter ( ( [ key ] ) => pattern . test ( key ) ) ) ;
344+ await probe ( name , stage , { ...strict , ...group } ) ;
345+ }
346+ }
347+ }
348+ console . log ( `CCX_WINDOWS_FIXTURE_PROBES ${ JSON . stringify ( results ) } ` ) ;
349+ }
350+
299351describe ( "WP13 composed toggle acceptance" , ( ) => {
352+ test . skipIf ( process . platform !== "win32" ) ( "Windows fixture OS environment diagnostic" , async ( ) => {
353+ await diagnoseWindowsFixtureEnvironment ( fixture ( ) ) ;
354+ } , 300_000 ) ;
355+
300356 /** RED: remove `shouldSyncCodexOnStart` or the under-lock desired-state read; an OFF row writes native bytes. */
301357 test ( "A-reduced: real CLI and HTTP entry points preserve an OFF Codex home" , async ( ) => {
302358 const fx = fixture ( ) ;
0 commit comments