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** (`