wiki / concepts / deterministic-lint-gates

Deterministic Lint Gates

high confidence updated 2026-08-30 coding-guidelines · feedback-loops · agents · workflow

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 via typescript-go and 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-cycle performance 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 principleAgent 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-varsSlow gates starve the inner agent loop — the exact misplacement failure named in constraint layering
Autofixable rules preferred; subjective style rules disabledFriction 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

  1. Every rule errors. A warning tier trains the loop to ignore the gate.
  2. 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.
  3. One check, one layer. Disable lint rules duplicated by the compiler; never prompt for what the linter enforces.
  4. Structured diagnostics over prose. Spans + docs links make agent auto-repair reliable.
  5. 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.json remains active. [source: lint-staged-official-readme-2026]
  • Husky is the local trigger. husky init creates a repository-managed pre-commit hook and a package-manager prepare script. 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

SymptomRoot causeFix
Lint passes but code is wrongGates cover style, not behaviorPair lint gates with eval/conformance suites
Gate bypassed via —no-verifyHooks treated as advisoryEnforce in CI, not just local hooks
Gate noise trains devs to ignore itRules without signal volume tuningError-only severity on new gates; expand after signal proves out
Evidence — verified primary sources
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…