🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

feat(agent): unify session env via EnvInfoer - #26099

Merged
mafredri merged 4 commits into
mainfrom
mafredri/agentssh-envinfo-seam
Jun 5, 2026
Merged

feat(agent): unify session env via EnvInfoer#26099
mafredri merged 4 commits into
mainfrom
mafredri/agentssh-envinfo-seam

Conversation

@mafredri

@mafredri mafredri commented Jun 5, 2026

Copy link
Copy Markdown
Member

SSH session tests lean on fragile bufio.Scanner and blind-write patterns against NewSession, which is the source of the flaky bare-EOF failures tracked in coder/internal#1560. The fix is a deterministic, protected test tool, landed in stages. This PR is stage one: the seam the tool depends on.

It adds an injectable usershell.EnvInfoer to agent.Options and agentssh.Config. sessionStart now sources the session's user, shell, home directory, and environment from it, and NewServer defaults it to usershell.SystemEnvInfo. Production never sets the field, so the resolved shell, environment, and working directory stay identical to before. The container override for ExperimentalContainers still takes precedence per session. The only new capability is that a test can force a deterministic shell.

The same EnvInfoer is threaded into the process API (agentproc), whose working-directory home fallback previously called os.UserHomeDir directly. NewAPI and newManager now take an EnvInfoer (nil defaults to SystemEnvInfo), and resolveWorkDir uses it for the home fallback. This keeps the seam consistent across SSH and the process API, and lets the stacked working-directory unification honor injected EnvInfo instead of hardcoding SystemEnvInfo. Production behavior is unchanged.

TestAgent_SSHEnvInfoShell covers the path from agent.Options.EnvInfo to the executed session command, and TestStartProcess/DefaultWorkDirUsesInjectedEnvInfoHome proves the injected home is honored as the process working-directory fallback.

Implementation plan and where this PR fits

The redesign replaces fragile bufio.Scanner and blind-write SSH session test patterns with a deterministic, protected, composable tool. It ships in stages:

  • PR1 (this PR): EnvInfo seam in production, inert default. Covers both agentssh and the agentproc process API.
  • PR2: resolveWorkingDir stat-validation bug fix, unifying SSH and process-API working-directory resolution.
  • PR3: test tooling, an agenttest session driver plus usershelltest.EnvInfo, with a sentinel-prompt readiness mechanism validated on Linux and Windows.
  • PR4+: migrate the ~32 NewSession sites and the cli ptytest path, by area.

Locked decisions relevant here:

  • Test-only seam. Production behavior is unchanged.
  • Injection goes through usershell.EnvInfoer. The default stays SystemEnvInfo.
  • The per-session container override path is preserved.

PR1 scope: add EnvInfo to agentssh.Config and agent.Options, default it in NewServer, source it in sessionStart, thread it into agentproc.NewAPI, and assert that an injected Shell() changes the session shell and an injected HomeDir() changes the process working directory.

🤖 This PR was created with the help of Coder Agents, and will be reviewed by a human. 🏂🏻

SSH session tests need to inject a deterministic shell and environment
to replace the fragile bufio.Scanner and blind-write patterns behind
the flaky failures in coder/internal#1560. Expose an EnvInfo seam on
agent.Options and agentssh.Config so a test can supply its own
usershell.EnvInfoer. Production leaves it unset, so NewServer falls
back to SystemEnvInfo and the resolved shell, environment, and working
directory stay unchanged.
@mafredri

mafredri commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Chat: Review in progress | View chat
Requested: 2026-06-05 14:12 UTC by @mafredri

deep-review v0.7.1 | Round 1 | eac7ee4..def4d8a

Last posted: Round 1, 5 findings (1 P3, 2 Nit, 2 Note), COMMENT. Review

Finding inventory

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 Nit Open agent/agent.go:93 Options.EnvInfo doc comment restates interface methods R1 Gon (downgraded from P2) Yes
CRF-2 Nit Open agent/agentssh/agentssh.go:110 Config.EnvInfo doc comment restates interface methods R1 Gon (downgraded from P2) Yes
CRF-3 P3 Open agent/agent_test.go:1774 Second test fake for EnvInfoer; fakeEnvInfoer in agentssh_test.go R1 Robin Yes
CRF-4 Note Open agent/agentssh/agentssh.go:631 EnvInfo injection scoped to sessionStart; 3 other callers bypass R1 Meruem, Kite, Ryosuke Yes
CRF-5 Note Open agent/agentssh/agentssh.go:198 NewServer default makes CreateCommand nil guard dead on SSH path R1 Robin Yes
CRF-6 Nit Dropped by orchestrator (standard Go test docs, minor verbosity) agent/agent_test.go:1744 Test doc comment on TestAgent_SSHEnvInfoShell is verbose R1 Gon No
CRF-7 Nit Dropped by orchestrator (explains sentinel testing strategy) agent/agent_test.go:1753 Fake shell comment restates script content R1 Gon No
CRF-8 Nit Dropped by orchestrator (standard Go type doc in test code) agent/agent_test.go:1772 shellOverrideEnvInfo doc restates type definition R1 Gon No

Round log

Round 1

Panel. 0 P0-P2, 1 P3, 2 Nit, 2 Note. 3 dropped. Reviewed against eac7ee4..def4d8a.
Netero: no findings. 14-reviewer panel (Bisky, Hisoka, Mafu-san, Mafuuu, Pariston, Ging-Go, Gon, Leorio, Ryosuke, Robin, Chopper, Meruem, Kite, Zoro + wildcard Zoro).

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@johnstcn johnstcn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! My only regret is that I named it EnvInfoer and not something better. 🤦

Comment thread agent/agent_test.go

@coder-agents-review coder-agents-review 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.

Clean seam work. The injection path from agent.Options.EnvInfo through agentssh.Config.EnvInfo to sessionStart is correct, production behavior is unchanged, and the test proves the full chain. 14 reviewers found no bugs; findings are minor.

Severity count: 0 P0, 0 P1, 0 P2, 1 P3, 2 Nit, 2 Note.

"Boring code. Exactly what stage-one seam work should be. ♦" (Hisoka)

🤖 This review was automatically generated with Coder Agents.

Comment thread agent/agent.go Outdated
Comment thread agent/agentssh/agentssh.go Outdated
Comment thread agent/agent_test.go
Comment thread agent/agentssh/agentssh.go
Comment thread agent/agentssh/agentssh.go
The EnvInfo seam stopped at agentssh. agentproc resolved its
working-directory home fallback via os.UserHomeDir directly, so an
injected EnvInfo could not reach the process API the way it reaches
SSH sessions. The stacked working-directory unification needs that
path to honor EnvInfo.

Thread a usershell.EnvInfoer through NewAPI and newManager and use
m.envInfo.HomeDir() for the home fallback in resolveWorkDir. With
EnvInfo nil (the production default), SystemEnvInfo.HomeDir() resolves
the same home, so behavior is unchanged.
@mafredri mafredri changed the title feat(agent): add injectable EnvInfo for SSH tests feat(agent): add injectable EnvInfo seam Jun 5, 2026
mafredri added 2 commits June 5, 2026 17:26
Reorder NewAPI and newManager parameters so the backing dependencies
(pathStore, envInfo) precede the updateEnv and workingDir callbacks.
This groups the env-resolution inputs source-first ahead of the
closures that consume them. No behavior change.
Drop the parenthetical re-listing EnvInfoer's method set and the
redundant host-environment restatement. Keep the load-bearing claims:
nil default to usershell.SystemEnvInfo, tests-only, and the per-session
container override. Addresses review findings CRF-1 and CRF-2.
@mafredri
mafredri marked this pull request as ready for review June 5, 2026 18:16
@mafredri
mafredri merged commit d00ffbd into main Jun 5, 2026
33 checks passed
@mafredri
mafredri deleted the mafredri/agentssh-envinfo-seam branch June 5, 2026 18:22
@mafredri mafredri changed the title feat(agent): add injectable EnvInfo seam feat(agent): unify session env via EnvInfoer Jun 5, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants