From 104b588e8668a1bc985c4f3bf6f766ca2522c734 Mon Sep 17 00:00:00 2001 From: slaguru666 <111923774+slaguru666@users.noreply.github.com> Date: Sun, 13 Sep 2026 00:16:04 +0100 Subject: [PATCH] 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 --- docs/REVIEW_LOG.md | 90 +++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/docs/REVIEW_LOG.md b/docs/REVIEW_LOG.md index 955fae9..5694608 100644 --- a/docs/REVIEW_LOG.md +++ b/docs/REVIEW_LOG.md @@ -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 -`` 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 +`` 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`.