From 4bdd63286f694c327244d025d5fdae89c9ca040e Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Wed, 2 Sep 2026 15:04:36 +0530 Subject: [PATCH 1/2] ci: fail closed on missing security tools --- .github/workflows/tests.yml | 6 +++--- docs/testing.md | 9 +++++++-- tests/full_validate.sh | 25 ++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 842d9c0..646f1ce 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -111,9 +111,9 @@ jobs: set -eu if [ "$DISTRO_FAMILY" = debian ]; then apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y bash python3 python3-pip python3-venv + DEBIAN_FRONTEND=noninteractive apt-get install -y bash nodejs npm python3 python3-pip python3-venv else - dnf install -y python3 python3-pip + dnf install -y nodejs npm python3 python3-pip fi python3 -m venv /tmp/base-cli-venv /tmp/base-cli-venv/bin/python -m pip install ".[dev,typer]" @@ -138,4 +138,4 @@ jobs: $drive = $env:GITHUB_WORKSPACE.Substring(0, 1).ToLowerInvariant() $path = $env:GITHUB_WORKSPACE.Substring(2).Replace('\', '/') $linuxWorkspace = "/mnt/$drive$path" - wsl --distribution Ubuntu --user root -- bash -lc "set -eu; cd '$linuxWorkspace'; sed -i 's/\r$//' tests/full_validate.sh tests/validate.sh; apt-get update -qq; apt-get install -y -qq python3-venv python3.14-venv; python3 -m venv /tmp/base-cli-venv; . /tmp/base-cli-venv/bin/activate; python -m pip install '.[dev,typer,quality]'; export BASE_CLI_BENCHMARK_PLATFORM=wsl; bash tests/full_validate.sh" + wsl --distribution Ubuntu --user root -- bash -lc "set -eu; cd '$linuxWorkspace'; sed -i 's/\r$//' tests/full_validate.sh tests/validate.sh; apt-get update -qq; apt-get install -y -qq nodejs npm python3-venv python3.14-venv; python3 -m venv /tmp/base-cli-venv; . /tmp/base-cli-venv/bin/activate; python -m pip install '.[dev,typer,quality]'; export BASE_CLI_BENCHMARK_PLATFORM=wsl; bash tests/full_validate.sh" diff --git a/docs/testing.md b/docs/testing.md index a36a0ef..c409227 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -4,7 +4,9 @@ The Base manifest declares `./tests/full_validate.sh` as the authoritative test command. It runs the repository baseline checks, Python tests with the coverage policy, strict typing, formatting and lint checks, schema and contract validation, documentation checks, compatibility-dashboard and -performance checks, and the available security gates. +performance checks, Bandit, and a strict `pip-audit` of the resolved +third-party environment. Bandit and pip-audit are required; a missing tool is +an error rather than a skipped check. Run it from a clean checkout after installing the development and quality extras: @@ -16,4 +18,7 @@ python -m pip install '.[dev,typer,quality]' `./tests/validate.sh` remains the fast repository-baseline check used when dependencies are not yet installed. It is not a substitute for the full -validation gate. +validation gate. The full gate writes a machine-readable result to +`$BASE_CLI_VALIDATION_RESULT` (or `/tmp/base-cli-validation-result.json`). If +Node.js is unavailable, the result is marked `partial`, the gate exits with +status `2`, and it cannot be reported as an authoritative pass. diff --git a/tests/full_validate.sh b/tests/full_validate.sh index 3452cf4..b046147 100755 --- a/tests/full_validate.sh +++ b/tests/full_validate.sh @@ -3,7 +3,7 @@ # Authoritative local validation entry point for the Base manifest. set -euo pipefail -required_commands=(python ruff mypy) +required_commands=(python ruff mypy bandit pip-audit) for command in "${required_commands[@]}"; do command -v "$command" >/dev/null 2>&1 || { printf 'Missing validation tool: %s. Install the dev and quality extras first.\n' "$command" >&2 @@ -29,8 +29,27 @@ python scripts/benchmark_runtime.py --check python -m compileall -q examples python scripts/validate_coverage.py coverage.json -if command -v bandit >/dev/null 2>&1; then - bandit -q -r lib/python/base_cli scripts -lll -iii +bandit -q -r lib/python/base_cli scripts -lll -iii + +# Audit the resolved third-party environment without asking pip-audit to +# resolve the unpublished editable checkout itself. `sed` keeps this safe +# under `set -o pipefail` even when the environment contains no other package. +audit_requirements="$(mktemp)" +trap 'rm -f "$audit_requirements"' EXIT +python -m pip freeze \ + | sed -E '/^base-cli([[:space:]=@]|$)/d' \ + > "$audit_requirements" +pip-audit --strict -r "$audit_requirements" + +validation_result="${BASE_CLI_VALIDATION_RESULT:-${TMPDIR:-/tmp}/base-cli-validation-result.json}" +if command -v node >/dev/null 2>&1; then + printf '%s\n' '{"status":"full","skipped":[]}' > "$validation_result" + printf 'Validation result: full (%s)\n' "$validation_result" +else + printf '%s\n' '{"status":"partial","skipped":["node contract validator"]}' > "$validation_result" + printf 'Validation result: partial; Node.js contract validation was skipped (%s).\n' "$validation_result" + printf 'This result is non-authoritative; install Node.js for the full gate.\n' + exit 2 fi printf 'Full base-cli validation passed.\n' From f959e925738881be5384305158911ad718529a83 Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Wed, 2 Sep 2026 15:26:28 +0530 Subject: [PATCH 2/2] fix: exclude editable checkout from dependency audit --- tests/full_validate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/full_validate.sh b/tests/full_validate.sh index b046147..d84ab8b 100755 --- a/tests/full_validate.sh +++ b/tests/full_validate.sh @@ -37,7 +37,7 @@ bandit -q -r lib/python/base_cli scripts -lll -iii audit_requirements="$(mktemp)" trap 'rm -f "$audit_requirements"' EXIT python -m pip freeze \ - | sed -E '/^base-cli([[:space:]=@]|$)/d' \ + | sed -E '/(^-e .*#egg=base[_-]cli|^base[_-]cli([[:space:]=@]|$))/Id' \ > "$audit_requirements" pip-audit --strict -r "$audit_requirements"