R-288: an empty cast declaration is fatal; a missing one still falls back

c0's point on R-286: the reader is unambiguous now, but the roster fallback that
made the failure look like success is still reachable. Narrowly closed -- sixteen
of the seventeen scenarios declare no cast and are rightly checked against the
whole roster, so only a marker that is PRESENT and names nobody is refused, with
its line named. Replacing the declaration with <!-- cast: --> passes before this
change and fails after it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
slaguru666
2026-09-13 15:31:41 +01:00
co-authored by Claude Opus 5
parent f3caaab04d
commit e3d222cacf
2 changed files with 26 additions and 0 deletions
+13
View File
@@ -6752,3 +6752,16 @@ sentences and there is no smaller slice that owns them, so it is left alone deli
rather than overlooked. check-rules builds its covered-set from labels it generates, not from
searching a document. check-lang, check-creatures, check-templates, check-kits and the
baseline guards do no document matching at all.
## R-288 — an empty declaration is not the same as no declaration
c0's note on R-286: the reader is unambiguous now, but the fallback that made the failure
look like success is still there. It is right, and the fix has to be narrow. **No marker at
all is the ordinary case** — sixteen of the seventeen scenarios here declare no cast and are
rightly checked against the whole duty roster. A marker that is present and names nobody is
a different thing: somebody wrote a declaration, the guard read nothing out of it, and the
fallback then widens the population silently, so a clue only Pollard can reach passes on the
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.
+13
View File
@@ -104,6 +104,19 @@ for (const [label, path] of scenarioFiles()) {
+ `skill in the document to it; the others were never seen. Keep one declaration and `
+ `put any example inside backticks, where the reader ignores it.`);
}
/* A MARKER THAT DECLARES NOBODY MUST NOT FALL BACK. No marker at all is the ordinary case —
sixteen of the seventeen scenarios here have none and are rightly checked against the whole
duty roster. A marker that is PRESENT and EMPTY is a different thing: somebody wrote a
declaration and this guard read nothing out of it, and the fallback then widens the
population silently, so a clue only Pollard can reach passes on the strength of an agent
the scenario does not cast. That widening is what made R-286 green rather than loud; the
reader is unambiguous now, and this closes the door it came through. c0 asked for it. */
if (markers.length === 1 && !markers[0].keys.trim()) {
problems.push(`${label}: declares a cast at line ${markers[0].line} and names nobody in it. `
+ `An empty declaration is not the same as no declaration — this guard would fall back to `
+ `the full duty roster and check every skill in the document against people the scenario `
+ `does not cast, and say OK. Name the cast or delete the marker.`);
}
const declared = markers[0];
const cast = declared
? declared.keys.split(",").map(x => x.trim()).filter(Boolean).map(k => {