docs(traps): the drift guard took three fixes, and the third one whitelisted the gap
Trap 12 told only the first act. The full story is the lesson: ThemeKeys.ALL excludes the font roles by its own docstring, and the builder styles some base types directly (RichTextLabel — which renders every line of DM prose on the creation screen). The meta-guard written specifically to prevent a third miss contained a `continue` that exempted exactly the gap it existed to catch. A guard-of-a-guard with an exemption in it is not a guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user