Skip to content

fix(#7218): ephemeral per-job OpenShell gateway on GitLab runners - #7244

Merged
ggallen merged 3 commits into
mainfrom
agent/7218-ephemeral-openshell-gateway
Sep 12, 2026
Merged

fix(#7218): ephemeral per-job OpenShell gateway on GitLab runners#7244
ggallen merged 3 commits into
mainfrom
agent/7218-ephemeral-openshell-gateway

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Summary

GitLab runner VMs no longer keep a long-lived OpenShell gateway. Each job now gets a fresh, version-matched gateway with an empty profile registry (GitHub Actions parity), and URL-resolved profile import no longer trusts a stale os.TempDir() cache against that empty registry.

Related Issue

Addresses the silent policy_denied failure from a stale _provider_vertex_ai profile (job 60629238): openshell provider profile import is a no-op on "already exists", so a gateway that outlived its pin never picked up **/claude.exe.

Changes

  • Per-job gateway (GCP + OpenShift): prepare.sh reaps leftover openshell.managed / openshell-* containers, installs the OpenShell version from the job image when it differs from the host, and starts the systemd user unit against a wiped ~/.local/state/openshell/{gateway,tls} store. cleanup.sh always tears the gateway down (even if the job id is missing). setup.sh no longer enables the unit, so a reboot cannot resurrect a long-lived daemon.
  • Cache-coherent import: new sandbox.ImportProfileVerified (ForgetProfileCache → import → ProfileExists → retry) is used by the generic/Vertex import path in run.go and by ensureOpenAIProfile.
  • Shared helpers live in executor/gateway.sh (copied by both create-*-vm.sh paths). Existing VMs pick this up by re-running setup.sh.

Testing

  • go test for ImportProfileVerified (stale-cache-vs-empty-gateway, retry success, import/list errors) and TestEnsureOpenAIProfile* / TestRunAgent_* in internal/cli
  • hack/gitlab-runner-vm/executor/gateway_test.sh (wipe, orphan reaping, no systemctl enable, version-mismatch install from the release tag)
  • Existing prepare_validation_test.sh and lib_test.sh

Checklist

  • PR title follows Conventional Commits (fix(#7218): …)
  • Autonomous agent commit (no DCO trailer)
  • Tests added/updated for the import path and gateway lifecycle

Closes #7218

Post-script verification

  • Branch is not main/master (agent/7218-ephemeral-openshell-gateway)
  • Secret scan passed (gitleaks — 773149d0e4f04f7ee5d831acbcf3b083baf9aa2b..HEAD)
  • PR body secret scan passed (gitleaks — no-git)

GitLab runner VMs kept one long-lived systemd --user gateway across
every job. The registry went stale (profile import is a no-op on
"already exists"), the OpenShell version drifted from the repo pin,
and leaked sandboxes pinned old policy. GitHub Actions does not have
this: each job installs a fresh, version-matched gateway.

prepare.sh now reaps leftover gateway/sandbox containers, installs
the OpenShell version the job image pins, and starts a gateway
against a wiped store (~/.local/state/openshell/{gateway,tls}).
cleanup.sh tears it down. setup.sh no longer enables the unit.

ImportProfileVerified applies the OpenAI ForgetProfileCache ->
import -> ProfileExists -> retry pattern to the generic/Vertex
import path so a stale os.TempDir() cache cannot skip the send
against a fresh gateway.

Closes #7218
@fullsend-ai-coder
fullsend-ai-coder Bot requested a review from a team as a code owner September 11, 2026 19:30
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Triggers review agent dispatch label Sep 11, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 11, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:32 PM UTC · Completed 7:58 PM UTC

Commit: 3e5f46d · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $9.23

@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/sandbox/sandbox.go 88.23% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 11, 2026

Copy link
Copy Markdown

Looks good to me

Previous run

Review

Findings

Medium

  • [logic-error] hack/gitlab-runner-vm/executor/gateway.sh:24gateway.sh resolves openshell-version.sh relative to BASH_SOURCE as ../.github/scripts (VM source-tree layout) or ../../../.github/scripts (repo checkout layout). At real per-job runtime, gitlab-runner executes $HOME/gitlab-runner-executor/prepare.sh, which sources the copy of gateway.sh that setup.sh's install_executor flattens into EXECUTOR_DIR=$HOME/gitlab-runner-executor (only job_id.sh/prepare.sh/run.sh/cleanup.sh/gateway.sh — no .github/scripts sibling is copied or symlinked there). From that flattened layout, gateway.sh's two relative guesses resolve to $HOME/.github/scripts/openshell-version.sh and a path outside $HOME; the actual provisioned pin lives at $HOME/gitlab-runner-vm/.github/scripts/openshell-version.sh and is never consulted, so OPENSHELL_VERSION/OPENSHELL_SHA are unset in the per-job process. This doesn't fail every job — ensure_job_openshell_gateway only reads the pin inside the openshell_versions_differ branch, so the common case (job image version == host CLI version) still starts the gateway fine. But whenever a job's image reports a different OpenShell version than whatever is currently baked into the host (exactly the version-drift scenario issue Ephemeral per-job OpenShell gateway on GitLab runners (GitHub-parity; supersedes profile/version/sandbox staleness) #7218 was filed to fix), the check [ "${job_ver}" != "${OPENSHELL_VERSION:-}" ] is always true with OPENSHELL_VERSION unset, so prepare.sh fails outright with "this host only trusts the Renovate-pinned <unset>" instead of installing the job-pinned version. hack/gitlab-runner-vm/executor/gateway_test.sh doesn't catch this because it sources gateway.sh from hack/gitlab-runner-vm/executor/ (the repo checkout layout), where the second fallback path happens to resolve — masking the bug that only manifests once install_executor has flattened the scripts onto a real runner VM.
    Remediation: Have install_executor also copy (or symlink) .github/scripts/openshell-version.sh into EXECUTOR_DIR (or a fixed subdirectory under it), and resolve that path first from gateway.sh. Add a regression test that copies gateway.sh into a temp directory laid out like the flattened EXECUTOR_DIR (no .github/scripts reachable via any relative guess) and asserts OPENSHELL_VERSION/OPENSHELL_SHA are still non-empty after sourcing it.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (2)

Review

Findings

High

  • [injection-pattern] hack/gitlab-runner-vm/executor/gateway.sh:191install_openshell_at_version pipes curl straight into sh, fetching https://raw.githubusercontent.com/NVIDIA/OpenShell/v<ver>/install.sh where <ver> is a mutable release tag (not a commit SHA) parsed from the job image's own openshell --version output, on prepare.sh's per-job hot path. The existing VM-provision installer (.github/scripts/install-openshell.sh) is deliberately SHA-pinned to avoid trusting a mutable tag; this PR adds a second, job-triggered curl|sh path that drops that pin. ver is regex-validated (^[0-9]+\.[0-9]+\.[0-9]+$), so this isn't shell/URL-metacharacter injection — but any job that can set image: (RUNNER_ACCESS_LEVEL defaults to not_protected, i.e. any branch of any project registered on the runner) can make the host download and execute NVIDIA's installer for an arbitrary/retagged/older release, bypassing the maintainers' commit-SHA allowlist.
    Remediation: Do not let the job image's self-reported version pick the host installer. On mismatch, either fail the job / require an operator-approved upgrade, or resolve the pin to a commit SHA (a version→SHA allowlist, or the same mechanism as .github/scripts/openshell-version.sh) before fetching install.sh. At minimum, refuse downgrades relative to the host's current version.

Medium

  • [permission-expansion] hack/gitlab-runner-vm/executor/gateway.sh:44job_image_openshell_version runs the job's own image on the host once per job (podman run --rm --entrypoint openshell -- "${image}" --version) with none of the hardening flags prepare.sh applies to the real job container later (--cap-drop=ALL, --security-opt=no-new-privileges, --pids-limit). A crafted openshell entrypoint gets one weaker-isolation execution before any of the job's normal sandboxing applies, and its stdout drives the install-tag selection in the finding above.
    Remediation: Avoid executing the job image to learn its pin (podman inspect/label metadata, or podman create + podman cp a version file without starting the entrypoint). If a run is unavoidable, apply the same hardening flags used for the real job container.

  • [logic-error] hack/gitlab-runner-vm/executor/gateway.sh:44job_image_openshell_version discards both stderr and podman's exit status (2>/dev/null || true), so any probe failure (missing entrypoint, OCI hook error, transient podman/registry error) is indistinguishable from "image genuinely has no OpenShell CLI" and yields the same empty job_ver. ensure_job_openshell_gateway then silently keeps the host's (potentially stale) install. Keeping the host version when an image legitimately lacks a CLI is intentional and tested, but folding hard probe errors into that same path is fail-open on exactly the version-skew class of bug issue Ephemeral per-job OpenShell gateway on GitLab runners (GitHub-parity; supersedes profile/version/sandbox staleness) #7218 was filed to close.
    Remediation: Capture podman's exit status separately from a successful-but-unparseable version string. On a hard podman error, fail prepare.sh (or retry) instead of silently falling through to the host version; only treat a clean run with no semver in the output as "image has no CLI, keep host."

Low

  • [logic-error] hack/gitlab-runner-vm/setup.sh:635configure_per_job_gateway's seed start is systemctl --user start openshell-gateway.service || true; a failure is silently swallowed, and verify() only checks the unit isn't left enabled/active — trivially true whether the seed start succeeded or never ran. In practice this delays detection to the first real job rather than breaking a runtime invariant, since start_fresh_openshell_gateway always wipes and restarts the unit per job regardless.
    Remediation: Wait for openshell-gateway.service to become active (reuse wait_for_openshell_gateway) before stopping/disabling it in the seed step, and fail setup() if it does not, as an explicit smoke test.

  • [error-handling] internal/sandbox/sandbox.go:380ImportProfileVerified's retry path folds a genuine list-profiles error into "provider profile %q is not on the gateway after import (err=%v)" using %v instead of %w, unlike the first ProfileExists check a few lines above which correctly distinguishes a list error from a confirmed-absent profile. The job fails either way, but the retry path loses errors.Is/As unwrapping and mislabels a listing failure as "missing profile."
    Remediation: Mirror the first check's structure for the retry: check the error first (%w-wrapped "checking provider profile"), then check absence separately.

  • [fail-open] hack/gitlab-runner-vm/executor/gateway.sh:205 — After a successful curl|sh install, install_openshell_at_version only runs systemctl --user disable ... || true (no stop first, and disable failure ignored). NVIDIA's RPM %post may enable --now the unit. The leftover-until-next-job risk is largely mitigated since cleanup.sh unconditionally tears the gateway down even when prepare.sh fails, but a narrow window remains if disable fails and the VM reboots before cleanup/the next prepare runs.
    Remediation: stop then disable the unit (reuse stop_openshell_gateway) and fail install_openshell_at_version if disable does not succeed, rather than || true.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 8:00 PM UTC · Completed 8:15 PM UTC

Commit: 3e5f46d · View workflow run →

Runtime: claude · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $2.60

Address the security-review findings on the ephemeral OpenShell gateway:

- gateway.sh: only install the OpenShell version a job image reports when
  it matches the Renovate-tracked pin (.github/scripts/openshell-version.sh),
  and fetch install.sh from that pin's commit SHA instead of a job-supplied
  release tag. A job could otherwise steer the host installer to an
  arbitrary/retagged/older NVIDIA/OpenShell release, bypassing the
  commit-SHA allowlist install-openshell.sh already enforces (High).
- gateway.sh: harden the podman run that probes a job image's OpenShell
  version with the same flags prepare.sh applies to the real job container
  (--cap-drop=ALL, --security-opt=no-new-privileges, --pids-limit), and
  distinguish a hard podman error from a clean "image has no CLI" run
  instead of silently keeping the host version on either (Medium x2).
- gateway.sh: stop before disabling the gateway unit after install, and
  fail if disable does not succeed, instead of swallowing the failure (Low).
- setup.sh: wait for the seed gateway start to become active (reusing
  wait_for_openshell_gateway) and fail setup() if it does not, instead of
  a verify() check that is trivially true either way (Low).
- sandbox.go: ImportProfileVerified's retry path now mirrors the first
  ProfileExists check - a listing error is wrapped and returned directly
  instead of being folded into a generic "not on the gateway" message (Low).

Addresses #7244
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (bot-triggered)

Addressed all 6 review findings on PR #7244 (1 High, 2 Medium, 3 Low), all in hack/gitlab-runner-vm/executor/gateway.sh, hack/gitlab-runner-vm/setup.sh, and internal/sandbox/sandbox.go. The core fix ties job-image OpenShell installs to the Renovate-tracked commit-SHA pin instead of trusting a job-supplied version tag, hardens the version-probe podman run, distinguishes hard probe errors from a legitimate no-CLI image, makes the gateway-unit disable after install fail-closed, makes setup.sh's seed gateway start an explicit smoke test, and fixes an error-wrapping bug in ImportProfileVerified's retry path. Updated/added shell tests in gateway_test.sh and a Go test in import_verified_test.go to cover the new behavior; all existing gateway_test.sh, lib_test.sh, prepare_validation_test.sh, and the relevant Go test suites (internal/sandbox, internal/cli) pass.

Fixed (6):

  1. [HIGH][injection-pattern] gateway.sh:191 install_openshell_at_version pipes curl into sh from a mutable job-supplied release tag, dropping the commit-SHA allowlist install-openshell.sh enforces (hack/gitlab-runner-vm/executor/gateway.sh): gateway.sh now sources the Renovate-tracked pin (.github/scripts/openshell-version.sh) and ensure_job_openshell_gateway refuses to install any job-reported OpenShell version that does not exactly match OPENSHELL_VERSION, failing the job instead. When it does match, install_openshell_at_version fetches install.sh from the pinned OPENSHELL_SHA commit, never from a job-chosen vX.Y.Z tag.
  2. [MEDIUM][permission-expansion] gateway.sh:44 job_image_openshell_version runs the job image's entrypoint without the hardening flags prepare.sh applies to the real job container (hack/gitlab-runner-vm/executor/gateway.sh): Added --cap-drop=ALL, --security-opt=no-new-privileges, and --pids-limit 4096 to the podman run that probes the job image's OpenShell version, matching the real job container's hardening in prepare.sh.
  3. [MEDIUM][logic-error] gateway.sh:44 job_image_openshell_version discards podman's exit status, conflating hard probe errors with a legitimate 'image has no CLI' (hack/gitlab-runner-vm/executor/gateway.sh): job_image_openshell_version now captures podman's exit status separately from its output. A nonzero exit is treated as a hard error and returned (propagated by ensure_job_openshell_gateway, which fails prepare.sh); only a clean run (exit 0) with no parseable semver falls back to 'keep the host version'.
  4. [LOW][logic-error] setup.sh:635 configure_per_job_gateway's seed start failure is silently swallowed and verify() cannot detect it (hack/gitlab-runner-vm/setup.sh): setup.sh sources executor/gateway.sh for wait_for_openshell_gateway and configure_per_job_gateway now waits for the seed start to become active, calling fail() (exit 1) if it does not, before stopping/disabling the unit.
  5. [LOW][error-handling] sandbox.go:380 ImportProfileVerified's retry path folds a genuine list error into the 'not on the gateway' message with %v instead of %w (internal/sandbox/sandbox.go): Mirrored the first ProfileExists check's structure: the retry's list error is now checked first and returned wrapped ('checking provider profile %q: %w'), separate from the 'not on the gateway after import' case for a confirmed absence. Added TestImportProfileVerified_RetryListError to cover it.
  6. [LOW][fail-open] gateway.sh:205 install_openshell_at_version only disables the gateway unit post-install with '|| true' and never stops it first (hack/gitlab-runner-vm/executor/gateway.sh): install_openshell_at_version now stops the unit before disabling it, and fails (returns 1) if the disable does not succeed, instead of silently ignoring the failure.

Tests: passed

Decision points
  • Enforce the job-vs-pin version check in ensure_job_openshell_gateway rather than inside install_openshell_at_version (alternatives: Duplicate the OPENSHELL_VERSION/OPENSHELL_SHA match check inside install_openshell_at_version, Check the match once at the decision point (ensure_job_openshell_gateway) and keep install_openshell_at_version a lower-level installer that trusts its caller; rationale: ensure_job_openshell_gateway is the only caller and already computes job_ver/host_ver; keeping the trust decision there avoids duplicating the check and keeps the diff minimal.)
  • Left job_image_openshell_version's 'image legitimately has no CLI' fallback (empty output on a clean exit) intact, per the finding's own remediation text, even though it also changes 'missing entrypoint' cases (which fail with a nonzero podman exit) to now hard-fail instead of falling back to the host version (alternatives: Treat any nonzero podman exit as 'no CLI, keep host' to avoid behavior change, Fail hard on any nonzero exit, per the finding's explicit remediation; rationale: The finding explicitly asks to fail prepare.sh on a hard podman error and only treat a clean run with unparseable output as 'no CLI' — implemented exactly as specified.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 11, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:17 PM UTC · Completed 8:35 PM UTC

Commit: a9e29aa · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $4.59

@fullsend-ai-review

Copy link
Copy Markdown

Risk Assessment: moderate (2/5)

Details

Sizeable but non-protected, non-security-sensitive, dependency-free change to a high-churn CLI/sandbox area with modest test coverage, an unflagged behavioral change to existing gateway/import logic, and an issue whose acceptance criteria are claimed but not independently confirmed by the issue checkboxes -- standard careful review is warranted but nothing crosses into elevated-risk territory.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 8:37 PM UTC · Completed 8:47 PM UTC

Commit: a9e29aa · View workflow run →

Runtime: claude · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $1.69

Addresses review feedback on PR #7244 (logic-error, gateway.sh:24).

gateway.sh's two relative guesses for .github/scripts/openshell-version.sh
(VM source-tree layout and repo checkout layout) never match the layout
prepare.sh/cleanup.sh actually source it from at per-job runtime: setup.sh's
install_executor flattens job_id.sh/prepare.sh/run.sh/cleanup.sh/gateway.sh
into EXECUTOR_DIR with no .github/scripts sibling. OPENSHELL_VERSION/
OPENSHELL_SHA end up unset there, so ensure_job_openshell_gateway's version-
mismatch branch fails every job whose image reports a different OpenShell
version than the host, exactly the version-drift scenario #7218 was filed
to fix.

- install_executor now also copies openshell-version.sh into
  EXECUTOR_DIR/.github/scripts/, alongside the flattened scripts.
- gateway.sh tries that flattened-layout path first, before falling back to
  the VM and repo-checkout guesses.
- Added a regression test that sources gateway.sh from an isolated temp dir
  laid out like the flattened EXECUTOR_DIR (no .github/scripts reachable via
  the other two guesses) and asserts the pin resolves from that layout
  specifically, using sentinel values so the assertion can't pass via
  environment leakage from the test's own earlier sourcing of gateway.sh.

Addresses #7244
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 2 (bot-triggered)

Fixed the one active Medium finding: gateway.sh now finds openshell-version.sh from the flattened EXECUTOR_DIR layout that prepare.sh/cleanup.sh actually run from in production, via install_executor shipping the pin file alongside the flattened scripts and a new first-priority relative guess in gateway.sh. Added a regression test reproducing the flattened layout in isolation. All findings from the prior review iteration (inside the

Details 'Previous run' block) were already addressed in an earlier commit and were not re-litigated per the fix-review procedure.

Fixed (1):

  1. gateway.sh:24 — version-pin path guesses never resolve once install_executor flattens scripts into EXECUTOR_DIR, so OPENSHELL_VERSION/SHA are unset at per-job runtime (hack/gitlab-runner-vm/setup.sh, hack/gitlab-runner-vm/executor/gateway.sh, hack/gitlab-runner-vm/executor/gateway_test.sh): install_executor now also copies .github/scripts/openshell-version.sh into EXECUTOR_DIR/.github/scripts/ alongside the flattened executor scripts; gateway.sh tries that flattened-layout path first before its existing VM-layout and repo-checkout fallbacks. Added a regression test in gateway_test.sh that sources gateway.sh from an isolated temp dir laid out exactly like the flattened EXECUTOR_DIR (with the other two relative guesses verified unreachable) and asserts OPENSHELL_VERSION/OPENSHELL_SHA resolve to sentinel values unique to that fixture, so the test can't pass via environment leakage from the file's own earlier sourcing of gateway.sh.

Tests: passed

Decision points
  • Chose to ship the version-pin file into the flattened EXECUTOR_DIR rather than the reviewer's alternative suggestion (alternatives: Symlink .github/scripts/openshell-version.sh into EXECUTOR_DIR instead of copying, Copy the resolved pin file into EXECUTOR_DIR/.github/scripts/ (chosen); rationale: A symlink into the source checkout would dangle if the VM's checkout is ever removed/rotated after setup, since EXECUTOR_DIR and the source tree are provisioned independently; a plain copy is self-contained and matches how install_executor already copies (not symlinks) the other executor scripts.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 11, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:49 PM UTC · Completed 9:01 PM UTC

Commit: 81fb8b0 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $2.59

@fullsend-ai-review fullsend-ai-review Bot removed the risk/moderate PR risk: moderate label Sep 11, 2026
@fullsend-ai-review
fullsend-ai-review Bot dismissed stale reviews from themself September 11, 2026 21:01

Superseded by updated review

@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Sep 11, 2026
@ggallen
ggallen added this pull request to the merge queue Sep 12, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 12, 2026
@ggallen
ggallen added this pull request to the merge queue Sep 12, 2026
Merged via the queue into main with commit ce5f805 Sep 12, 2026
69 of 74 checks passed
@ggallen
ggallen deleted the agent/7218-ephemeral-openshell-gateway branch September 12, 2026 02:29
@fullsend-ai-retro

fullsend-ai-retro Bot commented Sep 12, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 2:31 AM UTC · Completed 2:44 AM UTC

Commit: 81fb8b0 · View workflow run →

Runtime: claude · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $2.31

@fullsend-ai-retro

Copy link
Copy Markdown

PR #7244 (ephemeral per-job OpenShell gateway on GitLab runners, closing #7218) is a healthy example of the pipeline working as designed. The code agent correctly diagnosed a subtle root cause (long-lived gateway + no-op profile import + version drift) and the automated review agent caught a real High-severity security issue in round 1 (installer piping a job-controlled version tag into curl | sh, bypassing the commit-SHA pin allowlist) plus 2 Medium/3 Low issues, all fixed by the fix agent within ~15 minutes. Round 1's own security fix introduced a functional regression (relative-path lookup for openshell-version.sh didn't survive the executor-flattening step, which would have broken exactly the version-drift scenario #7218 targeted); round 2 review caught this and the fix agent resolved it with a regression test in ~10 minutes, and round 3 approved cleanly. The single human reviewer approved without comments after the bot's approval, which reflects a satisfactory review, not a rubber stamp — the bot review had already surfaced and resolved the substantive issues. Before this PR's successful run, 4 earlier code-agent attempts on issue #7218 failed or no-op'd. Two (run 34516625497, 34524179415) burned their full ~35-minute budget on exploration/test-debugging and were killed mid-commit, discarding all edits — this exactly matches fullsend-ai/agents#1259 and fullsend-ai/agents#1256, both closed as completed on 2026-09-11 (the day before/of these runs), so no new proposal is filed; this PR's data corroborates those fixes were needed. Related still-open issues fullsend-ai/agents#773, #990, #821, #1071, #207 track the broader 'commit early / checkpoint before timeout' discipline — worth keeping in view but already tracked, so not duplicated here. A 4th attempt (34548284669) failed due to GitHub App token lifetime issues, matching #7231/#7234, both closed/merged 2026-09-11 shortly before the successful 5th attempt — good corroborating evidence those fixes work. One new, narrow proposal is filed below: document the EXECUTOR_DIR script-flattening behavior in hack/gitlab-runner-vm so future scripts added to that directory don't repeat the exact relative-path mistake that cost this PR an extra review/fix round (mitigated in this PR only by a regression test, not by upfront documentation).

Proposals filed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-merge All reviewers approved — ready to merge ready-for-review Triggers review agent dispatch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ephemeral per-job OpenShell gateway on GitLab runners (GitHub-parity; supersedes profile/version/sandbox staleness)

2 participants