feat(omp): declare direnv preflight settings for agent bash commands - #2886
Merged
Conversation
|
Tick the box to add this pull request to the merge queue (same as
|
cameronraysmith
force-pushed
the
fm/vx-omp-direnv-autoload
branch
from
September 1, 2026 03:50
b50bfbc to
a092675
Compare
omp folds a clone's direnv environment into the bash commands it runs, which is what lets a devshell-provided tool resolve without wrapping the call in `nix develop` or `direnv exec`. The mechanism is on by default; what this sets is the budget it runs under. `bash.direnvLoadTimeoutMs` goes from the upstream 30000 to 180000. The first export in a clone has to realise the flake devshell, measured at 7.4 seconds in this repository against an already-populated nix store and running to minutes when the closure has to be built, while later exports served from the nix-direnv cache return in under 10 milliseconds. The higher ceiling cannot stall a short command, because the effective budget is the smaller of this value and the command's own deadline. Overrunning it runs the command without the direnv environment rather than failing, so a tight value loses devshell tools silently. `bash.direnv` is declared at the value it already defaults to, so that a change to that default appears as a diff here rather than as devshell tools disappearing from every bash command. A clone whose .envrc has not been through `direnv allow` still runs without the devshell. That gate belongs to direnv's own configuration and is untouched here.
cameronraysmith
force-pushed
the
fm/vx-omp-direnv-autoload
branch
from
September 1, 2026 05:37
a092675 to
106f539
Compare
cameronraysmith
changed the base branch from
main
to
fm/vx-atomic-0917-update
September 1, 2026 05:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Two keys added to
programs.omp.settingsinmodules/home/ai/omp/default.nix:Mechanism selected, and why
omp ships a direnv preflight in its bash tool. Before running a command it walks up from the command's working directory to the nearest
.envrc, runsdirenv export jsonthere, and folds the resulting variable diff into the command environment. The code isapplyDirenvPreflightinpackages/coding-agent/src/exec/bash-executor.ts, called fromexecuteBashin the same file and from the ACP-terminal and PTY branches ofpackages/coding-agent/src/tools/bash.ts. The two settings that steer it arebash.direnvandbash.direnvLoadTimeoutMs, declared inpackages/coding-agent/src/config/settings-schema.ts.bash.direnvis an enum overautoandoffwhose default is alreadyauto, so nothing here turns the mechanism on. It is declared anyway for the reason the mnemopi block in the same nix file gives for restating upstream defaults: an upstream flip tooffshould surface as a diff in this repository rather than as devshell tools quietly disappearing from every bash call.Three other candidates were considered and rejected.
pkgs.direnvcould be added toextraPackagesthe waymodules/home/ai/pi/default.nixdoes, but that only puts thedirenvbinary on the agent's PATH and still leaves every caller writingdirenv exec .by hand. Thedirenv/index.tsextension listed inmodules/home/ai/agent-settings.nixis a pi-lineage extension delivered to pi and atomic; omp carries this natively and does not need it. Wrapping the omp binary so it launches inside a devshell would bind one agent process to one project's environment, which is wrong for an agent that moves between repositories.Budget chosen, and why
180000 ms, raised from the upstream default of 30000.
The budget has to cover a first export that realises a flake devshell. Measured in a fresh worktree of this repository against an already-populated nix store, the first
direnv export jsonafterdirenv allowtook 7.39 seconds; an export that must fetch or build the devshell closure takes minutes. Every subsequent export, served from the nix-direnv cache, returned in under 10 milliseconds.A generous ceiling is safe in both directions. The effective budget is the smaller of this value and the command's own deadline —
applyDirenvPreflightcomputesMath.min(timeoutMs, callerTimeoutMs)— so raising it extends the wait only for calls that already carry a long timeout, and a short command cannot be stalled by a cold.envrc. Exceeding the budget is not an error either:loadDirenvEnvreturns null and the command runs without the direnv environment. Because the failure mode is a silent loss of the devshell rather than a visible error, a ceiling that comfortably covers a cold build is preferable to a tight one.Empirical result of the bare-command probe
Run in a fresh disposable worktree at
~/.treehouse/vanixiets-22808a/6/vanixiets, usingprekas the probe because it exists only in this repository's devshell and is absent from both the nix profile and a fresh login shell.Before
direnv allow, a barecommand -v prekreported not found,.pre-commit-config.yamldid not exist, anddirenv export jsonexited 1 with.envrc is blocked.After
direnv allowin that worktree, with no other change and nonix developwrapper, a barecommand -v prekin an omp bash command resolved to/nix/store/plfgv9vypicf6dkcigm4p8iqyxnqc26n-prek-0.4.10/bin/prekandprek --versionprintedprek 0.4.10. The second benefit holds as well:.pre-commit-config.yamlappeared as a symlink into the nix store, generated by the devshell throughconfig.pre-commit.devShellatmodules/devshells/default.nix:31, and the commit on this branch ran the gitleaks and treefmt hooks through it. This matters becausemodules/formatting.nix:18deliberately disables the pre-commit flake check for cache granularity, so the devshell is the only thing that produces that file.No omp restart was required. Because
bash.direnvwas already at its default ofautoand the preflight runs per bash command rather than at process start, the behaviour appeared on the very next command. A restart will be needed to pick up the raised timeout, since settings load at process start, but that affects only the ceiling and not whether the mechanism runs.Remaining gap, left for a separate decision
The probe needed one
direnv allow, and that is not incidental.loadDirenvEnvhonours direnv's own allow list and never auto-allows, by explicit design, so that cloning a repository with a hostile.envrcgrants it nothing. Disposable worktrees are created fresh and inherit no approval, so the goal of devshell tools resolving in any clone is not reached by omp settings alone.Closing it means a
whitelistin~/.config/direnv/direnv.toml, which this repository already manages throughprograms.direnv.configinmodules/home/terminal/direnv.nix. That is a change to the trust boundary of the interactive shell as much as the agent's, and it is not bundled here. A narrow form would whitelist prefixes holding repositories this workspace authors and their worktree pools, and would exclude~/ghq, which by convention holds third-party repositories that are only read.Testing
Built
.#checks.aarch64-darwin.treefmtand.#checks.aarch64-darwin.home-manager-crs58; both pass. Those are the checks that cover a change to a home-manager module:home-manager-crs58builds the generatedomp-config.ymlderivation and the activation script that merges it into~/.omp/agent/config.yml. The generated file was inspected directly and carries the expected nestedbashmapping rather than a flat dotted key.nix evalofconfig.programs.omp.settings.bashreturns{"direnv":"auto","direnvLoadTimeoutMs":180000}.The rest of the check set was deliberately left out. This change touches one home-manager module and alters no other derivation, so the remaining checks — the other users' home configurations, the darwin and NixOS machine closures, the kubernetes manifests — cannot be affected by it.