Most AI systems forget everything the moment you stop talking. This one does not. Here is what actually happens when a question arrives now.
The Old Way
Before memory, every question started cold. The language model had no context about my specific environment, past incidents, or patterns already observed. It was making educated guesses based on general training data - useful, but not grounded in reality.
The New Flow
When a question comes in, the system does not just send it to the language model. First, it searches long-term memory using both keywords and semantic meaning. The system pulls the most relevant past experiences - whether they came from error logs, customer tickets, or team discussions.
Every one of those past experiences was captured as an ExperienceEvent - the atomic unit of cognition in the Cognitive Substrate:
// packages/core-types/src/experience.ts
/** Classification of the event origin within the cognitive loop. */
export type EventType =
| 'user_input'
| 'tool_result'
| 'system_event'
| 'agent_action'
| 'environmental_observation'
| 'consolidation_output'
export interface ExperienceEvent {
readonly eventId: string
readonly timestamp: string
readonly type: EventType
readonly context: EventContext
readonly input: EventInput // text + embedding
readonly internalState?: InternalState
readonly action?: EventAction
readonly result?: EventResult
readonly evaluation?: EventEvaluation
readonly importanceScore: number
readonly tags: ReadonlyArray<string>
}The ingest worker is what turns raw blog telemetry into these events. It consumes the telemetry.logs.raw Kafka topic and writes to the experience_events OpenSearch index:
// packages/ingest-worker/src/index.ts
//
// Pipeline:
// blog VPS → KafkaTransport → telemetry.logs.raw → [this worker]
// → mapTelemetryToExperience → ExperienceWriter → experience_events
await consumer.subscribe<TelemetryEvent>([Topics.TELEMETRY_LOGS_RAW], async (message) => {
const event = message.value
if (!event?.type || !event?.sessionId) {
console.warn('[ingest-worker] Skipping malformed message at offset', message.offset)
return
}
const experience = mapTelemetryToExperience(event)
await writer.write(experience)
})By the time a question arrives and triggers a retrieval, the system has already been quietly converting reader behavior into structured, embedded memories for weeks.
Here is where it gets interesting: the retrieved memory is not used blindly. It goes through an arbitration step. The system scores how relevant and trustworthy each memory is, then decides whether to use it, how much to trust it, and what parts matter most.
Only then does the language model see the question. When it answers, it is not guessing - it is reasoning with real history from the actual environment.
The Difference Is Dramatic
Questions about my infrastructure that used to get vague answers now get precise ones, because the system actually remembers what happened last time. Questions about recurring errors reference the pattern already identified. Questions about service behavior draw on real telemetry observations, not general assumptions.
This is what real memory feels like in practice. Not just storing things - actually using them to get better answers.
The next article covers how the system learns which memories to trust over time.