Memory that
compounds.
Every completed task contributes to a project knowledge base. Every future task on the same entity arrives with that history. The AI gets better at your codebase over time, and a reviewer agent can see exactly why the implementing agent did what it did.
A project = one domain area.
A project is a domain your team knows things about, organized by what concepts feed the work rather than where the work comes from. A single repo usually hosts several projects, and a single project can span as many surfaces as it needs to.
Organize by what's known
Inside the triage-factory repo, you might define separate projects for agent sandboxing and agent memory — two coherent domain areas with distinct knowledge bases. Work that touches the sandbox layer pulls one body of knowledge; work that touches the memory layer pulls another. Neither pollutes the other. Sub-projects let you decompose further when an area gets dense enough to warrant its own thread.
The platform matches how your team already thinks about the surface area of your work.
Multi-project membership
A single entity can belong to more than one project — a PR that touches two domain areas pulls knowledge from both. Classification stores all matches; delegations load the union of matched knowledge bases. The reviewer doesn't have to choose between "this is the sandboxing project" and "this is the memory project" — both contexts arrive in the sandbox.
A librarian per project.
Each project gets a dedicated Curator agent: a long-lived session that turns the project's accumulated history, your team's recorded decisions, and the steady stream of completed-task memories into structured, evolving knowledge.
What it does
The Curator owns the project's knowledge base. As your team chats with it, it adds context, refines definitions, captures architectural decisions, dedupes overlapping notes, and indexes the result for the classifier and downstream agents.
Every run starts with the full picture.
Before an agent's process even starts, two directories are staged into its sandbox worktree. The agent reads both as ambient context throughout the run.
Persistent on host
Per-run sandbox worktree
/_scratch/project-knowledge/ A copy of every Markdown file in the project's knowledge base, as it stands at spawn. Architectural notes, glossary terms, prior incidents, the team's recorded conventions.
/_scratch/entity-memory/ Every prior task's memory file for this specific entity, written by the agents who ran them. A fresh agent on a re-opened PR doesn't start cold — it inherits the reasoning of every previous run on the same PR.
Reasoning gets written down.
Before a run reaches a terminal state, the agent is gated on writing a memory file describing what it did and why. The platform retries the run up to twice if the file is missing or empty — a missed memory write isn't acceptable, but one failed attempt shouldn't discard the work.
The memory write gate
Before a run reaches a terminal state, the agent is gated on writing a memory file describing what it did and why.
The memory file is then stored in the database and used in two ways:
- Re-injected into the next task on this entity. If a CI failure reopens the same PR three days later, the agent that picks it up sees the prior memory immediately — it knows what was tried, what worked, and what the reviewer said.
- Backfilled into the project's accumulated knowledge. The Curator picks up new entity memories and incorporates them into the project KB, so future entities classified into the same project benefit from the pattern.
example memory file
_scratch/entity-memory/run-9f4a-b7e2.md
written by the agent at termination show hide
# Run 9f4a…b7e2 — fix CI failure on event-handler refactor ## What I did The build broke on `internal/db/event_handlers_store.go:247` — trailing comma in the `ShippedEventHandlers` slice literal added by the most recent refactor. Removed the comma; verified locally with `go build ./...` and `go test ./internal/db/...`. ## Reasoning The pattern in this file is one entry per line with no trailing comma on the last element. Git blame on the surrounding lines shows the convention has held for ~6 months. The recent refactor appended an entry but kept its own trailing comma, breaking it. I considered just running `gofmt` but the failure was upstream of gofmt's normalisation rules — the file already passed `go vet` and `gofmt` locally, but the CI's stricter compile pass caught it. ## What to know next time - `ShippedEventHandlers` gets appended whenever a new system trigger ships. The convention is no trailing comma on the last entry. - If `event_handlers_validate_test.go` is taught to enforce the shape on the way in, future PRs won't reach CI before catching it. - The same pattern shows up in `ShippedPrompts` and `ShippedTaskRules` — worth a sweep.
The reviewer sees why.
A specialized implementer agent and a separate reviewer agent are both delegated runs in their own sandboxes with their own clean context windows. They never share a worktree. They never share live thoughts. But they share the same project KB and the same recorded entity memory — so the reviewer reads what the implementer wrote down.
Implementer agent
- · Own worktree, branch
tfac/implement-9f4a - · Own clean context window
- · Writes a memory file just before terminating
Reviewer agent
- · Own worktree, branch
tfac/review-3b27 - · Own clean context window
- · Reads the implementer's memory at spawn
What travels between them: recorded reasoning.
What doesn't: live context, worktree state, in-flight tokens.
Most automated PR review tools see the same diff a human sees — the code, the PR title, maybe the description. They don't see the reasoning that produced the diff, because the agent that wrote the code is gone and its context window is gone with it.
Triage Factory's reviewer agent reads the implementer's memory file before reviewing. The reviewer can ask "why did this branch use a synchronous fetch instead of the project's standard async helper?" and find the answer the implementer recorded — without inheriting the implementer's context window or worktree.
Both agents work from the same body of knowledge, but each runs in its own isolated sandbox with its own clean context.
Same knowledge. Separate worktrees.
Memory flows in; per-run state stays inside the run. Concurrent agents on different entities never cross-talk. Concurrent agents on the same entity run sequentially through the queue — never in parallel — so memory writes from one run are visible to the next.
Isolated worktrees
Each run gets a fresh git worktree on a unique branch. Implementer and reviewer agents never see each other's working files.
Clean contexts
Each agent boots with a fresh context window. No leaked tokens, no leaked reasoning between runs — only what's recorded on disk.
Sequential per entity
Tasks on the same entity queue and run one at a time, so each run sees the memory from the previous one. No races, no overwrites.