|
|
||
|---|---|---|
| .. | ||
| .gitkeep | ||
| README.md | ||
README.md
core/episode/
Episode lifecycle + stitching (V7 §2.4.1, §2.6 Tier 2b).
Why this directory is intentionally empty
V7 splits episode-related work across two responsibilities, and each already has its own module:
| Concern | Lives in |
|---|---|
| Lifecycle (open / close / reopen) | core/session/episode-manager.ts |
| V7 §0.1 relation classifier | core/session/relation-classifier.ts |
| Persistence adapter | core/session/persistence.ts (EpisodesRepo) |
| SQL schema | core/storage/migrations/001-initial.sql |
| Tier 2b "episode replay" | core/retrieval/tier2-trace.ts::rollupEpisodes |
| Event aggregation | core/session/events.ts |
Episode logic is intimate with session logic (same lifecycle bus, same
repo transactions), so folding it into core/session/ avoids a circular
dependency between core/episode/ and core/session/. The architecture
diagram in ARCHITECTURE.md §3.2 lists this directory for discoverability
only — actual code belongs next to the session manager.
Episode stitching in practice
V7 §2.4.1 calls out "episode stitching" as auxiliary — not a prerequisite for L2 induction. We implement it implicitly:
EpisodeManager.startopens a row inepisodes.pipeline/orchestrator.ts::onTurnStartclassifies the incoming user turn's relation to the previous episode (revision/follow_up/new_task) and either:- reopens the previous episode (revision, V7 §0.1),
- starts a fresh episode in the same session (follow-up), or
- starts a new session + episode (new task).
- Capture attaches
trace_idsto the episode on finalize. - Retrieval's Tier 2b reads all traces belonging to one episode and
renders a chronological action-sequence summary when the
episode's goal-level cosine clears
episodeGoalMinSim— this is the "sub-task episode replay" V7 §2.6 Tier 2b describes.
Invariants
- An episode always belongs to exactly one session.
episodes.status ∈ {'open', 'closed'}. Reopening a closed episode (V7 §0.1 revision path) flips status back to'open'and recordsmeta.reopenReason.- Trace rows hold the authoritative
episode_idforeign key; the episode'strace_ids_jsonis a denormalised convenience field (kept in sync byEpisodeManager.attachTraceIds). - Episode lifecycle events are emitted on the
SessionEventBus(episode.started,episode.turn_added,episode.finalized,episode.abandoned,episode.reopened,episode.relation_classified).
Tests
tests/unit/session/episode-manager.test.ts— lifecycle.tests/unit/session/relation-classifier.test.ts— V7 §0.1 routing.tests/unit/retrieval/tier2.test.ts— Tier 2b rollup + goal filter.tests/unit/pipeline/memory-core.test.ts— end-to-end through the orchestrator (revision + new_task routing integration).