From fafe9c2388cca03b015546faacc717a5883a0e96 Mon Sep 17 00:00:00 2001 From: fullsend-code <278716306+fullsend-ai-coder[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:08:35 +0000 Subject: [PATCH 1/2] docs(#181): add shell return-vs-exit correctness rule to AGENTS.md Add a new "Shell scripting" section to AGENTS.md with guidance on the return-vs-exit distinction in executed vs sourced scripts. The review agent previously dismissed a top-level return statement in an executed script as "harmless dead code" (PR #3182). In bash, return at script top level is invalid and causes a hard abort under set -euo pipefail, regardless of reachability. This new rule instructs reviewers to flag top-level return (outside a function body) in executed scripts as a medium-severity correctness finding, especially when code is being inlined from a sourced library. Note: pre-commit could not run in-sandbox due to a network error installing shellcheck-py (exit 3). The post-script runs an authoritative pre-commit check on the runner. Closes #181 --- AGENTS.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 5620b735f..02db81969 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,6 +46,16 @@ The e2e tests require GitHub credentials. There are three ways to provide them: If only `E2E_GITHUB_USERNAME` and a password source are available, `make e2e-test` will automatically generate a session file before running tests. See `make help` for all available targets. +## Shell scripting + +### `return` vs `exit` in executed scripts + +`return` is valid only inside functions or in scripts that are `source`d. At the top level of an executed script (one with a shebang or run via `bash script.sh`), `return` causes a hard error — and under `set -euo pipefail`, this aborts the script. + +This commonly occurs when inlining library code that was previously `source`d. Library-style load guards like `[[ -n "${LOADED:-}" ]] && return 0` must be removed or replaced when the code is inlined into an executed script. + +**When reviewing shell scripts:** Flag any top-level `return` (outside a function body) in a script that is executed rather than sourced as a medium-severity correctness finding. Check for this especially when a PR inlines or moves code from a library/sourced file into an executable script. + ## Forge abstraction All git forge operations (GitHub API calls, PR comments, issue creation, workflow dispatch, etc.) **must** go through the `forge.Client` interface defined in `internal/forge/forge.go`. This is a fundamental architectural rule — the codebase supports multiple forges (GitHub, GitLab, Forgejo) and direct coupling to any single forge breaks the abstraction. From febe916449ab718aa7168e3aae405f67d7705893 Mon Sep 17 00:00:00 2001 From: fullsend-fix <278716306+fullsend-ai-coder[bot]@users.noreply.github.com> Date: Sat, 11 Jul 2026 11:18:37 +0000 Subject: [PATCH 2/2] fix(#181): clarify return behavior precision in shell scripting rule Reword the return-vs-exit rule in AGENTS.md to precisely describe the failure mode: return produces exit status 2 (not a 'hard error'), and the abort is specifically from set -e (errexit), not the full set -euo pipefail triad. Addresses review feedback on #204 --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 02db81969..f1b3cd3bb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -50,7 +50,7 @@ If only `E2E_GITHUB_USERNAME` and a password source are available, `make e2e-tes ### `return` vs `exit` in executed scripts -`return` is valid only inside functions or in scripts that are `source`d. At the top level of an executed script (one with a shebang or run via `bash script.sh`), `return` causes a hard error — and under `set -euo pipefail`, this aborts the script. +`return` is valid only inside functions or in scripts that are `source`d. At the top level of an executed script (one with a shebang or run via `bash script.sh`), `return` produces an error (exit status 2) — and under `set -e` (commonly part of `set -euo pipefail`), this non-zero status triggers errexit and aborts the script. This commonly occurs when inlining library code that was previously `source`d. Library-style load guards like `[[ -n "${LOADED:-}" ]] && return 0` must be removed or replaced when the code is inlined into an executed script.