Skip to content

Findings and Severities

What a Finding is and how to interpret the three severity levels.

A Finding is the smallest unit of output from CodeCharter. It represents a concrete location in code where a specific rule matched.

Anatomy of a Finding

Every Finding has:

Field Content
Rule Slug and display name of the rule, e.g. datetime-direct-usage
Severity info, warn, or error (machine-readable output spells the middle level warning)
Category Freely chosen; groups related rules
Entity Name and kind (class, method, ...) of the code element that matched
File Absolute or relative path to the file
Line Line number
Column Optional, column number
Message What was specifically found here
Description What the rule checks (from @description in the rule)
Recommendation What to do about it (from @recommendation in the rule)
Fingerprint Stable, line-independent ID of the finding across runs; used by --baseline to suppress known findings (see Baseline)

In JSON output, findings appear as violations next to a summary block:

{
  "summary": {
    "totalViolations": 1,
    "totalTypes": 128,
    "totalMethods": 932,
    "durationMs": 28400
  },
  "violations": [
    {
      "ruleId": "datetime-direct-usage",
      "ruleName": "Direct DateTime/DateTimeOffset usage instead of TimeProvider",
      "severity": "warning",
      "category": "Testability",
      "entityName": "PricingEngine.CalculatePrice",
      "entityKind": "Method",
      "filePath": "src/Domain/PricingEngine.cs",
      "lineNumber": 42,
      "column": 18,
      "message": "Direct call to DateTime.UtcNow",
      "description": "Direct calls to DateTime.Now/UtcNow/Today make code untestable",
      "recommendation": "Inject TimeProvider via constructor and call GetUtcNow()",
      "fingerprint": "a1b2c3d4..."
    }
  ]
}

Severities

CodeCharter has three severity levels.

info

A hint. Like every finding it fails the build by default; pass --fail-on warn or --fail-on error if info findings should not gate the build. Good for rules that catch nice-to-haves: "this spot would be more readable with the following refactoring idea". Be careful not to accumulate too many of these in day-to-day work, or they will be ignored.

warn

A warning. By default it blocks the build like any other finding, and it is visible in the output and in the editor. Good for conventions you want to enforce collectively, such as async methods without a CancellationToken. Pass --fail-on warn to gate only on warn and error, letting info findings through.

error

An error. Reserved for violations that truly must not reach the main branch: broken architecture, security vulnerabilities, explicitly forbidden APIs.

Default --fail-on behavior: when no --fail-on flag is passed, any finding of any severity (including warn and info) causes exit code 1. Exit code 0 means zero findings at or above the active threshold. Use --fail-on warn to allow info findings through, or --fail-on error to allow both info and warn findings through without gating the build.

Which Severity to Use

Rule of thumb: as strict as necessary, as friendly as possible.

  • error only when the violation would cause real harm (security, stability, contract breach).
  • warn for conventions the team wants to enforce collectively, with the understanding that justified exceptions exist.
  • info for style recommendations that are "better, but acceptable as-is".

A rule that uses only error because "if we're writing a rule it should have teeth" is an anti-pattern. Within days, devs will reach for // codecharter-disable instead of fixing the issue.

Overriding a rule's severity

You change a rule's severity in .codecharter/config.yml under overrides:, and switch a rule off entirely under ignore:. Both are addressed per rule by slug, not per file or per line. See Configuration file for the full set of sections.

# .codecharter/config.yml
version: 1
overrides:
  datetime-direct-usage:     # a built-in rule slug
    severity: warning        # error | warning | info
ignore:
  - rule: empty-catch-block  # switch this rule off entirely

To silence findings at a specific location instead, use a // codecharter-disable comment (see Suppressions).

Aggregation

In the build output, findings are sorted by severity, then file, then line. Duplicate findings (same rule, entity, file, and line) are reported only once. Use --severity <level> to set the minimum severity to display (default: info, i.e. everything). At the end of the run there is a summary; severity buckets with zero findings are omitted:

  17 violations (3 errors, 14 warnings)
  Analyzed 128 types, 932 methods in 28.4s

For exit code behavior and CI integration see Exit Codes and Output Formats.