"""Scripted defender for attacker Gen-1 GRPO training. Always emits read_log — a do-nothing baseline an attacker can easily defeat. Mirrors scripted_attacker.py structure. """ from __future__ import annotations import random try: from ..models import DefenderAction except ImportError: from models import DefenderAction class ScriptedDefender: """Deterministic baseline defender: always emits read_log. Uses a seeded RNG for structural parity with ScriptedAttacker, even though the action is deterministic. """ def __init__(self, seed: int = 42) -> None: self._rng = random.Random(seed) def act(self) -> DefenderAction: """Return a read_log DefenderAction.""" return DefenderAction(action_type="read_log", log_tail_lines=10)