Skip to main content
Audit changed files for dead code, complexity, and duplication. Returns a verdict — pass, warn, or fail — based on the severity of issues found. Scoping to changed files keeps the signal-to-noise ratio high: you see only what this PR or commit introduced, not the entire project’s backlog.
fallow audit auto-detects your base branch. Run it without arguments for a zero-config quality check.
fallow audit

Options

Base ref

FlagDescription
--base <REF>Git ref to compare against (e.g., main, HEAD~5, a commit SHA). Alias for --changed-since. Auto-detects the default branch if omitted.

Output

FlagDescription
-f, --format <FORMAT>Output format: human (default), json, sarif, compact, markdown, codeclimate
-q, --quietSuppress progress and status output on stderr
--explainAdd metric explanations in JSON output (_meta objects with docs links)

Scoping

FlagDescription
-w, --workspace <NAME>Scope to a single workspace package
--productionExclude test/story/dev files

Verdict

VerdictExit codeWhenWhat to do
pass0No issues in changed filesShip it.
warn0Issues found, all warn-severityCI passes, but consider fixing before they become errors.
fail1Error-severity issues foundFix the reported issues before merging.
error2Runtime error (invalid ref, not a git repo, config error)Check the error message. In JSON format, emits {"error": true, "message": "...", "exit_code": 2}.
Dead code issues follow your rules configuration severity (error/warn/off). Complexity findings above configured thresholds are always errors — thresholds are inherited from your fallow health config (defaults: cyclomatic 20, cognitive 15). Duplication is a warning unless a --threshold is configured.
Inline suppression comments (// fallow-ignore-next-line) work in audit — findings in changed files are suppressed the same way as in fallow dead-code.

Examples

# Auto-detect base branch
fallow audit

# Explicit base ref
fallow audit --base main

# Audit last 3 commits
fallow audit --base HEAD~3

Example output

$ fallow audit (pass)
Audit scope: 8 changed files vs main (d4a2f91..HEAD)
 No issues in 8 changed files (1.18s)
$ fallow audit (warn)
Audit scope: 8 changed files vs main (d4a2f91..HEAD)
 dead code 0 · complexity 2 (warn, max cyclomatic: 12) · duplication 0
 dead code: 0 issues · complexity: 2 findings (warn) · 8 changed files (1.18s)
The summary line appears only on warn verdicts, before any detail sections. It is suppressed with --quiet.
$ fallow audit (fail)
Audit scope: 12 changed files vs main (d4a2f91..HEAD)

── Dead Code ──────────────────────────────────────

 Unused exports (2)
  src/components/Button.tsx (2)
    :42 OldButton
    :67 deprecatedHelper
  Exported symbols not imported by any reachable file https://docs.fallow.tools/explanations/dead-code#unused-exports

── Duplication ────────────────────────────────────

 Duplicates (1 clone group)

    23 lines  2 instances
    src/utils/helpers.ts:10-32
    src/legacy/compat.ts:5-27

── Complexity ─────────────────────────────────────

 High complexity functions (1)
  src/parser.ts
    :45 parseExpression
         28 cyclomatic  32 cognitive  80 lines
  Functions exceeding thresholds https://docs.fallow.tools/explanations/health#complexity-metrics

 dead code: 2 issues · complexity: 1 finding · duplication: 1 clone group · 12 changed files (2.14s)

How it works

  1. Resolve base ref: uses --base if provided, otherwise auto-detects the default branch (git symbolic-ref refs/remotes/origin/HEADmainmaster). Hard-errors if no base can be determined.
  2. Find changed files: runs git diff --name-only <base>...HEAD (three-dot diff — changes since the merge base).
  3. Run three analyses scoped to changed files: dead code, complexity, duplication.
  4. Compute verdict: aggregates severity across all three analyses into pass/warn/fail.

JSON output

$ fallow audit --format json
{
  "schema_version": 3,
  "version": "2.8.0",
  "command": "audit",
  "verdict": "fail",
  "changed_files_count": 12,
  "base_ref": "main",
  "head_sha": "d4a2f91",
  "elapsed_ms": 2140,
  "summary": {
    "dead_code_issues": 2,
    "dead_code_has_errors": true,
    "complexity_findings": 1,
    "max_cyclomatic": 28,
    "duplication_clone_groups": 0
  },
  "dead_code": {
    "schema_version": 3,
    "total_issues": 2,
    "unused_exports": [...]
  },
  "complexity": {
    "findings": [...]
  },
  "duplication": {
    "clone_groups": [],
    "stats": { "duplication_percentage": 0.0 }
  }
}

Key fields

FieldTypeDescription
verdict"pass" | "warn" | "fail"The audit result. Use this for CI gates.
changed_files_countintegerNumber of files changed between base and HEAD
base_refstringThe git ref used for comparison
summary.dead_code_issuesintegerTotal dead code issues in changed files
summary.dead_code_has_errorsbooleanWhether any dead code issues have error severity
summary.complexity_findingsintegerFunctions exceeding complexity thresholds
summary.max_cyclomaticinteger | nullHighest cyclomatic complexity found (null if none)
summary.duplication_clone_groupsintegerClone groups involving changed files
The dead_code, complexity, and duplication sub-objects contain full results in the same format as fallow dead-code, fallow health, and fallow dupes respectively. These are omitted when no files changed.
On exit code 2 (runtime error), JSON format emits {"error": true, "message": "...", "exit_code": 2} to stdout instead of the audit envelope.

MCP tool

The audit MCP tool wraps fallow audit --format json --quiet --explain:
Example request
{
  "tool": "audit",
  "arguments": {
    "base": "main"
  }
}
Auto-detects the base branch if base is not specified. The response always includes _meta explanatory metadata (the MCP wrapper enables --explain by default). Returns the same JSON envelope as the CLI. See MCP integration for setup instructions.

See also

Dead code analysis

Full dead code analysis with issue-type filters.

Health analysis

Complexity metrics, file scores, hotspots, and targets.

MCP integration

Use fallow tools from AI coding agents.