Persistent memory
A spec-driven workflow only pays off if intent survives. The decision you made in clarify last Tuesday, the reason a domain boundary sits where it does, the bug that taught you to never retry a non-idempotent call — none of that can live only in a chat transcript that vanishes at the next context compaction. Forge gives every project a durable memory so that context accumulates instead of evaporating.
That memory is backed by Engram, a spec-memory store. Forge wires Engram into your configured agents and exposes it through first-class commands; Engram owns the store itself. This page explains what gets remembered, how it fills up across the SDD spine, how a team shares it, and exactly which Forge commands touch it.
What Forge wires vs. what Engram owns
The boundary is deliberate and worth stating up front, because it explains why Forge never invents a memory schema.
| Concern | Owner |
|---|---|
| Wiring the memory backend into each configured agent | Forge |
Exposing memory through forge memory and forge recall | Forge |
| Populating memory across the SDD phases | Forge phase instructions |
| Storing observations and versioning them for sync | Engram |
| Search, retrieval, and project detection | Engram |
Forge is not in the model's inference loop
Memory is advisory context, not a gate. Forge surfaces prior decisions to inform explore and specify; it never blocks a change on what memory does or doesn't contain. The enforced ledger bounds runaway loops and spend — memory bounds nothing. It only makes the model better informed.
What memory remembers
The unit of memory is the observation — a discrete, retrievable fact distilled from the work. A save writes one; a search or recall reads them back by relevance. An observation is not a chat log. It's the distilled residue of a decision — "auth tokens are rotated every 15 minutes because of the AZ-failover requirement", "the payments domain owns idempotency keys, not the API layer" — the kind of thing you'd otherwise re-derive from scratch three sprints later.
The observations worth keeping fall into a few recurring kinds:
| Kind | What it captures |
|---|---|
| Decision | A choice made and the constraint that forced it |
| Discovery | Something the codebase turned out to be doing |
| Bug fix | A trap and the reason it bites, so it bites once |
| Convention | A rule the project follows that no spec spells out |
You interact with observations at the concept level through three operations — save, search, and pull-into-context — and never touch Engram's internal storage directly.
How memory fills up across the spine
You do not manage memory by hand for the common case. As each SDD phase runs, Forge's phase instructions have the agent save what it learned and recall what's relevant before it acts. Memory accumulates as a side effect of doing the work.
exploreopens by recalling prior decisions relevant to the change's intent, so investigation starts from accumulated context rather than a blank slate.specifyandclarifysave the intent and the resolutions to open questions, so the why behind each requirement is retrievable, not just the what.implementsaves the decisions and bug fixes made while writing code — the details that never make it into a spec but cost hours to rediscover.archivesaves a summary of the finished change, closing the loop so the nextexploreinherits it.
Automated saves stay quiet
Saves that come from SDD phase artifacts — proposal, spec, design, tasks, verify, archive reports — are marked as automated so they don't drown out the deliberate, human-intent saves. Recall surfaces the signal, not the machine chatter.
Project detection keeps memory scoped
Memory is grouped by project, and Engram detects the project automatically — it reads your Git remote URL at startup, normalizes it, and uses that as the project name. Outside a Git repo it falls back to the directory name. You never label a project by hand, and the same repository stops accumulating memories under three slightly different names.
One remote, one project
Because detection keys on the normalized Git remote, forks or renamed remotes can drift into a second project name. If recall comes back thinner than expected, check that you're on the remote whose memory you expect — consolidating split project names is a supported repair, not a re-derivation.
The commands that touch memory
Three surfaces reach the store. Use whichever fits the moment — they hit the same Engram backend.
| Surface | What it does |
|---|---|
forge memory save|search|context|sync | The direct CLI: save an observation, search by keyword, pull recent session context, or export for sharing |
forge recall | Advisory recall — surface prior specs and decisions relevant to the current change's intent, to inform explore and specify |
For the exact subcommands and flags, see Commands. forge recall is intentionally read-only and non-blocking: it feeds context in, never gates a change.
# save a deliberate decision
$ forge memory save "payments domain owns idempotency keys" # exit 0
# search before you re-derive something
$ forge memory search "idempotency" # exit 0
# pull it into a new change's exploration
$ forge recall # exit 0Team sharing by committing memory
Memory is local by default. To share the accumulated context of a project with your team, you export it and commit that export to Git. forge memory sync writes the shareable memory to .forge/memory/, and from there it is just files in your tree.
# after a work session, export memories into .forge/memory/
$ forge memory sync # exit 0
# then commit them like any other project file
$ git add .forge/memory/ && git commit -m "share project memory" # exit 0A teammate who clones the repo gets that memory with it and starts with the full, accumulated context of the project — every decision, convention, and hard-won bug fix the team recorded. This is where memory pays off most: onboarding. A new contributor doesn't begin cold; they begin with the team's collective understanding already loaded, and the SDD spine keeps adding to it from their very first change.
Memory is a project file, not a service
There is no hosted memory, nothing it stores is uploaded, and there is no external dependency. Shared memory is just files you diff, review, and commit — which means it inherits your existing access controls, review process, and history for free.
Next steps
- Spec-driven development — why durable intent is the point of the whole method.
- The workflow — the spine whose phases populate memory.
- Commands — the full
forge memoryandforge recallsurface. - The enforcement doctrine — what Forge enforces, and why memory stays advisory.