Proves the deck->hand transfer dimension (design §5 draw oracle) — the last deterministic, non-RNG card-effect class no prior milestone touched (M3/M4/M6/M8 moved stats, M2/M5/M7 the board, M3 the leader). Card 800114010 (clan-1 ELF cost-1 when_play draw 1 from own deck, ungated, no evo/preprocess). The resume-guide's skill_target=none/no-RNG shape does not exist in cards.json — EVERY draw selects from the deck via a random_count filter (skill_option is always literally 'none'). RNG neutralized structurally: seed the deck with EXACTLY ONE known card so random_count=1 is deterministic regardless of seed. New primitive HeadlessEngineEnv.SeedDeck (create via the null-view seam + engine AddToDeck). Oracle DrawSpellOracleTests asserts: seeded card moves deck->hand (by id + by reference), deck -1, drawn card IsInHand, spell pays cost + leaves hand + resolves to cemetery, board/opponent untouched. Load-bearing confirmed the M7 way (seed a different id -> the by-id assertion fails). Shim gap fixed (the predicted M9 cost): Skill_draw's BattleLog tail (UpdateFusionedCardSkillDrewCard, unguarded; + the IsBattleLog AddLogSkillDrawCard calls) dereferences BattleLogManager.GetInstance(), an M1 'default!' null singleton -> NRE after the draw already committed. One-line HEADLESS-FIX (M9) in BattleLogManager.g.cs returns the existing _instance singleton (all its methods are no-ops), per the M2/M7 Null*-singleton playbook. No Engine/ edit (drift clean). 9/9 green; check_drift.py clean; engine still 0 Error(s). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7.1 KiB
7.1 KiB