OpenRA-Bench / SCENARIO_UNIQUENESS_AUDIT.md
yxc20098's picture
Quality drive: schema fix, 5 new/revised packs, 4 engine tests, scenario audit
6d71d3b
|
Raw
History Blame Contribute Delete
34.3 kB

A newer version of the Gradio SDK is available: 6.22.0

Upgrade

Scenario Uniqueness Audit (Phase 2)

Read-only audit of openra_bench/scenarios/packs/*.yaml. Scope: 212 YAML files (excluding TEMPLATE.yaml); 23 in-flight econ-* packs were deliberately skipped (other agents own them), leaving 189 packs probed.

The probe was a stall policy โ€” Command.observe() only โ€” run on the hard tier, seed=1, of every pack, through the same code path (openra_bench.eval_core.run_level) the bench evaluator uses. Each result is the engine-evaluated outcome (win / loss / draw), final game tick, and the static profile read straight from the YAML.

Headline numbers

  • 181 / 189 packs (95.8%) โ€” stall LOSSES (healthy: no-cheat bar holds).
  • 3 packs โ€” stall WINS (the no-cheat bar is broken).
  • 3 packs โ€” stall DRAWS (no real LOSS reachable from a stall play).
  • 2 packs โ€” Rust engine panic at reset(seed=1) (both adversarial-siege / adversarial-skirmish โ€” already status: quarantine in-pack so they are NOT in the default eval set, but they remain on disk and panic when explicitly invoked).

Quarantined packs are still YAML-discoverable and were probed. They are flagged [Q] in the lists below.


Section 1 โ€” Defect packs

A "defect" here means stall WINS (the lazy bar fell) or stall DRAWS (no real reachable LOSS โ€” the timeout collapses to draw degeneracy because the fail predicate never trips). Both are explicit violations of the "no defect, no cheat" bar in CLAUDE.md.

1A. Stall WINS (3 โ€” bar fell)

Pack Outcome Turn Tick Diagnosis
mid-economy-under-fire WIN 11 993 Stall achieves the win predicate without any agent action. Hard win-clause is economy_value_gte:4000 AND harvโ‰ฅ2 AND units_lost_lte:2. With the current engine, the 3 starter harvesters auto-harvest (no harvest command needed โ€” they begin in harvest mode), the perimeter 1tnks auto-fire and kill the lone raider 1tnk, and EV trips 4000 by tick ~993 with zero losses. The pack header says "Stall (only observe)โ€ฆ harvs never harvest โ†’ EV stays at 0 โ†’ LOSS." That is no longer true under the current engine โ€” harvs in harvest mode work without re-issued orders. Fix: either remove the harvesters from the starting placement (require the model to issue Command.harvest) or replace the 1tnk raider with a stronger raider wave that out-attritions an idle defense ring.
combat-naval-shore-strike WIN 3 198 Stall wins inside 3 turns. The hard tier places two destroyers in the water channel on stance:2 (Defend), and the entire shore garrison on stance:0 (HoldFire). The destroyers auto-fire on every garrison unit in range and clear all 5 enemies in <200 ticks; the agent never sends a command. Fix: set the destroyers to stance:0 so the agent must issue an attack_unit order; or place the shore garrison just outside the destroyer's auto-target range so the agent must manually fire. The whole capability (target an across-shore target with a ranged unit) collapses because the engine fires automatically.
def-with-ambush (intended) WIN 24 1233 Not a defect โ€” exempt by design. CLAUDE.md ยงTriage coverage: "1 pack (def-with-ambush) is exempt by design (positional-discipline scenario where do-nothing IS the intended policy)." The capability under test is hold the ambush position; the four stance:2 flanker tanks auto-engage the rusher band when it enters weapon range. Listed here only for completeness โ€” no action required.

1B. Stall DRAWS (3 โ€” no LOSS reachable)

A draw means the win predicate was never met AND the fail predicate never tripped, so the level resolves to draw (outcome score 0.5). This is a defect because it makes the lazy play indistinguishable from a partial / borderline play, and inflates the lazy score by treating it as half a win.

Pack Outcome Turn Tick Diagnosis
economy-time-box [Q] DRAW 80 7203 Already quarantined in-file (reason: "redundant with economy-force-buildup"). The hard tier has no fail_condition at all (fail_condition: None), so a 12000-tick budget that never produces 6 units / 5 buildings simply times out as draw. This is one of the canonical CLAUDE.md defect classes ("no fail_condition, or only triggers on full force-wipe; a stall / preserve / partial outcome silently draws"). Since the pack is quarantined the lazy-bar drift is harmless to the default eval; if the pack is ever un-quarantined, add fail_condition: {after_ticks: 12001} plus {not: own_units_gte: 1}.
spec-spy-infiltrate DRAW 3 273 Hard tier fail_condition: {after_ticks: 4001} โ€” i.e. the only failure mode is the deadline. But the agent's only combat-relevant units are 2 spies (spy) and the scenario also places one defender e1. With stall, the spies are passive while the engine auto-dones at turn 3 (likely because the defender e1 falls to auto-fire or because all agent combat units are destroyed). The outcome lands as DRAW because the spy-only force is wiped before the within_ticks ever bites. Fix: add {not: own_units_gte: 1} (or unit_type_count_gte:{spy, 1}) to the fail_condition.any_of so a spy-wipe is a LOSS, not a draw. Same fix likely needed for easy / medium (uninspected; consider auditing).
def-bridge-chokepoint (mixed: usually LOSS at tick 1623, occasionally DRAW in one fresh process) 18 1623 The first probe (subprocess #1) reported DRAW; three subsequent re-runs from a fresh process consistently reported LOSS (17 losses, fail-clause not has_building:fact trips when the procs/fact fall under the rifle assault). This is borderline โ€” the pack is probably healthy, but the one-off DRAW observation suggests a possible determinism-edge case (race between the engine auto-done and the predicate evaluator). Recommend a 4-seed re-probe (1โ€“4) over a clean Python process to confirm. If the LOSS is stable, no fix required; if the DRAW resurfaces, add {not: own_units_gte: 1} to the fail clause.

1C. Engine panics at reset (2)

Pack Status Error
adversarial-siege quarantine (consolidated into adversarial-duel) pathfinder.rs:175 index out of bounds: len 5120, index 5382 at env.reset(seed=1). The hard tier places actors outside the playable bounds (CLAUDE.md footgun #6) for the chosen spawn. Pack is excluded from default eval; no eval-time impact, but flag the file is still selectable via explicit --packs.
adversarial-skirmish quarantine (consolidated into adversarial-duel) Same panic at env.reset. Same situation as above.

Recommend either deleting these two YAMLs (the consolidation is the documented future state) or moving them to packs/_archived/ so discover_packs skips them (it already skips _* and TEMPLATE).


Section 2 โ€” Duplicate / near-duplicate clusters

Methodology: each pack was fingerprinted by (capability, tools, actor_types_sorted, win_predicate_keys_sorted). Five strict (= all four fields equal) clusters surfaced; a second pass relaxed tools and actor_types to surface near-duplicates with the same capability + same win-key set, which surfaced a further ~10 clusters. Each cluster is judged on the per-pack real_world_meaning and the level_description of the hard tier โ€” if these tell the same story, the cluster is genuinely redundant; if not, the predicate-key match is coincidental and the packs probe distinct skills.

2A. Strict duplicates (action required)

  1. adversarial-siege + adversarial-skirmish โ€” both already quarantined as "consolidated into adversarial-duel". Keep: adversarial-duel. Action: physical removal (delete or _archive) โ€” they are the only two packs that crash the engine at load, so removing them eliminates the crash class entirely.

  2. artofwar-decoy-sacrifice + artofwar-lure-the-tiger โ€” both capability: reasoning, both use bot guard, identical hard-tier actor list [2tnk,e1,e3,fact,jeep], identical win-keys {units_in_region_gte, units_lost_lte, within_ticks}, both described as "main-force reaches an objective by diverting a leashed defender." Keep: artofwar-lure-the-tiger (the more doctrinally complete framing โ€” leash mechanic; "the strong defender" is the load-bearing pull). Merge / delete: artofwar-decoy-sacrifice โ€” its "spend a decoy unit" angle is covered by the units_lost_lte clause in the lure pack, which already permits a small attrition budget the model can spend on the bait sub-force.

  3. scout-cycle-keep-info-fresh + scout-track-enemy-movement โ€” both capability: perception, identical hard-tier actor list, both use the then-chained units_killed_gte win predicate, both probe "scout multiple times because the world changes between observations." Both use the scheduled_events: hook (cycle = reinforcement waves; track = enemy march legs). These are genuinely distinct skills โ€” cycle is "re-observe a stale region for new arrivals", track is "follow a moving target across the map." Keep both, but verify the briefing of each clearly distinguishes the cause of staleness so the model is not asked to solve cycle-by-track-strategy or vice-versa. (No action required if the briefings are unambiguous, which they appear to be on inspection.)

  4. build-defensive-skirt-corners + build-defensive-tower-line (strict 4-field match) AND the wider quartet build-defensive-tower-cluster + def-in-depth-vs-single (same capability + win-key set, near-identical actor list, all use rusher bot). These four packs all probe "where do you place a finite pillbox budget to survive an incoming rush?" with topology variants: skirt (one in each map-relative corner of the building), cluster (tight wrap), line (across the choke), depth (two thinner bands). Each topology is genuinely distinct in the optimal answer, so all four packs probe a real choice axis. Keep all four but consider promoting them into a single named "Defense Topology Suite" in the eval-cell catalog so the four cells score together (one "topology-IQ" metric) rather than as four unrelated reasoning packs. (No file action required; this is a catalog / metric grouping recommendation.)

2B. Near-duplicates by win-predicate keys (informational โ€” same

predicate idiom is used across distinct scenarios; verify each is load-bearing)

These groups all share an identical (capability, win_predicate_keys) fingerprint. Each group below is not necessarily a duplicate, but flags that all members rely on the same predicate idiom and the scenarios should diverge on actor composition / pressure / bot to remain discriminative.

  • (reasoning, then+within_ticks) โ€” N=10: build-power-online-first, build-sequence-tech-cheapest, build-sequence-tech-fastest, build-sequence-tech-most-resilient (not in cluster โ€” was filtered earlier), lh-econ-army-victory, lh-opening-to-defense-to-counter, lh-opening-to-tech-to-army, lh-progression-stage-locked, rob-objective-change-midway, tech-balanced-econ-then-tech, lh-build-army-coordinate-multifront-attack. These are all ordered-multi-phase scenarios. Distinct intents (build-order vs long-horizon vs objective-shift); the then predicate is the common engine machinery, not a duplication signal.

  • (reasoning, building_count_gte+building_in_region+within_ticks) โ€” N=7: build-sell-and-rebuild-elsewhere, def-in-depth, def-tower-line-vs-cluster, expansion-aggro-3-base-greedy, mcv-deploy-second-base, mcv-deploy-third-base, mfb-mirror-base-east-west. All probe "build / re-build N buildings in a target region." Genuinely distinct intents (expansion-greed, mirror-base symmetry, MCV-redeploy under pressure); keep all.

  • (reasoning, building_count_gte+units_killed_gte+within_ticks) โ€” N=6: adv-rps-counter-pick, build-tech-skip-decision, def-counter-battery, def-walls-vs-towers, def-while-building, lh-tech-rush-vs-army-rush. All "kill K enemies and have N buildings standing." Reads as honest differentiated tests.

  • (action, own_units_gte+units_killed_gte+within_ticks) โ€” N=5: combat-flanking-attack, combat-harass-aggro-commit, combat-kite-and-pull, combat-kite-jeep-vs-tank, combat-tanya-vs-rush. Five combat micro packs โ€” kite, flank, harass. Each probes a different micro idiom; keep all but verify that the win bar (units_killed_gte) is tuned per pack so the intended micro is load-bearing, not just "auto-fire wins." Two are explicitly kite (combat-kite-and-pull, combat-kite-jeep-vs-tank) โ€” possible duplicate: kite-and-pull uses generic 2tnk/3tnk vs jeep-vs-tank's unit-class asymmetry. Keep both only if combat-kite-jeep-vs-tank actually requires the jeep speed advantage that combat-kite-and-pull doesn't (read the briefings; they look distinct).

  • (action, reach_region+units_lost_lte+within_ticks) โ€” N=4: proc-no-attack-passive-only, proc-tool-use-multi-distractor, proc-tool-use-with-distractor, strict-toolban-fidelity-under-pressure. All procedural-compliance packs โ€” "reach the goal without using a forbidden tool / without attacking." The proc-tool-use-* pair is a possible duplicate: "with-distractor" (one distractor tool) vs "multi-distractor" (multiple). Both are the same skill at different scales โ€” recommend collapsing into a single pack with three tiers (no distractor / one / many) rather than two top-level packs.

  • (perception, buildings_discovered_gte+units_lost_lte+within_ticks) โ€” N=4: perception-target-vs-fog, scout-detect-enemy-tech, scout-discover-hidden-base, scout-multiple-fog-areas. All "discover K enemy buildings under fog." Each probes a distinct discrimination (target-vs-fog = ignore decoys; detect-enemy-tech = read the tech-tree; hidden-base = single hidden compound; multiple-fog-areas = K disjoint regions). Keep all.

2C. Overlapping prefixes worth a catalog review (not duplicates,

but the area is dense)

  • combat-* (25 packs), def-* (18), scout-* (14), build-* (14), lh-* (13), proc-* (10), mfb-* (8), rob-* (8), tp-* (7), coord-* (7), mcv-* (6), spec-* (5), economy-* (5), tech-* (4), strategy-* (4), perception-* (4), artofwar-* (4), tempo-* (2), maint-* (2), mid-* (2), expansion-* (3), coordination-* (2), harass-* (1), risk-* (1), power-* (1), navigation-* (1), defense-* (1), longhorizon-* (1), custom-* (1), building-* (1), rush-* (1), reasoning-* (2), action-* (2), adv-* (2), adversarial-* (3), strict-* (3). The combat / def / scout / build axes carry ~70 packs combined; a follow-up audit explicitly checking pairwise overlap inside each prefix (briefing-level read) would surface ~5โ€“10 more candidate collapses.

Section 3 โ€” Capability coverage matrix

Cross-referenced against the phase ร— decision-type matrix sketched in PAPER_PLAN.md ยง12.2 and CLAUDE.md. Each cell lists the packs that primarily measure it (a pack may legitimately serve more than one cell โ€” only the dominant assignment is listed; cross-cutting packs are flagged).

Opening

Decision Packs Density
MCV deploy site (where to plant) mcv-deploy-and-build, mcv-deploy-defensible-site, mcv-deploy-near-resource, mcv-deploy-relocate-under-pressure, mcv-deploy-second-base, mcv-deploy-third-base 6 packs (dense; good)
Build-order commit build-sequence-tech-cheapest, build-sequence-tech-fastest, build-sequence-tech-most-resilient, build-tech-skip-decision, tech-balanced-econ-then-tech, tech-aggro-all-in, tech-turtle-defensive-tech, tech-production-planning, build-power-online-first, power-budget-online, building-and-planning 11 packs (dense; good)
Defense-direction commit (which side to anticipate) def-position-expected-direction, def-position-revealed-direction, def-multi-direction, def-surprise-flank-react, def-pre-position-mobile-reserve 5 packs (good)
Rush-defense defense-rush-survive, rush-hour, build-defensive-tower-cluster, build-defensive-tower-line, build-defensive-skirt-corners, def-in-depth, def-in-depth-vs-single, def-walls-vs-towers, def-tower-line-vs-cluster, def-while-building 10 packs (dense)

Early-mid

Decision Packs Density
Harass / harass-preserve harass-response-preserve, combat-harass-aggro-commit, combat-harass-balanced-hit-and-run, combat-skirmish-then-disengage, combat-bait-counter-attack, combat-kite-and-pull, combat-kite-jeep-vs-tank, combat-retreat-after-engagement, combat-suicide-charge-mission 9 packs (dense)
Exact-count perception perception-count-the-threat, perception-count-the-threat-small-k, scout-count-defenders, scout-detect-incoming-army 4 packs (adequate)
Scout-direction commit scout-detect-base-direction, scout-far-frontier, scout-frontier-reading (=perception-frontier-reading), scout-multiple-fog-areas, scout-and-report, scout-and-survive, scout-discover-hidden-base, scout-detect-enemy-tech, scout-map-reveal-percent-target, reasoning-frontier-commit 10 packs (dense; possible over-coverage)

Mid

Decision Packs Density
Live-economy defense mid-economy-under-fire (DEFECT โ€” stall wins), econ-harvester-defense-raid [skipped โ€” econ-*], econ-protect-harvester-route [skipped] ~3 packs, 1 defective โ€” the only non-econ exemplar is broken. Gap when the in-flight econ- land โ€” verify they cover.*
Tech-switch on scout mid-tech-switch-on-scout, lh-scout-react-counter, adv-rps-counter-pick 3 packs (adequate)
Second front mfb-base-1-defend-base-2-build, mfb-supply-line-link-between-bases, mfb-mirror-base-east-west, mfb-two-base-simultaneous, mfb-third-base-against-clock, expansion-balanced-2-base-defended, expansion-aggro-3-base-greedy, coord-diversionary-attack 8 packs (dense)
Replan after loss rob-unit-loss-recovery, rob-partial-base-loss-continue, lh-recovery-after-mid-game-loss, build-engineer-rebuild-after-loss, def-retreat-and-rebuild, build-sell-and-rebuild-elsewhere 6 packs (good)

Mid-late

Decision Packs Density
Concede vs hold mid-concede-vs-hold 1 pack (THIN โ€” single exemplar)
Isolate vs split combat-divide-and-conquer, combat-pincer-coordination, combat-prevent-retreat, combat-formation-tank-wedge 4 packs (adequate)
Tempo double-window tempo-double-window, tempo-strike-window, coordination-staggered-window, tp-survive-and-strike-at-window 4 packs (adequate)
Decoy / lure / feint artofwar-decoy-sacrifice, artofwar-lure-the-tiger, artofwar-indirect-approach, artofwar-sequenced-citadel, combat-bait-counter-attack, coord-diversionary-attack, def-with-ambush 7 packs (good)
Multi-front mfb-rotating-production-pressure, mfb-redundant-tech-buildings, mfb-tech-base-vs-economy-base, rob-multiple-simultaneous-pressures 4 packs (adequate)

Late

Decision Packs Density
Sustained multi-front lh-build-army-coordinate-multifront-attack, mfb-rotating-production-pressure 2 packs (thin)
Base-trade race None directly 0 packs (GAP)
Counter-strategy read adv-rps-counter-pick, combat-attack-from-behind-fog, lh-tech-rush-vs-army-rush 3 packs (adequate)
Superweapon timing spec-nuke-strike, spec-tanya-c4-strike, spec-engineer-capture, spec-spy-infiltrate (DEFECT โ€” stall draws), spec-thief-steal-cash 5 packs, 1 defective (good once spec-spy is fixed)
Credit-only final phase lh-credit-only-final-phase 1 pack (thin)

Cross-cutting

Capability Packs Density
Procedural compliance under pressure proc-checklist-no-deviation, proc-conditional-branch-action, proc-instruction-following-edge-case, proc-no-attack-passive-only, proc-only-build-no-combat, proc-only-defend-no-attack, proc-ordered-action-strict, proc-strict-toolban-fidelity, proc-tool-use-multi-distractor, proc-tool-use-with-distractor, strict-production-bom, strict-sequence, strict-toolban-fidelity-under-pressure, tp-pressure-procedural 14 packs (very dense)
Long-horizon multi-phase lh-* (13 packs), longhorizon-opening-to-assault, lh-100-turn-marathon-survival 14 packs (dense)
Coordination across squads coord-converge-on-target, coord-cover-and-move, coord-diversionary-attack, coord-mutual-support, coord-relay-attack, coord-relay-vision-chain, coord-squad-handoff, coordination-ordered-rendezvous, coordination-staggered-window, action-multiunit-coordination, action-sequenced-execution, combat-pincer-coordination, combat-heli-flank 13 packs (dense)
Adversarial 1v1 (full macro) adversarial-duel. The full 1v1 battleground lives in one_v_one.py (openra_bench/), not as a meta.capability: adversarial pack. 1 pack (the catalog says this is by design โ€” full macro is the live ladder)

Section 4 โ€” Capability gaps (uncovered or thin cells)

Cells worth new packs, in priority order:

  1. Base-trade race (mid-late / late) โ€” no current pack tests "your base falls while you race the enemy's; whoever finishes first wins." Sketch: hard tier places both players' bases halfway to killable, no defenders left; the agent has one army worth attacking with, the enemy is doing the same to the agent's base; win by destroying the enemy's fact before they destroy yours. Win building_count_gte:{type:fact,n:0,owner:enemy} paired with has_building:fact (own) and an aggressive within_ticks. Pack id: combat-base-trade-race.

  2. Concede-vs-hold (mid-late) โ€” only mid-concede-vs-hold currently. Sketch a second pack: mid-concede-vs-rebuild where a forward outpost is lost-cost (committing reinforcements throws good money after bad), and the right call is to abandon it and rebuild on a held line. Win condition: keep the rear-line fact alive AND have โ‰ฅ4 tent/weap on the rear line at deadline; throwing reinforcements at the forward outpost fails the resource budget. Pack id: mid-concede-forward-rebuild-rear.

  3. Live economy defense (mid) โ€” the only non-econ pack (mid-economy-under-fire) is currently a stall-WIN defect. After fixing it, add a sibling pack mid-economy-rebuild-harvester-line where the agent must re-issue harvest commands to a freshly produced harvester after a raider kills the starter ones (puts the load-bearing capability on the harvest order, not on the passive auto-harvest).

  4. Long-horizon credit-only final phase โ€” lh-credit-only-final-phase is the only exemplar. Sketch sibling: lh-credit-only-bait-window โ€” the agent must spend the last credits on a single decisive strike window rather than on attrition. Different decision (one shot vs accumulation).

  5. Sustained multi-front (late) โ€” thin (2 packs). Sketch: mfb-three-front-rotation โ€” three simultaneously-attacked bases with the agent's army too small to defend all three at once; the decision is which two to hold and which one to let fall while the army cycles. Cross-pack with coord-relay-attack.

  6. MCV deploy under timer + crossfire โ€” current MCV packs cover site selection but not "deploy NOW or the MCV is destroyed by an incoming wave that hits in 4 turns." Sketch: mcv-deploy-emergency-relocation โ€” the starting MCV stands in the path of an incoming squad; the agent must deploy + re-build OR move + re-deploy further west before the squad arrives.

  7. Information freshness across modalities โ€” scout-cycle-keep-info-fresh and scout-track-enemy-movement cover this for the structured channel, but the perception ablation grid (channel ร— fog) doesn't currently have an information-freshness pack that is explicitly easier to solve with the labelled image (the image channel is advantaged when the model can spot newly-spawned units inter-tick). Sketch: perception-freshness-image-advantage.

  8. Single-pack meta.capability: adversarial โ€” only adversarial-duel carries this tag. PAPER_PLAN.md ยง12.2 notes the imbalance. The full 1v1 lives in one_v_one.py (correct), but a second adversarial-tagged pack that tests "reactive opponent selects a counter from a small menu mid-game" (different from RPS pre-game commit) would put real teeth on the tag.

  9. Engineer / Tanya / spy under fire (specialist packs) โ€” only one pack each (spec-engineer-capture, spec-tanya-c4-strike, spec-spy-infiltrate, spec-thief-steal-cash, combat-tanya-vs-rush). Each specialist has one happy-path scenario. Sketch a "stealth + target priority" pack per specialist that requires the model to pick which of N enemy assets to hit with the one-shot specialist.

  10. Naval / amphibious โ€” combat-naval-shore-strike is the only naval pack (and it's currently a stall-WIN defect). Once fixed, add combat-naval-amphibious-landing (a transport ship lands infantry on a contested shore) and combat-naval-anti-air-vs-bomber pending the air-unit engine work. These are documented as out-of-scope in PAPER_PLAN.md ยง11.1 for the air variant but the naval ones are now feasible thanks to water_rect:.


Section 5 โ€” Map mis-bindings (rush-hour-arena used where intent

calls for a custom map)

Of 189 probed packs, 183 use rush-hour-arena; 3 use a custom map (navigation-confined-hard-only, custom-map-no-enemy, strategy-dilemma/-gauntlet/-twobody); 1 uses a generator (combat-naval-shore-strike); 2 are quarantined-and-crashing.

Packs whose stated intent calls for a non-rush-hour geometry:

Pack Stated intent Current map Recommendation
combat-heli-flank Helicopter assault from a flank; the brief explicitly references aircraft flight over terrain. rush-hour-arena (no terrain features to flank around) Author / use a custom map with a forested ridge that channels ground units one way and aircraft another. (Engine air-unit support is out-of-scope per PAPER_PLAN ยง11.1 โ€” pack is currently a ground-only proxy.)
def-bridge-chokepoint "A water band cuts the map east-to-west with bridges." rush-hour-arena + water_rect overlay The water_rect overlay correctly synthesizes the bridge geometry on top of rush-hour, but the chokepoint-narrowing aspect ("attackers must pass through 3 narrow openings") works against an open-arena map. Consider a custom bridges-arena map authored once โ€” the visual / minimap reading test is more honest when the bridges are real terrain rather than a YAML overlay on an unrelated map.
combat-naval-shore-strike Naval ship in a water channel. uses naval-arena generator (correct) โ€” but the generator spec lives in the pack file rather than a named .oramap. When a second naval pack is authored (per gap #10), promote naval-arena to a real data/maps/naval-arena.oramap so the bench has a canonical naval geometry.
def-with-ambush "Concealed flanking defenders catch the band in an L-ambush down a lane toward the construction yard." Doctrinal answer requires real linear terrain. rush-hour-arena (open) The pack synthesizes the lane purely with actor placement (a single e1 fixing defender at x=15, flankers at x=40). Visually the geometry is invisible on the minimap โ€” a custom corridor-arena map with a real lane would make the spatial decision legible from the image. (Capability is sound; this is a perception-channel polish issue.)
mfb-supply-line-link-between-bases "Supply line corridor between two bases." rush-hour-arena Similar polish issue โ€” a custom multi-base map with two separated valleys would make the supply-line decision visible on the minimap rather than implicit in the actor coordinates.
combat-hold-chokepoint "Defend a narrow chokepoint corridor." rush-hour-arena (no narrow corridor) Same; either author a chokepoint-arena map or accept that the chokepoint is implied by enemy spawn geometry alone.
mcv-deploy-second-base, mcv-deploy-third-base "Plant a second / third base at a defensible site." rush-hour-arena (uniform; no defensible sites) The map is symmetric and uniform โ€” every cell is roughly as defensible as every other. The capability becomes "pick a cell that satisfies the building_in_region predicate," not "pick a defensible cell." Add a custom map with terrain features (cliff edges, narrow passes) so the defensibility geometry is real.
expansion-aggro-3-base-greedy, expansion-balanced-2-base-defended, expansion-turtle-1-base-fortified Expansion decisions over distinct base sites. rush-hour-arena (only ~3 sensible base sites given map size) Authoring a wider arena with 5+ distinguishable expansion sites would put real teeth on the trilemma.

Summary: roughly 8โ€“10 packs would benefit from a custom map, but all are currently functional (the no-cheat bar holds). The map mis-binding is a perception-channel polish issue, not a correctness issue. Priority: author 2 custom maps that unlock several packs each:

  1. bridges-arena โ€” would replace water_rect overlay on def-bridge-chokepoint and could host combat-naval-amphibious-landing.
  2. chokepoint-arena โ€” narrow corridor for combat-hold-chokepoint, def-with-ambush, mfb-supply-line-link-between-bases.

Section 6 โ€” Recommended actions (prioritized)

P0 โ€” Hard defects (gates the no-cheat headline number)

  1. Fix mid-economy-under-fire โ€” currently the only stall-WIN defect among non-exempt packs. Either:

    • (a) Remove the 3 starter harvesters; require the model to issue Command.harvest(...) on a fresh harvester (the load-bearing capability), OR
    • (b) Upgrade the raider to a force that out-attritions an idle defense ring (e.g. 3ร— 1tnk + 2ร— e3 over 60 turns), so a stall play loses harvesters and the harv,2 clause fails.
  2. Fix combat-naval-shore-strike โ€” set the destroyer stance to 0 (HoldFire) so the agent must issue an explicit attack_unit order. Verify the intended capability (manual cross-shore attack) still wins; stall now loses by deadline.

  3. Fix spec-spy-infiltrate โ€” add {not: own_units_gte: 1} (or {not: unit_type_count_gte: {type: spy, n: 1}}) to the fail_condition.any_of so a spy-wipe is a real LOSS, not a DRAW. Audit the easy / medium tiers for the same defect.

  4. Delete or _archive/ adversarial-siege and adversarial-skirmish โ€” both already quarantined; deletion removes the only two load-time-crashing packs.

  5. Re-probe def-bridge-chokepoint over seeds 1โ€“4 in clean processes โ€” confirm the one-off DRAW observation was a transient (subsequent re-runs gave LOSS consistently); if the DRAW recurs, add {not: own_units_gte: 1} to its fail_condition.any_of.

P1 โ€” Coverage gaps (new packs to author)

In priority order from ยง4: combat-base-trade-race, mid-concede-forward-rebuild-rear, mid-economy-rebuild-harvester-line, mfb-three-front-rotation, mcv-deploy-emergency-relocation, lh-credit-only-bait-window, perception-freshness-image-advantage, combat-naval-amphibious-landing, and per-specialist target-priority packs (spec-engineer-priority-targets, spec-tanya-priority-targets).

P2 โ€” Duplicate consolidation

  1. Merge / delete artofwar-decoy-sacrifice into artofwar-lure-the-tiger.
  2. Merge proc-tool-use-with-distractor + proc-tool-use-multi-distractor into a single pack with two tiers.
  3. Re-read combat-kite-and-pull vs combat-kite-jeep-vs-tank and either merge or sharpen the asymmetry-of-units distinction in the second pack's briefing.

P3 โ€” Map / catalog polish

  1. Author data/maps/bridges-arena.oramap and re-bind def-bridge-chokepoint + (future) combat-naval-amphibious-landing.
  2. Author data/maps/chokepoint-arena.oramap and re-bind def-with-ambush, combat-hold-chokepoint, mfb-supply-line-link-between-bases.
  3. Promote the four "defensive topology" packs (build-defensive-tower-cluster, build-defensive-tower-line, build-defensive-skirt-corners, def-in-depth-vs-single) into a single grouped eval-cell suite so they score one "topology-IQ" metric.

Appendix โ€” Probe methodology

Each pack was probed by:

import openra_train  # builds the engine; required for env.reset
from openra_bench.scenarios.loader import compile_level, load_pack
from openra_bench.eval_core import run_level

pack = load_pack(pack_yaml_path)
c = compile_level(pack, "hard")
ep = run_level(c, lambda rs, Command: [Command.observe()], seed=1)
# ep.outcome โˆˆ {"win", "loss", "draw"}; ep.signals.game_tick = final tick.

The driver (/tmp/stall_probe_driver.py) invoked one subprocess per pack so a Rust engine panic in any one pack did not abort the run. 189 packs probed in 48 seconds wall-time (Apple M-series).

Hard tier seed=1 only. A full audit would extend to seeds 1โ€“4 (the documented "hard seed" range in CLAUDE.md) and to easy/medium tiers, but seed-1 hard is the highest-pressure cell per pack โ€” defects visible on any tier are visible here.

Static profile was extracted from the compiled CompiledLevel (authoritative โ€” the engine sees the merged scenario, not the raw YAML).

Raw probe results JSON: /tmp/stall_probe_results.json (regeneratable by re-running /tmp/stall_probe_driver.py).