Skip to content

fix: fall back to workspace scripts dir for script companions - #41

Merged
waynesun09 merged 2 commits into
mainfrom
postrun-command
Jul 8, 2026
Merged

fix: fall back to workspace scripts dir for script companions#41
waynesun09 merged 2 commits into
mainfrom
postrun-command

Conversation

@waynesun09

@waynesun09 waynesun09 commented Jul 7, 2026

Copy link
Copy Markdown
Member

Summary

  • Fixes the same root cause as Post-script companion scripts not accessible when resolved from URL-based cache fullsend#3069 / #3070 as it manifests in this repo: post-code.sh, post-fix.sh, pre-code.sh, and pre-fix.sh locate companion scripts (resolve-precommit-tools.py, install-precommit-tools.sh, process-fix-result.py) via a SCRIPT_DIR-relative sibling lookup. Those companion scripts were never migrated into this repo during extraction, so the lookup has always silently failed here.
  • Effect: pre-commit tool auto-install is silently skipped (surfaces downstream as a confusing Executable X not found failure at the authoritative pre-commit gate), and fix-agent PR summary comments never post.
  • Adds a workspace-directory fallback for companion-file lookup, mirroring fullsend-ai/fullsend#3393 (now merged): after the SCRIPT_DIR-relative lookup misses (it always will here), fall back to ${GITHUB_WORKSPACE}/scripts/ then ${GITHUB_WORKSPACE}/.fullsend/scripts/ — the path the reusable workflow's "Prepare workspace" step materializes fullsend's own scaffold scripts/ directory at on every job.
  • Warns instead of silently skipping when companions are missing everywhere, so the failure no longer surfaces only as a confusing Executable X not found at the pre-commit gate.

Supersedes this PR's original approach. The first commit on this branch called two fullsend postrun subcommands that don't exist in any shipped fullsend binary — that CLI-surface approach was dropped in fullsend-ai/fullsend#3393 per review feedback there in favor of the workspace-fallback approach this PR now uses instead. No dependency on a fullsend release remains.

Related Issue

Fixes fullsend-ai/fullsend#3069
Fixes fullsend-ai/fullsend#3070

Changes

  • scripts/post-code.sh, scripts/pre-code.sh, scripts/pre-fix.sh: after the SCRIPT_DIR/TARGET_REPO-relative lookup for resolve-precommit-tools.py + install-precommit-tools.sh misses, fall back to ${GITHUB_WORKSPACE}/scripts/ then ${GITHUB_WORKSPACE}/.fullsend/scripts/; warn if still missing.
  • scripts/post-fix.sh: same fallback for the pre-commit auto-install block, plus the same fallback for process-fix-result.py.

Testing

  • bash -n syntax check on all four modified scripts
  • Existing scripts/post-code-test.sh and scripts/post-fix-test.sh suites pass unchanged
  • Isolated smoke test of the fallback block: BASH_SOURCE-relative lookup misses (as it always does here) → resolves via ${GITHUB_WORKSPACE}/scripts

Companion scripts (resolve-precommit-tools.py, install-precommit-tools.sh,
process-fix-result.py) are located via SCRIPT_DIR-relative sibling
lookups. That works when scripts are resolved from a local scaffold
checkout, but silently fails here: this repo's post-code.sh/post-fix.sh/
pre-code.sh/pre-fix.sh are fetched by fullsend as single files from a
URL base, and the harness fetch pipeline has no sibling-file mechanism
for scripts (only for skills) — so those companion scripts were never
present next to the fetched pre/post scripts in this repo.

Effect: pre-commit tool auto-install silently skipped (surfaces
downstream as a confusing "Executable X not found" pre-commit failure),
and fix-agent PR summary comments never posted.

Requires fullsend-ai/fullsend#3393 to be merged and released first —
this PR calls `fullsend postrun precommit-install` / `fullsend postrun
fix-summary`, which do not exist in any fullsend release yet.

Fixes fullsend-ai/fullsend#3069
Fixes fullsend-ai/fullsend#3070

Assisted-by: Claude
Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 7, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:54 PM UTC · Completed 6:03 PM UTC
Commit: 7d82582 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review — approve

PR: #41fix: fall back to workspace scripts dir for script companions
Author: waynesun09 · Draft: no · Base: main · Files: 4 · Δ: +120 / −1

Clean, well-scoped fix. The companion scripts (resolve-precommit-tools.py, install-precommit-tools.sh, process-fix-result.py) were never migrated into this repo during the ADR 0058 extraction, so the existing BASH_SOURCE-relative lookups always fail. This PR adds a workspace-directory fallback — trying ${GITHUB_WORKSPACE}/scripts/ then ${GITHUB_WORKSPACE}/.fullsend/scripts/ — which is where the reusable workflow's "Prepare workspace" step materializes fullsend's scaffold scripts. If the companions are still missing, a ::warning:: annotation now surfaces the problem instead of letting it propagate as a confusing "Executable X not found" pre-commit failure downstream.

The approach is the correct one: the existing [ -f ... ] && [ -f ... ] guards remain unchanged, so the failure mode when scripts are truly absent is identical to today (skip and continue) — but with better diagnostics. No behavioral regression is introduced.

Re-review note: The prior review (SHA 7d82582) evaluated a completely different approach (fullsend postrun CLI subcommands). That approach was dropped per review feedback on fullsend-ai/fullsend#3393. The current workspace-fallback approach is architecturally simpler and has no dependency on a fullsend binary release. All prior findings are obsolete.


Observations

1. ::warning:: messages interpolate paths without GHA workflow command sanitization

Severity low
Category GHA-workflow-command-injection
Files scripts/post-code.sh, scripts/post-fix.sh, scripts/pre-code.sh, scripts/pre-fix.sh

The ::warning::Expected ${RESOLVE_SCRIPT} and ${INSTALL_SCRIPT} lines interpolate path variables into GHA workflow commands without sanitizing for :: sequences or %0A/%0D URL-encoded newlines. These paths are derived from ${GITHUB_WORKSPACE} (runner-controlled infrastructure, not attacker-controllable) concatenated with hardcoded path segments, so the practical risk is negligible. This is an established pattern in the codebase — post-code.sh:54, post-fix.sh:71,337 already emit ::error:: with unsanitized path variables. A separate sanitization pattern exists at post-code.sh:419-423 for untrusted git output, but that addresses a meaningfully different threat profile (external process output vs. infrastructure-set paths). No action required unless the team decides to remediate all call sites together.

2. Fallback block duplicated across four scripts

Severity low
Category code-duplication
Files scripts/post-code.sh, scripts/post-fix.sh, scripts/pre-code.sh, scripts/pre-fix.sh

The 20-line fallback-and-warning block is repeated identically across all four scripts (with minor variation: post-scripts check .pre-commit-config.yaml in CWD, pre-scripts check ${TARGET_REPO}/.pre-commit-config.yaml). This follows the established codebase convention — the pre-commit tool installation block is already duplicated across these four files with explicit # SYNC: comments acknowledging the intentional parallelism. Extracting a shared helper could improve maintainability but would be a style change inconsistent with how the rest of the scripts are structured.


Dimensions reviewed

Dimension Result
Correctness ✅ Fallback logic is correct; edge cases handled; existing guards preserved
Security ✅ 1 low (unsanitized paths in workflow commands — pre-existing pattern)
Intent & coherence ✅ Scope matches authorized work; approach mirrors merged fullsend#3393
Style & conventions ✅ 1 low (duplication follows established codebase pattern)
Documentation ✅ No stale references
Cross-repo contracts ⏭ Skipped — no exported interfaces modified

📋 Review by fullsend — PR #41 · head 8e5ab3c


Protected paths detected — this PR modifies files under one or more
protected paths. The review agent cannot approve PRs that touch these paths.
A human reviewer must approve this PR.

Protected files in this PR:

  • scripts/post-code.sh
  • scripts/post-fix.sh
  • scripts/pre-code.sh
  • scripts/pre-fix.sh

Labels: PR modifies CI/CD pipeline scripts for pre-commit tool dependency resolution

Previous run

Review — comment

PR: #41fix: call fullsend postrun for pre-commit tools and fix summaries
Author: waynesun09 · Draft: yes · Base: main · Files: 4 · Δ: +24 / −86

Clean simplification — replaces dead sibling-script lookups (resolve-precommit-tools.py, install-precommit-tools.sh, process-fix-result.py) with fullsend postrun subcommands that ship inside the already-present fullsend binary. Net deletion of 62 lines. Scope is tight — only the 4 pre/post scripts are touched, and the PR body clearly documents the dependency on fullsend-ai/fullsend#3393.

One medium finding worth addressing before this leaves draft:


Findings

1. fullsend postrun precommit-install runs unguarded under set -euo pipefail — soft-failure → hard-failure regression

Severity medium
Category error-handling
Files scripts/post-code.sh, scripts/post-fix.sh, scripts/pre-code.sh, scripts/pre-fix.sh

The old code wrapped the tool-resolution step in an explicit guard:

if python3 "${RESOLVE_SCRIPT}" ... > "${MANIFEST}"; then
  ...
else
  echo "::warning::Pre-commit tool resolution failed — continuing without auto-install"
fi

A failure emitted a GitHub Actions warning and the script continued to the authoritative pre-commit check, push, and PR-creation steps.

The new code runs the replacement bare:

fullsend postrun precommit-install "${PRECOMMIT_INSTALL_ARGS[@]}"

Under set -e, any non-zero exit from this command terminates the entire script. In the post-scripts this blocks branch push and PR creation; in the pre-scripts it prevents the agent from running at all. Pre-commit tool installation is a best-effort optimization — a transient failure (network timeout, binary version mismatch, unexpected input) should not be fatal.

Other fullsend CLI calls in this codebase follow the exit-code-capture pattern (e.g., fullsend post-review ... || POST_REVIEW_EXIT=$? in post-review.sh:314). The fullsend postrun fix-summary call in this same PR correctly preserves the pattern.

Remediation: Guard the call in all four scripts, e.g.:

fullsend postrun precommit-install "${PRECOMMIT_INSTALL_ARGS[@]}" \
  || echo "::warning::fullsend postrun precommit-install failed — continuing without auto-install"

Alternatively, if fullsend postrun precommit-install is designed to always exit 0 (handling errors internally), add a comment documenting that contract so future maintainers know the bare call is intentional.

2. Token passed as CLI argument (--token) — visible in process table

Severity low
Category secrets-handling
File scripts/post-fix.sh

The new fix-summary invocation passes the token on the command line:

fullsend postrun fix-summary --result "${RESULT_FILE}" --repo "${REPO_FULL_NAME}" \
  --pr "${PR_NUMBER}" --token "${GH_TOKEN}"

This exposes the token in /proc/<pid>/cmdline (readable by same-UID processes). The old python3 call inherited GH_TOKEN from the environment, keeping it out of the process argument list.

Mitigating factors: This is an established pattern in the codebase — post-review.sh, post-triage.sh, and post-prioritize.sh all pass tokens via --token. The token is already masked via ::add-mask:: (line 83). The practical risk on an ephemeral single-user CI runner is low. No action required unless the team decides to remediate all call sites together.


Dimensions reviewed

Dimension Result
Correctness 1 medium (error-handling regression)
Security 1 low (token on CLI — established pattern)
Intent & coherence ✅ Scope matches authorized work; architectural direction is sound
Style & conventions ✅ Consistent with existing patterns
Documentation ✅ No stale references found
Cross-repo contracts ✅ Internal scripts, not public API — temporal dependency on fullsend#3393 is acknowledged via draft status

📋 Review by fullsend — PR #41 · head 7d82582

fullsend-ai/fullsend#3393 dropped the `fullsend postrun` subcommand
approach (per review feedback there) in favor of a workspace-directory
fallback for companion-script lookup, so the previous commit on this
branch now calls subcommands that were never shipped and never will
be. Rework to mirror 3393's actual fix instead.

post-code.sh, post-fix.sh, pre-code.sh, pre-fix.sh: after the
BASH_SOURCE-relative lookup for resolve-precommit-tools.py /
install-precommit-tools.sh / process-fix-result.py misses (it always
does here, since those companions were never migrated into this repo
during the ADR 0058 extraction), fall back to ${GITHUB_WORKSPACE}/scripts/
then ${GITHUB_WORKSPACE}/.fullsend/scripts/ — the path the reusable
workflow's "Prepare workspace" step materializes fullsend's own
scaffold scripts/ directory at on every job. Warn instead of silently
skipping when the companions are missing everywhere.

Fixes fullsend-ai/fullsend#3069
Fixes fullsend-ai/fullsend#3070

Assisted-by: Claude
Signed-off-by: Wayne Sun <gsun@redhat.com>
@waynesun09 waynesun09 changed the title fix: call fullsend postrun for pre-commit tools and fix summaries fix: fall back to workspace scripts dir for script companions Jul 8, 2026
@waynesun09
waynesun09 marked this pull request as ready for review July 8, 2026 14:57
@waynesun09
waynesun09 requested a review from a team as a code owner July 8, 2026 14:57
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix companion script lookup via GITHUB_WORKSPACE fallback

🐞 Bug fix 🕐 20-40 Minutes

Grey Divider

AI Description

• Add workspace fallback when locating pre-commit companion scripts used by hook runners.
• Emit GitHub Actions warnings when companions are missing to avoid silent skips.
• Restore fix-agent summary processing by falling back to workspace process-fix-result.py lookup.
Diagram

graph TD
  A["Hook scripts (pre/post)"] --> B["Locate companion scripts"] --> C["Pre-commit tool auto-install"] --> D["Pre-commit gate"]
  B --> E[("Workspace scripts dir")] --> F["Companion scripts"] --> C
  A --> G["Process fix result"] --> H["PR summary comment"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Vendor companion scripts into this repo
  • ➕ No reliance on reusable-workflow workspace preparation paths
  • ➕ Simpler runtime behavior (single lookup path)
  • ➖ Duplicates upstream scaffold logic and risks drift
  • ➖ Requires deciding ownership/versioning of those scripts here
2. Teach the fetch/harness pipeline to download sibling companion files
  • ➕ Fixes the root issue generically for any future companion scripts
  • ➕ Avoids path heuristics and reduces per-script glue
  • ➖ More invasive change with broader blast radius than this PR
  • ➖ Likely requires workflow/tooling changes outside this repo

Recommendation: Keep the workspace-directory fallback and warning behavior as implemented: it matches how the reusable workflow materializes the scaffold scripts and fixes the silent-skip failure mode with minimal surface area. Consider the more structural 'fetch siblings' approach only if additional missing-companion cases keep emerging.

Files changed (4) +120 / -1

Bug fix (4) +120 / -1
post-code.shFallback to workspace for pre-commit companion scripts + warnings +27/-0

Fallback to workspace for pre-commit companion scripts + warnings

• Adds a secondary lookup for resolve/install companion scripts under ${GITHUB_WORKSPACE}/scripts and ${GITHUB_WORKSPACE}/.fullsend/scripts. Emits GitHub Actions warnings when a repo has pre-commit config but the companion scripts are missing everywhere.

scripts/post-code.sh

post-fix.shWorkspace fallback for pre-commit install and fix-result processing +39/-1

Workspace fallback for pre-commit install and fix-result processing

• Adds the same workspace fallback and non-silent warning behavior for pre-commit auto-install companions. Also adds a workspace fallback when locating process-fix-result.py so fix summaries can be processed even when the script isn’t colocated with post-fix.sh.

scripts/post-fix.sh

pre-code.shWorkspace fallback for pre-commit companion scripts + warnings +27/-0

Workspace fallback for pre-commit companion scripts + warnings

• When BASH_SOURCE-relative companion scripts are not present, searches workspace scaffold script directories for resolve/install companions. Warns (instead of silently skipping) when the target repo has .pre-commit-config.yaml but companions cannot be found.

scripts/pre-code.sh

pre-fix.shWorkspace fallback for pre-commit companion scripts + warnings +27/-0

Workspace fallback for pre-commit companion scripts + warnings

• Mirrors the pre-code.sh behavior: falls back to workspace script directories to find resolve/install companions. Adds warnings to make missing-companion failures explicit when pre-commit is configured.

scripts/pre-fix.sh

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 8, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 2:58 PM UTC · Ended 3:09 PM UTC
Commit: e8381e3 · View workflow run →

@waynesun09
waynesun09 requested a review from ifireball July 8, 2026 14:58
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (2)

Context used
✅ Compliance rules (platform): 55 rules
✅ Skills: 4 invoked
  code-review
  code-implementation
  pr-review
  docs-review

Grey Divider


Remediation recommended

1. Protected scripts/ files modified 📜 Skill insight § Compliance
Description
This PR modifies files under the protected governance/infrastructure path scripts/, which must not
be auto-approved and requires explicit review handling per policy. Even with justification, this
must be surfaced as a protected-path change.
Code

scripts/post-code.sh[R273-299]

+# Fallback: these companion scripts were never migrated into this repo
+# during the ADR 0058 extraction, so the BASH_SOURCE-relative lookup above
+# always misses. The reusable workflow's "Prepare workspace" step always
+# materializes the full scripts/ directory (from fullsend's own scaffold)
+# at ${GITHUB_WORKSPACE}/scripts/ (per-org) or ${GITHUB_WORKSPACE}/.fullsend/scripts/
+# (per-repo). Try those paths when the BASH_SOURCE-relative lookup misses.
+if [ ! -f "${RESOLVE_SCRIPT}" ] || [ ! -f "${INSTALL_SCRIPT}" ]; then
+  for _ws_candidate in "${GITHUB_WORKSPACE:-}/scripts" "${GITHUB_WORKSPACE:-}/.fullsend/scripts"; do
+    if [ -f "${_ws_candidate}/resolve-precommit-tools.py" ] \
+       && [ -f "${_ws_candidate}/install-precommit-tools.sh" ]; then
+      RESOLVE_SCRIPT="${_ws_candidate}/resolve-precommit-tools.py"
+      INSTALL_SCRIPT="${_ws_candidate}/install-precommit-tools.sh"
+      break
+    fi
+  done
+fi
+
+# Warn instead of silently skipping when the repo needs the auto-install but
+# the companions are missing everywhere — a silent skip here surfaces later
+# as a confusing "Executable X not found" pre-commit failure.
+if [ -f .pre-commit-config.yaml ] \
+   && { [ ! -f "${RESOLVE_SCRIPT}" ] || [ ! -f "${INSTALL_SCRIPT}" ]; }; then
+  echo "::warning::Pre-commit tool auto-install skipped: companion scripts not found"
+  echo "::warning::Expected ${RESOLVE_SCRIPT} and ${INSTALL_SCRIPT}"
+  echo "::warning::Pre-commit hooks requiring system tools (e.g. lychee) may fail"
+fi
+
Relevance

⭐⭐ Medium

Protected-path review warnings were “undetermined” previously; no clear enforcement history for
scripts/ specifically.

PR-#59
PR-#29

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance checklist designates scripts/ as a protected path; the diff shows modifications to
multiple scripts/*.sh files, so this PR must be treated as requiring human review and not
auto-approval.

scripts/post-code.sh[273-299]
scripts/post-fix.sh[185-211]
scripts/pre-code.sh[133-159]
scripts/pre-fix.sh[113-139]
Skill: pr-review


2. Fallback can probe /scripts 🐞 Bug ☼ Reliability
Description
The fallback candidates are built as "${GITHUB_WORKSPACE:-}/scripts" and
"${GITHUB_WORKSPACE:-}/.fullsend/scripts"; if GITHUB_WORKSPACE is unset/empty this becomes the
absolute paths /scripts and /.fullsend/scripts, so the scripts may accidentally discover companions
outside the workspace. In post-code/post-fix this can result in running whatever is found there via
python3/bash under a security-sensitive token-enabled context.
Code

scripts/post-code.sh[R279-287]

+if [ ! -f "${RESOLVE_SCRIPT}" ] || [ ! -f "${INSTALL_SCRIPT}" ]; then
+  for _ws_candidate in "${GITHUB_WORKSPACE:-}/scripts" "${GITHUB_WORKSPACE:-}/.fullsend/scripts"; do
+    if [ -f "${_ws_candidate}/resolve-precommit-tools.py" ] \
+       && [ -f "${_ws_candidate}/install-precommit-tools.sh" ]; then
+      RESOLVE_SCRIPT="${_ws_candidate}/resolve-precommit-tools.py"
+      INSTALL_SCRIPT="${_ws_candidate}/install-precommit-tools.sh"
+      break
+    fi
+  done
Relevance

⭐⭐ Medium

No prior review history found about guarding empty GITHUB_WORKSPACE to avoid absolute /scripts
fallbacks.

PR-#12

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new fallback loop constructs paths by concatenating ${GITHUB_WORKSPACE:-} with /scripts and
/.fullsend/scripts, which becomes an absolute root path when the variable is empty. When those
companions are found, the scripts immediately execute them via python3/bash (and in post-fix,
python3 for process-fix-result.py), so unintended discovery can lead to unintended execution in
misconfigured environments.

scripts/post-code.sh[269-316]
scripts/post-fix.sh[181-229]
scripts/post-fix.sh[344-401]
scripts/pre-code.sh[125-175]
scripts/pre-fix.sh[103-158]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workspace fallback uses `${GITHUB_WORKSPACE:-}` which expands to an empty string when `GITHUB_WORKSPACE` is unset/empty, producing absolute fallback paths (`/scripts`, `/.fullsend/scripts`). If those exist, the scripts may pick up companion files from outside the intended workspace; if they don’t exist, it still causes confusing probing of root paths.

### Issue Context
These scripts later execute the resolved companions via `python3`/`bash`, so unintended discovery can matter even if it’s unlikely on GitHub-hosted runners.

### Fix Focus Areas
- scripts/post-code.sh[279-288]
- scripts/post-fix.sh[191-200]
- scripts/post-fix.sh[350-357]
- scripts/pre-code.sh[139-148]
- scripts/pre-fix.sh[119-128]

### Suggested fix
- Only attempt the workspace fallback when `GITHUB_WORKSPACE` is non-empty, e.g.:
 - `if [ -n "${GITHUB_WORKSPACE:-}" ]; then ... fi`
 - and use `${GITHUB_WORKSPACE}/scripts` (no `:-` inside the concatenation).
- Optionally also ensure the candidate is a directory (`[ -d "${_ws_candidate}" ]`) before checking files.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. Unsanitized ::warning:: variables 📜 Skill insight ⛨ Security
Description
The new GitHub Actions workflow commands (::warning::...) interpolate ${RESOLVE_SCRIPT} and
${INSTALL_SCRIPT} without sanitization, allowing workflow-command injection via ::, newlines, or
control characters in those values. This violates the requirement that every interpolated value in
workflow commands be sanitized individually.
Code

scripts/post-code.sh[R295-297]

+  echo "::warning::Pre-commit tool auto-install skipped: companion scripts not found"
+  echo "::warning::Expected ${RESOLVE_SCRIPT} and ${INSTALL_SCRIPT}"
+  echo "::warning::Pre-commit hooks requiring system tools (e.g. lychee) may fail"
Relevance

⭐ Low

Workflow-command sanitization suggestions were rejected previously (e.g., ::debug:: interpolation)
in PR #37.

PR-#37

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance requires all interpolated values in GitHub Actions workflow commands to be sanitized
individually. The added echo "::warning::Expected ${RESOLVE_SCRIPT} and ${INSTALL_SCRIPT}" lines
interpolate variables inside ::warning:: commands without any sanitization.

scripts/post-code.sh[295-297]
scripts/post-fix.sh[207-209]
scripts/pre-code.sh[155-157]
scripts/pre-fix.sh[135-137]
Skill: pr-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The scripts emit GitHub Actions workflow commands (e.g., `::warning::...`) while interpolating variables like `RESOLVE_SCRIPT` and `INSTALL_SCRIPT` without sanitization. GitHub Actions requires escaping/sanitizing values to prevent command injection via `::`, `%0A/%0D`, ANSI/control characters, etc.

## Issue Context
These warnings are emitted in multiple scripts and include interpolated paths derived from environment variables (e.g., `GITHUB_WORKSPACE`) and script path computations, so the interpolated values must be sanitized individually before being placed into a workflow command.

## Fix Focus Areas
- scripts/post-code.sh[293-297]
- scripts/post-fix.sh[205-210]
- scripts/pre-code.sh[153-158]
- scripts/pre-fix.sh[133-138]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread scripts/post-code.sh
Comment on lines +273 to +299
# Fallback: these companion scripts were never migrated into this repo
# during the ADR 0058 extraction, so the BASH_SOURCE-relative lookup above
# always misses. The reusable workflow's "Prepare workspace" step always
# materializes the full scripts/ directory (from fullsend's own scaffold)
# at ${GITHUB_WORKSPACE}/scripts/ (per-org) or ${GITHUB_WORKSPACE}/.fullsend/scripts/
# (per-repo). Try those paths when the BASH_SOURCE-relative lookup misses.
if [ ! -f "${RESOLVE_SCRIPT}" ] || [ ! -f "${INSTALL_SCRIPT}" ]; then
for _ws_candidate in "${GITHUB_WORKSPACE:-}/scripts" "${GITHUB_WORKSPACE:-}/.fullsend/scripts"; do
if [ -f "${_ws_candidate}/resolve-precommit-tools.py" ] \
&& [ -f "${_ws_candidate}/install-precommit-tools.sh" ]; then
RESOLVE_SCRIPT="${_ws_candidate}/resolve-precommit-tools.py"
INSTALL_SCRIPT="${_ws_candidate}/install-precommit-tools.sh"
break
fi
done
fi

# Warn instead of silently skipping when the repo needs the auto-install but
# the companions are missing everywhere — a silent skip here surfaces later
# as a confusing "Executable X not found" pre-commit failure.
if [ -f .pre-commit-config.yaml ] \
&& { [ ! -f "${RESOLVE_SCRIPT}" ] || [ ! -f "${INSTALL_SCRIPT}" ]; }; then
echo "::warning::Pre-commit tool auto-install skipped: companion scripts not found"
echo "::warning::Expected ${RESOLVE_SCRIPT} and ${INSTALL_SCRIPT}"
echo "::warning::Pre-commit hooks requiring system tools (e.g. lychee) may fail"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Protected scripts/ files modified 📜 Skill insight § Compliance

This PR modifies files under the protected governance/infrastructure path scripts/, which must not
be auto-approved and requires explicit review handling per policy. Even with justification, this
must be surfaced as a protected-path change.

Comment thread scripts/post-code.sh
Comment on lines +279 to +287
if [ ! -f "${RESOLVE_SCRIPT}" ] || [ ! -f "${INSTALL_SCRIPT}" ]; then
for _ws_candidate in "${GITHUB_WORKSPACE:-}/scripts" "${GITHUB_WORKSPACE:-}/.fullsend/scripts"; do
if [ -f "${_ws_candidate}/resolve-precommit-tools.py" ] \
&& [ -f "${_ws_candidate}/install-precommit-tools.sh" ]; then
RESOLVE_SCRIPT="${_ws_candidate}/resolve-precommit-tools.py"
INSTALL_SCRIPT="${_ws_candidate}/install-precommit-tools.sh"
break
fi
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Fallback can probe /scripts 🐞 Bug ☼ Reliability

The fallback candidates are built as "${GITHUB_WORKSPACE:-}/scripts" and
"${GITHUB_WORKSPACE:-}/.fullsend/scripts"; if GITHUB_WORKSPACE is unset/empty this becomes the
absolute paths /scripts and /.fullsend/scripts, so the scripts may accidentally discover companions
outside the workspace. In post-code/post-fix this can result in running whatever is found there via
python3/bash under a security-sensitive token-enabled context.
Agent Prompt
### Issue description
The workspace fallback uses `${GITHUB_WORKSPACE:-}` which expands to an empty string when `GITHUB_WORKSPACE` is unset/empty, producing absolute fallback paths (`/scripts`, `/.fullsend/scripts`). If those exist, the scripts may pick up companion files from outside the intended workspace; if they don’t exist, it still causes confusing probing of root paths.

### Issue Context
These scripts later execute the resolved companions via `python3`/`bash`, so unintended discovery can matter even if it’s unlikely on GitHub-hosted runners.

### Fix Focus Areas
- scripts/post-code.sh[279-288]
- scripts/post-fix.sh[191-200]
- scripts/post-fix.sh[350-357]
- scripts/pre-code.sh[139-148]
- scripts/pre-fix.sh[119-128]

### Suggested fix
- Only attempt the workspace fallback when `GITHUB_WORKSPACE` is non-empty, e.g.:
  - `if [ -n "${GITHUB_WORKSPACE:-}" ]; then ... fi`
  - and use `${GITHUB_WORKSPACE}/scripts` (no `:-` inside the concatenation).
- Optionally also ensure the candidate is a directory (`[ -d "${_ws_candidate}" ]`) before checking files.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

Comment thread scripts/post-code.sh
if [ -f .pre-commit-config.yaml ] \
&& { [ ! -f "${RESOLVE_SCRIPT}" ] || [ ! -f "${INSTALL_SCRIPT}" ]; }; then
echo "::warning::Pre-commit tool auto-install skipped: companion scripts not found"
echo "::warning::Expected ${RESOLVE_SCRIPT} and ${INSTALL_SCRIPT}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] GHA-workflow-command-injection

::warning:: messages interpolate ${RESOLVE_SCRIPT} and ${INSTALL_SCRIPT} without sanitizing for :: sequences or %0A/%0D. These paths derive from ${GITHUB_WORKSPACE} (runner-controlled) + hardcoded segments, so practical risk is negligible. Pre-existing pattern in codebase (post-code.sh:54, post-fix.sh:71,337).

Suggested fix: No immediate action required. If the team decides to remediate all call sites, apply the sanitization pattern from post-code.sh:419-423 before interpolating paths into workflow commands.

Comment thread scripts/post-code.sh
# Fallback: these companion scripts were never migrated into this repo
# during the ADR 0058 extraction, so the BASH_SOURCE-relative lookup above
# always misses. The reusable workflow's "Prepare workspace" step always
# materializes the full scripts/ directory (from fullsend's own scaffold)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] code-duplication

The 20-line fallback-and-warning block is repeated across all four scripts. This follows the established codebase convention — the pre-commit tool install block is already duplicated with explicit SYNC comments acknowledging the pattern.

Suggested fix: Consider extracting a shared helper function if the team decides to consolidate the existing duplication pattern across these scripts.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment bug Something isn't working and removed requires-manual-review Review requires human judgment labels Jul 8, 2026
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:58 PM UTC · Completed 3:09 PM UTC
Commit: 8e5ab3c · View workflow run →

@waynesun09
waynesun09 added this pull request to the merge queue Jul 8, 2026
Merged via the queue into main with commit 284bcfd Jul 8, 2026
14 checks passed
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jul 8, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 3:43 PM UTC · Completed 3:51 PM UTC
Commit: 8e5ab3c · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #41 — workspace fallback for script companions

Timeline

  1. Jul 7 17:53 UTC — PR opened as draft with first approach: fullsend postrun CLI subcommands.
  2. Jul 7 18:03 UTC — Review agent reviewed (COMMENT). Caught a medium error-handling regression: bare fullsend postrun call under set -e could convert a soft-failure into a hard-failure that blocks branch push and PR creation.
  3. Jul 8 14:56 UTC — Author replaced the entire approach with workspace-directory fallback (mirroring merged fullsend#3393). First approach abandoned per upstream review feedback.
  4. Jul 8 15:01 UTC — Qodo review flagged: (a) protected scripts/ path modification (compliance), (b) ${GITHUB_WORKSPACE:-}/scripts probes /scripts when GITHUB_WORKSPACE is empty (bug).
  5. Jul 8 15:07 UTC — Human reviewer (rh-hemartin) approved silently — no comments, Qodo finding not addressed.
  6. Jul 8 15:09 UTC — Review agent completed second review (APPROVE). Found two low observations (GHA workflow command sanitization, code duplication) — both correctly assessed as pre-existing patterns. Did not catch the GITHUB_WORKSPACE empty-string issue.
  7. Jul 8 15:41 UTC — PR merged.

What went well

  • Good re-review handling: The review agent correctly noted that all prior findings (from the fullsend postrun approach) were obsolete and re-evaluated the new approach from scratch.
  • First review was valuable: The medium error-handling finding on the original approach was a legitimate bug that the author addressed by switching approaches entirely.
  • Protected-path enforcement worked: Both Qodo and the review agent surfaced the protected-path flag, ensuring human review was required.

Review quality observations

  • Qodo caught a bug the review agent missed. The ${GITHUB_WORKSPACE:-}/scripts pattern produces /scripts (absolute root path) when GITHUB_WORKSPACE is unset/empty. Qodo flagged this; the review agent did not. The human approved without addressing it. The upstream PR (fullsend#3393) has the identical pattern. Practical risk on GHA runners is low (GITHUB_WORKSPACE is always set), but it's still a defensive-coding gap.
  • This is evidence for the broader pattern tracked in agents#46 (review agent missed vouch-check permissions caught by Qodo) and fullsend#3477 (review agent shell-safety gaps). The common thread: the review agent evaluates shell code at a higher abstraction level and misses edge cases in variable expansion and environment assumptions.

Stale issues

Proposals filed

fullsend-ai-coder Bot added a commit that referenced this pull request Aug 20, 2026
…yword

- Extend GitLab closing-keyword regex to match comma-separated issue
  lists (e.g., "Closes #41, #42") by adding a repeating group for
  preceding issue refs separated by commas
- Remove implement(?:s|ed|ing)? from keyword list — GitLab only
  recognizes close/fix/resolve variants as closing keywords
- Update stale block comment describing the old search strategy
- Update SKILL.md to replace stale gh pr list --search pattern with
  closedByPullRequestsReferences GraphQL query

Addresses review feedback on #887
maruiz93 pushed a commit that referenced this pull request Aug 21, 2026
…yword

- Extend GitLab closing-keyword regex to match comma-separated issue
  lists (e.g., "Closes #41, #42") by adding a repeating group for
  preceding issue refs separated by commas
- Remove implement(?:s|ed|ing)? from keyword list — GitLab only
  recognizes close/fix/resolve variants as closing keywords
- Update stale block comment describing the old search strategy
- Update SKILL.md to replace stale gh pr list --search pattern with
  closedByPullRequestsReferences GraphQL query

Addresses review feedback on #887
maruiz93 added a commit that referenced this pull request Aug 21, 2026
Extend the closing-keyword regex separator to match space-separated
(Closes #41 #42) and and-joined (Closes #41 and #42) issue lists in
addition to comma-separated ones.

Signed-off-by: Marta Anon <manon@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working requires-manual-review Review requires human judgment

Projects

None yet

2 participants