wiki / concepts / deterministic-lint-gates
Deterministic Lint Gates
loading…
Deterministic Lint Gates
A deterministic lint gate is a sub-second, native-speed linter run after every coherent agent edit, configured so that every enabled rule fails the build. It converts code-style and bug-pattern policy from probabilistic prompt compliance into mechanical backpressure — the concrete Tier 1 implementation of constraint layering’s “script the mechanical” maxim inside agentic code quality.
The Reference Stack: Oxlint
Oxlint is a high-performance JavaScript/TypeScript linter built on the Oxc compiler stack in Rust. Its published benchmarks show it is “50 to 100 times faster than ESLint”, with “more than 865 rules” covering ESLint core, TypeScript, React, Jest, Vitest, Import, Unicorn, and jsx-a11y. [source: oxlint-linter-overview-2026]
Architecture properties relevant to agent harnesses:
- Correctness-focused defaults — out of the box it prioritizes “high-signal correctness checks” over style noise. [source: oxlint-linter-overview-2026]
- Type-aware linting — delegated to
tsgolint, which builds TypeScript programs viatypescript-goand returns structured diagnostics; supports 59 of 61 type-aware rules from typescript-eslint. Enables checks like detecting floating promises. [source: oxlint-type-aware-linting-2026] - Multi-file analysis — a project-wide module graph shared across rules, avoiding the
import/no-cycleperformance cliff seen in ESLint. [source: oxlint-linter-overview-2026] - AI-friendly diagnostics — diagnostics carry precise spans, contextual data, and documentation links so agents “understand issues and apply fixes reliably”. [source: oxlint-linter-overview-2026]
- Reliability policy — crashes and performance regressions are both treated as bugs, prioritizing CI and large-monorepo throughput. [source: oxlint-linter-overview-2026]
The Reference Policy: Error, Never Warn
@nkzw/oxlint-config (christoph nakazawa) is an opinionated preset whose principles map directly onto agent-loop failure modes: [source: nkzw-oxlint-config-2026]
| Config principle | Agent failure mode it closes |
|---|---|
| “Error, Never Warn: Warnings are noise and get ignored” | Agents (and humans) ignore non-blocking output; exit code 0 means the loop proceeds |
Debug-only code disallowed (no-console, no-only-tests) | Leftover debug logging; test.only silently skipping the suite — a reward-hacking vector flagged in agentic code quality |
Problematic patterns banned (instanceof via @nkzw/no-instanceof) | Plausible-looking generated code that breaks across bundle/realm boundaries |
Fast: slow rules avoided; TypeScript noUnusedLocals preferred over no-unused-vars | Slow gates starve the inner agent loop — the exact misplacement failure named in constraint layering |
| Autofixable rules preferred; subjective style rules disabled | Friction and noise without bug-prevention payoff |
Deterministic sorting (perfectionist/sort-objects, sort-interfaces, sort-jsx-props) | Noisy diffs and syntactic merge collisions across parallel agent worktrees |
The config also demonstrates layering discipline in miniature: for TypeScript files it disables rules the type-checker already enforces (no-undef, no-dupe-keys, no-unreachable) — each check lives in exactly one layer. [source: nkzw-oxlint-config-2026]
Design Rules
- Every rule errors. A warning tier trains the loop to ignore the gate.
- The gate must be faster than the generator. Sub-second feedback keeps repair inside the inner loop; minute-scale linting pushes fixes to review, where they cost more.
- One check, one layer. Disable lint rules duplicated by the compiler; never prompt for what the linter enforces.
- Structured diagnostics over prose. Spans + docs links make agent auto-repair reliable.
- Sort mechanically. Deterministic ordering is merge-conflict prevention for multi agent orchestration, not aesthetics.
Commit-Time Gate Topology
Oxlint, lint-staged, Husky, and CI solve different problems and should not be collapsed into one giant hook:
flowchart LR
E[Coherent edit] --> O[Oxlint fast correctness gate]
O --> T[Typecheck and changed tests]
T --> S[Stage focused files]
S --> L[lint-staged selects staged paths]
L --> H[Husky pre-commit hook]
H --> C[Protected CI full-suite oracle]
C --> P[Proof packaged with patch]
- Oxlint is the diagnostic engine. Its correctness-focused defaults, structured spans, multi-file analysis, and fast execution make it suitable for frequent agent feedback. [source: oxlint-official-linter-2026]
- lint-staged is the selector. It passes staged files to commands, reducing commit-time work. Project-wide tools such as TypeScript typechecking must be invoked through a function command so filenames are not appended and
tsconfig.jsonremains active. [source: lint-staged-official-readme-2026] - Husky is the local trigger.
husky initcreates a repository-managed pre-commit hook and a package-managerpreparescript. Hooks remain bypassable, so they accelerate feedback rather than establish release authority. [source: husky-official-get-started-2026] - CI is the authority. It repeats non-bypassable full checks on a clean checkout. This follows constraint layering: script mechanical checks locally, then gate consequential merges with protected oracles.
A good default is staged formatting plus Oxlint in pre-commit, with project-wide typecheck, tests, dependency contracts, and builds in CI. Keep the hook comfortably faster than a model iteration; move expensive checks outward rather than teaching agents to bypass slow hooks.
Failure Modes
| Symptom | Root cause | Fix |
|---|---|---|
| Lint passes but code is wrong | Gates cover style, not behavior | Pair lint gates with eval/conformance suites |
| Gate bypassed via —no-verify | Hooks treated as advisory | Enforce in CI, not just local hooks |
| Gate noise trains devs to ignore it | Rules without signal volume tuning | Error-only severity on new gates; expand after signal proves out |
Related
- agentic code quality — Tier 1 fast inner loop this pattern implements
- constraint layering — the allocation principle (“script the mechanical”)
- five debts of agentic engineering — verification debt closed by mechanical gates
- releasable patch rate — the factory metric fast gates protect
- agentic engineering patterns — bounded fix loops and execution budgets
| oxlint-linter-overview-2026 | https://oxc.rs/docs/guide/usage/linter.md | ingested 2026-08-28 sha256:c0c548a921af… |
| oxlint-official-linter-2026 | https://oxc.rs/docs/guide/usage/linter.html | ingested 2026-08-29 sha256:7cb3deead4b3… |
| nkzw-oxlint-config-2026 | https://github.com/nkzw-tech/oxlint-config | ingested 2026-08-28 sha256:6fef6bb53023… |
| oxlint-type-aware-linting-2026 | https://oxc.rs/docs/guide/usage/linter/type-aware.html | ingested 2026-08-27 sha256:f22fe71ea605… |
| husky-official-get-started-2026 | https://typicode.github.io/husky/get-started.html | ingested 2026-08-29 sha256:42253ec2e973… |
| lint-staged-official-readme-2026 | https://github.com/lint-staged/lint-staged | ingested 2026-08-29 sha256:6c106f06eb2a… |
| addy-osmani-agentic-code-quality-2026 | https://addyosmani.com/blog/agentic-code-quality/ | ingested 2026-08-27 sha256:7fa8c35a8f4c… |