agentleFS
ElasticKnown publisherelastic/terraform-provider-elasticstack/.agents/skills/flaky-test-catcher/SKILL.md

flaky-test-catcher

Skill210 starsChanged 6 months agoApache-2.0View on GitHub

Detects broken and flaky acceptance tests from recent CI failures on main and opens structured GitHub issues for automated remediation. Follow this skill strictly when analyzing CI failures.

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 7 are distinctive, and 12 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use grep -B3 -A3 or similar when you also need surrounding context for the "Sample Failure Output" issue section.

    line 58
  2. Very specific:

    If a job list response has 100 items and there may be more, check the Link header for a next page URL and repeat the request.

    line 63
  3. Distinctive:

    One issue per base test name: All scenario variants (subtests/suffixes) belonging to the same base name are consolidated into a single …

    line 124
  4. Very specific:

    Fallback for non-TestAcc tests: All acceptance tests in this project follow the TestAcc prefix convention.

    line 126
  5. Very specific:

    Check if any file in files[].filename matches patterns like:

    line 165
  6. Distinctive:

    If a relevant commit is found:

    line 171
  7. Distinctive:

    If no relevant commits found:

    line 175
  8. Distinctive:

    Before creating an issue for a base test name, check whether one already exists:

    line 186
  9. Distinctive:

    If an exact title match exists, skip creating a new issue for that base test name.

    line 194
  10. Very specific:

    Do not re-query or recalculate issue_slots_available.

    line 195
  11. Very specific:

    If the response contains exactly 100 results, check for a next link in the Link response header and repeat the request for subsequent pages …

    line 196
  12. Distinctive:

    Every issue you create must contain exactly these 5 sections in this order:

    line 202
  13. Very specific:

    Use ❌ for broken tests (100% fail rate).

    line 230
  14. Very specific:

    Use ⚠️ for flaky tests (20%–99% fail rate), and always include the fraction and percentage.

    line 231
  15. Distinctive:

    Keep "Sample Failure Output" to the most informative excerpt.

    line 232
  16. Very specific:

    Cap enforcement: Before creating each issue, verify that the number of issues created so far in this run has not reached …

    line 234
  17. Very specific:

    Call noop with a descriptive explanation (do not create any issues) when any of these conditions holds:

    line 238
  18. Very specific:

    When calling noop, state which condition applied and include basic counts (e.g.

    line 246
  19. Very specific:

    If no issues were created, call noop.

    line 257

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Flaky Test Catcher — Analysis Protocol

1. Overview / Purpose

This skill defines the end-to-end protocol for detecting broken and flaky acceptance tests by analyzing recent CI failures on main, then opening structured GitHub issues so that automated remediation workflows can address the root causes.

You must follow this protocol strictly. Do not improvise or skip steps.

2. Inputs from pre-activation context

The workflow pre-activation step has already computed all run-level data. Do not re-query GitHub for run lists or issue counts. Use the values injected into your prompt:

VariableMeaning
failed_run_idsJSON array of run IDs of failed test.yml runs on main in the last 3 days
total_run_countCount of completed runs with meaningful conclusions (success, failure, timed_out, neutral, action_required) — cancelled runs excluded
open_issuesCurrent count of open flaky-test issues
issue_slots_availableHow many new issues you may create (max 3)

Parse failed_run_ids as a JSON array immediately. Example: ["12345678","87654321"].

3. Fetching job logs

For each run ID in failed_run_ids:

3.1 List jobs for the run

gh api /repos/{owner}/{repo}/actions/runs/{run_id}/jobs?per_page=100

Replace {owner} and {repo} with the values from the repository's GitHub remote (visible in git remote get-url origin).

3.2 Filter to relevant failing jobs

From the returned jobs array, keep only jobs where both conditions hold:

  • conclusion == "failure"
  • The job name contains Matrix Acceptance Test (this is the job group that runs acceptance tests)

Ignore infrastructure jobs (e.g. lint, build, generate) — they do not produce --- FAIL: lines.

3.3 Fetch the log for each failing job

The GitHub API log endpoint returns a ZIP archive. Use the gh CLI to stream plain-text logs for a job:

gh run view --job {job_id} --log | grep '^--- FAIL:'

Log size warning: Job logs can be very large (10 MB+). Do not load the full log into context. Instead:

  • Stream the log output through grep so only matching lines are retained.
  • Scan only for lines matching the --- FAIL: pattern (see §4).
  • Use grep -B3 -A3 or similar when you also need surrounding context for the "Sample Failure Output" issue section.
  • Capture a small surrounding context (3–5 lines before/after each --- FAIL: line) for the "Sample Failure Output" issue section.

3.4 Pagination

If a job list response has 100 items and there may be more, check the Link header for a next page URL and repeat the request. In practice, a single run rarely has more than 100 jobs.

4. --- FAIL: extraction pattern

Scan each log for lines that match this exact pattern:

^--- FAIL: TestName (timing)

Examples of matching lines:

--- FAIL: TestAccResourceAgentConfiguration_alternateEnvironment (12.34s)
--- FAIL: TestAccSomeResource_basic (0.45s)

Rules:

  • The line must start with --- FAIL: (three hyphens, a space, FAIL:, a space).
  • The test name follows Go test naming: TestAcc... with optional underscore-separated sub-name.
  • Extract only the test function name — strip the timing suffix (12.34s).
  • Ignore bare FAIL lines without the --- prefix; those are package-level failure markers, not individual test failures.

Collect all extracted test names across all runs and all jobs. A test may appear multiple times (once per run where it failed) — track counts.

Same-run deduplication: If the same test name appears in multiple failing jobs within a single run (e.g. multiple shards both failing the same test), count it only once for that run. Deduplication is by run ID, not job ID — use a set per run when accumulating test names.

5. Fail-rate formula and thresholds

For each unique test name:

fail_rate = fail_count / total_run_count

Where:

  • fail_count = number of distinct run IDs in which this test appeared as --- FAIL:
  • total_run_count = the value from pre-activation context (already excludes cancelled runs)
ClassificationConditionAction
Brokenfail_rate == 1.0 (fails in 100% of runs)Create issue
Flakyfail_rate >= 0.20 and < 1.0Create issue
Noisefail_rate < 0.20Ignore — do not create issues

6. Base-test-name grouping rule

Extract the base test name from each test function name using this rule:

Take the substring from the beginning up to (but not including) the first underscore _.

Pattern: TestAcc[^_]+

Examples:

Full test nameBase test name
TestAccResourceAgentConfiguration_alternateEnvironmentTestAccResourceAgentConfiguration
TestAccResourceAgentConfiguration_minimalTestAccResourceAgentConfiguration
TestAccResourceAgentConfigurationTestAccResourceAgentConfiguration
TestAccSomeResource_basicTestAccSomeResource

One issue per base test name. All scenario variants (subtests/suffixes) belonging to the same base name are consolidated into a single issue. List each specific variant inside the issue body.

Fallback for non-TestAcc tests: All acceptance tests in this project follow the TestAcc prefix convention. If a non-TestAcc test name appears in the logs, treat everything up to the first _ (or the full name if no _) as the base name.

7. Commit analysis steps

For each base test name that will receive an issue, investigate whether any recent commit may already address the failure:

7.1 Find the oldest failing run timestamp

From the failed_run_ids list, identify the oldest run's created_at timestamp. You can get metadata for a single run:

gh api /repos/{owner}/{repo}/actions/runs/{run_id}

Take the minimum created_at across all failed runs.

7.2 Fetch commits on main since that timestamp

gh api "/repos/{owner}/{repo}/commits?sha=main&since={timestamp}&per_page=50"

Replace {timestamp} with the ISO 8601 value from step 7.1 (e.g. 2024-01-15T12:00:00Z).

7.3 For each commit, check relevance

For each commit returned:

a. Commit message relevance — does it reference any of:

  • The base test name (e.g. TestAccResourceAgentConfiguration)
  • The resource name (derive from the test name, e.g. agent_configuration → AgentConfiguration)
  • Keywords: fix, flaky, test, revert

b. Changed file relevance — fetch the full commit detail to get changed file paths:

gh api /repos/{owner}/{repo}/commits/{sha}

Check if any file in files[].filename matches patterns like:

  • *_test.go files whose name contains a token from the resource name
  • Files in the same Go package directory as the test

7.4 Include findings in issue body

  • If a relevant commit is found:
    ⚠️ may already be addressed in `{short_sha}` — {one-line message summary}
  • If no relevant commits found:
    No recent commits appear to address this failure.

Frame the analysis as "has this been fixed yet?" — not as blame attribution.

Do not suppress issue creation: Even if a fix commit is found, always proceed with creating the issue and include the fix-detection note in the Commit Analysis section. The issue serves as the remediation trigger regardless.

8. Issue deduplication

Before creating an issue for a base test name, check whether one already exists:

gh api "/repos/{owner}/{repo}/issues?labels=flaky-test&state=open&per_page=100"
  • Inspect each returned issue's title.
  • The full rendered title for flaky-test issues is: [flaky-test] {BaseTestName} (the [flaky-test] prefix is applied automatically by the create-issue safe output). When checking for duplicates, compare against this full title as it appears in GitHub.
  • If an exact title match exists, skip creating a new issue for that base test name.
  • Do not re-query or recalculate issue_slots_available; use only the value from pre-activation.
  • If the response contains exactly 100 results, check for a next link in the Link response header and repeat the request for subsequent pages until all open issues are fetched.

9. Required issue body sections

Issue title: Pass only {BaseTestName} to the create-issue safe output — the [flaky-test] prefix is added automatically.

Every issue you create must contain exactly these 5 sections in this order:

## Broken Tests

List each test function name (including scenario suffix) that failed in 100% of runs:
- ❌ `TestAccResourceFoo_basic` — failed in 5/5 runs

## Flaky Tests

List each test function name that failed in ≥ 20% but < 100% of runs, with the observed rate:
- ⚠️ `TestAccResourceFoo_update` — failed in 3/5 runs (60%)
- ⚠️ `TestAccResourceFoo_import` — failed in 1/5 runs (20%)

## Commit Analysis

{Output from §7. Either a ⚠️ note about a possible fix commit, or the "No recent commits" message. Include commit SHA, message, and affected file paths when relevant.}

## Sample Failure Output

{Short excerpt (5–15 lines) of the actual log output surrounding a `--- FAIL:` line. Include any immediately preceding error messages for context.}

## Affected Stack Versions

{List the Elastic Stack versions / matrix dimension values (e.g. Elasticsearch version, Kibana version) from the failing job names or log metadata. If not determinable, write "Unknown — not present in log output".}

Formatting rules:

  • Use ❌ for broken tests (100% fail rate).
  • Use ⚠️ for flaky tests (20%–99% fail rate), and always include the fraction and percentage.
  • Keep "Sample Failure Output" to the most informative excerpt; do not paste hundreds of lines.

Cap enforcement: Before creating each issue, verify that the number of issues created so far in this run has not reached issue_slots_available. Stop creating issues once the cap is reached, even if additional base test names remain.

10. Noop conditions

Call noop with a descriptive explanation (do not create any issues) when any of these conditions holds:

  1. All failures already have open issues — every qualifying base test name matched an existing open flaky-test issue during deduplication; nothing new to open.
  2. All failures are below the 20% threshold — every observed --- FAIL: test has fail_rate < 0.20; there are no broken or flaky tests to report.
  3. No --- FAIL: patterns found — none of the logs for the provided failed_run_ids contained a --- FAIL: line; the CI failures were likely infrastructure failures (network timeouts, setup errors, etc.) rather than test logic failures.

When calling noop, state which condition applied and include basic counts (e.g. "3 failures observed, all below 20% threshold").

Summary of execution order

  1. Parse failed_run_ids from pre-activation context.
  2. For each run ID: list jobs → filter to failing Matrix Acceptance Test jobs → fetch and scan logs for --- FAIL: lines.
  3. Aggregate per-test fail counts across all runs.
  4. Apply fail-rate thresholds; discard noise (< 20%).
  5. Group surviving tests by base test name.
  6. Deduplicate against existing open flaky-test issues.
  7. For each remaining base test name (up to issue_slots_available): run commit analysis, then create an issue with all 5 required sections.
  8. If no issues were created, call noop.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.