linting and formatting

why

  • reviewer attention is the scarce resource a review spends.
  • unowned formatting puts mechanical noise in every diff — reviewers fight it line-by-line or learn to ignore it; ignoring eventually hides real defects.
  • package-owned mechanical gates keep style out of human review, so remaining human signal is behavior.
  • separate owned format/lint commands make each failure tell the repair loop exactly which loop to run.

rule

  • formatting and linting are compulsory quality gates: code works only when it behaves correctly and follows one consistent project style, so reviewers focus on changed behavior, not formatting noise.
  • formatting = mechanical presentation; linting = correctness, stable boundaries, durable source conventions.
  • keep their ownership and failure messages separate so each signal tells the repair loop what to do.

formatting

  • each package owns a format check and an explicit format:fix command.
  • one formatter configuration for authored files in that package.
  • format only files the formatter owns; never format generated output, applied migrations, or protected files.
  • inspect the focused diff after a formatter writes, especially in a concurrent working tree.

linting

  • each package owns a lint check for the language and framework it runs.
  • enforce structural facts statically when objective: forbidden import direction, generated-output edits, generic filenames, aliasing, component placement.
  • judgement calls that are not mechanically provable go to a design review rule; no opaque lint heuristics for taste.
  • suppression is narrow, documented, temporary; removed with the underlying cause.

workspace execution

  • root Turbo tasks coordinate package-local format, lint, typecheck.
  • run the narrow package check while iterating; run the relevant workspace pipeline before claiming shared readiness.
  • a lint or formatting failure blocks handoff until the responsible source or configuration is corrected.

choose enforcement by proof strength

rule kindenforcementreason
syntax, formatting, import direction, generated-file ownershipformatter/linter/static checkobjective source fact with deterministic detection.
type compatibility or public contracttypecheck/generationcompiler/generator owns the proof.
runtime/user-visible behaviorfocused test, smoke path, or UATstatic analysis cannot observe the outcome.
ownership judgement or visual coherencedocumented review questiona heuristic would produce false authority and encourage bypasses.

repair loop

  • read the exact tool output; identify the owning file/configuration.
  • make the narrowest source correction; rerun the same narrow command.
  • no global disables, exclusions, or formatter overrides to make unrelated violations disappear.
  • broaden from package check to workspace graph only after the local failure is understood and repaired.

verification

  • the command runs from the package that owns the files.
  • the failure points at a real source/configuration boundary.
  • a suppression — if truly unavoidable — names its reason, scope, owner, and removal condition.
  • inspect the formatter diff separately from behavior changes.

good and bad

bad

eslint . --rule "no-restricted-imports: off" # global disable
  • a global disable makes unrelated violations disappear; the failure message can no longer tell the repair loop what to fix.
  • the enforced rule — import direction, generated-file ownership, naming — stops being checked anywhere in that run; violations accumulate silently behind the disable.
  • the next reader inherits both the defects and the habit of switching rules off to make output green.

good

pnpm --filter @app/web lint # package-owned check fails
pnpm --filter @app/web lint # rerun the same command after the narrow fix
  • each package owns its lint gate; the narrowest source correction repairs the failure and the same command proves it.
  • reviews stay free of mechanical noise — human attention spends only on behavior.
  • structural conventions are enforced deterministically on every run, not by a reviewer remembering them.
  • the gate stays cheap enough to run continuously, which keeps drift from compounding between checks.

do not

  • treat a formatter pass as proof of correctness.
  • hide lint violations with broad disable directives or configuration excludes.
  • use a root script to reach into package files without that package owning the command.

search pages

go to any page