The light/dark pairing was held by a @Preview and nothing else. A preview fails
no build and nothing runs it, and the KDoc on OnboardingPreviews.kt already said
why that matters: "a set of eight where seven have a night variant looks
completely fine in light mode."
The failure mode is what makes this worth a guard. A missing drawable-night file
does not crash, does not warn, and does not fall back to nothing — Android
resolves the light drawable and draws it on a dark screen. The only other way to
find it is to open that one screen in that one theme, which is how #44 was found
and how it sat unnoticed until somebody looked.
checkThemedDrawables walks both directions: a light asset with no night twin,
and a night asset with no light one. The second is the same defect from the
other side and renders as nothing rather than as the wrong picture.
Exemptions are a named map with a reason each, rather than a narrowed scope.
ic_launcher_monochrome is the only entry: the launcher tints it from the system
palette, so a night copy would be a second source of truth for one shape. A
scope that only listed today's eight illustrations would not cover tomorrow's,
and the defect this guards against is a file somebody forgot.
Proved four ways, because prove-guard.sh cannot drive this one — it replaces a
string inside a file, and this guard's failure mode is a file that is not there,
in a set that is all .webp. GUARDS.md gains section 9 for that class of guard,
and the manual recipe from section 1 was run instead:
- a night twin deleted -> exactly 1 violation, naming art_welcome
- a dark-only asset added -> exactly 1 violation, naming art_orphan
- both restored -> green, 64 resources across 5 folder pairs
- roots pointed at a folder
that does not exist -> "no drawables were found ... not a pass"
The fourth is the one worth copying. Refusing to report a pass over an empty
observation is itself a thing to prove: a guard that finds nothing and says
"clean" is the failure GUARDS.md was written after, and two guards in this
project have done exactly that.
closes#42
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>