60 minutes · The only attack surface that survives logout — a poisoned memory is a prompt injection with a fuse, and the fuse crosses the session boundary
B2 built five layers of defense inside a session. Memory breaks the assumption that the attacker and the defense are alive at the same time. You inject today; the payload fires next week.
Pillar 1 — Injection & Poisoning
Long-term memory
Persists across sessions. Stored outside the model — DB, vector store, files. Loaded into context at session start, before the user types anything. Survives logout/login.
Context window
Per-session. System prompt, conversation history, retrieved context, tool outputs this turn. Born at session start, dies at session end. B2's five layers all live here.
| B2 layer | What it does | Does it see memory? |
|---|---|---|
| L1 untrusted tagging | Tags content crossing into context | No — memory loaded before tagger runs |
| L3 taint gate | Blocks high-impact calls with tainted args | No — memory reads not marked tainted |
Inject in session 1 · persist · activate in session 2 (Course 1 Module 4.3)
SESSION 1 — INJECTION SESSION BOUNDARY — THE FUSE
───────────────────────── (logout · login · days pass)
attacker delivers payload user forgets session 1
agent writes SEED to memory │
seed is INERT this session ▼
session ends SESSION 2 — ACTIVATION
─────────────────────────
user starts fresh session
memory loader runs
seed loaded as TRUSTED
no tag · no gate · already in window
▼
SEED FIRES — obeyed as if system prompt
| Vector | Cost per activation | Blast radius |
|---|---|---|
| Transient injection (B2) | 1 delivery : 1 activation | One session |
| Sleeper / memory poison | 1 delivery : N activations | Every session until found |
| Shared retrieval poison | 1 write : N users × N queries | Every tenant on the index |
RAG poisoning · context-window flooding · cascading hallucination (ASI06)
The retrieval store is writable — and not all write paths are trusted.
| Write path | Trusted? |
|---|---|
| User-uploaded document | Untrusted |
| Crawled / synced external content | Untrusted (compromisable) |
| Agent-generated summary (laundered injection) | Untrusted |
| Cross-tenant leak (weak isolation) | Untrusted |
The model PROPOSES · the harness VALIDATES · only the harness COMMITS
MODEL PROPOSES ──▶ HARNESS VALIDATES ──▶ HARNESS COMMITS
(content + (3 checks, in order) (tagged with
justification + provenance + trust)
provenance) │
│ ▼
│ CHECK 1 — PROVENANCE memory store
│ CHECK 2 — TRUST LEVEL (model NEVER
│ CHECK 3 — CONTENT touches it)
▼ │
proposal ▼
ALLOW or DENY
any check fails ─▶ DENY (logged + surfaced)
// The load-bearing line — the sleeper signature:
if (trustLevel === "untrusted" && looksLikeInstruction(content))
return DENY; // untrusted-sourced AND instruction-shaped
| Field | Why it matters |
|---|---|
source | user_direct · retrieval:doc · tool · agent_inferred |
trust_level | trusted · semi_trusted · untrusted |
written_at / written_by | Audit trail back to the injection point |
validation_result | What the gate decided and why |
Lab (07): (1) the sleeper-attack demo — inject a seed in session 1, watch it activate in session 2 against an undefended agent, then watch the gate block it. (2) build the memory-write gate — validateAndCommit() with provenance, trust, and content checks, plus a provenance-tagging read path.