Problem
npm run lint:ceiling fails on master, with no change in the working tree:
$ npm run lint:ceiling
ESLint errors: 318 (ceiling 321)
✗ ESLint regressed. These rules got worse:
no-irregular-whitespace: 3 (ceiling 1, +2)
The total is comfortably under the ceiling. The failure is entirely a stale per-rule
entry: .lint-ceiling.json records "no-irregular-whitespace": 1, and the tree has three.
The three are all pre-existing, and none of them is a defect — they are deliberate non-breaking
spaces in test fixtures and expectations:
frontend/e2e/empty-states.spec.ts:167
frontend/src/i18n/__tests__/format.test.ts:17
frontend/src/i18n/__tests__/translate.test.ts:19
The last two are the i18n formatter's own tests, which assert French number formatting — and
French number formatting is a narrow no-break space. Removing the character would make the
test assert the wrong thing.
Found while working #438: the gate flagged a "regression" on a branch that had actually
reduced total ESLint errors from 318 to 315.
Why this matters beyond the noise
D-022 set this ratchet deliberately: "the frontend lint gate is ratcheted at 321, not swept and
not downgraded." A ratchet that fails on an untouched tree trains everyone to ignore it, which
is precisely how the next real regression gets waved through.
Acceptance criteria
- Given
master with a clean working tree, When npm run lint:ceiling runs, Then it passes.
- Given the three sites above, When they are read, Then either the non-breaking space is kept
and the rule is configured to allow it in test fixtures (skipStrings, or an override for
**/__tests__/** and e2e/**), or each site carries a targeted disable comment saying why
the character is intentional. The character must not be silently replaced with a normal
space in the i18n tests: that would make them assert formatting French does not use.
- Given
.lint-ceiling.json, When it is updated, Then the total is not raised — only the
stale per-rule count is corrected to match a tree that genuinely has no new violations.
- Given a deliberately introduced new violation of any ratcheted rule, When the gate runs,
Then it still fails. The fix must not disarm the ratchet.
Definition of Done
Out of scope
- Reducing the 315 existing errors. That is the ratchet's job over time, not this issue's.
- Raising the ceiling. D-022 is explicit.
Problem
npm run lint:ceilingfails onmaster, with no change in the working tree:The total is comfortably under the ceiling. The failure is entirely a stale per-rule
entry:
.lint-ceiling.jsonrecords"no-irregular-whitespace": 1, and the tree has three.The three are all pre-existing, and none of them is a defect — they are deliberate non-breaking
spaces in test fixtures and expectations:
frontend/e2e/empty-states.spec.ts:167frontend/src/i18n/__tests__/format.test.ts:17frontend/src/i18n/__tests__/translate.test.ts:19The last two are the i18n formatter's own tests, which assert French number formatting — and
French number formatting is a narrow no-break space. Removing the character would make the
test assert the wrong thing.
Found while working #438: the gate flagged a "regression" on a branch that had actually
reduced total ESLint errors from 318 to 315.
Why this matters beyond the noise
D-022 set this ratchet deliberately: "the frontend lint gate is ratcheted at 321, not swept and
not downgraded." A ratchet that fails on an untouched tree trains everyone to ignore it, which
is precisely how the next real regression gets waved through.
Acceptance criteria
masterwith a clean working tree, Whennpm run lint:ceilingruns, Then it passes.and the rule is configured to allow it in test fixtures (
skipStrings, or an override for**/__tests__/**ande2e/**), or each site carries a targeted disable comment saying whythe character is intentional. The character must not be silently replaced with a normal
space in the i18n tests: that would make them assert formatting French does not use.
.lint-ceiling.json, When it is updated, Then the total is not raised — only thestale per-rule count is corrected to match a tree that genuinely has no new violations.
Then it still fails. The fix must not disarm the ratchet.
Definition of Done
npm run lint:ceilinggreen on a cleanmasterthen its removal)
Out of scope