Measures: observation 64 KB (~16k tokens) for 7 combatants / 22 KB for a 2v2;
124 policy calls per battle, i.e. 124k calls per 1000-run sweep cell -> a
per-turn LLM in a sweep is infeasible (D9 validated) and a compact view is
mandatory. Danger map (default vs focus-fire monsters, 100 runs): the default
policy understates danger (PC deaths 13%->24% and 0%->19%, TPK 0%->2%) and the
win rate alone misleads (rises to 98% while deaths rise) -> D12/D13 validated.
Notes the spike limits and the remaining P0.2-P0.5 items.
All recommendations accepted by the user except prompt location: prompts live
outside this repo (separate pack, configurable path, versioned; prompt_version
feeds the cache key and the replay record; a pinned pack for integration, a
minimal local fixture for unit tests, no silent fallback). Also records the
repo-scope decision (code only: calculation + LLM + report) with the final
detachment of data/sheets/prompts as a backlog item and the design constraint
to avoid hardcoded data paths in the new code. Priority: cartography first.
The execution tiers answer 'how to run a tactic', not 'which tactic is best'
nor 'where is the danger'. Adds two decision layers: an optimizer over
StrategySpec (objectives incl. tail risk, coarse-to-fine search, LLM as
candidate seeder) and an adversarial cartography (AdversarySpec + alternating
min-max + scenario sweeps + danger frontier + sensitivity), giving the danger
view for BOTH sides. Reframes the LLM as hypothesis generator / red team /
explicator / reporter, never the optimizer or per-turn executor in sweeps.
Adds D12-D14 and phases P3 (optimizer) / P4 (robustness).
Key correction: the LLM must not sit on the per-turn hot path of a Monte
Carlo sweep (runs x rounds x combatants calls, no cross-run cache reuse).
Adopts a two-tier design - a compiled, parameterised deterministic Policy for
quantitative sweeps (tier A) and a per-turn NLPolicy for a handful of showcase
battles (tier B). Also fixes: 'engine unchanged' -> rules unchanged/additive
boundary; replay keyed by a monotonic call_seq (delay re-queues, summons);
composite response-cache key incl. model id; ObservationView as a structured
object; candidates derived from pairs instead of a second legality engine;
per-run PolicyFactory; cost guardrails in P1; concurrency; D1 to settle in P0.
Design-only document (no code): target architecture (compact versioned
observation view, legal-actions API, LLM client + cache, NL policy with
parse/validate/repair/fallback, strategy sweep, replay/eval harness), the
concrete gaps in the current runner/CLI wiring, the decisions to settle and a
phased implementation plan (P0 foundations, P1 client+policy, P2 strategy
sweep, P3 provider+report) with exit criteria and risks.
Brings in the last four out-of-scope mechanics: the nonlethal damage track
(unarmed strikes, minimum damage), splash weapons (direct + scatter),
combat skills (skill checks, Acrobatics Tumbling, Stealth/opposed Perception)
and 3D flight over ground terrain (vertical line of effect deferred). Updates
the out-of-scope and residual tables to drop the now-modeled items and marks
the round-2 disposition tables as historical. Gate 1981.
A read-only audit of the transcript rendering, map and loader formats found
14 confirmed bugs (4 Med, 10 Low: duplicate --side, id-disambiguation
collision, range_increment_ft division by zero, silent spell_slots/features
drops, negative round-cap, multi-char legend keys, blank rows, id parsing,
duplicate YAML keys, move_cost default) - all fixed. The transcript/format
area is audited; only the structural out-of-scope items remain. Gate 1900.
Sunder now uses object hardness/HP with the SRD broken condition (usable at
-2), steal transfers real carried items and unarmed disarm auto-picks up the
dropped weapon. Objects/inventory leave the out-of-scope list; skills,
nonlethal, splash, 3D flight and the transcript remain. Gate 1861.
107/108 spells carry their SRD components; arcane_caster and
armor_spell_failure are set from the sheets; the deafened 20% verbal
failure and the arcane spell failure roll are modeled. Components/ASF
leave the out-of-scope list. Gate 1850.
Adds the alignment field + axis flags, the AlignmentGate on spell damage
(Shard of Chaos, Spear of Purity) and the attacker-alignment-conditional
wards (Protection from Evil/Law + communal). Alignment leaves the
out-of-scope list; objects/inventory, skills, nonlethal and ASF are recorded
as the remaining out-of-scope mechanics. Gate 1829.
Guidance (new OneShotEffect), resistance (+1 resistance save buff, with the
cantrip-skip policy guard), virtue (temporary HP track) and stabilize
(auto-stabilization) are now modeled; spiritual_weapon and saving_finale
remain deferred with a precise engine reason. Gate 1734.
Rounds 1-3 closed the assumed residuals: run bounded by CON endurance + Run
feat, harmless spells forgo the save on willing targets, self-centered bursts
for bless/bane, Selective Channeling, the lich stat block aligned to the KB,
summon-stats disambiguation, healing_done exposure, multi-cell difficult-terrain
move pricing, and the grazed-caster-cell cone/line fix. The burst intersection
origin is deferred with a precise rationale. Rewrites the residual table to
drop the now-fixed and stale rows, leaving only the genuinely remaining items.
An independent pass confirmed the sampled High/Med fixes are genuinely
implemented, then found previously-undocumented divergences in the default
policy (spell combat without a slot, out-of-range heal wasting the turn,
wasted grit on a melee deed, fixed hex range), dice (wrong exception for
d1), the channel-heal trigger, and the foundry migration tool. All fixed;
corrects the stale 'goblin dies round 4' note (now round 5) and records the
Bless centering residual.
Records the 12 fixes of the final pass (engine Lows, LOS area templates,
runner/metrics/observation/CLI): dying creatures occupy their square,
blinded cannot charge/run/withdraw, cone/line aim and caster footprint,
square_size_ft validation, channel-heal no longer counted as damage dealt,
summon aggregation no longer KeyErrors, non-attack damage counted, README
examples refreshed, ACTION_RESULT_REASONS completed, zone-letter validation.
The remaining 35 spells were field-verified against the KB with zero
outcome divergences, closing the spell coverage gap.
Round 3 (attack resolution, bestiary/PC stat blocks, action economy) and
round 4 (remaining spells, PC feats) found 2 High, ~11 Med and ~70 Low
findings. Records the 22 fix commits (e0bf484..0c3f5fd), both justified
golden updates (Weapon Focus, Divine Favor), and the residual inventory:
~13 deferred spell effects, 20 feat/racial mismatches, and the missing
subsystems (alignment, items, skills). Journal marked paused at round 4.
Round-2 audits (feats/class abilities, combat maneuvers, conditions,
spell data) surfaced 6 High / ~28 Med / ~45 Low findings. This commit
records them with a per-finding disposition (fixed / out of scope /
assumed residual) plus the 17 fix commits (b03a61d..e89ea42) and the
single justified golden update (Weapon Focus now applies).
Consolidates the round-1 audit: 15 fixed divergences (one commit each,
312f9fd..ea60b2e), the deliberate out-of-scope rules, the assumed
residuals, and the verified-conformant guard rails. Linked from README.