From b465b2c562764ce53435067b4247643d0d8fd31f Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Fri, 17 Jul 2026 08:10:16 +0200 Subject: [PATCH] chore: document installer invariants, wire shell tests into CI scripts/AGENTS.md gains the four invariants behind this week's fixes (no PATH-lookup verification, environments are not installations, stdin-detached quiet wrappers, whole-file shellcheck hook). tests/test_guide_multi_install.sh and tests/test_reconcile_dryrun.sh ran in no CI job; a dormant assertion there predicted the nvm/npm classification bug fixed in #106. New Shell Tests job runs both. Signed-off-by: Sebastian Mendel --- .github/workflows/ci.yml | 13 +++++++++++++ scripts/AGENTS.md | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 477993d..61142dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,6 +99,19 @@ jobs: pip-audit continue-on-error: true + shell-tests: + name: Shell Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + - name: Run shell test suites + run: | + bash tests/test_guide_multi_install.sh + bash tests/test_reconcile_dryrun.sh + build: name: Build Distribution runs-on: ubuntu-latest diff --git a/scripts/AGENTS.md b/scripts/AGENTS.md index 946f135..7bf7e0a 100644 --- a/scripts/AGENTS.md +++ b/scripts/AGENTS.md @@ -412,6 +412,28 @@ update_rust() { ## House rules +**Hard-won invariants** (each caused a shipped bug; keep them intact): + +- **Never verify an install via PATH lookup.** `go install`, `uv tool install` + etc. land in manager-owned dirs (`$(go env GOBIN)`, `~/.local/bin`) that may + be off PATH — resolve the manager's bin dir explicitly, or a successful + install reports "binary not found" and repeated runs orphan artifacts + (PRs #107, #111). With multiple installs, `command -v` also resolves to + whichever copy shadows the others — pass the *detected* path into removal + code, never re-resolve (PR #106). +- **Environments are not installations.** Virtualenv/conda bins must be + excluded by every detection layer. Both `scripts/lib/capability.sh` + (`detect_all_installations`) and `cli_audit/reconcile.py` + (`_is_virtualenv_bin`) enforce this — keep them in sync; a gap in one + caused removal of the wrong installation (PR #110). +- **Quiet command wrappers must detach stdin** (`