Repository navigation
Conversation
Add scripts/test-acq-bash32, which runs the vendored bats suite (or focused files) under a verified GNU Bash 3.2.57 and fails closed on any other version. It resolves the interpreter from ACQ_BASH32, a cache install, macOS /bin/bash or the CI path, and exposes it as `bash` on a private PATH so nested `#!/usr/bin/env bash` scripts also use it. Also add: - --syntax: `bash-3.2 -n` over the host-side shell files plus a heredoc scan - scripts/scan-heredoc-subst.py: heuristic for heredocs in $( ) / <( ) whose bodies bash 3.2 mis-parses - --install: source build with the same GNU OpenPGP signature check as CI - --install-oci: digest-pinned Docker Hub bash:3.2.57 fetch for sandboxes with no compiler or GNU mirror access - docs/howto/bash32-testing.md, ADR-0038 and a bats suite (152) The CI workflow is unchanged and remains authoritative. Refs: #632 Co-authored-by: OpenCode Agent <user@gsa.gov>
basiliskus
left a comment
There was a problem hiding this comment.
Verdict: request changes — 91046fb0308208fa397c2e9cc7f06a559aa76262
- Major —
scripts/fetch-bash32-oci.py:102-111: Please shell-quote or reject unsafe absolute prefixes before generating the OCI launcher. A prefix containing'produces invalid shell, and crafted path text can become shell syntax when the launcher is immediately executed. - Major —
.github/workflows/bash32-compat.yml:133-139: Please include the new runner and helpers in the Bash 3.2 relevance paths. Otherwise a future runner-only change skips the only real-3.2 CI lane while host tests may skip genuine-parser coverage. - Minor —
scripts/scan-heredoc-subst.py:72-73: Please avoid indexing the comment-stripped string with offsets from the original line; a<<TAGexample in a trailing comment currently raisesIndexErrorand prints a traceback.
Assisted-by: OpenCode [gpt-5.6-sol-latest-guardrails-defaultv2] skill:change-review
…workflow paths - fetch-bash32-oci.py: generate the launcher with shlex.quote for every path, reject non-absolute, control-character, non-UTF-8 and root prefixes before any network or disk work, and unlink existing files instead of writing through them. - scan-heredoc-subst.py: blank trailing comments with length-preserving spaces so opener offsets match the masked line (fixes IndexError); report an unexpected exception as a single line with exit 2 and tolerate a closed stdout pipe. - tests: hostile-prefix launcher execution, fail-closed prefixes, comment/string heredoc cases, repo-wide scanner fuzz, exception-guard, and a workflow relevance path test that skips with a reason until bash32-compat.yml lists the new paths. Co-authored-by: OpenCode Agent <user@gsa.gov>
|
🤖: AI agent (First Mate) — addressed in ff4574d (all CI checks green: bash 3.2 build, pre-commit, markdown, link check, PR title).
A pre-merge adversarial review (launcher injection, extraction, scanner) found no blockers. It did produce minor hardening, which is in this commit: the UTF-8 and root-prefix checks, the broken-pipe handling, and a stronger assertion in the fail-closed prefix test. Not addressed: very long pathological lines (tens of thousands of repeated |
basiliskus
left a comment
There was a problem hiding this comment.
Verdict: request changes — ff4574d4641baf9493bfbf71f5d738449c400d80
Prior launcher-quoting and scanner-crash findings are resolved. The CI relevance finding remains open:
- Major —
.github/workflows/bash32-compat.yml:133-139andtest/bats/152-bash32-runner.bats:482: Addscripts/test-acq-bash32,scripts/fetch-bash32-oci.py, andscripts/scan-heredoc-subst.pyto the relevance paths, and make missing coverage fail rather than skip. Otherwise later tooling-only changes skip the real Bash 3.2 lane. Merge the companion correction first if necessary; deferral does not resolve this prerequisite.
Assisted-by: OpenCode [gpt-6.1-sol-latest-guardrails-defaultv2] skill:change-review
🤖: AI agent (First Mate / OpenCode). AI-assisted; human review required.
Refs #632
Context
macOS ships Bash 3.2.57. The only 3.2 gate is CI (9 to 16 minutes per round trip), and it recently caught several 3.2-only failures that newer bash accepts (empty array under
set -u; a heredoc in a process substitution with an apostrophe/backtick/paren in its body). This adds a repo-owned local command so developers, including agents in Linux sandboxes, get that feedback first. The CI workflow is untouched and stays authoritative.Plan / what changed
scripts/test-acq-bash32 [bats args]: resolves a Bash 3.2.57 (ACQ_BASH32, cache install, macOS/bin/bash,/opt/bash32), fails closed unlessBASH_VERSIONis exactly 3.2.57, exposes it asbashon a private PATH dir (so bats and nested#!/usr/bin/env bashuse it), then runsscripts/test-acq-batswith the arguments unchanged. No args = full suite.--syntax [FILE...]:bash-3.2 -noveracq,acq.backends/*.sh,install.sh, bash/sh scripts inscripts/,test/bats/helper.bash, plus the heredoc scan.--lint,--which.scripts/scan-heredoc-subst.py: best-effort heuristic for heredocs in$( )/<( )whose body has odd quotes, unpaired backtick or unbalanced parens.bash-3.2 -nis the authority. Open PR for the Windows fixes proposes a similar scanner (test/bats/heredoc-scan.py) that had not merged; the hazard rules are the same and the ADR says to fold them into one file.--install: source build with the same fingerprint-anchored OpenPGP verification as CI (a bats test asserts the fingerprint matches the workflow).--install-oci: digest-pinned Docker Hubbash:3.2.57fetch (no Docker, no remote script) for sandboxes with no compiler or GNU mirror.docs/howto/bash32-testing.md, ADR-0038 (options comparison), CONTRIBUTING.md note, pre-commit file filter,test/bats/152-bash32-runner.bats(28 tests).Provisioning comparison (tried in an offline-restricted aarch64 Linux sandbox: no compiler, no sudo, GNU mirrors and cache.nixos.org blocked; GitHub/PyPI/npm/Debian/Docker Hub reachable; Nix 2.24 present; mise absent): Nix/devenv could not fetch or build (no cache, no compiler); mise not installed and has no bash 3.2 backend; override works anywhere; source build is the strongest route where mirrors and a compiler exist; OCI fetch worked. Implemented: override + source build + OCI fallback. Nix/devenv/mise not implemented (the override accepts their output).
Verification
--syntax(32 files parse), the whole152-bash32-runner.bats(28/28, no skips), the runner script itself parses/runs under 3.2, and a full-suite run under 3.2: 1078 ok, 2 failures, both environmental to this sandbox (117 msysneeds a writable/tmp/opencode, fails under bash 5 too;103 kit-fetch-lifecyclere-execs"$BASH", which is the raw binary under the OCI launcher; documented limitation of that route).152-bash32-runner.bats28/28 (tests needing a real 3.2 skip with a reason).scripts/run-shellcheck: clean. markdownlint: clean.scripts/fix-exec-bits --check: OK. Scanner reports nothing on the repo;bash-3.2 -nagrees.--syntax0.8 s; one small bats file about 3 s; full suite about 15 min (883 s), so use focused files while iterating.--installEXIT trap leak on success) and should-fixes (signal traps, relativeACQ_BASH32, scanner false negatives, docs) fixed. Round 2: no blockers; scanner quoting/false-positive/unterminated issues and a false-green cleanup test fixed.--installagainst real GNU mirrors with a compiler (mirrors blocked here; exercised only with stubbed curl/gpg/make, plus fail-closed on bad signature); anything on macOS; CI results (pending).Limitations
Validates the bash interpreter only, not BSD/macOS utilities (
sed,find,stat,xargs). The OCI interpreter is musl, content-pinned not signer-authenticated.Rollback
Revert the commit; no runtime or workflow code is touched, and
acqdoes not depend on any of this.Security impact
Dev tooling only. New network use is opt-in (
--install,--install-oci) and documented as needing user approval in agent sessions. OCI path verifies the manifest and every layer sha256 and extracts three fixed paths (no archive-controlled destinations). No secrets handled.