Expand description
The aggregate: what an episode is, and what it is not.
An episode is a provider’s conversation boundary. It begins when a client attaches and ends when it detaches, whether or not anybody declared a task, and whether or not the last task anybody declared was finished a week ago (ADR 0052).
A task is a unit of intended work that a person opens and closes. It is related to
an episode and it is not part of one. The relation is Option<TaskId> and nothing more:
no outcome, no profile, no scope, no obligations. Those are the task aggregate’s, and an
episode that carried a copy of them would be a second account of a record that already
exists — the shape of every defect this subsystem has produced.
The separation is not stylistic. On 2026-09-05 task t-20260905034523-a9f1 was marked
handed_over and never replaced, and for six days this repository wrote no checkpoint
and no handover while doctor and watch reported health. Three code paths each asked
a task whether an episode’s artefact should be written, and each refusal was correct
against its own contract. In this model there is no such question to ask: nothing on
Episode can gate a transition on a task, because a transition is
super::EpisodeState::may_move_to and it takes no task.
use majordomus_cli::session::{Episode, EpisodeId, EpisodeState, TaskId};
use std::path::Path;
let id = EpisodeId::parse("s-20260910205542-e2a6").expect("an episode id");
let episode = Episode::opening(id, Path::new("/r"))
.opened_at("2026-09-10T20:55:42Z", "master", "9f3a2a0", 1_789_073_742)
.with_task(TaskId::parse("t-20260905034523-a9f1").expect("the task from the audit"));
// the task is `handed_over` in the incident, and the episode still closes
assert!(episode.may_move_to(EpisodeState::Closed));
assert!(Episode::opening(episode.id.clone(), Path::new("/r")).task.is_none());Structs§
- Episode
- One execution episode: a provider’s conversation boundary, with the identities that say whose and where it is, and at most a relation to a task.
Enums§
- Outcome
- How an episode ended, as the record states it.