Skip to content

Memory & Context Builder ​

See memory-context selection for the shared visual model.

Agentweaver maintains persistent memory for each project. Before an eligible agent turn, a structured context block is compiled from that memory and injected into the agent's system prompt. Stored text is serialized inside an explicitly untrusted JSON envelope; it is historical data, never prompt structure or executable instructions.

How context is built ​

MemoryContextCompiler.CompileAsync(projectId, agentName) gathers approved decisions, eligible memory, and the current session into one envelope-aware compilation result. The total token budget applies to the complete serialized context block, not just memory content. Its bounded composition metadata reports omitted memory/session counts and causes plus the stable record id, revision number, and immutable revision id of every selected knowledge record. It never emits record content in telemetry.

text
Decisions: active, approved architectural/scope records, ordered by creation time
Memory candidates: eligible active own core context + active learnings/patterns
Selection for runs: decisions mandatory; then task relevance, importance, recency, and record id; one bounded item/envelope budget
Session: most recent open session (ties by record id), included only as one complete record

If all layers are empty the method returns null and no context block is injected.

Layer 1 — Decisions (team boundaries) ​

Decision rows where Type = architectural | scope, Status = active, and TrustState = approved, ordered by creation time.

These are serialized first in the untrusted context envelope. Their position and type make them the highest-priority project data, but their stored strings remain untrusted.

FieldValues
Typearchitectural · scope · process · technical
Statusactive · superseded · archived
TrustStatelegacy · pending · approved

Only active, approved architectural and scope decisions are injected (high-signal, team-wide). process and technical decisions stay in the database for governance and bookkeeping.

Layer 2 — Core context memories ​

AgentMemory rows where Type = core_context, scoped to this agentName, and TrustState != legacy, ordered by creation time.

Core memories are eligible regardless of importance, not guaranteed inclusion. They share the ranked memory item limit with eligible learnings/patterns. Defaults are 20 items and about 4,000 tokens at four characters per token. Positive call-site overrides precede MemoryContext:MaxItems / MaxTokens, then legacy Memory:ContextMaxItems / ContextMaxTokens. The complete serialized envelope must fit the token budget; selection stops before the next full record would exceed it. Active approved decisions are mandatory: compilation fails before a model call with a typed budget error if all decision records cannot fit. The session is included only if its entire serialized record fits the remaining envelope budget.

AKS deployments set the same defaults with MemoryContext__MaxItems=20 and MemoryContext__MaxTokens=4000 on both the API and worker pod templates. These are deployment-scoped operator settings. Agentweaver intentionally has no request header, query parameter, run option, project setting, or public API that overrides context budgets. The staging API harness can temporarily lower the deployment values through its explicit non-production pressure profile; it snapshots and restores the exact prior Kubernetes environment entries and requires the independently managed namespace label agentweaver.io/environment=staging. It must never be used as a production fixture. A failed restoration retains the profile Lease and snapshot to fence out another run until an operator recovers the deployments.

Layer 3 — High-importance learnings & patterns ​

High-importance learning and pattern rows are selected when either:

  • they belong to the target agent and are not legacy; or
  • they are approved and tagged cross-team.

The cross-team tag alone is not authority. Cross-agent selection requires explicit approval by a project owner or verified Coordinator run.

Before a fresh or delegated run, eligible learnings and patterns are filtered against the run task. Normalized tags are the primary relevance signal; memory content also requires multiple meaningful terms to overlap the task, and the exact irrelevant tag always excludes a record. This keeps unrelated retained facts out of the prompt. Relevant records are ranked deterministically before the existing importance, recency, and record-id tie breakers. Core context remains available to fresh runs, while delegated runs omit core context and session state to preserve their lean worktree-safe prompt.

Layer 4 — Current session ​

The most recent open SessionContext (no EndedAt) for the project. Provides the current focus area, active issues, and running summary.


Memory entities ​

Provenance and trust ​

AgentMemory and Decision expose:

FieldValues / meaning
SourceKindhuman, run, or legacy
SourceIdentityAuthenticated user or verified run:{id} identity
SourceRunIdSource run when SourceKind = run
TrustStatepending, approved, or legacy
ApprovedBy, ApprovedAtAudit identity and time for approved records

New memory starts pending. It can inform its named agent under the normal layer rules, but cannot cross to another agent until approved. Direct active decisions and promoted inbox decisions are created as approved.

Rows that existed before provenance tracking migrate as SourceKind = legacy and TrustState = legacy. They remain queryable but are excluded from prompt compilation until a project owner or verified Coordinator explicitly approves them.

Exact-write convergence ​

Memory and active-decision writes are idempotent at the database boundary. Repeating the same logical write, including concurrent requests, resolves to one durable record and one stable id. The first request returns 201 Created; retries that resolve the existing record return 200 OK. Exports therefore contain one entry for that identity.

Identity includes the project, author/agent, content fields, normalized tags, and source provenance. Memory identity also includes its session, type, and importance. Decision identity includes its type, status, and supersession link. Approval metadata and timestamps do not create a new identity, so separate identical inbox entries and Scribe retries converge on the same promoted decision.

Superseding or archiving a decision changes its identity. A later write may therefore create a new active version with the same content without reviving or overwriting the historical record.

Immutable revisions and optimistic writes ​

Every memory and decision record has a stable numeric id plus a current revision and current_revision_id. Creation and every content, provenance, trust, approval, or lifecycle change append an immutable snapshot. Revision history stores a predecessor, actor or source run, timestamp, and reason. History responses redact recognized secrets and PII and expose fingerprints instead of raw source identities.

Updates, approvals, and restores require expected_revision. If another writer already advanced the record, the API returns 409 with error: stale_revision and the current revision. A restore copies the selected snapshot into a new active, pending revision; it never edits or deletes an older revision and never silently carries approval forward.

Memory lifecycle states are active, superseded, and archived. Superseded memory must identify a replacement in the same project, and replacement chains cannot cycle. Normal list/search and prompt compilation include only active memory. Pass status=all, or request a specific state, to inspect inactive records explicitly.

Project memory search accepts q, type, and comma-separated tags, applies all filters before paging, orders by update time and stable id, and caps pages at 100 items. The revision list, single-revision, compare, and restore routes use the same project authorization boundary.

In-run agents use the native get_memory and list_decisions tools with page and pageSize to retrieve later pages. get_memory also accepts text, agent, type, tag, and lifecycle filters. The read-only get_memory_history and get_decision_history tools expose paginated immutable revisions without exposing raw source or approver identities.

AgentMemory ​

Per-agent long-term memory. New entries are written through record_memory and retain the server-resolved human or run identity. record_memory commits directly to the memory database and returns without rebuilding the filesystem snapshot. This keeps the agent tool call independent of remote workspace-volume latency; export_memory refreshes .squad/ and .agentweaver/context/ explicitly at the end of the Scribe pass. An explicit export also publishes only the generated ledger files to the project's default branch, so they are visible through list_project_workspace and can be read with get_project_workspace_file. The response lists every repository-relative path written. The boundaries.md and patterns.md files are created even when they contain no entries, so a successful export always leaves a visible .agentweaver/context/ snapshot. Unrelated working-tree changes are not staged or committed.

FieldDescription
Typecore_context — eligible for Layer 2 when non-legacy; learning — observation from a run; pattern — reusable practice; update — correction to prior knowledge
Importancehigh (injected in L3) · medium · low
TagsComma-separated. cross-team makes approved memory eligible for another agent's Layer 3
Statusactive by default; superseded requires an acyclic same-project replacement; archived is retained but inactive
RevisionMonotonic expected-revision token used for updates, approvals, and restores

Decision ​

Team-wide architectural or scope decisions. Injected in Layer 1 for all agents on the project.

Only a project owner or verified Coordinator run can create or update an active decision. Agents propose decisions through the inbox. Active architectural and scope decisions compile only when TrustState = approved.

DecisionInboxEntry ​

Drop-box for agent-proposed decisions. Agents write here via submit_inbox_entry. Inbox entries carry provenance but no independent trust state; their pending, merged, or rejected status records the review transition.

FieldDescription
Typearchitectural · scope · process · pattern · learning · update
Statuspending → merged or rejected

Scribe only auto-merges learning, pattern, and update entries that are attributed to the exact completed run and its agent. Ordinary-agent architectural and scope entries stay pending. Manual merge, promote, and reject require a project owner or verified Coordinator; Coordinator finalization may promote architectural and scope entries authored by that same verified Coordinator run.

Inbox promotion is atomic across API replicas. Concurrent merge/promote requests and deterministic Scribe reruns resolve the existing inbox-to-decision link, return the same decision id, and retain one completed Scribe audit outcome. PostgreSQL serialization, deadlock, and bounded lock-wait conflicts are retried before the operation fails.

SessionContext ​

Tracks the current work focus for a project. One open session at a time (EndedAt = null).

Updated by agents via update_session(summary). Scribe closes/summarises the session at run end via export_memory.


Scribe's role in memory ​

Standalone completion and Coordinator finalization own their Scribe work. Coordinator children stop at assemble-ready, bypassing their own review/merge/Scribe stages. Where the final Scribe pass runs, it:

  1. Select pending inbox entries for the completed run's agent, creation window, and verified source run id.
  2. Promote learning/pattern/update entries to approved ledger records; leave ordinary-agent architectural/scope proposals pending.
  3. update_session(summary) — record what the agent accomplished in this run
  4. export_memory() — write updated state to .squad/ and .agentweaver/context/

For memories to accumulate, the running agent must call submit_inbox_entry when it discovers something worth remembering. The agent has to judge relevance.

Runtime prompt guidance names project-memory and coordination tools only after the final session tool list is built. A turn with no callable project-memory tools receives no memory section; a partial tool set lists only its callable names. Tool declarations remain the authority for required arguments and scopes.


Context injection point ​

RunOrchestrator.BuildContextAsync calls MemoryContextCompiler.CompileAsync and passes the result to the agent as systemPromptContext in SetupAsync. This runs once per turn, before the agent session is created. Selected data is serialized into one guarded JSON envelope:

## Untrusted Project Context Data
BEGIN_AGENTWEAVER_UNTRUSTED_CONTEXT_JSON
{"schema":"agentweaver.untrusted-context.v1","decisions":[...],"memory":[...],"session":{...}}
END_AGENTWEAVER_UNTRUSTED_CONTEXT_JSON

If there is no memory yet for a project, the block is omitted entirely and the agent runs with only the base prompt.

memory.context_composition records this structured-context selection on the run stream. Its payload includes included, omission counts and causes, and revisionReferences. Each reference contains only the knowledge kind, stable record id, revision number, and immutable revision id. Prompt text, source identities, and character/token measurements are deliberately excluded. Consumers must treat a changed revision reference as a new approval/cache input rather than reusing an approval for an older snapshot.


Coordinator child workers — lean relevant context ​

Coordinator child runs (a run with a ParentRunId) do not receive the full four-layer stack. Core context and session state duplicated the child's charter and carried artifact-write instructions that pointed at session-state / .copilot paths absent from a child worktree, which the sandbox rejected and stalled the child.

Instead, RunOrchestrator.BuildContextAsync injects the child's charter plus active, approved architectural/scope decisions and task-relevant high-importance learning or pattern memory eligible for that agent. Core context and session data stay omitted. The same deterministic item/envelope budgets and omission telemetry apply to fresh and child runs. Compilation non-budget failures are logged as warnings and the child proceeds with its charter alone. A mandatory-decision budget failure is terminalized before model invocation.

Runtime tools record_memory, submit_inbox_entry, update_session and export_memory correspond to public MCP memory_record, decision_inbox_submit, session_update and memory_export. MCP also exposes bounded memory_search, memory_history, memory_compare, memory_restore, decision_history, decision_compare, and decision_restore; mutation tools require the current expected revision.

Diagram details and constraints
ElementContract
titleContext is selected data, not instructions
takeawayApproved decisions, jointly ranked memories and the open session converge into untrusted JSON.
group-title0SCOPED INPUTS
group-title1SELECTION AND SERIALIZATION
Active decisionsActive decisions
Active decisionsProject-wide boundaries
Active decisionsApproved architecture / scope
Active decisionsOldest-created first
Active decisionsChild prompts: decisions plus task-relevant memory
Core + learningsCore + learnings
Core + learningsAgent-scoped candidates
Core + learningsCore: exclude legacy trust
Core + learningsHigh learning / pattern
Core + learningsApproved cross-team allowed
Open sessionOpen session
Open sessionLatest active session
Open sessionFocus / issues / summary
Open sessionEnded sessions excluded
Open sessionLatest StartedAt wins
Joint rank + budgetJoint rank + budget
Joint rank + budgetOne combined memory list
Joint rank + budgetImportance, then recency
Joint rank + budgetStop at item / char limit
Joint rank + budgetApproximation: 4 chars/token
Context compilerContext compiler
Context compilerAssemble scoped sections
Context compilerDecisions + selected memory
Context compilerAdd current session
Context compilerEmpty inputs → null
Untrusted JSONUntrusted JSON
Untrusted JSONHistorical data, not authority
Untrusted JSONExplicit boundary markers
Untrusted JSONIgnore embedded instructions
Untrusted JSONuntrusted-context.v1
relation-01 combine / sort
relation-12 approved
relation-23 latest open
relation-34 selected
relation-45 serialize
assuranceDefaults: 20 memory items / ≈4,000 tokens. The complete serialized envelope must fit; active approved decisions are mandatory and fail compilation when they exceed it.
assurance-0-labelJoint memory ordering
assurance-0-factImportance first; recency breaks ties.
assurance-0-sourceMemoryContextCompiler.cs
assurance-1-labelBounded selection
assurance-1-factItem / character limits cover the complete envelope.
assurance-2-labelInjection resistance
assurance-2-factContext is wrapped as untrusted JSON.
assurance-2-sourceMemoryContextCompilerSecurityTests.cs
n0Approved architecture / scope; Oldest-created first
n1Core: exclude legacy trust; High learning / pattern
n2Focus / issues / summary; Ended sessions excluded
n3Importance, then recency; Stop at item / char limit
n4Decisions + selected memory; Add current session
n5Explicit boundary markers; Ignore embedded instructions
groupsSCOPED INPUTS; SELECTION AND SERIALIZATION