R-262: the second R-261, renumbered, deferring to the one that was committed

Two sessions numbered an entry against the same committed log, which ended at
R-260, and both picked R-261. Mine was written first but was uncommitted, so the
other session could not have seen it and had every reason to think the number was
free. When it staged docs/REVIEW_LOG.md my entry was sitting in the file, so it
went out inside 1d915c5 under that commit's message, and HEAD reached origin with
two R-261 headings in it.

Mine renumbers to R-262 and moves below theirs so the log stays monotonic. Theirs
keeps R-261 because theirs is the one that was committed; this diff moves and
renumbers nothing but my own prose, and their entry appears in it only as context.

The hazard is now a matter of record in both directions: their note at the foot of
R-261 caught check-rollable arriving from another session mid-build and handled it
without clobbering anything, and this is the same collision on a file whose
convention is to append to the end. A shared working tree makes the end of
REVIEW_LOG.md the likeliest place for two sessions to meet, and an uncommitted
entry there has no claim on its own number.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
slaguru666
2026-09-13 00:16:04 +01:00
co-authored by Claude Opus 5
parent 1d915c55cf
commit 104b588e86
+45 -45
View File
@@ -5580,51 +5580,6 @@ ladder as the reason, which was right for the wrong reason. It now gives the rea
survives measurement, and states that the effect roughly doubles from two enemies to
three or more.
## R-261 — a real skill is not a route, and the first guard for that reported success
`check-scenarios` resolves every skill a scenario NAMES against the catalogue. That is a
different question from whether anybody at the table can roll one, and the gap is wide
enough to hide a clue in.
CLEAN GROUND shipped four commits with three clue routes gated on **Track** (base 10),
**Navigate** (base 10) and **Science (Botany)** — base **1**, so the 1% floor was the whole
of it. Every guard passed at every commit, because all three are perfectly real skills that
resolve perfectly well. Nothing in the build had an opinion about who was holding the dice.
A desk playtest found it, by auditing the acts against the sheets the scenario actually
casts, before rolling anything. That audit is mechanical, so it is now `check-rollable`.
**Two tiers.** Corpus-wide, some duty-roster agent must reach **VIABLE** for every skill any
scenario names — a scenario may bring anyone, so a skill no roster agent can roll is a dead
route whoever turns up. Per scenario, a document that **declares** its cast is held to that
cast instead.
**VIABLE is 25, and it is derived rather than chosen.** It is the commonest base chance in
the catalogue — what an untrained agent brings to Spot, Listen or Brawl — so it is the level
the game itself treats as worth attempting. Below it a clue is not gated, it is buried: at
10 the GM improvises a bridge four times in five, and at 1 the tag is decoration.
**The first version of this guard passed the bug it was written for.** It inferred the cast
by scraping `pc_` keys out of the prose, which swept up the substitutes named in CLEAN
GROUND's player-count scaling — a declared six became an inferred nine, Sandoval and his
Track 35 came into scope, and the strict tier went green. The cast is now declared in a
`<!-- cast: ... -->` comment and read off the raw text, because `scenarioText` strips HTML
comments. A guard that guesses its own scope is worse than no guard, because it reports
success and stops anyone looking.
**Verified load-bearing against the real document, not a fixture.** Re-injecting the
original Track tag into `CLEAN_GROUND.md` fails the guard and names the skill, the base
chance and the declared cast. Worth recording *why the fixture was not enough*: the
corpus-wide tier would never have caught this at all, because **Lindqvist trains Science
(Botany) at 40**. The skill is rollable by the roster and simply not by the six who were
cast, so the first fixture test passed and was reassuring and wrong. Only the declared-cast
tier finds this defect class.
`check-scenarios` now exports its tag parser behind the `invokedDirectly` pattern
`simulate.mjs` already uses, rather than letting a second copy grow in the new guard —
which is the one thing this repository forbids. `update-readme` caught the omission fairly
on the first attempt, since it cross-checks the advertised list against `npm run check`.
## R-261 — the focus-fire claim is now an artifact, not a sentence
R-258 put a tactic on a GM-facing page from an unguarded harness. R-259 found it worth
@@ -5668,3 +5623,48 @@ more, best case 6 × The margin at 42.0% → 61.1%.
*Note: guard eleven, `check-rollable`, arrived from another session mid-build; this is
twelve. Both were added to `package.json` and the README list without either clobbering
the other, and the README's count word tracked it on its own.*
## R-262 — a real skill is not a route, and the first guard for that reported success
`check-scenarios` resolves every skill a scenario NAMES against the catalogue. That is a
different question from whether anybody at the table can roll one, and the gap is wide
enough to hide a clue in.
CLEAN GROUND shipped four commits with three clue routes gated on **Track** (base 10),
**Navigate** (base 10) and **Science (Botany)** — base **1**, so the 1% floor was the whole
of it. Every guard passed at every commit, because all three are perfectly real skills that
resolve perfectly well. Nothing in the build had an opinion about who was holding the dice.
A desk playtest found it, by auditing the acts against the sheets the scenario actually
casts, before rolling anything. That audit is mechanical, so it is now `check-rollable`.
**Two tiers.** Corpus-wide, some duty-roster agent must reach **VIABLE** for every skill any
scenario names — a scenario may bring anyone, so a skill no roster agent can roll is a dead
route whoever turns up. Per scenario, a document that **declares** its cast is held to that
cast instead.
**VIABLE is 25, and it is derived rather than chosen.** It is the commonest base chance in
the catalogue — what an untrained agent brings to Spot, Listen or Brawl — so it is the level
the game itself treats as worth attempting. Below it a clue is not gated, it is buried: at
10 the GM improvises a bridge four times in five, and at 1 the tag is decoration.
**The first version of this guard passed the bug it was written for.** It inferred the cast
by scraping `pc_` keys out of the prose, which swept up the substitutes named in CLEAN
GROUND's player-count scaling — a declared six became an inferred nine, Sandoval and his
Track 35 came into scope, and the strict tier went green. The cast is now declared in a
`<!-- cast: ... -->` comment and read off the raw text, because `scenarioText` strips HTML
comments. A guard that guesses its own scope is worse than no guard, because it reports
success and stops anyone looking.
**Verified load-bearing against the real document, not a fixture.** Re-injecting the
original Track tag into `CLEAN_GROUND.md` fails the guard and names the skill, the base
chance and the declared cast. Worth recording *why the fixture was not enough*: the
corpus-wide tier would never have caught this at all, because **Lindqvist trains Science
(Botany) at 40**. The skill is rollable by the roster and simply not by the six who were
cast, so the first fixture test passed and was reassuring and wrong. Only the declared-cast
tier finds this defect class.
`check-scenarios` now exports its tag parser behind the `invokedDirectly` pattern
`simulate.mjs` already uses, rather than letting a second copy grow in the new guard —
which is the one thing this repository forbids. `update-readme` caught the omission fairly
on the first attempt, since it cross-checks the advertised list against `npm run check`.