Enumerated all 484 Biome 2.5.10 rules, enabled every non-recommended one at
`error` in a throwaway config, and linted the repo to measure real cost:
13,690 diagnostics across 111 rules — and 196 rules that fire zero times.
The zero-cost set is what landed.
`pnpm lint` now fails on warnings. `biome check` exits 0 when every
diagnostic is warn/info, and 87 of the 182 recommended rules default to that
severity — useConst, noApproximativeNumericConstant, useDefaultSwitchClauseLast
and friends were all advisory in CI. The repo passes clean under the stricter
gate, so this closes the hole without a code sweep.
Type-aware rules, all at zero violations: noFloatingPromises, noMisusedPromises,
useExhaustiveSwitchCases, noUnsafePlusOperands, noUselessTypeConversion. They do
not need `domains.project`, which matters — that domain would also drag in
noUnresolvedImports and noUndeclaredDependencies, both unusable here.
useImportExtensions is on for the packages and off for apps/ui: packages/*/src is
already 100% extension-ful because it ships NodeNext ESM, while all 251
violations are Vite-bundled UI code where extensionless is idiomatic.
Small fixes unlocked four more rules — noAssignInExpressions (a dead
`ancestors ??=` in jsonUnsafeAt), noParameterAssign, useTemplate,
noUselessStringConcat — and the test-integrity rules caught four real defects:
duplicate `round 33` describe block, afterAll declared before beforeEach, a type
exported from a test file, and bare `Array(4)`.
Rejected rules are recorded with counts and reasons in
docs/reviews/2026-08-lint-strictness.md, including nine whose findings are
false positives from Biome's inference and should be re-tested on upgrade.
Lint wall-clock: 0.65s -> 7s, the type-inference scanner.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017nyvcrD1We7vV3Tjsjdq9j
What this is
An empirical audit of Biome 2.5.10's rule surface against this repo, plus the tightening it justified.
Method: enumerated all 484 rules from Biome's config schema, enabled every one of the 302 non-recommended rules at
errorin a throwaway config, and linted the repo with--reporter=json. That produced 13,690 diagnostics across 111 rules — and, more usefully, 196 rules that fire zero times. A rule at zero violations is free: it changes no code today and stops the pattern from arriving tomorrow. That is most of what landed.Full write-up with per-rule counts:
docs/reviews/2026-08-lint-strictness.md.Changes
pnpm lintnow fails on warnings. This was the largest soundness hole and had nothing to do with which rules were on.biome checkexits0when every diagnostic is warn/info, and 87 of the 182 recommended rules default towarn(57) orinfo(30) —useConst,noApproximativeNumericConstant,useDefaultSwitchClauseLast,noConstEnum. Verified directly: a file with auseConstviolation reports "Found 1 warning" and exits0. The repo passes clean under--error-on-warnings, so this closed the hole without a code sweep.Type-aware rules, all at zero violations:
noFloatingPromises,noMisusedPromises,useExhaustiveSwitchCases,noUnsafePlusOperands,noUselessTypeConversion.noFloatingPromisesreturning zero on a codebase this async-heavy was surprising enough to verify against a synthetic floating promise — the rule fires, the repo is simply clean. Locking that in is the most valuable line in the diff, given the engine's correctness rests on awaited journal writes. These do not requiredomains.project(confirmed withproject: "none"), which matters: that domain would also drag innoUnresolvedImportsandnoUndeclaredDependencies, both unusable here.useImportExtensions, scoped.packages/*/srcis already 100% extension-ful (293.ts+ 1.tsxrelative imports, zero extensionless) because the published packages are NodeNext ESM, where a missing extension is a runtimeERR_MODULE_NOT_FOUND. All 251 violations live inapps/ui, which is Vite-bundled. On globally, off forapps/uivia an override — zero code changed, and the "works in tests, breaks on install" class is now unrepresentable in the shipped packages.96 rules enabled beyond
recommendedacross suspicious (24), style (29), correctness (14), nursery (18), complexity (9), security (2).Code changes
Nine small fixes, each unlocking a rule:
core/src/jsonschema.ts—const seen = (ancestors ??= new WeakSet())×2; the mutation was dead, recursion already passesseendownnoAssignInExpressions,noParameterAssigncli/src/commands/answer.ts— parameter reassignment → localsnoParameterAssigngate/src/load.ts,store-fs/src/journal.ts,examples/03,isolation/test/tmp/nested.mts— string concat → templateuseTemplate,noUselessStringConcatapps/ui/src/domain/views.ts—!!value→value !== undefinednoImplicitCoercionsAnd four real defects the test-integrity rules found:
core/test/review-regressions.test.tshad twodescribeblocks titled "codex review findings, round 33 (PR Initial Weft implementation: durable multi-agent workflows #1)"host/test/task-removal-durability.test.tsdeclaredafterAllbeforebeforeEachdaemon/test/api.test.tsexported a type from a test filegate/test/gate.test.tsusedArray(4)rather thannew Array(4)Alongside them:
noFocusedTests(a stray.onlysilently shrinks CI to one test),noSkippedTests,noDuplicateTestHooks,useTestHooksOnTop,noExcessiveNestedTestSuites.What was deliberately rejected
Nine rules produce false positives from Biome's inference — every finding was read in context and is wrong.
noUnresolvedImports(74) claimsreacthas noStrictModeorFragment;noUnnecessaryConditions(61) callsif (readyTimer.current)always-falsy because it cannot model a React ref;useAwaitThenable(5) flagsawaitonT | Promise<T>unions;useNullishCoalescing(1) flags a deliberate||where0must fall through. These are worth re-testing on each Biome upgrade.Deferred real debt, ranked:
useErrorCause(21 rethrows discarding the original stack — highest value),noEvolvingTypes(10),noShadow(36),noExplicitAny(49, concentrated in 8 files and adoptable as a scoped override rather than a blanketoff),noNonNullAssertion(241, of which 184 are tests).Framework rules for stacks this repo doesn't use were excluded outright — note Biome runs them regardless of what's installed, so
noReactSpecificProps(604) andnoSolidDestructuredProps(213) are noise, not findings.Verification
pnpm lint— clean under--error-on-warningspnpm typecheck— cleanpnpm test— 992 passed, 1 pre-existing failure (daemon/test/api.test.tsEACCES case, which cannot fail as root; confirmed identical on the untouched tree)pnpm build,pnpm verify:examples— cleanpnpm sync:meta --check— fails onpackages/testing/README.md, pre-existing onmain, unrelatedLint wall-clock goes from 0.65s → 7s — the type-inference scanner. That's the price of
noFloatingPromises, in a 10-minute CI job.Note for reviewers
18 of the 96 rules are in Biome's
nurserygroup, which is explicitly unstable.@biomejs/biomeis pinned to an exact2.5.10, so they can't shift under CI — but a Biome upgrade should re-run this measurement.Generated by Claude Code