Context Engine
How Stella remembers — bi-temporal memory, prompt-cache-native recall, the citation loop, reflections, the tree-sitter code graph, and the domain taxonomy that ties it all together.
Stella accumulates knowledge about your workspace so each session starts smarter than a blank slate — and it does so prompt-cache-natively: durable knowledge rides the provider's prompt cache instead of being re-billed at full price every call.
Where knowledge lives
Everything is on your disk, under .stella/:
| Path | What it holds |
|---|---|
.stella/memories/*.md | Workspace memories — one Markdown lesson per file, written by save_memory |
.stella/context.db | The bi-temporal context store: episodes, reflection memories, domain facts |
.stella/reflections.jsonl | The reflection mining log — one JSON lesson per line |
.stella/codegraph.db | The tree-sitter code-graph index |
.stella/rules/*.md | Rules — promoted memories and guard rules |
.stella/skills/ | Project skills |
.stella/domains.toml | The domain taxonomy — the shared tagging vocabulary |
.stella/store.db | The citation ledger and telemetry |
Bi-temporal means the context store keeps both when a fact was true and
when Stella believed it: re-running stella init supersedes stale facts
rather than deleting them, so "what did we believe then?" stays answerable.
Two injection points, one cache discipline
Stella feeds context to the model at exactly two places, chosen so the expensive part never changes:
- The baked prefix (stable). At session start, workspace memories and Tier-1 rules are concatenated into the system prompt — deterministically, byte-stable for the whole session. That stability is what lets the entire prefix ride the provider's prompt cache (~0.1× input cost on cached reads). A memory saved mid-session deliberately takes effect next session: hot-injecting it would invalidate the cache on every save.
- The recall block (volatile). Each turn, a single
[auto-recalled context]message is refreshed in place right after the stable prefix — never accumulating. It carries what's relevant to this prompt: matching memories (similarity + domain overlap + recency), code-graph hits, past episodes, and selected skills — capped by default at 5 frames / ~1,200 tokens. Nothing relevant? No block at all.
Recall fans out through the Open Context Protocol (OCP) host to in-process providers — the workspace memory store and the code graph — fused by score under one token budget.
Invalidation doesn't happen — and why that matters
Most agents treat memory as dynamic injection: retrieve per turn, splice into the prompt. It maximizes relevance and destroys prompt-cache locality — every turn's prompt is different, the cache misses every call, and the whole system prompt re-bills at full input price, forever.
Stella is built so invalidation structurally cannot happen, at two layers:
- The cache layer. The prefix is byte-stable by discipline — same memories, same order, same bytes, every call of the session — and the volatile recall block lives in its own message after the prefix, refreshed in place. Nothing ever rewrites the cached bytes, so the cache entry is never invalidated mid-session. That is the difference between paying ~0.1× (cache-read) and 1.0× (cache-miss) on every call — a 10× structural cost gap that compounds across a session. It is also why a freshly saved memory waits for the next session: hot-injecting it would convert every subsequent cache hit into a miss.
- The knowledge layer. The context store is bi-temporal: new facts supersede old ones with validity windows — they never overwrite or delete them. Re-initializing a workspace doesn't invalidate what Stella believed before; it records what changed and when. History stays queryable, provenance stays intact, and a recalled fact can always say when it was true.
The practical significance: Stella's memory gets cheaper and richer as a session runs and as a workspace ages — where per-turn-injection designs get more expensive with every memory they add. Cost architecture, not a cache trick.
The Open Context Protocol
The recall seam isn't private plumbing — it is a versioned, open wire
protocol: the Open Context Protocol
(ocp/1.0-draft), now its own project, with Stella as its reference host.
- Zero-dependency wire types. The protocol's types depend on nothing but a JSON codec — a context provider can be written in any language without importing a line of Stella.
- Machine-checked conformance. "OCP conformant" isn't marketing — it's green on the public conformance suite. A conforming provider works with any OCP host, checked at CI time rather than discovered at integration time.
- A trust architecture, not just a transport: provenance (every frame says where it came from), budget honesty (providers respect the token budget they're given), consent, citation guarantees, version stability, and temporal validity — the bi-temporal "invalidation doesn't happen" property, standardized.
The consequence for you: the context engine is extensible without forks. Your company wiki, your issue tracker, your vector store — anything that speaks OCP can feed Stella's recall block under the same budget, scoring, and citation rules as the built-in providers. The full analysis lives in the OCP advantages paper.
The citation loop: memories that earn their place
Memory in Stella is not write-only. It is a feedback loop:
save_memorywrites a lesson (a slug plus ≤ 2,000 chars of Markdown) to.stella/memories/.- Recalled memories carry a stable id (
nod_…). When one actually informs a turn, the model callscite_memorywith a usefulness score (1–5), a truthfulness flag, and a remark. Citations aggregate into a ledger in.stella/store.db. stella memory listranks memories by citation count, average usefulness, and truthful rate.stella memory validateflags memories whose file-path anchors no longer exist.- Promotion: a memory cited successfully more than 10 consecutive
times (one negative citation resets the streak) becomes eligible for
stella memory promote <id>, which turns it into a durable rule at.stella/rules/<slug>.md. - Quarantine: a memory repeatedly cited as untruthful is filtered out of every future recall block. Bad memories don't just rank lower — they disappear.
One memory's arc: from lesson to rule
Concretely, over a few sessions:
- Save. Mid-turn, the agent learns something durable — say, "the
integration suite needs
TEST_DB=memory; against a real socket it hangs" — and callssave_memorywith a slug and the lesson (at most 2,000 characters of Markdown). It lands as a file in.stella/memories/and, per the cache discipline above, takes effect from the next session. - Recall. In a later session, a prompt about the integration tests
matches; recall surfaces the lesson in the
[auto-recalled context]block as a frame tagged with its stable id (nod_plus 24 hex characters) — competing with everything else relevant for the default cap of 5 frames / ~1,200 tokens. - Cite. The lesson actually informs the turn, so the model calls
cite_memorywith thatnod_…id, a usefulness score (1–5), a truthfulness flag, and a one-line remark. The citation lands in the ledger in.stella/store.db. - Inspect.
stella memory listshows the memory climbing the ranking — citation count, average usefulness, truthful rate — and flags it once it has earned promotion. - Promote. After more than 10 consecutive positive citations (one
negative citation resets the streak to zero), the memory is eligible:
stella memory promote <id>writes it as a durable rule at.stella/rules/<slug>.md. - Graduate. From the next session on, the promoted rule rides the byte-stable prompt prefix as a Tier-1 rule — standing guidance on every call, at cached-read prices, no longer needing to win recall's 5-frame contest to be seen.
Reflections: learning from every working turn
After any turn that did real work (tool calls happened — a pure chat turn is
skipped to save the call), Stella spends one cheap, deterministic model call
to extract 0–3 lessons, tagged with allowed domains, written to both the
context store and .stella/reflections.jsonl. Failed turns get a dedicated
root-cause prompt — failure is treated as the highest-value learning signal,
not something to forget.
Every working turn is also recorded as an episode — a summary, the files touched, the outcome, and its time window — so future recall can surface "the last time we touched this area."
Recurring lessons that keep showing up in the reflection log are
auto-promoted into skills (a new .stella/skills/<slug>/SKILL.md),
capped per session and never clobbering an existing skill.
Honest measurement: A/B control turns
Does recall actually help? Stella measures instead of assuming: at a fixed rate (about every 10th turn), recall is deterministically suppressed and the turn recorded as a control turn. Comparing outcomes with and against controls keeps the memory system accountable for real, measured lift.
The code graph
graph_query gives the agent structural answers instead of grep guesses,
backed by a native tree-sitter index of your code:
- Languages: Rust, Python, JavaScript, TypeScript, TSX, and SQL.
- Indexed: symbol definitions and import edges.
- Queries:
definitionsandreferences(by symbol name);imports,importers, andneighbors(by file path). The same five operations back the offlinestella graphCLI.
The index builds automatically: stella init
builds it eagerly, and every session also builds/refreshes it in the
background — the moment it's ready, graph_query switches on mid-session.
An in-process file watcher (200 ms debounce, no daemon) keeps it fresh as
files change, for exactly as long as the session runs.
One honest capability gap: importers edges resolve for relative
TypeScript/JavaScript and Python imports. Rust use paths are indexed
unresolved — an empty importers answer for a Rust file is a limitation,
not a stale index.
The domain taxonomy
stella init infers a short tagging vocabulary for your project —
.stella/domains.toml — and it becomes the connective tissue of the whole
engine: memories, reflections, episodes, skills, and code-graph nodes all
carry domain tags, so recall can relate a lesson, a past episode, and a file
to the same area of the codebase.
Version-control your agent's brain
Memories, rules, skills, and the taxonomy are plain files — commit them, and
your whole team's agents share the same accumulated knowledge. The .db
files are local state; see
what to commit.
Inference Pipeline
How Stella turns a prompt into verified work — the agent step loop, the staged pipeline (triage, recall, plan, scope review, witness, execute, verify, judge), deterministic verification, and per-role model routing.
Agent Engine Paths
Every entry point into Stella's agent engine — one-shot runs, the REPL, the Command Deck, goal rounds, CI monitoring, sub-agents, and fleets — what actually differs between them, and when to use each.