Exact Anytime Arbitrary-Opponent Certificate¶
Purpose and claim boundary¶
src.true_shield.adversarial implements the first theorem-facing certificate
path. It is deliberately separate from TruePolicyTransitionShield and the
learned WM/OM shield:
- transitions come from the raw exact
src.joint_graph.common.Graph; - the opponent is allowed to choose any joint opponent action represented by that graph at every state;
- the certificate is per focal agent and per episode;
delta_cov = 0only relative to the serialized exact graph, the matching environment contract, and the graph's declared reset support;- the certified statement starts at
reset(). Any WM/OM pretraining prefix is outside its scope.
For a certified reset state and budget p, the checked Bellman invariant gives
an eventual unsafe-reachability bound of at most p against arbitrary
opponent actions in the finite kernel. This is not a claim about dynamics
outside that abstraction or reset states absent from graph.start_keys.
For deterministic matrix games, the graph builder snapshots and steps the live environment, so the graph rows use the simulator transition implementation. The stochastic gridworld builders currently call separate pure successor functions. Their configuration is now bound and their rows are checked strictly, but a gridworld should be described as certified relative to the serialized graph until its successor function has an exhaustive equivalence audit or is shared directly with the simulator. In the retained paper suite, Bertrand and Chicken are therefore the primary simulator-bound cases; Pursuit-2 is useful as a boundary diagnostic rather than evidence of simulator equivalence.
Outer kernel¶
compile_exact_adversarial_outer_kernel(...) keeps one sparse row for each
(s, a_i, a_-i). It never multiplies by an opponent policy and never uses the
opp_prob or prob edge fields. The robust action backup is
R_beta(s, a_i) = max_{a_-i} sum_s' P(s' | s, a_i, a_-i) beta(s')
T beta(s) = min_{a_i} R_beta(s, a_i).
Opponent tuples are segmented rows, not synthetic shield “levels”. A missing
opponent tuple makes that focal action demand risk 1. Missing probability mass
within a present row is also sent to the implicit unsafe sink. Negative or
non-finite probabilities are rejected; mass above one is rejected beyond the
small representation allowance.
Exact graph generation rejects negative, non-finite, and excess probability mass and never renormalizes a deficient successor distribution. The compiler sends any deficit to the implicit unsafe sink. The vectorized solver first computes the largest robust invariant safe set, then runs lower/upper reachability iteration. A build is rejected unless the lower/upper gap converges. The final float vector is closed upward against exact rational evaluations of the serialized decimal probabilities.
Independent validation¶
validate_exact_adversarial_certificate(...) uses a deliberately slow nested
loop over raw graph edges rather than the vectorized compiler or synthesis risk
routine. It checks:
- graph, public-state encoding, unsafe-label, and environment-config hashes;
- finite/non-negative probability rows and excess/missing mass handling;
- complete focal/opponent action groups;
- finite
betavalues in[0, 1]andbeta=1on unsafe states; - every stored exact action-risk fraction, action mask, row ID, and worst-case opponent witness;
- the robust Bellman inequality
T beta <= betawithFractionarithmetic; - equality between the certificate reset support and
graph.start_keys; - support membership and
beta(reset) <= p_shieldfor every reset key.
Certificate NumPy arrays are copied and made read-only. The official runtime factory recomputes the environment contract and unsafe labels, revalidates the persisted certificate against the raw graph, and checks agent order and every Discrete action-space size before constructing the wrapper. Runtime state encoding accepts only exact finite binary values and compares the bits with the stored graph node after key lookup.
solver_converged and certificate_inductive are separate report fields. A
non-converged or non-inductive artifact is rejected. An inductive artifact can
still have status infeasible when its reset risk exceeds the requested
budget; retaining that result is useful for negative controls.
Reset metadata distinguishes deterministic, exhaustively enumerated, sampled,
and conditional supports. Feasible artifacts with incomplete or unknown reset
support use certified_on_declared_reset_support; only a complete support uses
the unqualified certified status. Both runtimes reject an undeclared reset.
Artifact and runtime contract¶
The opt-in notebook diagnostic writes:
The report records status, scope, reset support and risks, p_total,
p_shield, delta_cov, graph sizes/hashes, solver and validator versions,
wall-clock diagnostic time, and training_environment_steps=0.
After the Bertrand, Chicken, and two-agent Pursuit reports exist, render the paper tables without manually copying fields:
uv run python scripts/summarize_exact_anytime_diagnostics.py \
--exports-root exports \
--require-complete
This writes anytime_certificate_results.tex,
anytime_certificate_costs.tex, and a combined JSON provenance record beneath
exports/reports/exact_anytime/. The certificate table reports audit status,
worst declared-reset risk, and Bellman residual; the cost table reports graph
size, cache state, graph time, synthesis-plus-audit time, solver iterations,
and the zero RL-training-step count. It intentionally excludes the separate
evaluation-only shield harness.
ExactAdversarialTransitionShield is the strict runtime consumer. It starts
each episode at q=p_shield, admits an action only by exact rational comparison
against the precomputed robust action risk, and then sets
q_next=beta(next_state). There is no positive admissibility tolerance. An
optional ActionScorer only ranks actions after the safety mask is fixed; it
cannot make an unsafe action admissible. The wrapper refuses an infeasible
certificate, an undeclared reset, or a reached state outside the graph.
It also implements the trainer's action_mask(agent) and
last_executed_actions contracts and streams decisions into EpisodeLog
through record_shield_step(...).
Notebook switch and cost¶
Every standard environment experiment notebook exposes
run_exact_anytime_diagnostic=False. Enabling it builds or reuses the exact
graph, solves and validates the certificate, and writes the report. It does not
initialize PPO, collect RL rollouts, or retrain a policy. On a cache hit the
cost is certificate synthesis plus validation; on a miss, exact graph
enumeration can dominate.
This is intentionally an offline audit first. Evaluation with a saved policy
can use make_exact_anytime_shielded_env_factory(...); a full shielded PPO
retraining condition should only be added if the offline certificate is
feasible and the paper needs reward results under the strict shield.
evaluate_exact_anytime_policies(...) is the lean evaluation-only path for
already reconstructed policy adapters. It performs no updates, exports one
aggregate row per episode plus a summary, and retains no per-transition trace.
The summary includes unsafe episodes, override rate, maximum runtime residual,
minimum margin, return, steps, and evaluation time.
Environment routing¶
| Environment | Reporting value | Guidance |
|---|---|---|
| Bertrand, Chicken | High, very cheap | Primary retained positive certificate table; tiny exact graphs and clear safety fallbacks. |
| Inspection | High, very cheap | Useful if the retired environment is restored; otherwise keep outside the active paper table. |
| Congestion | High | Useful if the retired environment is restored. Start with 2 agents; larger agent counts make exact joint graphs grow rapidly. |
| DPGG | Medium-high | Modest exact graph and useful additional matrix-game result; inspect whether the robust value is non-trivial. |
| Ice Duel | High diagnostic value, not yet a primary guarantee | Exercises multi-successor rows. Its stochastic game can expose an upper/lower value-iteration plateau; include it in a guarantee table only when the report is certified. |
| Pursuit | High as a negative control | Report infeasibility if arbitrary opponent motion defeats the reset budget; larger agent counts also stress graph memory. |
| Gathering | Conditional | Run only with reset support appropriate to the claim. The default exact builder samples starts; use complete start enumeration before claiming coverage over all resets. |
| Markov Stag Hunt | Conditional and expensive | The exact builder samples reset states and the reachable graph can be large. Treat it as an engineering audit until reset-support coverage is established. |
Matrix games may produce mostly 0/1 certificates. The stochastic unit case in
tests/test_true_shield.py supplies a checked non-trivial value and budget
propagation path. Ice Duel is a useful next integration target, but is not a
substitute unless its environment report actually converges and is certified.
The current lower/upper solver detects a numerical fixed-point stall and emits
an invalid diagnostic rather than looping to vi_max_iterations. This occurs
for stochastic games whose ordinary bounded value iteration needs end-component
deflation. The retained coarse upper vector may be inductive, but
solver_converged=false means it is rejected by the runtime and must not be
reported as the theorem guarantee. A future Ice Duel certificate should add a
formally checked deflation or strategy-iteration step, not weaken this gate.
Deliberate exclusions¶
This version does not assign statistical coverage to learned transitions. The
existing shield_credible_* fields describe posterior opponent-level tails;
they are not delta_cov. A later learned-model theorem path should reserve
p_shield = p_total - delta_cov and attach a time-uniform transition coverage
event without changing the exact certificate's meaning.