From fe9d98fad34b58cc65e69e0dfcf0ecb622f4fa9b Mon Sep 17 00:00:00 2001 From: notplants-bot Date: Fri, 21 Aug 2026 03:52:39 +0000 Subject: [PATCH] =?UTF-8?q?README:=20drop=20the=20PATH=20note=20=E2=80=94?= =?UTF-8?q?=20the=20fix=20belongs=20in=20the=20host=20config,=20not=20the?= =?UTF-8?q?=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator: rather than documenting the workaround, notplants-nix should put the system profile on the agent PATH. It already does (two orchestrator units export it); the gap is that the change is committed and not yet deployed. The /proc rewrite in agents.py stands on its own — harness code should not depend on an external tool for something the kernel exposes. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01V3LdmEL7CvCYTNpoBq1kce --- README.md | 49 ------------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/README.md b/README.md index 7ac16dd..849821d 100644 --- a/README.md +++ b/README.md @@ -480,55 +480,6 @@ The agent CLIs themselves (`claude`, `opencode`) are **external, non-Nix tools** per their own docs and make sure they are on `PATH` before launching live agents. The devShell documents this in its banner. -### PATH on a NixOS host: why a tool that IS installed says "command not found" - -**An agent's `PATH` does not include the system profile.** On `notplants-orchestrator` the agent -shell gets a pinned list of individual store paths (bash, git, python, coreutils, findutils, grep, -sed, systemd, tmux, openssh, net-tools) and **not** `/run/current-system/sw/bin`. Everything the -host declares in `environment.systemPackages` therefore exists and is unreachable. - -Measured 2026-08-21: `ps`, `pgrep`, `free`, `cmp`, `awk`, `curl`, `diff`, `strings`, `nm`, `getent` -and `ping` were ALL installed (notplants-nix `hosts/notplants-orchestrator/configuration.nix`, -"give agents a real toolbox") and all reported `command not found`. - -**Why this is worse than an inconvenience.** A missing binary run through `shell=True` returns -**rc=127 with empty stdout**, and empty stdout is indistinguishable from a real answer of "none": - -- `agents.py` shelled out to `pgrep -P` to find a pane's child processes. With `pgrep` unreachable - it returned *no children*, so `_build_running` was **always False** and the stall detector could - reboot an agent in the middle of a build. It shipped that way and no test caught it, because the - unit tests **mocked `pgrep`** — the fake stood in for the broken dependency. -- The same session read an empty `ps` as "0 agent processes running", and an empty `strings` as - proof that a binary had its features stripped. - -**Check before concluding a tool is absent:** - -```bash -ls /run/current-system/sw/bin/ # installed but unreachable? -command -v # reachable? -``` - -**Put the system profile on PATH** (appended, so the sandbox's pinned store paths keep priority): - -```bash -case ":$PATH:" in *":/run/current-system/sw/bin:"*) ;; - *) export PATH="$PATH:/run/current-system/sw/bin" ;; esac -``` - -For something genuinely not installed, fetch it without changing the host: - -```bash -nix shell nixpkgs#tcpdump -c tcpdump ... # one command, nothing persisted -nix run nixpkgs#git-filter-repo -- --help -``` - -`nix` itself may also be off `PATH`; it lives at `/nix/var/nix/profiles/default/bin/nix`. - -**Rule for harness code: do not shell out for something the kernel already exposes.** `agents.py` -now reads `/proc//stat` and `/proc//comm` directly instead of calling `pgrep` and `ps`. -That has no PATH dependency and cannot fail silently in the direction that matters. If you must -call an external tool, check the return code — never treat empty output as an answer. - --- ## Testing