Cognitive science gave us a 50-year head start. Humans don't store everything in one undifferentiated bucket — and neither should your agents. Statefulai borrows the distinctions that matter and grounds them in the data shapes coding work actually produces.
01 Episodic memory
The story of your repository. Every change, decision, conversation, and accepted diff — timestamped, branch-scoped, and replayable.
Episodic memory is what makes "why did we do it this way" answerable six months later. It's an append-only stream of events: things that happened at a particular time, in a particular branch, by a particular actor (human or agent).
Mar 14 · init
Mar 22 · ADR-007
Apr 12 · stripe switch
Apr 19 · review
May 02 · deploy
May 11 · incident
May 18 · fix merge
Apr 12 09:14Switched usage tracking from internal counter to Stripe usage API. Rationale: idempotency under retry, billing alignment with invoice.@rena · adr-014
May 02 16:30Deployed billing.flush() to prod replica. Soak: 4h. Errors: 0. Latency p99: 84ms.@deploy-bot
May 11 03:42Incident · invoice double-flush. Root cause: lock not held across retry. Mitigation: pin idempotent-writes rule.@on-call
Each event carries a structured payload (commit SHA, files touched, accepted diff, prompt) and free-form context (author note, Slack quote, ADR body). The pair makes events both queryable and quotable.
What episodic memory answers
› Why did we switch the queue to Kafka?→ ADR-014 · Apr 12 · @rena
› Who last touched billing.ts and when?→ @marko · May 18 · PR #492
› What broke at 3am on May 11?→ invoice double-flush · lock contract violated
› Show me everything that touched the auth module this quarter.→ 23 events · 4 contributors · ADR-007
Episodic ≠ git log. Git tells you the diff. Episodic memory tells you the conversation that produced the diff, the rationale captured along the way, and the runtime evidence that came after.
02 Semantic memory
What your codebase means. Modules, contracts, decisions, and the relationships between them — modeled as a typed graph.
Semantic memory captures the durable, structural understanding of a project: which module owns which capability, what calls what, which API depends on which type, who decided what. It's a graph because the relationships are the value.
Node types & edges
Module, Symbol, Type — extracted from source via Tree-sitter + LSP.
› Show every consumer of the User type.→ 14 modules · 3 across services
› What does our payment flow look like end-to-end?→ Checkout → Billing → Stripe → Webhook → Ledger
› Which modules depend on this contract?→ 6 internal · 2 external · 1 deprecated
› Who knows the most about auth?→ @rena (.42) · @marko (.28) · @claude-code (.20)
03 Procedural memory
How the team actually works. Lint rules, deploy steps, review preferences, naming patterns, and unwritten conventions — encoded so agents follow them by default.
Procedural memory is the layer most likely to feel like a team's culture in code. It's where "we don't do that" lives, alongside the affirmative habits that make a codebase consistent.
Rules are extracted (from accepted diffs, review comments, and rejected agent suggestions) and asserted (you can write them directly). Each rule has a scope, a confidence, and a provenance.
@idempotent-writesmodule · billing
Any write that crosses an external boundary must be safe to retry. Acquire a per-resource lock and use a deduplication key.
▸ derived from ADR-014, 6 accepted diffs
@no-jwt-cookiesmodule · auth
We store session IDs in HttpOnly cookies, not JWTs. JWT-in-cookie suggestions should be rewritten.
▸ ADR-007 · 4 reviewer rejections of JWT
@zod-on-boundaryall services
Validate every external input with Zod and narrow types before passing to internal code.
▸ 38 instances · 0 violations in main
@composition-over-inheritanceall packages
No class hierarchy > 2 levels in app code. Use composition + small interfaces.
▸ inferred · 96% confidence · @rena reviews
@pnpm-typecheck-pre-commitworkspace
Run pnpm typecheck before any commit; agents should add it to suggested commands.
▸ husky · 100% workspace
@redact-pii-logsall logs
Strip emails, names, and tokens from log lines. Use the redact() helper before logger.info.
▸ DLP policy · derived 04-18
What procedural memory does
Re-shapes agent prompts at retrieval time — the rules show up alongside the context, so the agent acts with them, not against them.
Flags violations in proposed diffs before they leave the agent.
Captures negative rules from reviewer rejections — "we keep rejecting JWT" becomes a first-class fact.
04 Comparison
When to expect each layer to do the work.
Dimension
Episodic
Semantic
Procedural
Shape
events
graph + vectors
rules
Decays?
recency-weighted
rarely
only when retired
Best at
"when / who / why"
"what / how / depends-on"
"the way we do X"
Write source
commits, ADRs, chats, prompts
source code, LSP, ADRs
reviews, accepted diffs, asserts
Storage
postgres · s3
neo4j · qdrant
redis · postgres
Retrieval primitive
time range + filter
vector + graph walk
scope match
05 Interplay
A real question almost always pulls from all three.
Take a common Tuesday morning prompt: "Refactor billing.ts to use Stripe's usage API." Statefulai will retrieve, in parallel:
Semantic. The BillingService module, its dependencies, the StripeUsageClient contract.
Episodic. ADR-014 (why we switched), the May 11 incident (why we now lock), the last 5 PRs touching billing.
Procedural.@idempotent-writes, @zod-on-boundary, the team's PR template.
All three get compressed into a single ≤1.2 k token bundle, with citations the agent can quote. The agent isn't being given more context — it's being given the right context.
06 Lifecycle
Memory isn't write-once. It learns, decays, and can be retired.
Write
Events arrive, get classified, embedded, and routed. A single event can populate all three layers (commit → episodic, symbol → semantic, accepted-pattern → procedural).
Reinforce
When a memory is retrieved and the agent uses it, its importance increases. Rules accumulate confidence as the team accepts diffs that follow them.
Decay
Episodic events fade with a half-life. Semantic facts that haven't been referenced in N commits drop out of default retrieval. Procedural rules degrade if recent diffs contradict them.
Retire
Explicitly mark a rule or fact as obsolete and Statefulai will surface a note ("retired: was used in 14 prior decisions") so agents can recognize when historical context no longer applies.
Forget
Hard delete is a tombstone propagated across primary, vector, graph, and cache within 24h. The event is gone; the audit of "an event was deleted" remains.