# Teacher-context variants Each **variant** is one way to build the teacher's refined trajectory `r` — a self-contained folder that overrides only what differs from the live default. The shared machinery (HTTP transport, MC rollouts, divergence metrics, the batched training loop) lives in the core and is **never copied**, so adding a variant never adds an `if variant == ...` branch. ## Layout ``` agents/variants/ base.py TeacherVariant — the interface + shared defaults + t* helpers __init__.py registry: load(name) / available() / utils.py a TeacherVariant subclass (+ VARIANT = TheSubclass) prompts.yaml strategy + maker_system_prompt (+ optional teacher_user wrapper) README.md what it is, the bet, the pre-registered prediction ``` ## The interface (what a variant may override) | method | default | overridden by | |---|---|---| | `resolve_prefix(problem, solution, rollout, maker)` | maker rewrite, fall back to reference | P4 (answer-only, maker-free), P6 (captures diagnosis quote) | | `accepts(prefix, reference)` | `is_acceptable_prefix` (len ≥ 80 ∧ boxed-match) | P2 / P4 (answer-only bypass: boxed-match only) | | `build_ctx(tok, client, problem, prefix, cfg)` | user turn + `` analysis + close + transition | P5 (reactive wrapper), P4 (no thinking) | | `t_star(prefix, rollout, tok)` | `difflib` first non-matching block | P3 (`lcp`), P6 (quote-match) | | `thinking` | `True` | P4 (`False`) | Everything else — `score_topk`, `mc_branch`, `select_divergent`, M1–M3, the trainer loss — is shared and calls these methods. ## Two seams this relies on (both in `agents/maker.py::build_prefix`, backward-compatible) - `prompts=` — a variant supplies its own `{strategy, maker_system_prompt, maker_user_template}` instead of a file swap. - `accept=` — a variant supplies its own gate (e.g. answer-only bypass). ## Usage ```python from agents.variants import load, available v = load("p1_surgical") # available() -> ['p1_surgical', 'p2_...', ...] prefix = v.resolve_prefix(problem, solution, rollout, maker_client) ctx = v.build_ctx(tok, client, problem, prefix, cfg) tstar = v.t_star(prefix, rollout, tok) ``` ## Scope Variants are the prompt-space ranking substrate (probe / Stage-1). The loss-side mask and per-sample gate (the reactive-constructor spec) are deferred; when they land, `build_ctx`'s declarations feed the trainer but generation stays shared. ## Adding one Copy the closest folder, edit `prompts.yaml` + the few overridden methods in `utils.py`, write the `README.md`. No core edits.