Alice still queries her counter-rule graph — but now she also observes Bob's move-to-move transitions and uses them. Instead of countering what Bob just did, she predicts what Bob will do next (given his last move) and counters that. Watch the predictive policy off; turn it on; watch the win rate flip when Bob has a pattern.
| prev \\ next | strike | block | throw | movement |
|---|
(bob, last_committed_move, X). From those she derives transitions in temporal order: (prev → next) counts. Predicting what bob does next given his last is just argmax over the row of that table — predict_next_after(beliefs, 'bob', bob_last). Counter the prediction instead of the observation and one-ply lookahead has paid off: against a cyclic Bob, you're one move ahead of him for free.
examples/cognition_dojo_f_v7.py — the policy fighter_react_predictive is a drop-in swap of fighter_react. Same belief graph, same pick_counter, same resolve table; only the decision target changes from bob_last to predict_next_after(bob_last). The transition counts are themselves derivable from (bob, last_committed_move, X) observation facts — the model of Bob lives in the same graph as Alice's rules. Predictive policy emerges from data already in the graph.