Problem
StructuredEpisodeManager maintains 17 parallel lists (episode.py:149-168) that must stay synchronized for every episode. _append_structured_logs (episode.py:257-281) is essentially bookkeeping for that invariant — every time a new episode-level field is added, it must be threaded through here too, or it silently drops out of get_logs().
Proposal
Store list[EpisodeSummary] instead. EpisodeSummary already carries every one of those fields. Compute the per-key column views lazily inside get_logs().
Wins
_append_structured_logs deletes entirely.
- The 17 list attributes collapse to one.
- A class of "I added a field to
EpisodeSummary but forgot to log it" bugs disappears by construction.
Acceptance criteria
Problem
StructuredEpisodeManagermaintains 17 parallel lists (episode.py:149-168) that must stay synchronized for every episode._append_structured_logs(episode.py:257-281) is essentially bookkeeping for that invariant — every time a new episode-level field is added, it must be threaded through here too, or it silently drops out ofget_logs().Proposal
Store
list[EpisodeSummary]instead.EpisodeSummaryalready carries every one of those fields. Compute the per-key column views lazily insideget_logs().Wins
_append_structured_logsdeletes entirely.EpisodeSummarybut forgot to log it" bugs disappears by construction.Acceptance criteria
episode.pystores_episodes: list[EpisodeSummary].get_logs()returns the same dict-of-lists shape it returns today (no API change for callers)._append_structured_logsremoved.