Skip to content

ADR-0006: Six-layer context system; layers 1–2 immutable

ADR-0006: Six-layer context system; layers 1–2 immutable

Section titled “ADR-0006: Six-layer context system; layers 1–2 immutable”

Status: Accepted Date: 2026-04-20

An agent’s prompt is assembled from multiple sources: a system prompt defining who the agent is, business facts shared across agents, per-task instructions from a parent agent, recent conversation history, and retrieved long-term memories.

These sources have different authorities. The agent’s identity is authored by the platform operator and should never change. A delegated task comes from another agent and is scoped to one piece of work. Working memory is ephemeral per-session. Long-term memory is persistent and retrieved by similarity. Conflating these makes it impossible to reason about whether something can override something else.

The platform’s adversarial model includes prompt injection. An attacker whose text ends up in a tool output, a stored memory, or a delegated task must not be able to hijack the agent’s identity or violate its hard constraints.

Context is structured as six strictly ordered layers. Higher priority wins on conflict. Layers 1 and 2 are immutable after agent definition load; layers 3–6 are runtime-populated with different access rules.

PriorityLayerMutabilitySource
1Core ContextImmutableAgent definition
2CharacteristicsImmutableAgent definition
3Shared ContextRead-only (by agent)Shared store
4Delegated ContextPer-task from callerTask payload
5Working MemoryEphemeralSession log
6Long-term MemoryPersistentVector store

The Context Assembler — a runtime component not yet built — is the single enforcement point for priority and immutability. Agents never touch the raw layers.

  • Clear security boundary: an attacker in control of layers 3–6 cannot alter layers 1–2. This is the platform’s central invariant.
  • The Context Assembler is a small, focused component with one job. It’s the natural first thing to build in the runtime because it forces us to validate everything else.
  • Compile-time immutability is expressed via readonly on all fields in packages/core/src/context.ts. Runtime enforcementObject.freeze, cryptographic signing, or similar — is deferred to a future ADR; see open-questions.
  • The layer model is the main coupling point between the runtime and agents. Changing it later is expensive. Getting it right now matters.
  • More ceremony than a single system-prompt string. Developers must understand the six layers. The upside is that the structure makes security reasoning tractable.
  • Single system prompt: no structure, no security boundary, no way to separate authored-by-operator from supplied-by-tool-output.
  • Two layers (static + dynamic): collapses “per-task” and “long-term memory” into one bucket. Loses the ability to say “delegated instructions can override working memory but not identity.”
  • Four layers (identity / shared / task / memory): merges working and long-term memory. We think these should be distinct: working memory is append-write ephemeral, long-term is semantic-search persistent, and they fail differently.
  • Layer priority as runtime data instead of type structure: makes misconfiguration possible (“actually, delegated overrides core this time”). Structural priority is safer.