feat(host): capture HostEnvironment once at entry points
Summary
HostEnvironment = { env, cwd } now has one owner. Entry points capture it once, and the daemon runtime, request scope and command spawning receive it instead of reading process. 178 files changed, about 2,150 gross lines, most of them test call sites.
- Type and capture:
HostEnvironmentis in@agent-device/kernel/source-value.captureHostEnvironment(process)is in@agent-device/host-kit/process. It copies the environment. - Entry points:
src/bin.ts,src/cli.ts(runCli(argv, deps, host)),src/daemon.tsandcreateAgentDeviceClient(config, { host })capture once. The client keeps itsprocessdefault. - Daemon:
startDaemonRuntimerequireshost.DaemonRuntimeDepsInput.hostreplacesenv.RequestRouterDeps.hostandRequestExecutionScope.hostcarry it. - Command spawning:
withCommandHost({ host, requestEnv }, fn)replaceswithRequestCommandEnv. Spawned commands start fromhost.env.commandHostEnvironment()gives platform code that host and throws outside one. - Explicit inputs:
whichCmd,resolveUserPath,expandSessionPath, the device-claim functions,loadDaemonPolicy,launchDaemonProcessand kernel allowlist and simulator-set resolvers take env or cwd as parameters. - Done when: host-kit, kernel and daemon-contracts non-test sources have no
process.envorprocess.cwd().
Behavior changes: a relative state dir without a cwd is refused (relative_state_dir_without_cwd); callers now pass one. Unit tests enter the live process environment as their host (src/__tests__/host-environment-setup.ts).
Non-owned packages keep their direct reads as inline process.env / process.cwd() for #3750 and #3751 to migrate.
Validation
pnpm check:affected --run --head 2ebb8869c7 (exactCommit) passed. GitHub-authoritative lanes (coverage, integration, native) are not run locally. No device-facing behavior changed.
🤖 Generated with Claude Code