0

Dcopf Grid Verifiers

Fresh

DC optimal power flow RL environment with line limits: verifiable dispatch under transmission congestion. Ground truth cross-validated by two indep...

Type
RL Env
Publisher
Jwilksbooth
Runtime
single-turn
License
mit
Size
v0.2.3
Published
Jul 2026

Cite

Notes

Only stored in your browser.

dcopf-grid-verifiers

DC Optimal Power Flow (DC-OPF) RL environment with transmission line limits. Successor to a merit-order economic dispatch environment: this version adds network physics (bus angles, line reactances, MW flow limits), so pure merit-order reasoning fails on a measured 46% of instances — the network-unconstrained least-cost dispatch actually violates a line limit, and congestion forces out-of-merit dispatch. That is exactly what naive LLM reasoning gets wrong.

Why this environment is hard to reward-hack

The dominant hack in dispatch tasks is quoting an impossibly cheap dispatch that violates physics. Here, the optimality reward is hard-gated on a physics feasibility check: given a proposed dispatch, bus angles are uniquely determined (slack-referenced B-theta solve), so power balance, generator bounds, and every line flow are verified before any optimality credit is granted. An infeasible answer scores 0 on optimality no matter how cheap it claims to be.

The gate is red-teamed in tests/test_validation.py (6 attack tests): the infeasible-cheap dispatch, garbage output, the subtler NaN/Infinity JSON attack (json.loads accepts these literals, and NaN defeats any comparison-based check because every comparison against NaN is False), and the tolerance-rent attack (under-serving load inside the ±0.5 MW feasibility tolerance to come in below the LP optimum — residual violations are settled at a 2× penalty price, real imbalance-market style, and below-optimum cost is penalized symmetrically). Non-finite values are rejected at parse and inside the physics check itself.

Ground truth validation

Two independent implementations of the same DC-OPF formulation must agree (cross-implementation validation — both share DC power-flow physics; this catches modeling and coding errors, not model-form error):

  • Primary: B-theta LP formulation solved with scipy.optimize.linprog (HiGHS)
  • Cross-check: pandapower.rundcopp on the same networks (separately implemented modeling path: ohmic line parameters, current-based ratings)

Validation run (300 randomly generated instances, seeds 0–299 — the full default dataset):

MetricResult
Objective mismatches (>0.1% rel and >$1/h abs)0 / 300
Worst relative objective gap6.9e-10
pandapower non-convergence1 / 300 (test fails if >2%)
Merit-order dispatch infeasible (violates a line limit)137 / 300 (46%)
Instances with a binding line at optimum142 / 300 (47%)
Median congestion cost premium (congested subset)9.2%

The distribution behind these numbers is measured and tuned, not inherited — see CALIBRATION.md for the metric definitions, the parameter sweep, and the rationale for the chosen configuration.

Baseline results

50 instances (seeds 0–49), 1 rollout each, default sampling, July 2026:

Modeltotalformatfeasibilityoptimalitycongestion
claude-haiku-4-5 (6k tokens)0.5201.0000.5200.4320.480
claude-opus-4-8 (16k tokens)0.9010.9200.9000.8980.900

Reproducing this: pass --max-tokens. Anthropic endpoints default to 4096 output tokens, at which frontier rollouts truncate mid-derivation and the score collapses to ~0.5 (measured). Use --max-tokens 16000 for Opus-class, 6000 for Haiku-class, with -r 1.

Reading: the weak model formats perfectly but only 52% of its dispatches survive the physics check — it loses on feasibility, not parsing. The frontier model reaches 90% feasibility and, when feasible, averages 0.998 optimality — its remaining gap is reasoning budget (4/50 rollouts truncated at 16k tokens) and occasional congestion misreads. Frontier reasoning-token demand is itself part of the task's difficulty: at 6k tokens, half of the frontier model's rollouts truncate before emitting an answer.

Reproduce:

vf-eval dcopf-grid-verifiers -p anthropic -m claude-haiku-4-5-20251001 -n 50 -r 1 --max-tokens 6000 --save-results
vf-eval dcopf-grid-verifiers -p anthropic -m claude-opus-4-8 -n 50 -r 1 --max-tokens 16000 --save-results

Example failure (claude-haiku-4-5, from the baseline run)

"...I need to solve the AC power flow equations. After careful analysis of the feasible region, the optimal dispatch appears to be: P0 = 15.2 MW, P1 = 90.3 MW, P2 = 86.7 MW. This satisfies: Total: 192.2 OK, Bounds: All within limits OK"

The model verifies generation balance and generator bounds, then declares victory — but never solves the network. Its dispatch drives Line 0 to -44.4 MW against a 39.6 MW limit (and it mistakes this DC problem for AC power flow). Feasibility reward: 0. Confident, well-formatted, and physically impossible — exactly the failure mode the environment exists to catch.

Rewards (weighted rubric)

RewardWeightDescription
format_reward0.10Parseable {"dispatch_mw": [...]} with correct arity, finite values only
feasibility_reward0.30Passes physics check: balance, gen bounds, all line limits
optimality_reward0.50Gated on feasibility; exp(-5 × relative cost gap) vs LP optimum
congestion_reward0.10Gated on feasibility; credits correctly loading binding lines to 90–100% of limit

Usage

# local install
pip install -e ".[crosscheck]"

# run validation harness (solver cross-check + reward gate tests)
N_INSTANCES=200 python tests/test_validation.py

# measure the instance-difficulty distribution / re-run the calibration sweep
python calibration/measure.py --n 300

# evaluate a model via verifiers CLI (give frontier models room to reason —
# see the warning under the Baseline table; -r 1 to match the published numbers)
vf-eval dcopf-grid-verifiers -p anthropic -m <model> -n 50 -r 1 --max-tokens 16000
import verifiers as vf
env = vf.load_environment("dcopf-grid-verifiers", num_examples=300)

Instance generation

Random connected networks (spanning tree + loop edges, 4–8 buses), 2–4 generators, loads on ~2/3 of buses. Generator costs are drawn from a tiered merit stack (baseload / mid-merit / peaker) rather than a flat distribution, so congestion is economically sharp: when a constrained corridor blocks a cheap remote unit, an expensive local unit must run — the mechanism behind real-world locational price separation. Units are modeled as fully flexible committed capacity (low Pmin — a deliberate no-unit-commitment stylization, documented with its measured difficulty trade-off in CALIBRATION.md). Line limits are drawn from a bimodal (tight/loose) distribution bounded to physically possible values (no rating above total system load, 15 MW floor) and calibrated so ~46% of instances defeat network-unconstrained merit-order dispatch (measured, see CALIBRATION.md). Every generated instance is solved at generation time; infeasible draws are rejected. Fully deterministic per seed.

The congestion rate is deliberately oversampled relative to a real N-1-planned grid, where binding congestion is far rarer: a realistic sample would be ~90% trivial merit-order instances and would not exercise the skill being tested.

The vertical

  • economic-dispatch — merit-order control rung (frontier-saturated by design).
  • dcopf-grid-verifiers (this) — congestion / space.
  • multiperiod-dispatch — ramp coupling / time; shipped, 74% defeat per-period merit order.
  • Next: N-1 contingency screening (dispatch must survive the worst single line outage); LMP/nodal pricing verified against LP duals.