R-293: a desk playtest is a record, not a scenario with rolls in it

Counting the readers that had broken on their own format turned up one nothing had
caught. docs/scenarios holds scenarios, eight playtest records and two art prompt
sheets, and every guard treated all three as scenarios -- harmless for citations
and skill spellings, false for reachability. Six quotations across passes 4, 6 and
7 were checked as live rolls, so a record of a session already played could fail
the build over a skill nobody can reach. Planting Science (Physics) in pass 4 fails
before the split and passes after; the same skill in CLEAN_GROUND still fails.

Classified by the document's own H1, not its filename, because tools/scenario-*
naming is what swept a tools file into this corpus in R-268. An unclassified
document is fatal: an allowlist that silently drops what it does not recognise
would take a new scenario out of reachability checking on the day it was written.

89 rolls across 18 files becomes 83 across 8.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
slaguru666
2026-09-13 16:05:03 +01:00
co-authored by Claude Opus 5
parent 6171d1e9b9
commit daf77f4aac
4 changed files with 115 additions and 5 deletions
+8 -4
View File
@@ -38,7 +38,7 @@ import { readFileSync } from "node:fs";
import { SKILL_CATALOGUE } from "./content.mjs";
import { ROSTER } from "./roster.mjs";
import { expandFromRegister } from "./expand-spec.mjs";
import { scenarioFiles, scenarioText, tagsIn, skillsIn } from "./check-scenarios.mjs";
import { playableFiles, scenarioText, tagsIn, skillsIn } from "./check-scenarios.mjs";
import { castMarkersIn, castLikeIn } from "./declared-cast.mjs";
/**
@@ -89,7 +89,11 @@ const problems = [];
const report = [];
let checkedTags = 0;
for (const [label, path] of scenarioFiles()) {
/* playableFiles(), not the whole corpus: this guard's claim is that every clue a GM can put
behind a roll is reachable by somebody at the table. A desk playtest report quoting a beat
to say which one a roll hung off is not a roll anybody will make, and holding it to that
claim means a record of a session already played can fail the build. */
for (const [label, path] of playableFiles()) {
const raw = readFileSync(path, "utf8");
const text = scenarioText(raw);
@@ -174,5 +178,5 @@ if (problems.length) {
process.exit(1);
}
console.log(`check-rollable: OK — ${checkedTags} rolls across ${scenarioFiles().length} `
+ `scenario files, every one reachable at ${VIABLE}% or better by somebody present`);
console.log(`check-rollable: OK — ${checkedTags} rolls across ${playableFiles().length} playable `
+ `scenarios (records and art sheets are not rolls), every one reachable at ${VIABLE}% or better by somebody present`);