R-282: guard the bestiary against the powers, including the next one

check-bestiary proves the page matches its generator, and the generator had never
heard of powers.mjs -- so the redcap sat in "the ones that take the most
stripping" under eighteen green guards while its own entry said it never spends a
defence. Two files agreeing with each other while both disagree with the engine
is a quorum, not a check.

check-powers now asserts per effect kind what the page must say: defenceStacking
requires the creature off the stripping list, named as exempt, and the "across N
creatures that spend defences" count reconciled against powers.mjs; attackFactor
requires the rating the simulator actually uses printed as a number, which the
courier's entry now carries.

The clause that matters is the failure on an unknown effect kind -- a wired effect
with no DOCUMENT_RULE fails the build, so the next one cannot arrive without
somebody deciding what the document owes it. Without that this would guard the
mistake already made and nothing else.

Proved three ways in a worktree, exit codes read directly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
slaguru666
2026-09-13 15:01:04 +01:00
co-authored by Claude Opus 5
parent 8705b00631
commit 1a80d3637c
4 changed files with 130 additions and 5 deletions
+37
View File
@@ -6573,3 +6573,40 @@ have been paid off by the widening.
The middle case is the useful one to understand: **the ratchet only bites where the existing
claim does not**, in the band between "still helps everywhere" and "helps as reliably as it
did". That band is exactly where a slow degradation lives, and it was unguarded until now.
## R-282 — the bestiary is now checked against the powers, including the next one
R-275 wired NOT TIRED into the simulator and the bestiary went on listing the redcap among
"the ones that take the most stripping" — the exact opposite of what its own entry says
three pages down — with **eighteen guards green over it**. `check-bestiary` proves the page
matches its generator; the generator had never heard of `powers.mjs`. Two files agreeing
with each other while both disagree with the engine is not a check, it is a quorum.
**check-powers now asserts what the page must say, per effect kind.**
- `defenceStacking` — the creature must not appear in the stripping list, must be named as
off the ladder, and the section's "across N creatures that spend defences" count must
equal the dodgers minus the exempt. Arithmetic tying prose to `powers.mjs`.
- `attackFactor` — the page must print the rating the simulator actually uses, as a number.
"HALF the rating above" is a rule a GM has to do arithmetic on and a guard cannot read;
**40%** is both. The courier's entry now carries it.
**The part that matters is the failure on an UNKNOWN kind.** A wired effect with no rule in
`DOCUMENT_RULES` fails the build by itself:
> `effect "reachBonus" has no rule about what BESTIARY must say. Add one to DOCUMENT_RULES:
> an effect the harness applies and the page never mentions is how the redcap came to be
> listed under advice that does not work on it.`
Without that clause this guard would cover the mistake already made and nothing else —
which is the failure mode of most guards written the day after a defect. The next effect
kind cannot reach the simulator without somebody deciding what the document owes it.
**Proved three ways** in a throwaway worktree: the redcap put back on the ladder fails with
both the list and the missing exemption named; the courier's real rating removed fails; a
new `reachBonus` effect fails for having no page rule. Exit codes read directly.
**What this does not cover, stated so it is a decision rather than a silence.** The
assertions are textual — they check that the page says a thing, not that what it says is
true. A `damageFactor` rule is registered as a no-op because nothing wires one today, and
it will need writing when something does; the guard will demand it, but it cannot write it.