ADR-1762: Every translation unit is read by a clang-tidy lane or excepted by name¶
- Status: Accepted (status update 2026-10-06 below)
- Date: 2026-10-05
- Deciders: Lusoris
- Tags: ci, clang-tidy, lint, ratchet, metal, fuzz, mcp, fork-local
Context¶
ADR-1142 applies clang-tidy to the whole tree through per-lane baselines, but a baseline only counts the translation units its lane compiles. An audit of master found 107 of 759 tracked translation units in no lane's measured_sources: the embedded MCP server and its tests (meson builds them only with -Denable_mcp=true), the libFuzzer harnesses (-Dfuzz=true is a configure error under gcc), the Objective-C++ Metal host code and Metal-only C tests (they need Apple's SDK), the Metal kernels, the HISS rule fixtures, an eBPF program, Windows-only files, the Rust glue, the Pelorus mirror and two standalone probes. Nothing failed when a unit was in no lane, so the set could only grow.
Decision¶
Every tracked .c, .cc, .cpp, .cxx, .cu, .hip, .mm and .metal file is in the measured_sources of at least one scripts/ci/tidy-baseline-<lane>.json, or in the shared lint exception list (.config/lint-exceptions.d/) with one path, the rule clang-tidy-coverage, a reason naming the missing tool or toolchain, and an expiry date. A check (a pre-commit hook, run by CI on every pull request; it lands in the follow-up pull request) fails on an unread unit, an expired entry, an entry for a missing file and an entry for a file a lane reads. The readable files join a lane: the cpu lane configures the MCP server; a new clang lane builds the fuzz harnesses and measures only them; a macOS metal lane (Homebrew llvm@22, the Xcode SDK, workflow tidy-metal.yml) measures the Metal host code. Lanes that read one part of the tree take --select; a scoped baseline write records the units it measures. Upstream clang-tidy has no Metal language mode (clang -x metal answers "language not recognized"), so the 17 kernels are listed with that reason.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
| Gate on the coverage gap (chosen) | A new unit cannot enter the tree unread; the debt is bounded by dated entries | One more list to keep | |
| Leave the gap as a recorded state row | No tooling | The set only grows; the audit found it by accident | A gap with no gate is the failure this decision ends |
| One big lane that builds everything | One baseline | gcc and clang, CUDA and SYCL, Linux and macOS cannot configure together; a failed configure hides every file | The unit of measurement is a configuration the toolchain can build |
Fuzz in the cpu lane through a clang build | No extra lane | Moves the hosted Tidy Ratchet job, which must stay gcc-15, to clang | The hosted measurement must stay byte-identical to the container's |
| macOS lane as a required per-pull-request check | Strongest gate | A macOS runner bills ten times a Linux one | Weekly, on Metal changes and on dispatch, like the tester bundle (ADR-1595); required once it has passed on master |
Consequences¶
- Positive: the unread set is bounded and dated; new MCP and fuzz code is measured; Metal host code gets a gate of its own.
- Negative: a
clangbaseline and ametalbaseline to maintain; themetallane has no container and cannot be written from the workstation. - Neutral / follow-ups: a Rust-enabled lane, a lane with CUDA and SYCL together and a Windows lane retire the matching entries before their expiry.
References¶
Q(maintainer popup answer, 2026-10-05, "Gated debt first"): before the rc.3 tag every C, C++ and Objective-C++ translation unit is read by a clang-tidy lane with zero findings, or, only where no tool can read it, is listed with a reason.- ADR-1142 (the ratchet), ADR-1243 (scoped writes), ADR-1471 (container lanes), ADR-1113 (the Pelorus mirror).
Status update 2026-10-06: Accepted¶
The decision was applied while this record still said Proposed. Checked on origin/master fd8b8c93b: #2101 (483c8274b, 2026-10-05) added the coverage check scripts/ci/check-tidy-coverage.py and its pre-commit hook clang-tidy-coverage, the shared exception list .config/lint-exceptions.d/clang-tidy-coverage.toml, the clang and metal baselines (scripts/ci/tidy-baseline-clang.json, scripts/ci/tidy-baseline-metal.json) and the macOS lane .github/workflows/tidy-metal.yml; docs/development/tidy-lanes.md describes the lanes.
The body above is unchanged.