Companion artefact to the post "Auditing a Rails Side Project with the thoughtbot Audit Skill."
This file is written for a coding agent (Claude Code, etc.) to act on. The intended workflow:
-
Run
/rails-audit-thoughtboton your Rails project so you have aRAILS_AUDIT_REPORT.mdunderscratch/rails-audit/. -
Save this file into your project as
scratch/rails-audit/AGENT_PLAYBOOK.md. -
In a Claude Code session, hand it over with one line:
read scratch/rails-audit/AGENT_PLAYBOOK.md and execute it
The agent will do the rest. Skim the sections below if you want to know what you're authorising before you do.
You are turning the findings in scratch/rails-audit/RAILS_AUDIT_REPORT.md into a labelled GitHub backlog. Work in this order. Do not skip ahead; each step assumes the previous one's artefacts exist.
- Confirm
scratch/rails-audit/RAILS_AUDIT_REPORT.mdexists. If not, stop and ask the human to run/rails-audit-thoughtbotfirst. - Confirm
gh auth statussucceeds. If not, stop and ask the human to rungh auth login. - Read the report end-to-end before drafting anything. Count the findings; you will reference the count later.
For each finding in the report, create a file at scratch/rails-audit/issues/<short-kebab-slug>.md using the Issue file template below. Fill in every section. Keep titles short and imperative (Add trigram index on visits.url, not There is a missing index on the visits table).
Use the report's own severity/category as the source of truth. If the report doesn't assign a severity, pick one and note your reasoning in the issue body.
Do not push anything to GitHub yet. Iterating on local files is much cheaper than editing live issues.
Before creating labels, run gh label list and read the project's existing labels. The Default label scheme below is a starting point — adapt it:
- If the project already has equivalents (e.g.
priority/highinstead ofseverity: high), use the existing names and skip creating duplicates. - If a proposed area label has no issues that would carry it, drop it.
- If the audit surfaces a category not covered (e.g. lots of accessibility findings), propose an extra area label and explain why.
Write your final proposal to scratch/rails-audit/github-issue-new-labels.md as a table with name | hex | description, then ask the human to confirm before creating anything destructive.
Once confirmed, create the labels with gh label create "<name>" --color <hex> --description "<desc>". Add --force only if the human explicitly asks to overwrite existing labels.
Edit every file in scratch/rails-audit/issues/. Add (or update) a **Labels**: line in the header so each issue carries:
- Exactly one severity label.
- One or more area labels.
- The
audit(or equivalent origin) label. - Any existing project labels that fit (
chore,enhancement,documentation, etc.).
The **Labels**: line is what Step 4 parses, so keep the format exactly: backtick-quoted, comma-separated, on a single line.
For each file in scratch/rails-audit/issues/:
- Title comes from line 1 (strip the leading
#). - Labels come from the
**Labels**:line (strip backticks, keep the comma-separated list). - Body is the full file contents.
Before running any gh issue create calls, print a dry-run summary of titles + labels for every file and ask the human to confirm. Then create the issues:
gh issue create --title "<title>" --label "<label1,label2,...>" --body-file "<path>"After pushing, report back: how many issues were created, link to the filtered list (gh issue list --label audit --web), and any files that failed.
- Run
gh issue list --label audit --state open | wc -land confirm the count matches the number of findings drafted in Step 1. - Spot-check one issue in the browser. Confirm severity colour, label set, and the provenance callout at the bottom all render correctly.
Use this verbatim shape for each file in scratch/rails-audit/issues/. Every section is required; if a section genuinely has nothing to say, write one sentence explaining why rather than deleting the heading.
# <ID>: <short imperative title>
**Severity**: <High | Medium | Low>
**Category**: <Testing | Security | Models | Controllers | Code Design | Views | Database & Performance | ...>
**Labels**: `severity: <high|medium|low>`, `<area-label>`, `audit`
## Problem
What's broken or smelly. Be concrete — quote the offending code, name the file path.
## Why We're Addressing It
The motivation in plain language. What goes wrong if we don't fix it? Who feels the pain, and when?
## Expected Result
What "done" looks like. One or two sentences describing the end state — not the steps to get there.
## How to Verify
A numbered checklist a future agent can follow without re-reading the audit.
1. Run `bin/rspec` — all existing tests still pass.
2. <Run the command / open the file / inspect the output that proves the change took effect>.
3. <Any DB / console / curl check that confirms behaviour at runtime>.
## Implementation Notes
Example code, migration snippets, gotchas. Anything that would have taken 10 minutes to figure out the first time.
```ruby
# illustrative snippetNote
This issue was identified by the Rails Audit skill, a code audit tool based on thoughtbot best practices.
Why this shape:
- **Problem / Why** separates *what's wrong* from *why we care* — useful when triaging weeks later.
- **Expected Result / How to Verify** is the contract a future agent needs to close the issue without re-reading the audit.
- **Implementation Notes** captures the audit's example code so it survives even if the report is archived.
- The provenance callout at the bottom is non-negotiable — it tells future readers (human or agent) where the issue came from.
---
## Default label scheme
Eight labels across three groups. Adapt freely (see Step 2).
### Severity (one per issue)
| Label | Hex | Description |
|---|---|---|
| `severity: high` | `#dc2626` | Needs attention before next production push |
| `severity: medium` | `#d97706` | Address this sprint |
| `severity: low` | `#16a34a` | Technical debt, schedule when convenient |
### Area (one or more per issue)
| Label | Hex | Description |
|---|---|---|
| `security` | `#f97316` | Security vulnerabilities and hardening |
| `performance` | `#0ea5e9` | Database indexes and runtime performance |
| `testing` | `#7c3aed` | Test coverage and spec quality |
| `code-quality` | `#db2777` | Code smells, duplication, readability |
### Origin (one, on every audit issue)
| Label | Hex | Description |
|---|---|---|
| `audit` | `#65a30d` | Surfaced by an automated Rails audit |
---
## Stop conditions
Stop and ask the human before proceeding if any of these are true:
- The report has more than ~50 findings. Confirm scope before drafting that many files.
- `gh auth status` shows a different account than the project's repo owner.
- The repo already has audit-style issues open (search by `label:audit` or similar). Don't double-file.
- Any `gh` command fails with a permission error.