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
Context
Section titled “Context”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.
Decision
Section titled “Decision”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.
| Priority | Layer | Mutability | Source |
|---|---|---|---|
| 1 | Core Context | Immutable | Agent definition |
| 2 | Characteristics | Immutable | Agent definition |
| 3 | Shared Context | Read-only (by agent) | Shared store |
| 4 | Delegated Context | Per-task from caller | Task payload |
| 5 | Working Memory | Ephemeral | Session log |
| 6 | Long-term Memory | Persistent | Vector 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.
Consequences
Section titled “Consequences”- 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
readonlyon all fields inpackages/core/src/context.ts. Runtime enforcement —Object.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.
Alternatives considered
Section titled “Alternatives considered”- 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.