R-289: test the cast reader on strings, and fix the spelling that found

Both earlier cast defects were shown by editing CLEAN_GROUND.md in the shared tree,
which is how this session came within a git checkout of c0's uncommitted work and
is also the weaker test. Seven cases now live in check-behaviour as strings.

Writing them found a live one: "<!-- cast : ... -->", one space before the colon,
matched nothing -- not an empty declaration R-288 would refuse but no declaration
at all, so check-rollable widened to the whole duty roster and printed its usual OK
line. check-cited's three spellings again. The reader now takes cast\s*:.

castLikeIn adds the asymmetric half: anything comment-shaped containing cast\w* the
reader did not consume is named by check-rollable, so a spelling nobody anticipated
fails the build instead of silently declaring nobody. Looser than the reader on
purpose -- a false alarm costs a reword, the opposite error costs a guard that
checks the wrong six people and says OK.

Tests then mutation-checked for being load-bearing, each mutation asserted to have
applied after a first pass where three silently did not.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
slaguru666
2026-09-13 15:41:19 +01:00
co-authored by Claude Opus 5
parent e3d222cacf
commit 2cf9721fa3
4 changed files with 141 additions and 4 deletions
+39
View File
@@ -6765,3 +6765,42 @@ strength of an agent the scenario does not cast.
Replacing CLEAN GROUND's declaration with `<!-- cast: -->` passes before this change and
fails after it, naming the line. A scenario with no marker still falls back, unchanged.
## R-289 — the cast reader, tested on strings, and the spelling that testing found
c0's point after R-286: both cast defects were demonstrated by editing CLEAN_GROUND.md in the
shared tree to watch what the reader did with it. That is how one session came within a
`git checkout` of another's uncommitted work — and it is also the weaker test. It holds one
shape at a time, it leaves nothing behind, and it cannot be run again next month.
Seven cases now live in `check-behaviour`, as strings: the real document's shape; the mention
moved above the declaration (the R-286 bug, which must still read the six); two real
declarations both seen, with line numbers surviving the code-blanking; a fenced declaration
ignored; present-and-empty told apart from absent (R-288); spelling; and the odd-marker
counter.
**Writing them found a live one.** `<!-- cast : ... -->` — one space before the colon —
matched nothing. Not an empty declaration that R-288 would refuse: *no declaration at all*, so
check-rollable fell back to the whole duty roster and printed its usual OK line having checked
every skill in the document against people the scenario does not cast. This is check-cited's
defect exactly, where `Cite:`, `CITE:` and `cite :` all failed open while the guard reported a
count identical to a clean tree. The reader now takes `cast\s*:`, case-insensitively.
**And the asymmetric half, because widening only fixes the spellings we thought of.**
`castLikeIn` recognises anything comment-shaped containing `cast\w*` that the strict reader did
not consume, and check-rollable names it: `cast =`, `casting:`, `the cast is` all fail the
build rather than silently declaring nobody. It is deliberately looser than the reader — an
ordinary comment near the casting section can trip it, and the message says prose belongs in
backticks, where nothing here looks at it. A false alarm costs a reword; the opposite error
costs a guard that checks the wrong six people and says OK.
**The tests were then checked for being load-bearing**, by mutating the reader in a worktree
and reading which of them went red — each mutation asserted to have applied, after a first
pass where three silently did not and the green that followed proved nothing:
| mutation | red |
|---|---|
| `cast\s*:` back to `cast:` | spacing |
| code-span blanking removed | four, including both R-286 cases |
| marker list truncated to the first hit | two declarations both seen |
| odd-marker counter disabled | cast-shaped marker named |