Episodic Memory: Storing What Happened
For new readers
This page documents one component of the self-model reference implementation, a working PatLang system that models cognitive processes for study. Episodic Memory's job is deliberately unglamorous: it durably records specific past interaction instances and answers queries about what it holds. It does not interpret, judge, or generalise from what it stores — that is Abstraction's job, not this one.
What Episodic Memory does
Episodic Memory's required function, per the requirements specification's component table, is to store specific past interaction instances, fed by Short Term, and to feed Imagination (for recombination) and Reason/Plan (as causal precedent). The implementation stores every percept it receives on the short_term_episodic topic and answers a recall signal with the most recent stored episodes.
The store is the queue's own append-only log
The implementation makes a specific, load-bearing choice: rather than building a separate persistence layer, Episodic Memory appends every incoming percept to a durable episodic_store queue topic and never acknowledges it. Because the message queue's own log is append-only, that unacknowledged, ever-growing log is the store — durability and restart-survival fall out for free, the same way they do for the queue library's own recovery demo elsewhere in this project. There is no separate database, no separate file format, and no separate recovery logic to get wrong.
Answering recall
episodic_tick claims one percept at a time from short_term_episodic (via qh_claim_one/queue_ack — unlike the never-acked store topic, the source topic is consumed normally, since only one Episodic Memory instance needs to see each incoming percept once) and republishes it onto episodic_store. A recall signal reads back the last episodic_default_recall_limit() entries — 10 by default — as a JSON array. The corresponding scenario in features/short_term_episodic.feature is the whole pipeline in miniature: a percept about "Rome" is published to a Perception writer-topic, and the scenario asserts that Episodic Memory eventually recalls a percept mentioning "Rome" — proving the fan-out from Short Term and the store-and-recall round trip both actually work, not just that the code compiles.
The component's own status reply goes further than the shared snapshot format alone would: episodic_status_text adds an episode_count field (via instr_snapshot_extra), computed by reading the live length of the episodic_store topic — so an external auditor can see how much history has accumulated without issuing a separate recall query.
What it deliberately does not do yet
The component's header notes plainly that wiring recall into Imagination's recombination and Reason/Plan's causal-precedent lookups is later work, scoped to a subsequent milestone — this component's job right now is to make the store real, durable, and queryable, not to consume its own output elsewhere in the architecture.
Instrumentation and lifecycle
Episodic Memory composes the same lib/component_base.patlang / lib/instrumentation.patlang pair every component in this project uses — claiming a signals port and announcing itself via component_start, answering status through the shared snapshot format, and shutting down cleanly on quit.
See also
Episodic Memory receives percepts from Short Term, the same source that feeds Procedural Memory and Abstraction. See the architecture overview for how Imagination and Reason/Plan are intended to draw on recalled episodes.