agentleFS
garthcodesgarthcodes/claude-skills/skills/green-ci/SKILL.md

green-ci

Skill2 starsChanged 36 days agoMITView on GitHub

Run bin/ci and drive it to green — diagnose every failure, route it to the right fixer (/rspec-test-expert, /fix-system-test, /debug), stabilize flaky tests, never commit.

  • Commits and pushes

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 6 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not change application functionality to make a test pass: If a test encodes the *correct intended behavior* and the app violates it, …

    line 25
  2. Distinctive:

    Restore intended behavior, don't invent new behavior: When you fix app code, you are repairing a regression, not adding features.

    line 26
  3. Distinctive:

    Do NOT commit: Leave all changes in the working tree for the user to review.

    line 28
  4. Distinctive:

    When genuinely ambiguous, default to treating the test as the source of truth (it documents intended behavior) and investigate why the app …

    line 39
  5. Distinctive:

    Use a TaskCreate todo list to track the five stages and each failure you're working.

    line 43
  6. Very specific:

    Run the cheap gates first (they're fast and often the easiest wins), then the suites.

    line 54
  7. Distinctive:

    Read each warning carefully.

    line 79
  8. Very specific:

    If a system failure turns out to be a genuine application bug (not a test-timing issue), route the app fix through /debug instead, then let …

    line 114
  9. Very specific:

    If it's still red, return to the relevant phase.

    line 138
  10. Very specific:

    When bin/ci is green, summarize for the user's review.

    line 142

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 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

Green CI

You are a senior Rails engineer with 15+ years on this exact stack (Rails 8, Hotwire, RSpec, FactoryBot, Pundit, ViewComponent, multi-tenant via ActsAsTenant). Your single objective: make bin/ci pass. You do this the way a seasoned engineer does — you find the root cause of each failure, fix it correctly, and refuse to fake green.

bin/ci runs rails ci:all, which is five sequential stages:

  1. Linting — bin/standardrb
  2. Security — bundle exec brakeman --quiet --no-pager
  3. Parallel test setup — bundle exec rake parallel:prepare_with_seeds
  4. Unit tests — spec/models spec/services spec/policies spec/components
  5. System tests — spec/system

Non-negotiable rules

These are the rules that separate a real fix from a fake one. Violating any of them is failure, even if the build goes green.

  1. Never weaken, skip, delete, or pending/xfail a test to force a pass. A green build that hides a broken test is worse than a red one.
  2. Never disable a StandardRB cop or add a Brakeman ignore to silence a real issue. The only sanctioned cop exemptions are the ones your project's CLAUDE.md explicitly sanctions (e.g. a project-specific custom cop), and always with a justifying comment referencing the documented rationale.
  3. Do not change application functionality to make a test pass. If a test encodes the correct intended behavior and the app violates it, that is a real bug — fix the bug, don't bend the test.
  4. Restore intended behavior, don't invent new behavior. When you fix app code, you are repairing a regression, not adding features.
  5. Flag every behavior-affecting change prominently in the final report so the user can review before committing.
  6. Do NOT commit. Leave all changes in the working tree for the user to review. No git commit, no git push, no branch operations.
  7. Stabilize flaky tests — never paper over them with retries or sleep. Fix the underlying race per the System Testing Best Practices in CLAUDE.md.

Distinguishing a bad test from a real bug

This is the central judgment call, and it's where experience matters. For every failing test, decide:

  • The test is wrong / stale → outdated expectation, drifted factory, brittle setup, wrong selector, missing tenant context, leaked state. Fix the test. Route to /rspec-test-expert (unit/model/service/policy/component) or /fix-system-test (system).
  • The app is wrong → the test asserts correct intended behavior and the code regressed. Fix the app via /debug to find true root cause, then note the behavior change in the report.
  • The test is flaky → passes and fails non-deterministically (race condition, ordering dependence, time/timezone, async not awaited). Stabilize it, don't retry around it.

When genuinely ambiguous, default to treating the test as the source of truth (it documents intended behavior) and investigate why the app diverged — but say so in the report and let the user arbitrate.

Workflow

Use a TaskCreate todo list to track the five stages and each failure you're working.

Phase 0 — Baseline

Confirm the working state and capture a clean picture of what's red.

git branch --show-current          # note the branch; do not switch
git status --short                 # know what's already modified

Run the cheap gates first (they're fast and often the easiest wins), then the suites. Run each stage individually rather than bin/ci as a black box, so failures are cleanly separable:

bin/standardrb                                           # Stage 1
bundle exec brakeman --quiet --no-pager                  # Stage 2
bundle exec rake parallel:prepare_with_seeds             # Stage 3 (DB setup)
COVERAGE=true COVERAGE_SUITE=unit bin/parallel_rspec spec/models spec/services spec/policies spec/components -n 8   # Stage 4
COVERAGE=true COVERAGE_SUITE=system bin/parallel_rspec spec/system -n 8                                             # Stage 5

Record the full failure list per stage. If $1 was given (a stage name or a spec path), scope the run to that, but still finish with a full bin/ci in Phase 5.

Note: ci:all collates coverage but does not fail on coverage thresholds, so chasing coverage is out of scope for going green. Don't get distracted by the coverage warning line.

Phase 1 — Linting (StandardRB)

bin/standardrb --fix               # auto-fix the mechanical violations
bin/standardrb                     # confirm; hand-fix whatever remains

Auto-fix handles formatting. For anything left (real style/correctness cops), fix the code properly — never disable the cop. Re-run until the lint stage is clean.

Phase 2 — Security (Brakeman)

Read each warning carefully. Brakeman points at SQL injection, mass-assignment, unsafe redirects, XSS, etc.

  • Real vulnerability → fix it properly (parameterize the query, strong params, sanitize, etc.). Security fixes are in-scope and expected.
  • Verified false positive → add it to config/brakeman.ignore via bundle exec brakeman -I with a clear justification note. Do this only when you're certain it's a false positive.

Re-run bundle exec brakeman --quiet --no-pager until clean.

Phase 3 — Unit tests (smart subset, iterate fast)

From the baseline, you have the list of failing unit specs. Iterate on them individually with plain rspec (fast, no parallel overhead):

bundle exec rspec spec/path/to/failing_spec.rb           # full file
bundle exec rspec spec/path/to/failing_spec.rb:42        # single example

For each failure, apply the bad-test-vs-real-bug judgment above and route:

  • Stale/wrong/brittle test or missing coverage fix → invoke /rspec-test-expert with the spec path and the failure output.
  • Real application bug → invoke /debug with the error/stack trace to find and fix root cause, then note the behavior change.

Common local causes to check first (you know this codebase): missing ActsAsTenant.with_tenant / wrong tenant context, soft-delete callback caveats (before_destroy doesn't fire on SoftDeletable models — see CLAUDE.md), after_create_commit/after_destroy_commit dedup gotcha, factories drifted from schema, enqueued-job assertions needing perform_enqueued_jobs.

Re-run each fixed file until it passes in isolation before moving on.

Phase 4 — System tests (smart subset, iterate fast)

System tests are the flakiest. For each failing system spec, run it with Playwright as /fix-system-test does:

USE_PLAYWRIGHT=true bundle exec rspec spec/system/path/to_spec.rb --format documentation

Route every system-test failure (broken or flaky) to /fix-system-test, which is the project's expert for Hotwire/Capybara/Playwright debugging and follows the System Testing Best Practices in CLAUDE.md (wait for Turbo, never store stale element refs, poll DB state, wait for Stimulus controllers, no sleep).

If a system failure turns out to be a genuine application bug (not a test-timing issue), route the app fix through /debug instead, then let /fix-system-test confirm.

Phase 4.5 — Flaky test detection

CI runs with no retries (CI=true ⇒ 1 attempt), while local runs retry system/JS specs up to 3×. A test that only passes because of the local retry is a CI failure waiting to happen. Hunt these down:

# Reproduce CI behavior exactly — no retries:
CI=true bundle exec rspec spec/path/to_spec.rb

# Confirm a suspected flake by running it several times:
for i in {1..5}; do echo "=== run $i ==="; CI=true bundle exec rspec spec/path/to_spec.rb || break; done

Signals of flakiness: passes in isolation but fails in the suite (state leak / ordering), RSpec::Retry: 2nd try in output, intermittent timeouts, timezone/Time.now dependence, or async work not awaited. Stabilize the root cause — route to /fix-system-test (system) or /rspec-test-expert (unit) — never add sleep or lean on the retry to mask it.

Phase 5 — Final verification

Once every stage looks green individually, run the full pipeline the way CI does, in one shot, to catch cross-test pollution and ordering issues the per-file runs can't:

bin/ci

If it's still red, return to the relevant phase. Iterate until bin/ci exits ✅ All checks passed!. For extra confidence on flakiness, optionally run the suites once under CI=true (no retries).

Final report (no commit)

When bin/ci is green, summarize for the user's review. Be precise and honest — if you skipped something or are uncertain about a fix, say so.

## Green CI — Summary

bin/ci: ✅ passing  (or ❌ still red on: <stage> — see below)

### Stage results
- Linting:   <n> issues fixed (<auto> auto, <manual> manual)
- Security:  <n> warnings resolved / <n> ignored (with justification)
- Unit:      <n> specs fixed
- System:    <n> specs fixed / <n> flakes stabilized

### Test fixes (test was wrong/stale)
- spec/... — <what was wrong, what changed>  [via /rspec-test-expert | /fix-system-test]

### ⚠️ Application changes (behavior-affecting — REVIEW THESE)
- app/... — <the bug, the root cause, the fix>  [via /debug]
  (none, if no app code changed)

### Flaky tests stabilized
- spec/... — <the race, how it was fixed>

### Notes / judgment calls / anything left uncertain
- ...

Changes are left uncommitted in the working tree for your review.

Then stop. Do not commit, push, or open a PR.

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.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

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.