From 9445c9cbee3c4142400239a7da32a1b946339d18 Mon Sep 17 00:00:00 2001 From: Rudy Celekli Date: Mon, 28 Sep 2026 01:19:06 -0400 Subject: [PATCH] fix(installer): avoid SIGPIPE when checking selected agents --- .github/workflows/check-tools.yml | 3 ++ scripts/install.sh | 4 +- .../test-install-selection-completeness.sh | 39 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 scripts/test-install-selection-completeness.sh diff --git a/.github/workflows/check-tools.yml b/.github/workflows/check-tools.yml index ec13b3ec..e0db58d0 100644 --- a/.github/workflows/check-tools.yml +++ b/.github/workflows/check-tools.yml @@ -32,3 +32,6 @@ jobs: - name: Validate agent selection (install.sh --agent / --agents-file) run: bash scripts/test-agent-selection.sh + + - name: Validate complete selected installs + run: bash scripts/test-install-selection-completeness.sh diff --git a/scripts/install.sh b/scripts/install.sh index 50f46893..b28fcad0 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -235,7 +235,9 @@ build_selection() { slug_allowed() { $SELECTION_ACTIVE || return 0 local s="${1#agency-}" - printf '%s\n' "$_ALLOWED_SLUGS" | grep -qxF "$s" + # grep -q closes a pipe as soon as it finds an early match. With pipefail, + # printf may then get SIGPIPE and make a valid slug look unselected. + grep -qxF "$s" <<< "$_ALLOWED_SLUGS" } # selected_agent_count — how many agents the current selection installs. diff --git a/scripts/test-install-selection-completeness.sh b/scripts/test-install-selection-completeness.sh new file mode 100644 index 00000000..2973dd78 --- /dev/null +++ b/scripts/test-install-selection-completeness.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# grep -q must not make an early selected slug fail under pipefail/SIGPIPE. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +tmp="$(mktemp -d "${TMPDIR:-/tmp}/agency-selection.XXXXXX")" +trap 'rm -rf "$tmp"' EXIT + +# Exercise the installer's actual slug predicate with a list beyond the pipe +# buffer. An early grep -q match can close its input before printf finishes. +eval "$(sed -n '/^slug_allowed() {/,/^}/p' "$SCRIPT_DIR/install.sh")" +SELECTION_ACTIVE=true +_ALLOWED_SLUGS="$(awk 'BEGIN { print "first"; for (i = 0; i < 20000; i++) print "other-" i }')" +if ! slug_allowed first; then + echo 'FAIL: an allowed early slug was rejected after grep closed the pipe' >&2 + exit 1 +fi +slug_allowed other-19999 || { + echo 'FAIL: an allowed final slug was rejected' >&2 + exit 1 +} +echo 'PASS: early and final slugs remain selectable in a large roster' + +# Confirm the real division install copies every source agent, not a variable +# subset that happens to survive the pipeline race. +source "$SCRIPT_DIR/lib.sh" +expected=0 +while IFS= read -r -d '' file; do + is_agent_file "$file" && expected=$((expected + 1)) +done < <(find "$REPO_ROOT/engineering" -name '*.md' -type f -print0) +HOME="$tmp/home" bash "$SCRIPT_DIR/install.sh" --no-interactive --tool claude-code \ + --division engineering --path "$tmp/agents" > "$tmp/output" 2>&1 +actual="$(find "$tmp/agents" -maxdepth 1 -name '*.md' -type f | wc -l | tr -d ' ')" +if [[ "$actual" != "$expected" ]]; then + printf 'FAIL: engineering install copied %s of %s source agents\n' "$actual" "$expected" >&2 + exit 1 +fi +echo "PASS: engineering install copies all $expected selected agents"