feat(gate): catch the tokens that resolve to nothing - #7
Merged
Conversation
Wind drops an unrecognised token SILENTLY: no warning, no throw, nothing at the call site. So a token that never existed, one that was renamed, and one that works look identical in the source, and the only symptom is a colour that never appears. That is the rare rule worth a test rather than a reviewer, because the failure is invisible exactly where a person reads. This guard mirrors one that first paid for itself in a product built on this boilerplate, where it found four dead tokens, two of them invisible to a full-tree review. It found two more here on its first run, and both are fixed in this commit rather than allowlisted: `text-destructive` resolved to nothing, so the dashboard's heart glyph rendered in the inherited colour. `design:sync` emits `bg-destructive` and `text-on-destructive` (the colour that sits ON the solid) but no `text-` peer, which is a shape worth naming: the role exists in DESIGN.md, the prefix does not exist in the generated map, and the near-miss reads perfectly. `config/view.dart` reached straight for `bg-white`, `text-gray-600` and `bg-red-500`. Those resolve, so the first check cannot see them, which is why the second one exists: a hardcoded colour cannot answer to a theme change, and regenerating `wind_theme.g.dart` from a different DESIGN.md restyled the whole app while every dialog kept the old palette. Those strings are as much a design surface as a widget's className. THE DIALOG TONES MOVE as a result, and deliberately: `bg-white dark:bg-gray-800` becomes `bg-surface-container`, the card tone, because a dialog sits above the page rather than on it. The `dark:` peers disappear from that file because each alias already carries its own. Two supporting changes. `buildWindTheme()` moves the assembly out of `main()` so a test can ask the same theme the app runs on; a second copy would drift and certify the wrong map. And `supplementAliases` gives hand-authored tokens a home beside the generated file rather than inside it, since `design:sync` overwrites that file wholesale and would drop them silently. Both halves mutation-tested: restoring one palette colour reddens the Token-Only check, dropping the supplement reddens the dead-token one. `bin/check` green. NOT VISUALLY VERIFIED. Driving this app locally fails on a CORS preflight between the web build and its API, which is an environment problem this change did not cause and does not fix, so the moved dialog tones have been reasoned about rather than looked at.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wind drops an unrecognised token silently: no warning, no throw, nothing at the call site. So a token that never existed, one that was renamed, and one that works look identical in the source, and the only symptom is a colour that never appears.
That makes this the rare rule worth a test rather than a reviewer: the failure is invisible exactly where a person reads.
Mirrored from the guard in
uptizm, where it found four dead tokens, two of them invisible to a full-tree review. It found two more here on its first run, and both are fixed rather than allowlisted.1.
text-destructivepainted nothingThe dashboard's heart glyph rendered in the inherited colour.
design:syncemitsbg-destructiveandtext-on-destructive(the colour that sits on the solid) but notext-peer.Worth naming as a shape: the role exists in DESIGN.md, the prefix does not exist in the generated map, and the near-miss reads perfectly.
2.
config/view.dartreached for the raw palettebg-white,text-gray-600,bg-red-500. Those resolve, so the first check cannot see them, which is why the second one exists: a hardcoded colour cannot answer to a theme change, and regeneratingwind_theme.g.dartfrom a different DESIGN.md restyled the whole app while every dialog kept the old palette. Those strings are as much a design surface as a widget'sclassName.The dialog tones move as a result, deliberately:
bg-white dark:bg-gray-800becomesbg-surface-container, the card tone, because a dialog sits above the page rather than on it. Thedark:peers disappear from that file because each alias already carries its own.Two supporting changes
buildWindTheme()moves the assembly out ofmain(), so a test can ask the same theme the app runs on. A second copy would drift and certify the wrong map.supplementAliasesgives hand-authored tokens a home beside the generated file rather than inside it, sincedesign:syncoverwrites that file wholesale and would drop them silently.Verification
bin/checkgreen. Both halves mutation-tested: restoring one palette colour reddens the Token-Only check, dropping the supplement reddens the dead-token one.Not visually verified. Driving this app locally fails on a CORS preflight between the web build and its API, an environment problem this change did not cause and does not fix, so the moved dialog tones have been reasoned about rather than looked at.