How Claude Code Reads a BrassCoders Findings File

BrassCoders writes .brass/ai_instructions.yaml sorted by severity, with line numbers and remediation notes. Here's what Claude Code does with each field and why the structure matters.

Copper Sun Brass Team · · 5 min read
ai-code-reviewoss-coreengineering

Claude Code reads .brass/ai_instructions.yaml as a pre-digested work queue: the severity field determines review order, the line number field anchors each finding to a specific code location, and the remediation field gives a fix direction before the model reads a single line of source. BrassCoders writes this file; Claude Code reads it. That division is the whole workflow.

Understanding what each field does explains why the structure produces better triage sessions than an open-ended code review prompt.

What the File Looks Like in Practice

BrassCoders emits .brass/ai_instructions.yaml in the scanned project directory after every scan, sorted so that critical-severity findings appear before high-severity findings before medium-severity ones; the file carries one entry per finding, each with an id, severity, file path, line number, title, description, and remediation field.

A finding for the SQL injection in api/views.py looks like this:

issues:
  - id: bandit-B608-001
    severity: critical
    file_path: api/views.py
    line_number: 47
    title: SQL Injection via String Formatting
    description: Query string assembled with % operator interpolating user input
      directly into SQL. Allows an attacker to modify the query structure.
    remediation: Replace with a parameterized query using ? or %s placeholders
      with a separate values tuple passed to cursor.execute(). Do not use
      str.format(), f-strings, or % formatting in SQL query strings.

Claude Code reads this entry and knows: the finding is critical priority, it’s on line 47 of api/views.py, and the fix is parameterized queries. It doesn’t need to read the whole file to understand the problem. It reads the flagged line and a narrow window around it, confirms the finding is real, and generates the fix.

How Severity Drives the Session

BrassCoders sorts findings severity-first before writing the file, which means Claude Code encounters a critical SQL injection before a medium-severity missing-timeout before a low-severity style note — without any instruction to prioritize in that order.

This matters for triage sessions. Without sorted input, an AI assistant reading raw source code has to assess each finding’s importance on its own and might address a style issue before a security vulnerability. The sorted file removes that judgment call. The session starts at the critical findings, works through the highs, and reaches the lows only after the dangerous findings are addressed.

BrassCoders applies a secondary severity filter when writing the file: if the total finding count exceeds the cap, it fills the critical slots before the high slots before the medium slots. A codebase with 1,500 raw scanner findings never produces a file where a high-severity finding gets dropped to make room for a low-severity one.

What the Line Number Does

BrassCoders writes a line_number field for every finding that has one; Claude Code uses this to pull a narrow code window around the flagged location rather than reading the entire file.

Without a line number, a code review starts from the file level: read the file, scan for patterns, form hypotheses about what might be wrong. With a line number, it starts from the exact location: read lines 44-50, check whether line 47 interpolates user input into the SQL string, confirm the vulnerability. The difference is roughly 20 lines of context versus 200.

For large files — a 400-line Flask view or a 600-line data processing module — the line anchor saves the session from getting lost in code that isn’t relevant to the finding. The model reads what matters.

What the Remediation Field Does

BrassCoders writes a remediation field for findings where a fix direction can be stated deterministically; Claude Code reads this field and starts fix generation from the stated pattern rather than deriving the correct approach from first principles.

For SQL injection, the remediation is always “use parameterized queries.” For shell=True subprocess calls, it’s “pass a list instead of a shell string.” For string concatenation in a loop, it’s “collect into a list and use ''.join().” These fix directions are correct for the structural pattern they match. The model reads the remediation, confirms it applies to the specific code, and writes the patch.

The finding where the model still adds value is when the stated remediation is right but the application is complex. A multi-table SQL query that needs parameterization might require restructuring the query, not just replacing %s with a values tuple. The model reads the remediation as a direction, reads the code as the constraint, and generates a fix that satisfies both. The remediation field narrows the solution space; the model handles the specific implementation.

Where Claude Code Adds What BrassCoders Can’t

BrassCoders missed one finding in the published benchmark that Claude Code caught: sum(readings) / len(readings) with no guard for an empty list — a ZeroDivisionError that leaves no structural marker for a rule to match.

This is the class of finding where Claude Code wins regardless of the pre-pass. A bug that requires reasoning about what a function receives in the unhappy path — “what happens when readings is empty?” — can’t be expressed as a deterministic rule. The .brass file doesn’t flag it because no pattern matches it. Claude Code finds it by reading the function and thinking through edge cases.

The pre-pass clears the structural layer; Claude Code covers the reasoning layer. Neither gap requires the other to pretend it doesn’t exist.

pip install brasscoders
brasscoders --offline scan /path/to/your/project

Frequently Asked Questions

Does BrassCoders integrate directly with Claude Code?

BrassCoders writes .brass/ai_instructions.yaml to the scanned project directory; Claude Code reads it automatically as part of the project context. No plugin or API integration is required — the file format is plain YAML, and Claude Code treats it as a local context file.

What does BrassCoders add that Claude Code's built-in review doesn't?

Claude Code's built-in review runs when invoked and samples non-deterministically. BrassCoders runs before Claude Code opens, on every scan, with the same findings every time. The .brass file tells Claude Code which lines to read and in what order — it focuses the model's reasoning without replacing it.

How do I run BrassCoders before opening Claude Code?

Install with pip install brasscoders, then run brasscoders --offline scan /path/to/project. The .brass/ai_instructions.yaml file is written to the project directory. Open Claude Code in the same directory and it picks up the file as project context.

What happens when Claude Code reads a remediation note?

Claude Code reads the remediation field, which describes the fix direction — for example, 'Replace with a parameterized query using ? or %s placeholders with a separate values tuple.' It reads the flagged line, confirms the finding, and generates the fix. The remediation note removes the discovery step; Claude Code starts at implementation.