Skip to content

fix(server): resolve the login-shell env only for launchers that opt in - #714

Merged
Rinat S (rsolmano) merged 4 commits into
mainfrom
investigate-stuck-bash
Oct 12, 2026
Merged

Rinat S (rsolmano) merged 4 commits into
mainfrom
investigate-stuck-bash

Conversation

@rsolmano

Copy link
Copy Markdown
Collaborator

Problem

Since #689, bootHost() always imports the user's login-shell environment (provider API keys included), skipping it only when TERM is set. bun test drops TERM=dumb, which is what agent shells and turbo provide. So src/host/boot.test.ts copied the developer's real login env into the shared bun test process, and later faux-model suites resolved a real provider instead of the faux one. On a machine with ANTHROPIC_API_KEY in ~/.zshrc, chatResources.test.ts then talks to real Anthropic: its scripted tool calls never happen, tests time out one after another, and the server suite hangs indefinitely at about 150% CPU while spending real tokens.

Impact today: every bun run test started from a ThinkRail agent hung until the 30-minute bash timeout. Because the tool's timeout doesn't kill turbo's child process groups, the hung bun test processes then stayed running for hours and slowed every other workspace (load average ~77; e2e took over an hour; pre-commit typecheck timed out).

Bisected: at 57a1361a (the parent of #689) boot.test.ts leaves the env alone; at ea08fbdc (#689) the boot.test.ts + chatResources.test.ts pair imports the key and hangs.

Approach

Make the login-shell resolution opt-in instead of something tests must opt out of. BootHostOptions.resolveShellEnv defaults to off; the three real launchers (dev.ts, the CLI bootstrap, the desktop host generator) pass true, so shipped behavior is unchanged. Any embedder or test that does not pass the flag keeps the environment it was given.

Trade-off: the flag gates the whole resolveShellEnv() (PATH, locale and SSH_AUTH_SOCK repairs too), so a future launcher that forgets it loses all of them. That is the safer failure mode than leaking credentials into test processes.

Changes

  • packages/server/src/host/boot.ts: new resolveShellEnv?: boolean boot option; resolveShellEnv() runs only when it is set.
  • packages/server/src/dev.ts, apps/cli/src/bootstrap.ts, apps/desktop/preBuild.ts: opt in.
  • packages/server/src/host/boot.test.ts: deterministic regression test using a fake login shell that exports a canary variable. The canary must stay absent without the flag and be imported with it. The test fails with the guard reverted. Skipped on win32, where resolveShellEnv does nothing.
  • Specs: packages/server/SPEC.md, packages/server/src/host/SPEC.md (with the post-mortem), apps/cli/SPEC.md and apps/desktop/SPEC.md describe the opt-in.

Not in this PR (follow-ups):

  • A direct bun test from an agent shell still inherits the key the app itself imported. A test preload that strips ambient provider credentials would close that.
  • pi's bash timeout kills only its own process group, so turbo and e2e shard children survive it. That fix belongs in pi.
  • A pre-existing order dependency: run in one process after boot.test.ts, the detached-Agent tests in chatResources.test.ts fail. It does not hang and predates feat: upgrade pi to 1.1.0, gate session reloads and teardown, import the login env #689.

Screenshots

Not applicable — no frontend changes.

Related issues

Regression from #689.

Checklist

  • Fast gates pass: bun run lint, bun run typecheck, bun run test (lint and typecheck re-run green after the rebase onto 9d6ad0b2. bun run test: server 1464 pass and 4 fail, finishing in 2m36s instead of hanging. The 4 failures are changes CRLF/final-newline tests that also fail on main without this change. All other tasks are green.)
  • E2E suite passes for app-affecting changes (bun run e2e: all 8 shards passed in 268s, run before rebasing over the web-only feat(web): calm the topbar location bar #712)
  • Before/after screenshots are included for frontend changes, or marked not applicable
  • Relevant SPEC.md / top-level specs updated to reflect any boundary, contract, or behavior change
  • I have read the Contributing guide and agree to the Code of Conduct

Also run: bun run check:deps, check:boundaries, check:seams and check:spec-surface are green. bun test src/host/boot.test.ts gives 16 pass. env -u ANTHROPIC_API_KEY bun test src/host/boot.test.ts src/agent/chatResources.test.ts now finishes in 50s; before the fix it hung.

@jetbrains-air jetbrains-air Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — ready to merge.

@rsolmano
Rinat S (rsolmano) added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit 1166af0 Oct 12, 2026
17 checks passed
@rsolmano
Rinat S (rsolmano) deleted the investigate-stuck-bash branch October 12, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant