diff --git a/docs/traps.md b/docs/traps.md index c71b09f..835835f 100644 --- a/docs/traps.md +++ b/docs/traps.md @@ -219,11 +219,38 @@ variation/state pairs, so every variation added since — including all five thi milestone added for the creation screen — could drift from its generator with the test still green. -**The guard:** when a guard is described as covering "every X," check that it actually -enumerates `X.ALL` (or equivalent) rather than a literal list someone wrote down once. And -make the failure message name the specific variation and property that drifted — a guard -that only says "theme mismatch" does not tell the next person which of forty checks -failed. +**It took three fixes, and that is the actual lesson.** + +- **Fix 1** replaced the hardcoded three with `ThemeKeys.ALL`. Still could not fail: `ALL`, + *by its own docstring*, holds stylebox variations only — it deliberately excludes the six + **font roles**. Change a palette colour used only by a font role, skip the regen, ship a + stale theme, green. +- **Fix 2** added `FONT_ROLES` and iterated both. Still could not fail: the builder also + styles some **base types** directly (`RichTextLabel`'s font, italics font, size and + colour), and those are in neither set. `RichTextLabel` is what renders every line of DM + prose on the creation screen. +- **Fix 2 also added a meta-guard** — a test that walks the builder's own output and fails + if it styles anything that no set covers. That guard was written *specifically* to make a + third miss impossible. It contained this: + + ```gdscript + if fresh.get_type_variation_base(variation) == &"": + continue # a BASE type, not a variation + ``` + + **The meta-guard's one exemption was exactly the gap it existed to catch.** + +**The guard:** when a guard is described as covering "every X," check that it enumerates +`X.ALL` (or equivalent) rather than a literal list someone wrote down once — and then check +what `X.ALL` actually *contains*, because a set's name is not its contents. Make the failure +message name the specific variation and property that drifted; a guard that only says "theme +mismatch" does not tell the next person which of forty checks failed. + +**And the harder lesson: a guard-of-a-guard with an exemption in it is not a guard.** If you +write a meta-test to prove a set is complete, every `continue` and every `if … : return` in +it is a hole you are cutting on purpose. Assert on the exempted case instead of skipping it, +or you have built the very thing you were trying to prevent, one level up, where nobody will +look for it. ---