Skip to content

fix(dev-lead): handle SonarQube Quality Gate failures (issue #279) - #280

Merged
don-petry merged 2 commits into
mainfrom
fix/dev-lead-sonarqube-279
May 19, 2026
Merged

fix(dev-lead): handle SonarQube Quality Gate failures (issue #279)#280
don-petry merged 2 commits into
mainfrom
fix/dev-lead-sonarqube-279

Conversation

@don-petry

Copy link
Copy Markdown
Collaborator

Summary

Fixes three compounding bugs that prevented the dev-lead agent from ever addressing a SonarQube Quality Gate failure (observed on PR #276, documented in issue #279).

  • Fix 1 — ci-relay fallback for GitHub App check_runs: check_run.pull_requests is empty for App-sourced checks (SonarCloud, external CodeQL gates, etc.), causing the relay to silently skip. Now falls back to GET /commits/{sha}/pulls API, with fork protection via head.repo.full_name.
  • Fix 2 — fix-bot-comment SonarQube guidance: SonarQube comments report hotspot counts without file/line references, leaving the agent with nothing actionable. Added a SonarQube-specific section instructing the agent to diff the PR and scan for known hotspot patterns (curl|bash, hardcoded secrets, eval, HTTP downloads).
  • Fix 3 — collect_logs external quality gate fallback: For check_runs whose details_url isn't a GitHub Actions URL (no /runs/ segment), collect_logs now falls back to gh pr diff output. fix-ci.md gains an "External quality gate" guidance section keyed on the new log header.

Test plan

  • tests/dev-lead/unit/test_fix_ci.bats — two new tests covering Fix 3:
    • external quality gate (non-GHA details_url) → pr diff in logs, script exits 0
    • GHA details_urlrun view used, pr diff not called
  • New fixture check_run_failure_sonarcloud.json documents the GitHub App check_run case for ci-relay
  • Pre-existing test failures (12, 13, 16 in test_fix_ci.bats) confirmed unchanged from main — not introduced by this PR
  • E2E: push a PR with a curl | bash step and verify the full fix-ci path fires and removes it

Closes #279

🤖 Generated with Claude Code

…ternal gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 18, 2026 23:28
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@don-petry has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 59 minutes and 22 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 87c89f67-fa17-44f2-baa9-dcf5d1174b09

📥 Commits

Reviewing files that changed from the base of the PR and between fd01c7e and 7dde470.

📒 Files selected for processing (9)
  • .github/workflows/dev-lead.yml
  • prompts/dev-lead/fix-bot-comment.md
  • prompts/dev-lead/fix-ci.md
  • scripts/dev-lead-ci-relay.sh
  • scripts/dev-lead-fix-ci.sh
  • tests/dev-lead/fixtures/events/check_run_failure_no_pr.json
  • tests/dev-lead/fixtures/events/check_run_failure_sonarcloud.json
  • tests/dev-lead/unit/test_ci_relay.bats
  • tests/dev-lead/unit/test_fix_ci.bats
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/dev-lead-sonarqube-279

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — human-pr (no-changes)

No changes were needed for this PR.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-bot-comment (no-changes)

Engine ran but made no changes.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces support for handling external quality gate failures, such as SonarCloud, by providing the PR diff to the AI agent when standard GitHub Actions logs are unavailable. The changes include updated prompt instructions, modifications to the dev-lead-fix-ci.sh script to fetch diffs via the GitHub CLI, and new test fixtures. Feedback from the review highlights a significant discrepancy where the ci-relay implementation mentioned in the PR description is missing from the patches. Additionally, the reviewer pointed out that the new unit tests are ineffective as they do not correctly verify the content of the collected diffs, and suggested increasing the line limit for captured diffs to provide better context for the agent.

Comment thread tests/dev-lead/fixtures/events/check_run_failure_sonarcloud.json
Comment thread scripts/dev-lead-fix-ci.sh Outdated
Comment thread tests/dev-lead/unit/test_fix_ci.bats Outdated
Comment thread tests/dev-lead/unit/test_fix_ci.bats Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes three compounding bugs that prevented the dev-lead agent from handling SonarQube Quality Gate failures: the ci-relay job silently skipping GitHub App check_runs (empty pull_requests), the fix-bot-comment flow lacking guidance for SonarQube comments that omit file/line refs, and collect_logs producing empty context for non-GitHub-Actions details_url. The patch adds a commits-to-pulls API fallback (with fork protection), enriches the two prompts with SonarQube-specific hotspot guidance, and falls back to gh pr diff for external quality gates.

Changes:

  • ci-relay falls back to GET /commits/{sha}/pulls when check_run.pull_requests is empty, skipping forks via head.repo.full_name.
  • collect_logs emits a labeled # External quality gate header plus PR diff when no GHA run ID can be extracted; fix-ci.md and fix-bot-comment.md add hotspot-pattern guidance.
  • Two new bats tests cover the external-gate path; new check_run_failure_sonarcloud.json fixture documents the App check_run shape.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
.github/workflows/dev-lead.yml Adds commits-to-pulls fallback + fork check to ci-relay.
scripts/dev-lead-fix-ci.sh collect_logs now emits a labeled header and gh pr diff when no run ID is found.
prompts/dev-lead/fix-ci.md Documents the new "External quality gate" log header and hotspot patterns.
prompts/dev-lead/fix-bot-comment.md Adds SonarCloud-specific guidance for comments without file/line refs.
tests/dev-lead/unit/test_fix_ci.bats Two new tests for external vs. GHA details_url handling.
tests/dev-lead/fixtures/events/check_run_failure_sonarcloud.json New fixture documenting the GitHub App check_run shape.
tests/dev-lead/fixtures/events/check_run_failure_no_pr.json Updates note to reflect the new commits-to-pulls fallback behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/dev-lead.yml Outdated
Comment thread tests/dev-lead/fixtures/events/check_run_failure_sonarcloud.json
Comment thread tests/dev-lead/unit/test_fix_ci.bats
@don-petry

Copy link
Copy Markdown
Collaborator Author

No description provided.

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@don-petry

Copy link
Copy Markdown
Collaborator Author

No description provided.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-bot-comment (no-changes)

Engine ran but made no changes.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (no-changes)

No changes were needed for the open review threads.

@don-petry
don-petry merged commit 0023f4e into main May 19, 2026
20 checks passed
@don-petry
don-petry deleted the fix/dev-lead-sonarqube-279 branch May 19, 2026 01:32
don-petry added a commit that referenced this pull request Jun 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 21, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 23, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 23, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 23, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 23, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 25, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 25, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 25, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 25, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Jun 25, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 2, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
)

* fix(dev-lead): handle SonarQube failures — relay, hotspot context, external gate logs

Three bugs prevented the dev-lead agent from ever fixing a SonarQube
Quality Gate failure (observed on PR #276, tracked in issue #279):

1. ci-relay skipped GitHub App check_runs (SonarCloud, CodeQL, etc.)
   because check_run.pull_requests is empty for App-sourced checks.
   Fix: fall back to GET /commits/{sha}/pulls when pull_requests is [],
   including fork protection using head.repo.full_name from that API.

2. fix-bot-comment had no guidance for SonarQube comments that list
   hotspot counts with no file/line references, leaving the agent with
   nothing actionable. Fix: add a SonarQube-specific section instructing
   the agent to diff the PR and scan for known hotspot patterns
   (curl|bash, hardcoded secrets, eval, HTTP downloads).

3. collect_logs() returned a bare "No run logs available" for external
   quality gates (details_url with no /runs/ segment), giving the agent
   empty context. Fix: fall back to gh pr diff output so the agent can
   identify what the gate flagged. fix-ci.md also gains an "External
   quality gate" guidance section matching the new log header.

Tests: two new fix-ci bats tests covering the external quality gate
collect_logs path (non-GHA URL → pr diff; GHA URL → run view).
New fixture: check_run_failure_sonarcloud.json for ci-relay fallback.

Closes #279

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(dev-lead): address review feedback on PR #280

- Extract ci-relay PR-lookup logic into scripts/dev-lead-ci-relay.sh so
  it can be unit-tested with bats; YAML step now calls the script.
  Includes the open-PR filter (select(.state=="open")) to prevent
  relaying against merged PRs that share the same commit SHA (Copilot).

- Increase PR diff capture from LOG_MAX_LINES (200) to 1000 lines for
  the external quality gate fallback — diffs typically exceed 200 lines
  and hotspots may appear anywhere (Gemini).

- Replace ineffective test 17 with a prompt-file inspection: extract the
  rendered prompt path from dry-run output, then grep for the
  "External quality gate" header and diff content (Gemini/Copilot).

- Replace ineffective test 18 with sentinel files: the gh stub touches
  .ran_run_view or .ran_pr_diff; test asserts run view was called and
  pr diff was not (Gemini/Copilot).

- Add tests/dev-lead/unit/test_ci_relay.bats: 7 unit tests covering
  the new ci-relay script — GHA path, App fallback, fork rejection,
  no-PRs, merged-only PRs, and API failure (Copilot).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Gemini CLI <gemini-cli@example.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: dev-lead fails to handle SonarQube check failures (ci-relay skips GitHub App check_runs)

2 participants