lintdiff maps structured Rust compiler / Clippy diagnostics to lines touched by a PR and emits a stable, schema-validated receipt suitable for CI ingestion.
Question answered: "Which diagnostics from the head analysis are located on PR-touched lines, and why?"
See PRODUCT.md for the supported product boundary, limitations, and comparison with adjacent tools.
The supported product is the release-binary CLI and the GitHub Action. The
release target is the exact v0.1.1 Action tag; use it only after the tag and
post-release canary gates pass.
- Deterministic receipt:
lintdiff.report.v1is the canonical output protocol. - Repository proof: tests, benchmarks, fuzzing, coverage, and
xtaskchecks support maintenance; their counts are not product readiness claims. - Narrow scope: the current mode locates diagnostics on changed lines. It does not establish diagnostic newness relative to a base analysis.
- Build-truth consumer: it consumes an existing diagnostics stream (usually
cargo clippy --message-format=json). - Diff-scoped: it maps diagnostics onto the PR diff (new-side line numbers).
- Deterministic: same inputs → byte-stable JSON + Markdown.
- Protocol-shaped: emits
artifacts/lintdiff/report.jsonin a strict envelope. - Budgeted: capped surfaced findings; full detail lives in artifacts.
- Produce a diagnostics stream:
cargo clippy --message-format=json > artifacts/clippy.jsonl- Produce a diff:
git diff --unified=0 "$BASE_SHA..$HEAD_SHA" > artifacts/patch.diff- Run lintdiff:
lintdiff ingest --diagnostics artifacts/clippy.jsonl --diff-file artifacts/patch.diff --out artifacts/lintdiff/report.json --md artifacts/lintdiff/comment.md --annotations githubThe easiest way to use lintdiff is with our GitHub Action:
name: Lintdiff
on: pull_request
jobs:
lintdiff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for git diff
- run: cargo clippy --message-format=json > clippy.jsonl
- uses: EffortlessMetrics/lintdiff@v0.1.1
with:
diagnostics: clippy.jsonl
fail_on: warn # Optional: error, warn, or neverSee action.yml for all available inputs and outputs.
docs/architecture.md– role, boundaries, IO contracts, failure modesdocs/requirements.md– requirements and invariantsPRODUCT.md– supported product contract and limitationsdocs/design.md– internal layered engine/application designdocs/implementation-plan.md– phased plan + test strategy
The enforced workspace currently contains five members: four runtime packages and
the repository-only xtask control plane. fuzz/ remains excluded. The normal
runtime graph is lintdiff → {lintdiff-engine, lintdiff-render, lintdiff-types};
the engine and renderer depend on lintdiff-types only among lintdiff packages.
lintdiff-types is the only package with publication intent. The engine, renderer,
application, and xtask remain publish = false; no public engine crate is implied
by the internal package boundary. The dated disposition ledger at
plans/microcrate-collapse-ledger.toml is
the migration record, and cargo run -p xtask -- architecture-check is the
enforcement surface.
Dual-licensed under MIT or Apache-2.0.