Orchestrata Ultimate › Plans › context-tiers-design
Tiered Context Model (L0 / L1 / L2)
Source: plans/context-tiers-design.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-08 · 109 lines.
Prose pending.
Plan text
Tiered Context Model (L0 / L1 / L2)
Status: design · Author: orchestrator session · Date: 2026-07-08
Motivation: an orchestrator (Claude) repeatedly re-derived basic infra facts —
"are the graphs docker?", "where is Neo4j?", "which Memgraph has the tools?" — because
the project's foundational context (infra topology, the two graphs, the tool inventory)
is documented on disk but never loaded into any session's context. The docs exist
(INFRASTRUCTURE.md, docs/CODEBASE_MAP.md) and are even stale/incomplete (Memgraph is
absent from INFRASTRUCTURE.md). This design defines what is always in context, what is
pulled on demand, and what is pushed per task, plus the mechanism that keeps L0 from
going stale.
The three tiers
| Tier | Audience | Delivery | Size budget | Contents |
|---|---|---|---|---|
| L0 — Foundation | orchestrator and volks, every session/turn | always loaded (pull-at-start, zero query) | ≤ ~1.5 KB | identity, goal/vision, infra topology, the two-graph map, tool + volk inventory (pointers), the non-negotiable hard rules |
| L1 — Reference | whoever needs it | on demand (pull) — L0 names the entry points | unbounded, not resident | CODEBASE_MAP.md, full INFRASTRUCTURE.md, AST toolkit, graph query CLIs, specs/RTM |
| L2 — Task | the executing volk | injected per task (push) — SPEC-009 | targeted, per task type | KG nodes relevant to THIS task (specs, reqs, code, prior decisions) via ContextInjector |
Rule of thumb: L0 answers "where am I and what can I use"; L1 answers "show me the detail"; L2 answers "what does this task need". A fact belongs in L0 only if not knowing it makes an agent flail on fundamentals (the graphs qualify; a function signature does not — that's L1 via the AST toolkit).
Why L0 is currently ineffective (evidence)
- The only channels actually loaded every session for the orchestrator are
~/.claude/CLAUDE.md(global) + the projectCLAUDE.md+ the memory index. The projectCLAUDE.mdcontains one word about infra ("infra + gates"). docs/CODEBASE_MAP.mdself-describes as "always in context" but is not@-imported anywhere, so it isn't. It also covers code structure only — never the infra topology.INFRASTRUCTURE.mddocuments Incus + Redis + Neo4j but omits Memgraph entirely and predates the two-project co-mingling of the Memgraph graph.- SPEC-009's
ContextInjectoris real but is L2 (volk runtime, KG-driven) — it does nothing for the orchestrator and carries no foundational infra map.
Net: there is no assembled, loaded, current L0. This design creates one.
L0 mechanism — generated, imported, drift-gated
L0 must be generated from authoritative sources, never hand-maintained (hand-maintained = stale, exactly today's failure).
- Source of truth (read-only inputs):
- infra endpoints ←
.env(NEO4J_URI*,MEMGRAPH_URI(S),REDIS_*) +INFRASTRUCTURE.mdtable - tool inventory ←
tools.registryToolRegistry.all_metadata()(name/description/category — the SPEC-072 index) - volk roster ←
agents/volks/*/ - goal/vision ← session
context.jsongoal (SPEC-023) +docs/architecture-overview.mdone-liner
- infra endpoints ←
- Generator:
scripts/gen_level0.pyrenders a single compactdocs/LEVEL0.md(≤ ~1.5 KB) from those inputs. Deterministic; no network. - Load path: project
CLAUDE.mdgains a single line —@docs/LEVEL0.md— so every session actually loads it. (The global~/.claude/CLAUDE.mdalready uses@-imports, so the mechanism is proven.) - Drift gate:
gen_level0.py --checkre-renders and diffs against the committeddocs/LEVEL0.md; non-zero exit on drift. Wire into the existing gate/CI so a changed endpoint or a new tool forces a regen. Also runnable at session start.
L0 content template (what the generator emits)
# LEVEL 0 — always in context (generated; edit sources, not this file)
IDENTITY orchestrata-ultimate — Python 3.14t free-threaded, uv, absolute imports.
GOAL <current SPEC-023 session goal>
INFRA Incus (LXD) containers on 10.92.53.x — NOT docker, NOT localhost.
Redis .10:6379 · Neo4j .11:7687 (neo4j/knowledge123; replicas .13/.14/.19)
· Prolog .16/.17/.18 · Memgraph .174 + HA .111/.192/.159 (ctrl .153:8080)
GRAPHS Neo4j .11 = orchestrata OPERATIONAL KG (sessions/audit/packets/code).
Memgraph .192 = SHARED semantic/RAG graph — knowledge-wiki AND orchestrata
doc/source ingest write here; labels co-mingle. Chunk labels split-brained.
Neither graph models the tool registry (see tools.registry).
TOOLS <N> registered volk tools: read_file, write_file, ..., design_patterns
(query tools.registry.all_metadata() for the live list + categories).
VOLKS analyst, architect, codedirector, compliance, concierge, documentor,
junior, pm, qa, senior_dev, ux.
DETAIL(L1) code → AST toolkit (scripts/serialize_codebase_ast.py) · infra → INFRASTRUCTURE.md
· graph → scripts/neo4j_query.py / scripts/graph_browser.py · specs → specs/ + RTM.
RULES no-mock/no-skip/no-xdist tests · fix code not tests · uv only · review diffs.
Interaction with SPEC-009 (L2)
SPEC-009 stays as-is and is L2. This design layers above it: L0 gives every agent
the map; L2 gives the executing volk the task-specific payload. The ContextInjector may
optionally prepend the L0 block to its bundles so volks share the orchestrator's foundation,
but that is additive — SPEC-009's task-query behavior is unchanged.
Deliverables (this effort)
docs/LEVEL0.md(generated) +scripts/gen_level0.py(+--checkdrift gate). — Task #2INFRASTRUCTURE.mdcorrected: add Memgraph (single + HA + controller), the two-graph / co-mingling reality, Incus prominence, "neither graph models the tool registry". — Task #2CLAUDE.md:@docs/LEVEL0.mdimport + a pointer to this design. — Task #2- (separate track) graph-data remediation so the contents the map points at are sane. — Task #3
Open decisions (defaults chosen; flag if wrong)
- L0 goal source: session
context.jsongoal (SPEC-023) — regen on goal change. If the goal churns too often, fall back to a static vision line + "see /goal for the live goal". - Size ceiling: ~1.5 KB hard budget for L0; anything larger is L1 by definition.
- Scope of
@-import: projectCLAUDE.mdonly (repo-scoped), not the user-global file.