Skip to content

Add PR Buildkite Detective and Beats Detective Workflows - #49589

Merged
strawgate merged 10 commits into
mainfrom
bill/test-buildkite-detective
Mar 23, 2026
Merged

strawgate merged 10 commits into
mainfrom
bill/test-buildkite-detective

Conversation

@strawgate

@strawgate strawgate commented Mar 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Switches PR Buildkite Detective from a pull_request-based polling loop to a check_run event trigger, which fires immediately when Buildkite reports a failure and has the correct PR context in the event payload (no SHA lookup required)
  • Adds four scheduled code quality sweeper workflows that run weekly and file GitHub issues with confirmed findings

PR Buildkite Detective changes

The previous implementation polled on pull_request events and used github.sha to look up the associated Buildkite build. This was unreliable because github.sha on a pull_request event refers to the merge commit, not the head commit that Buildkite ran against. The new implementation triggers on check_run: completed from the Buildkite GitHub App, which includes the PR list directly in the event payload.

Sweeper workflows

Four weekly sweepers that audit different areas of the Beats codebase:

Workflow Schedule Focus
sweep-filestream-registry.yml Monday Registry correctness: cursor loss, identity mismatches, cleanup races
sweep-libbeat-pipeline-lifecycle.yml Wednesday Pipeline shutdown: channel ordering, ACK callback blocking, goroutine leaks
sweep-otel-beatreceiver-isolation.yml Thursday OTel receiver isolation: global state races when multiple receivers run concurrently
sweep-streaming-input-resilience.yml Friday Streaming input resilience: cursor corruption, tight retry loops, error responses published as events

Each sweeper uses a consistent investigation strategy:

  • Leads with the component's design guarantee so agents reason against an invariant, not a pattern list
  • Instructs agents to use git log to distinguish regressions from original omissions — a handler removed in a refactor is higher priority than one that was never added
  • Frames the reproduction as the argument: if you cannot write a failing test, the investigation is not done
  • Explicitly tells agents that one confirmed, reproducible bug is worth more than ten suspicious patterns described from reading alone
  • Encourages agents to find failure modes not described in the prompt

A sweep-packetbeat-parser-safety.yml was drafted and removed: that sweeper would find crash bugs from malformed network input, which are better routed through a private security process than filed as public issues.

Test plan

  • Verify check_run trigger fires on next Buildkite failure on a PR
  • Verify sweeper workflows appear in the Actions tab and can be triggered manually via workflow_dispatch
  • Trigger one sweeper manually and confirm it files an issue with the expected prefix

…olation for testing)

Adds a workflow that triggers on pull_request synchronize, waits up to
15 minutes for a Buildkite failure to appear, then invokes the
gh-aw-estc-pr-buildkite-detective to analyze the failure and comment
on the PR with a diagnosis and fix recommendation.

The new test in matchers_test.go intentionally violates testifylint
(assert.Equal(t, "", ...) instead of assert.Empty) and errcheck
(unchecked SetString errors) to trigger a Buildkite lint failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@strawgate
strawgate requested review from a team as code owners March 20, 2026 18:52
@botelastic botelastic Bot added the needs_team Indicates that the issue/PR needs a Team:* label label Mar 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🤖 GitHub comments

Just comment with:

  • run docs-build : Re-trigger the docs validation. (use unformatted text in the comment!)

@mergify

mergify Bot commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

This pull request does not have a backport label.
If this is a bug or security fix, could you label this PR @strawgate? 🙏.
For such, you'll need to label your PR with:

  • The upcoming major version of the Elastic Stack
  • The upcoming minor version of the Elastic Stack (if you're not pushing a breaking change)

To fixup this pull request, you need to add the backport labels for the needed
branches, such as:

  • backport-8./d is the label to automatically backport to the 8./d branch. /d is the digit
  • backport-active-all is the label that automatically backports to all active branches.
  • backport-active-8 is the label that automatically backports to all active minor branches for the 8 major.
  • backport-active-9 is the label that automatically backports to all active minor branches for the 9 major.

@coderabbitai

coderabbitai Bot commented Mar 20, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This change introduces six new GitHub Actions workflows for automated code quality and safety audits. One workflow (trigger-pr-buildkite-detective) triggers on failed Buildkite check runs and invokes a downstream AI-powered workflow to investigate failures. Five additional workflows (sweep-filestream-registry, sweep-libbeat-pipeline-lifecycle, sweep-otel-beatreceiver-isolation, sweep-packetbeat-parser-safety, sweep-streaming-input-resilience) are scheduled weekly via cron and manual dispatch to audit specific codebase areas for safety issues including cursor loss risks, pipeline lifecycle correctness, global state mutations, byte-access bounds violations, and error-path resilience. All workflows delegate to shared Elastic AI GitHub Actions reusable workflows with detailed audit instructions.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bill/test-buildkite-detective
  • 🛠️ Update Documentation: Commit on current branch
  • 🛠️ Update Documentation: Create PR

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

@strawgate strawgate changed the title Add PR Buildkite Detective trigger workflow [DO NOT MERGE} Add PR Buildkite Detective trigger workflow Mar 20, 2026
@strawgate strawgate changed the title [DO NOT MERGE} Add PR Buildkite Detective trigger workflow [DO NOT MERGE] Add PR Buildkite Detective trigger workflow Mar 20, 2026
pull_request: synchronize only fires on subsequent pushes, not when
the PR is first created (that fires opened). Adding opened ensures
the detective also runs on initial PR creation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Add a Python setup-commands script that fetches failed Buildkite job
data before the AI agent runs, so the agent never needs direct
Buildkite API access:

- Reads PR check links to discover all Buildkite builds for the PR
- Calls the Buildkite REST API (BUILDKITE_API_TOKEN in setup-commands
  env, never passed to the AI sandbox) to enumerate failed jobs
- Fetches the tail of each failed job's raw log, stripping OSC escape
  sequences (timestamps) and ANSI color codes
- Writes /tmp/gh-aw/buildkite-failures.txt (summary with job metadata
  and log file paths) and /tmp/gh-aw/buildkite-logs/<pipeline>-<job>.txt
  (one file per failed job)

The detective agent reads the pre-fetched files and skips Buildkite
MCP/API calls entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
strawgate and others added 2 commits March 20, 2026 16:02
…tream)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Buildkite data fetch is now built into the detective workflow itself.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/trigger-pr-buildkite-detective.yml:
- Around line 26-31: The current detection uses STATUS and greps for any "fail",
which is too broad; instead filter the gh pr checks output for
Buildkite-specific entries before checking failure. Modify the block that sets
STATUS (from the gh pr checks "$PR_NUMBER" call) and the subsequent conditional
so you first narrow STATUS to Buildkite-related lines (e.g., pipe STATUS through
grep -iE "buildkite") and then check those lines for "fail" (e.g., ... | grep
-iE "buildkite" | grep -iE "fail"), ensuring only Buildkite failures trigger the
failure-detected=true branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9ed7270d-17cf-4889-9efe-812e473b310d

📥 Commits

Reviewing files that changed from the base of the PR and between 1a5b9ba and 5d026e3.

📒 Files selected for processing (1)
  • .github/workflows/trigger-pr-buildkite-detective.yml

@github-actions

Copy link
Copy Markdown
Contributor

Buildkite detective triggered, but there is no failed Buildkite build for commit 5d026e3145abba3a80d4dbd58cdcf9e7040e920a.

Build: https://buildkite.com/elastic/beats/builds/42756 (pending), plus filebeat/29841 and beats-xpack-filebeat/28857 checks are pending/success in PR statuses.

What failed: The workflow job wait-for-buildkite-failure treated non-Buildkite failures as Buildkite failures and set failure-detected=true on attempt 1.

Error: From job wait-for-buildkite-failure logs:

Relevant log lines
fragments    fail
lint (macos-latest)    fail
Failure found on attempt 1

Root cause: In .github/workflows/trigger-pr-buildkite-detective.yml line 27, this condition is too broad:

if echo "$STATUS" | grep -iE "fail" | grep -vE "^\s*$"; then

gh pr checks returns all checks (GitHub Actions + Buildkite). Any failed check containing fail trips the detector, even when no Buildkite context failed.

Recommended fix: Filter to Buildkite rows before checking failure, e.g.:

STATUS=$(gh pr checks "$PR_NUMBER" --repo "${{ github.repository }}" 2>&1 || true)
BK_STATUS=$(echo "$STATUS" | grep -i "buildkite" || true)
if echo "$BK_STATUS" | grep -iE "\bfail\b" >/dev/null; then
  echo "failure-detected=true" >> "$GITHUB_OUTPUT"
  ...
fi

(Alternatively: use gh pr checks --json + jq and require both name/context contains buildkite and state == FAIL.)

Verification: Confirmed from PR status payload that Buildkite contexts are currently pending/success, while non-Buildkite checks (fragments, lint (macos-latest)) were fail; these exact non-Buildkite failures are what the workflow log matched.


What is this? | From workflow: PR Buildkite Detective

Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.

@github-actions

Copy link
Copy Markdown
Contributor

TL;DR

golangci-lint failed on all three runners because filebeat/processor/add_kubernetes_metadata/matchers_test.go has 3 unchecked SetString errors (errcheck) and one assert.Equal("", ...) violation (testifylint). Update that test file to handle SetString errors and use assert.Empty.

Remediation

  • In filebeat/processor/add_kubernetes_metadata/matchers_test.go (reported at lines 188, 192, 214, 229), wrap each testConfig.SetString(...) with explicit error handling (for example require.NoError(t, testConfig.SetString(...))).
  • Replace assert.Equal(t, "", output) with assert.Empty(t, output).
  • Re-run golangci-lint (or CI lint jobs) to confirm all three lint jobs pass.
Investigation details

Root Cause

The workflow run failed in golangci-lint (macOS, Ubuntu, Windows) for the same lint findings in one file. This is a code-quality failure in the test file, not an infrastructure/runtime flake.

Evidence

filebeat/processor/add_kubernetes_metadata/matchers_test.go:188:23: Error return value of `testConfig.SetString` is not checked (errcheck)
filebeat/processor/add_kubernetes_metadata/matchers_test.go:192:23: Error return value of `testConfig.SetString` is not checked (errcheck)
filebeat/processor/add_kubernetes_metadata/matchers_test.go:214:22: Error return value of `testConfig.SetString` is not checked (errcheck)
filebeat/processor/add_kubernetes_metadata/matchers_test.go:229:2: empty: use assert.Empty (testifylint)

Validation

  • Not run locally in this detective workflow (read-only analysis). Diagnosis is from failed job logs for run 23363387057.

Follow-up

  • After the test-file edits above, re-run the golangci-lint workflow to verify resolution.

What is this? | From workflow: PR Actions Detective

Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.

…o check_run event

Replace the pull_request + 15-minute polling loop with a check_run event trigger.
Fires immediately when a Buildkite check run completes with failure on a PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@strawgate strawgate changed the title [DO NOT MERGE] Add PR Buildkite Detective trigger workflow Add PR Buildkite Detective trigger workflow Mar 20, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/trigger-pr-buildkite-detective.yml:
- Around line 18-21: Replace the mutable tag in the reusable workflow reference
on the line starting with "uses:
elastic/ai-github-actions/.github/workflows/gh-aw-estc-pr-buildkite-detective.lock.yml@v0"
with the full 40-character commit SHA for the v0 release (instead of `@v0`) so the
workflow is pinned; leave the secret mappings (COPILOT_GITHUB_TOKEN and
BUILDKITE_API_TOKEN) unchanged and ensure the SHA corresponds to the v0 tag
commit before committing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4bc3725b-d931-48bd-a32f-9dfa6164eb19

📥 Commits

Reviewing files that changed from the base of the PR and between 5d026e3 and 46bf252.

📒 Files selected for processing (1)
  • .github/workflows/trigger-pr-buildkite-detective.yml

The TestLogsPathMatcher_EmptyResult test was added only to trigger
Buildkite lint failures for testing the PR Buildkite Detective workflow.
Remove it now that testing is complete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@strawgate strawgate added backport-skip Skip notification from the automated backport with mergify skip-changelog labels Mar 20, 2026
strawgate and others added 2 commits March 20, 2026 18:16
Each sweeper runs weekly on a different weekday and uses the
gh-aw-code-quality-audit workflow to proactively hunt for specific
bug classes identified from 2 years of beats issue history:

- sweep-packetbeat-parser-safety (Mon): remotely-triggerable bounds
  panics in protocol parsers; writes failing Go tests for each instance
- sweep-filestream-registry (Tue): registry cursor loss and re-ingestion
  risk paths in filestream state machine
- sweep-libbeat-pipeline-lifecycle (Wed): shutdown hangs, silent event
  drops, and channel races in the publisher pipeline
- sweep-otel-beatreceiver-isolation (Thu): global state mutations during
  concurrent BeatReceiver construction
- sweep-streaming-input-resilience (Fri): panics, data loss, and CPU
  spin loops in streaming inputs under network failure

Each sweeper is grounded in specific file paths, function names, and
code patterns from the actual codebase, with instructions to write
and run reproduction tests before filing issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cript it

Remove specific line numbers and commit hashes (which go stale) in favor
of component-level guidance: what the bug class is, how to think about
the investigation, what patterns to look for, and how to write tests that
confirm findings before filing issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@strawgate
strawgate enabled auto-merge (squash) March 20, 2026 23:45
@strawgate strawgate changed the title Add PR Buildkite Detective trigger workflow Add PR Buildkite Detective and Beats Detective Workflows Mar 20, 2026
Each sweeper now has a clear 'The bar for filing' section that tells the
agent to only report bugs a real user could encounter under realistic
conditions — not theoretical findings or scenarios that require
unrealistic preconditions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@pierrehilbert pierrehilbert added the Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team label Mar 23, 2026
@botelastic botelastic Bot removed the needs_team Indicates that the issue/PR needs a Team:* label label Mar 23, 2026
@elasticmachine

Copy link
Copy Markdown
Contributor

Pinging @elastic/elastic-agent-data-plane (Team:Elastic-Agent-Data-Plane)

@github-actions github-actions Bot mentioned this pull request Mar 23, 2026
@strawgate
strawgate merged commit 11d1fe7 into main Mar 23, 2026
28 checks passed
@strawgate
strawgate deleted the bill/test-buildkite-detective branch March 23, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-skip Skip notification from the automated backport with mergify skip-changelog Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants