Skip to content
lawlint
Esc
navigateopen⌘Jpreview
On this page

JSON output

The schema of --format json — diagnostics, spans, fixes, and stats.

lawlint draft.md --format json
{
  "diagnostics": [
    {
      "ruleId": "no-em-dash",
      "severity": "warning",
      "tier": "static",
      "intent": "detection",
      "span": { "start": 42, "end": 45 },
      "message": "An em dash where a comma would do.",
      "line": 3,
      "column": 12,
      "endLine": 3,
      "endColumn": 15,
      "excerpt": "The clause — which we drafted — is void.",
      "suggestion": "Use a comma.",
      "weight": 1,
      "fix": {
        "edits": [{ "range": { "start": 42, "end": 45 }, "replacement": "," }],
        "applicability": "machineApplicable"
      }
    }
  ],
  "stats": { "wordCount": 812, "sentenceCount": 41, "score": 73 }
}

Optional fields are omitted rather than emitted as null.

diagnostics[]

PropType
ruleIdstring

Namespaced for package rules: <package>/<id>.

Typestring
severity"error" | "warning" | "suggestion"

"info" is accepted on input as an alias for "suggestion".

Type"error" | "warning" | "suggestion"
tier"static" | "statistical" | "inferential"

The stable kind contract. static and statistical are hard rules; inferential is soft.

Type"static" | "statistical" | "inferential"
intent?"detection" | "style"

Only detection findings charge the score. Absent in results serialized before intent existed.

Type"detection" | "style"
Default"detection"
span{ start, end }

Byte offsets into the linted text.

Type{ start, end }
messagestring

What the rule found.

Typestring
linenumber

1-based.

Typenumber
columnnumber

1-based, in UTF-16 code units.

Typenumber
endLine?number

1-based. Omitted for single-position findings.

Typenumber
endColumn?number

1-based, UTF-16 code units.

Typenumber
excerptstring

The trimmed source line the finding sits on.

Typestring
suggestion?string

Prose advice. Present even when there is no applicable fix.

Typestring
weight?number

Score penalty multiplier. Density rules scale it by how far past threshold the text runs.

Typenumber
confidence?number

Inferential (soft-rule) findings only.

Typenumber
fix?Fix

Present only when the rule produced one.

TypeFix

fix

PropType
edits{ range: { start, end }, replacement: string }[]

Byte ranges to replace. A fix may carry more than one edit.

Type{ range: { start, end }, replacement: string }[]
applicability"machineApplicable" | "maybeIncorrect"

--fix applies machineApplicable edits only.

Type"machineApplicable" | "maybeIncorrect"

See Fixes and tracked changes.

stats

PropType
wordCountnumber

Words in the linted text — the denominator for score normalization.

Typenumber
sentenceCountnumber
Typenumber
scorenumber

Human-likeness score, 0–100.

Typenumber

judge

Present only when the AI judge ran, carrying that run’s judging statistics. A “chunk” here is one judge request.

PropType
chunksnumber

Requests the run planned. Depends on the backend's batching — one per rule for hosted models, one per section for local ones.

Typenumber
cacheHitsnumber

Requests answered from the on-disk cache instead of the provider.

Typenumber
chunksFailednumber

Requests that failed after a retry. Those chunks contributed no findings and fell back to the deterministic tiers.

Typenumber
groundednumber

Findings whose quote was matched back to a source span. Only these become diagnostics.

Typenumber
hallucinatedRecord<string, number>

Discarded findings per rule id: an ungroundable quote, or a rule the request never asked about.

TypeRecord<string, number>
firstFailure?string

Why the first failed chunk failed. Absent when chunksFailed is 0.

Typestring
{
  "chunks": 2,
  "cacheHits": 0,
  "chunksFailed": 0,
  "grounded": 3,
  "hallucinated": { "empty-hedge": 1 }
}

Rule metadata

lawlint rules --json prints the loaded rule set rather than a lint result:

[
  {
    "id": "empty-hedge",
    "meta": {
      "tier": "inferential",
      "scope": "text",
      "severity": "warning",
      "description": "Flags hedges that carry no information about actual uncertainty.",
      "docsUrl": "https://lawlint.com/rules/empty-hedge",
      "examples": [],
      "rationale": "A hedge earns its place only when it tells the reader what is uncertain and why."
    }
  }
]

This is what generates the rule reference.

Compatibility

Key off tier, not the hard/soft terminology — tier is the serialized contract and will not change. New optional fields may be added; parse permissively.

Last updated on July 24, 2026