11import { execFile , spawn as spawnChild } from 'node:child_process' ;
22import { createHash , createHmac , createPublicKey , verify } from 'node:crypto' ;
33import { EventEmitter } from 'node:events' ;
4- import { chmod , lstat , mkdir , mkdtemp , readFile , realpath , rm , writeFile } from 'node:fs/promises' ;
4+ import { chmod , lstat , mkdir , mkdtemp , readdir , readFile , realpath , rm , writeFile } from 'node:fs/promises' ;
55import { createConnection , type Socket } from 'node:net' ;
66import { tmpdir } from 'node:os' ;
77import { join } from 'node:path' ;
@@ -546,15 +546,19 @@ describe('hosted v1 browser E2E sandbox', () => {
546546 const socketRoot = await mkdtemp ( '/tmp/hv1-r5-' ) ;
547547 roots . push ( socketRoot ) ;
548548 const lifecycleSocket = join ( socketRoot , 'orchestrator-lifecycle.sock' ) ;
549- const drainSocket = join ( socketRoot , 'auth-drain.sock' ) ;
550- const proofPath = join ( sandbox . fakeRuntimeStateDir , 'auth-drain' , 'drain-proof.json' ) ;
549+ // Keep the independently owned test socket below Darwin's Unix-domain path limit.
550+ // Production uses the likewise short /run/agent-teams-auth-drain mount.
551+ const authDrainRoot = await mkdtemp ( '/tmp/hv1-ad-' ) ;
552+ roots . push ( authDrainRoot ) ;
553+ const drainSocket = join ( authDrainRoot , 'auth-drain.sock' ) ;
554+ const proofPath = join ( authDrainRoot , 'drain-proof.json' ) ;
551555 const runtimeEnvironment = {
552556 ...process . env ,
553557 E2E_SEED_APP_DATA_ROOT : sandbox . appDataDir ,
554558 E2E_SEED_CLAUDE_ROOT : sandbox . claudeDir ,
555559 E2E_FAKE_RUNTIME_STATE_ROOT : sandbox . fakeRuntimeStateDir ,
556560 E2E_LIFECYCLE_RUN_ROOT : socketRoot ,
557- E2E_AUTH_DRAIN_ROOT : join ( sandbox . fakeRuntimeStateDir , 'auth-drain' ) ,
561+ E2E_AUTH_DRAIN_ROOT : authDrainRoot ,
558562 E2E_LIFECYCLE_TRUST_ROOT : sandbox . lifecycleTrustDir ,
559563 E2E_LIFECYCLE_LAUNCHER_ROOT : sandbox . lifecycleLauncherDir ,
560564 E2E_AUTH_DRAIN_INDETERMINATE_ONCE : '1' ,
@@ -590,6 +594,10 @@ describe('hosted v1 browser E2E sandbox', () => {
590594 waitForPath ( drainSocket ) ,
591595 waitForPath ( join ( socketRoot , 'lifecycle-owner-admission.json' ) ) ,
592596 ] ) ;
597+ expect ( ( await readdir ( socketRoot ) ) . sort ( ) ) . toEqual ( [
598+ 'lifecycle-owner-admission.json' ,
599+ 'orchestrator-lifecycle.sock' ,
600+ ] ) ;
593601 const manifestEnvelope = JSON . parse (
594602 await readFile ( join ( socketRoot , 'lifecycle-owner-admission.json' ) , 'utf8' )
595603 ) as { payload : string } ;
@@ -2562,6 +2570,7 @@ describe('hosted v1 browser E2E sandbox', () => {
25622570 readFile ( 'test/fixtures/hosted-v1/seedContainer.ts' , 'utf8' ) ,
25632571 readFile ( '.github/workflows/ci.yml' , 'utf8' ) ,
25642572 ] ) ;
2573+ const securitySpec = await readFile ( 'test/e2e/hosted-v1/phase-6-security.spec.ts' , 'utf8' ) ;
25652574 expect ( compose ) . toContain ( 'dockerfile: docker/Dockerfile' ) ;
25662575 expect ( compose ) . not . toContain ( 'docker/e2e/Dockerfile' ) ;
25672576 expect ( compose ) . toContain ( 'COMPOSE_PROJECT_NAME' ) ;
@@ -2583,6 +2592,18 @@ describe('hosted v1 browser E2E sandbox', () => {
25832592 expect ( compose ) . toContain (
25842593 'AUTH_DRAIN_EVIDENCE_FILE: /run/agent-teams-auth-drain/drain-proof.json'
25852594 ) ;
2595+ expect ( seed ) . toContain (
2596+ 'const AUTH_DRAIN_SOCKET_PATH = `${AUTH_DRAIN_ROOT}/auth-drain.sock`;'
2597+ ) ;
2598+ expect ( seed ) . not . toContain (
2599+ 'const AUTH_DRAIN_SOCKET_PATH = `${LIFECYCLE_RUN_ROOT}/auth-drain.sock`;'
2600+ ) ;
2601+ expect ( securitySpec ) . toContain (
2602+ "createConnection('/run/agent-teams-auth-drain/auth-drain.sock')"
2603+ ) ;
2604+ expect ( securitySpec ) . not . toContain (
2605+ "createConnection('/run/agent-teams-orchestrator/auth-drain.sock')"
2606+ ) ;
25862607 expect ( compose ) . toContain ( 'E2E_LIFECYCLE_TRUST_DIR' ) ;
25872608 expect ( compose ) . toContain ( 'agent-teams-lifecycle-trust-init:' ) ;
25882609 expect ( compose ) . toContain (
0 commit comments