Skip to content

Move the eval bench's direction probe onto per-line direction and report stripped events honestly #211

Description

@schmug

Task

Update the TTS eval bench (skills/tts-eval/bench.py) for what #201 changed in the renderer: its direction probe should exercise per-line direction over a clone (a lines scene whose one line carries instruct), not only the episode-level voice_instruct path, and its events probe should report that an engine without events never received the markers (they are stripped before the render) instead of a bare markers heard: none that reads as "performed".

Context

#201 made render.py consume the events and direction capabilities: on an engine without events the renderer strips (laugh) / (sigh) from every take before the model sees it, and a scene line may carry instruct, rendered through Breeze's clone-plus-instruct form and folded into the take's cache key. The bench renders only through render.validate_manifest / render.render_segments (the invariant in CLAUDE.md), so two of its probes now measure something different from what they were written for:

  • The events probe on the control (qwen3) measures a marker-stripped take: WER 0, markers_heard: []. tests/test_tts_eval.py::test_bench_renders_candidate_and_control_and_writes_both_artifacts already asserts that per engine, but the ledger row and the HTML report present it the same way as a candidate that performed the markers. A reader comparing engines cannot tell "performed" from "never handed them".
  • The direction probe goes through voice_instruct (design mode on a plain segment), which skills/tts-eval/SKILL.md line 28 explicitly says is a stand-in until Gate vocal events and per-line voice direction on the engine's capabilities #201 lands. The identity drift that motivates st_write.MAX_DIRECTED_LINES_PER_SCENE = 1 (Ethan 93 → 183 Hz, similarity 0.96 → 0.88 in the 2026-09-04 eval) needs to be measured on the form a show actually uses: a cast clone with instruct, compared against the same clip undirected.

Pointers

  • skills/tts-eval/bench.pyTAKE_KINDS, strip_events, the events/direction entries in the corpus expansion (~line 195-235), markers_heard in the per-take rows (~line 674-723) and the report (~line 951, ~line 1005).
  • skills/tts-eval/corpus.json — the events and direction entries (append-only; a changed line makes earlier ledger entries incomparable).
  • skills/tts-eval/SKILL.md — the probe table and the metrics table, both pinned to bench.METRICS / the corpus by tests/test_tts_eval.py drift tests.
  • skills/daily-podcast/render.pyEVENT_MARKERS, strip_event_markers, _validate_engine_capabilities (the per-line instruct refusal), _generate_breeze (the clone-plus-instruct form), _segment_cache_key(instruct=).
  • skills/surface-tension/st_write.pyDIRECTIONS (word → instruct phrase) and lines_for_engine; the probe should direct with a phrase from that table so the bench measures what the show would ship.
  • tests/test_tts_eval.py — the per-engine events assertion added in Gate vocal events and per-line voice direction on the engine's capabilities #201's PR, and the fake engine/analyzers the bench tests run on.

Constraints

  • The bench keeps rendering through the registry only (test_bench_never_calls_mlx_audio_directly stays green).
  • The corpus stays append-only and under every finite max_take_chars in render.ENGINES; adding a directed variant of an existing line is fine, changing a line is not.
  • On an engine without direction the per-line probe is skipped and the report says so (the existing posture for an engine without design).
  • Ledger entries written before this change must still parse; a new field is added, never renamed.

Acceptance criteria

  • The events probe row and report cell distinguish "performed" (engine has events, markers absent from the transcript) from "stripped before the render" (engine lacks events), and the daily-skill metric name for it is pinned by the existing drift test.
  • The direction probe renders a clone line with instruct (a DIRECTIONS phrase) through render.render_segments and reports its pitch/similarity against the same line undirected.
  • skills/tts-eval/SKILL.md no longer says the direction probe waits on Gate vocal events and per-line voice direction on the engine's capabilities #201.
  • pytest and both ruff gates pass.

Out of scope

Cross-references

Generated by Claude Code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions