# The Six-Layer Reuse Stack

V9 (codename **Metis**) does not invent a generation platform; it inherits one.
The architecture monolith opens by adopting the platform's own recommended
target stack — six horizontal layers, from raw model access at the bottom to the
consumer experience at the top — and then states the defining constraint of the
whole version in one line: _"One stack, six layers; V9 is a consumer of all
six"_ ([../V9_ARCHITECTURE.md](../V9_ARCHITECTURE.md) §1). This page is the
layer-by-layer accounting the [overview](./overview.md) defers to: what each
layer _is_, which real in-repo substrate _realizes_ it, and — the part that
separates a reuse claim from a reuse _fact_ — exactly how V9 consumes it, and
whether it adds anything. The companion
[subsystem map](./subsystem-map-and-reuse-ledger.md) audits the same code along
the _vertical_ axis (which `libs/` surface each V9 subsystem builds on); this
page reads it _horizontally_ (which platform plane each of the six layers is,
and where in that stack V9's ~20% of net-new code actually sits).

The reason the layering matters is that it is the structural form of V9's
central bet. If a lesson must be _grounded, gated, governed, and reproducible_,
those are not features you bolt onto a generator — they are the platform planes
a generator must run inside. By declaring itself a consumer of all six layers
rather than a new vertical, V9 buys grounding from the retrieval/kernel
substrates, governance from the V1 Agentic AI Studio envelope, and the agent
loop from Iris, and is left to write only the _connective tissue_ (the Atlas
spine, the Prometheus forge, the Aletheia gate). The clearest single proof is
the one place V9 could most easily have cheated: the agent runtime. V9 ships a
governance module whose entire job is to _attest, in code,_ that it added no
seventh-or-eighth agent loop of its own (`libs/v9/governance/src/iris-loop.ts`)
— and to file a tracked platform gap when the shared substrate is not yet
unified, rather than paper over it. Honest "consumes the layer / files the gap"
beats fake "owns the layer."

## What ships, honestly

The stack is a mix of **real platform substrate V9 consumes**, **real V9 code
that realizes two of the six layers**, and **layer descriptions in the monolith
that are aspirational framings of how the consumption is wired**. This page
keeps the three apart.

**Implemented and tested (real today).** The **governance plane (L5)** is the
shipped `@oshun/v9-governance` package: the AgentRun-envelope registration with
a visible DAG, budget inheritance, kill switches and a replay manifest
(`agent-family.ts`); the seven-gate-suite confirmation (`gate-suite.ts`); the
"no eighth loop" Iris attestation with gap-filing (`iris-loop.ts`); and the
deny-by-default entitlement/age/region/cross-product grant logic
(`entitlements.ts`) — all exercised by `governance.spec.ts`. The **agent runtime
(L2)** it points at is equally real: the canonical `AgenticLoop` lives at
`libs/iris/agents/core/src/agentic/loop.ts` with a hard
`DEFAULT_MAX_ITERATIONS = 24` guard, budget metering before every call, and
explicit terminations. The **production orchestration (L4)** is the real
`forgeLesson` pipeline (`libs/v9/prometheus/src/pipeline.ts`).

**Spec-described / aspirational framings.** Three of the monolith's layer
captions describe a _target_ wiring that the V9 code does not literally use.
**L3** is captioned as "domain tool servers on the shared catalog (MCP-shaped):
`sophia.ground`, `nyx.ephemeris/render`, `kalika.cas/solve`…"; the MCP machinery
is real platform code (`@iris/mcp`), but V9's forge reaches those capabilities
by **direct library import**, not by MCP tool-server RPC (detail below). **L4**
is captioned "Prometheus … on Yemaya HTN-planned dynamic pipelines," yet no
`libs/v9` file imports `@yemaya` — the HTN planner V9 runs is its own
self-contained `planLesson` (`libs/v9/prometheus/src/plan.ts`). **L6**'s
rendered consumer app is the version's largest open build; `libs/v9/experience`
ships only the tested view-models. None of these are faked; they are honest
seams or self-contained realizations where the monolith names a future
integration.

**Provider-gated seams (fail-loud, not faked).** The **model plane (L1)** —
`@iris/model-routing` for routing/cost/fallback and `@nous/*` for local
inference — is real platform code, but **no `@iris` or `@nous` symbol is
imported anywhere in `libs/v9`**. V9 reaches L1 _only_ through the injected
writer / embedder / quality-judge boundaries in the pipeline; when one is absent
the forge fails loud (`LessonWriterNotConfiguredError`,
`libs/v9/prometheus/src/write.ts:37`) rather than fabricating a lesson.

## The stack, top to bottom

| Layer                           | What it is                                                                                                | Realized by (real substrate)                                               | V9's relationship                                                                       |
| ------------------------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| **L6 Delivery & Experience**    | Consumer web/mobile; Nyx WebGL + Kalika WASM in-browser; Chiron embodied teacher; the personal Atlas map  | `libs/v9/experience` view-models; `apps/metis/*` (instructor-shaped today) | **Consumes + the open net-new build.** No Bellona/UE dependency for P1 (§8).            |
| **L5 Governance plane**         | AgentRun envelopes, budget inheritance, kill switches, approval gates, provenance/ledger, the seven gates | `@oshun/v9-governance` over the V1 Agentic AI Studio + shared release gate | **V9 net-new code.** Registers as an agent family; runs nothing ungoverned.             |
| **L4 Production orchestration** | The lesson forge: staged pipeline, mid-pipeline HITL, failure recovery, cost caps, determinism + caching  | `@oshun/v9-prometheus` `forgeLesson` (self-contained HTN planner)          | **V9 net-new code.** Monolith frames it as a Yemaya planner; the import is not present. |
| **L3 Capability tools**         | Domain capabilities (`sophia.ground`, `nyx.ephemeris`, `kalika.cas`, `mnemosyne.schedule`…)               | The substrate libs themselves; MCP machinery at `@iris/mcp`                | **Consumes by direct import**, not MCP RPC.                                             |
| **L2 Agent runtime**            | THE agentic loop: tool-call iteration, max-iteration guard, sub-agent spawn, budget, memory               | `@iris/agents-core` `AgenticLoop` (`agentic/loop.ts`)                      | **Consumes; spawns NO new loop.** Attested + gap-filed in code.                         |
| **L1 Model plane**              | Provider gateway, routing, fallback, caching, cost metering; local inference                              | `@iris/model-routing`; `@nous/core`, `@nous/llm`                           | **Consumes only through injected seams** (no `@iris`/`@nous` import in `libs/v9`).      |

The rest of this page works **bottom-up** — the way the stack actually executes,
each layer standing on the one below — because that order makes the single most
important claim (V9 adds code to only L4 and L5) fall out naturally.

## L1 — the model plane

The bottom plane is raw, governed model access: a provider gateway that routes a
request to a model, falls back on failure, caches, and meters cost. In-repo this
is `@iris/model-routing` — a real `ModelRouter` with cost/quality/latency
optimizers, a `TaskClassifier`, and composable routing policies
(`createCostConsciousPolicy`, `createQualityFirstPolicy`, …) — plus `@nous/core`
and `@nous/llm` for local inference where privacy or cost favors it. All three
are shipped platform packages with path mappings in `tsconfig.base.json`.

V9's relationship to this layer is the strictest in the stack: **it does not
touch it directly.** A grep for `@iris` or `@nous` imports across `libs/v9`
(tests excluded) returns nothing. The model plane is reached _only_ through the
typed boundaries the Prometheus pipeline injects — the `LessonWriter`, the
`WonderEmbedder` dense reranker, the `MisconceptionAnticipator`, and the
`QualityJudge`. That is a deliberate inversion: rather than V9 reaching _down_
to choose a model, the host wires a model-backed writer _up_ into the forge as a
dependency. The benefit is that the entire model plane — routing, fallback,
caching, local-vs-remote — is the platform's concern, and V9 inherits whatever
policy the envelope sets, with no per-product model code to drift.

## L2 — the agent runtime (the loop V9 refuses to re-implement)

This is the layer V9 leans on hardest and the one its honesty discipline most
visibly protects, so it earns the deepest treatment.

**The real loop.** The canonical tool-calling loop every Oshun domain runs on is
`AgenticLoop` in `libs/iris/agents/core/src/agentic/loop.ts` (package
`@iris/agents-core`, re-exported from its `index.ts:226`). Its shape is the
textbook one — _LLM call → `tool_use`? → validate + execute tools → feed results
→ repeat_ — but the load-bearing properties are the guards around that shape:

- A **hard max-iteration guard**, `DEFAULT_MAX_ITERATIONS = 24` (`loop.ts:102`),
  checked at the top of every turn so an agent cannot spin forever.
- **Budget enforcement before every LLM call and every tool execution** — a
  `BudgetMeter` runs `checkBeforeLlmCall()` (`loop.ts:163`) and
  `checkBeforeToolCall()` (`loop.ts:230`) and stops the run the instant a token,
  cost, or call ceiling is crossed.
- **Explicit, non-lying terminations.** The run status is a closed union —
  `completed | truncated | max_iterations | budget_exceeded | content_filtered | aborted`
  (`loop.ts:33`) — and the loop "never dresses a cut-off run up as a finished
  one": a `max_tokens` stop becomes `truncated`, a content filter becomes
  `content_filtered`, a tripped `AbortSignal` becomes `aborted`.
- **Cooperative cancellation** (an `AbortSignal` checked before each iteration
  and before each tool call) and **parallel tool execution** that still
  preserves transcript order.

**V9 adds none of it.** The whole point of L2 in V9 is the _negative_ claim, and
V9 makes that claim falsifiable in code. `confirmConsumesSharedLoop`
(`libs/v9/governance/src/iris-loop.ts:41`) takes the V9 agent-family
registration, asserts `consumesSharedLoop === true`, hard-codes
`ownAgentLoops = []` ("V9 libs add zero tool-call loops," `iris-loop.ts:46`),
and returns `ok` only when both hold. The connection from V9's orchestration
(L4) down into this loop is the single injected `LessonWriter` seam in Stage 3
(`write.ts:24`) — the writer is _the_ place a model-backed Iris run plugs in,
and the forge's tests exercise it with a deterministic in-process writer, while
production wires a real loop run.

**The gap it files instead of faking.** The subtle, honest detail: the
confirmation's `sharedLoopIsSingleSubstrate` option **defaults to `false`**
(`iris-loop.ts:47`). So unless the caller positively asserts that Iris v2 is
already the single agentic substrate platform-wide, the function _files a gap_ —
a typed `IrisGapReport` with `finding: 'F2'`, `phase: 'A2'` (`iris-loop.ts:49`),
recording that V9 itself owns no loop but the platform-wide consolidation
remains open. This is the layer's integrity made executable: V9 will not claim
the loop is unified when it cannot prove it; it reports the open consolidation
as a tracked finding and moves on. `governance.spec.ts` tests both branches —
`ok` with no gap when the substrate is declared unified, and a filed `F2`/`A2`
gap when it is not.

## L3 — capability tools (consumed by import, not by MCP)

L3 is the menu of domain capabilities the agent can call: in the monolith's
words, "domain tool servers on the shared catalog (MCP-shaped): `sophia.ground`,
`nyx.ephemeris/render`, `kalika.cas/solve`, `mnemosyne.schedule/trace`,
`isis.generate.*`, `psyche.speak`, …". The MCP substrate that caption invokes is
real platform code — `@iris/mcp` ships an `mcp-client.ts`, `tool-discovery.ts`,
`resource-access.ts`, and `prompt-templates.ts`.

Here the page must be precise, because the monolith's framing and the code
diverge in a way worth understanding. **V9 does not route its capability calls
through an MCP catalog.** No `libs/v9` file imports `@iris/mcp`. Instead, the
forge composes those capabilities as **direct TypeScript library imports**:
`@mnemosyne/core` for prerequisite reasoning and scheduling,
`@sophia/semantic-search` for BM25 retrieval, `@kalika/cosmology` and
`@nyx/constants`/`@nyx/ephemeris` for the STEM kernels. (The exact
symbol-by-symbol import ledger is the
[subsystem map](./subsystem-map-and-reuse-ledger.md)'s job.) The difference is
not cosmetic: an MCP tool call is a discovered, schema-described, RPC-shaped
boundary; a direct import is a compile-time-checked function call. V9 chose the
latter for the deterministic, reproducible core, because a lesson that must be
seed-reproducible benefits from _in-process, type-checked_ capability calls over
network-shaped tool RPC. The MCP-shaped framing is best read as how a _future_
multi-tenant capability catalog would expose these same engines — not as the
wiring V9's forge uses today. The capabilities are real and reused; the
transport is direct binding, not a tool server.

## L4 — production orchestration (the lesson forge)

L4 is the dynamic pipeline that turns a wonder into a gated artifact: staged
execution, mid-pipeline human-in-the-loop, failure recovery, cost caps, and the
determinism + caching that make a lesson reproducible. In V9 this layer **is**
`@oshun/v9-prometheus`, and `forgeLesson`
(`libs/v9/prometheus/src/pipeline.ts:111`) composes Stages 0–8 end-to-end —
resolve (Atlas) → ground/solve-first → plan (HTN) → write (the injected Iris
boundary) → build explorable (Hephaestus) → assess & schedule (Mnemosyne) → gate
→ compile & cache. A lesson that fails any gate is returned `blocked: true` with
the failing gate ids and **no artifact is compiled, delivered, or cached**
(`pipeline.ts:235`).

The honest nuance is the planner. The monolith captions L4 "on Yemaya
HTN-planned dynamic pipelines," but **no `libs/v9` file imports `@yemaya`** —
`planLesson` (`libs/v9/prometheus/src/plan.ts`) imports only `@oshun/contracts`
and is a self-contained, deterministic HTN-style planner over the verified
skeleton. So L4 is _realized by V9's own orchestration code_, sharing the HTN
_discipline_ the monolith names without taking a dependency on the Yemaya
planner library. This is a place V9 wrote connective tissue rather than
consuming a substrate — which is exactly why L4 is one of only two layers that
carry net-new V9 code. The full stage-by-stage treatment is in
[./prometheus-lesson-pipeline.md](./prometheus-lesson-pipeline.md).

## L5 — the governance plane (V9's other net-new layer)

L5 wraps everything below it in the V1 Agentic AI Studio envelope: every lesson
generation is an **AgentRun** with a visible DAG, budget inheritance, kill
switches, approval gates, a provenance bundle, and an immutable ledger — and the
seven release gates are enforced here. This is the second layer V9 realizes in
code, as `@oshun/v9-governance`. Because the
[delivery-and-cross-cutting](./delivery-and-cross-cutting.md) page covers the
governance and cross-cutting libraries in full, this section stays at the
_layer_ altitude — what makes L5 a real plane rather than a promise.

`registerV9AgentFamily` (`libs/v9/governance/src/agent-family.ts:73`) builds the
registration **deterministically from the real pipeline stage graph**. The
governable DAG has eight nodes for stages `0,1,2,3,5,6,7,8` — note that media
realization (stage 4) is intentionally _not_ a separately governed node — and
each node (after the first) `dependsOn` the previous one, so the run is a
visible chain, not a black box (`STAGE_TITLES`, `agent-family.ts:55`; the test
pins the stage list exactly). **Budget inheritance** is concrete: an inherited
ceiling is split into per-stage caps (`agent-family.ts:86`), and
`validateBudgetInheritance` (`agent-family.ts:111`) verifies the caps sum to ≤
the ceiling — a child run cannot out-spend its parent envelope. Two **kill
switches** are registered with typed fallbacks (`fallbackBehavior` ∈
`pause | skip_stage | text_only | manual_review`): a family-scoped switch that
`pause`s, and a provider-scoped switch that degrades to `text_only`. A **replay
manifest** names the fields that make a run reproducible — `cacheKey`
(deterministic inputs), `skeletonHash` (the plan), `ledgerEntryId` (the
evidence) — with `replayable: true`.

L5 also owns access. `checkLessonAccess` (`entitlements.ts:52`) is a
**deny-by-default** decision over a single account's age band, region, and tier,
where adult-gating and region blocks take precedence over the paywall — a
sensitive lesson cannot be unlocked by a subscription if the learner is
under-age. And it encodes the portfolio's cross-product story literally:
`CROSS_PRODUCT_GRANTS` (`entitlements.ts:91`) maps a V2 racing podium finish to
the applied-physics lesson, a meditation 7-day streak to the
neuroscience-of-attention lesson, and a V8 case solved to the
logic-and-deduction lesson, and `applyCrossProductGrant` adds that grant to the
learner's profile. The seven gates this plane enforces are two real framings of
the same discipline (an architecture-§ numbering and a ledger-§J numbering) —
both run on the shared `@oshun/content-release-gates` service, never a bespoke
per-product checker, which is the concrete meaning of "no eighth loop" at the
gate level. The divergence is documented in
[./seven-gates-and-aletheia.md](./seven-gates-and-aletheia.md).

## L6 — delivery & experience

The top layer is the consumer surface: a web/mobile app that streams a lesson,
runs the Nyx WebGL planetarium and the Kalika physics in the browser, hosts the
embodied Chiron teacher, and renders the learner's personal Atlas map. The
deliberate architectural decision here is the **non-dependency on Bellona**:
V9's P1 experience is web-first and does _not_ ride the Unreal cook path
([../V9_ARCHITECTURE.md](../V9_ARCHITECTURE.md) §8), because the two heaviest
"wow" surfaces are already web-native and only the _game-bridge_ explorables
would need the engine bridge — so they are scoped to P2/P3 and do not block P1.
In code, L6 is the layer with the most ground still ahead of it:
`libs/v9/experience` ships the _tested view-models_ the screens would bind to
(`buildWonderFrontDoor`, `buildLessonPlayer`, the personal star-map), but the
rendered consumer-first app is, by the architecture's own admission (§7), "the
largest net-new build." The fuller account is in
[./delivery-and-cross-cutting.md](./delivery-and-cross-cutting.md).

## Where the net-new code actually lives

Laid out as six layers, the version's "~20% net-new over ~80% composed" claim
stops being a slogan and becomes a map you can point at. Of the six planes, V9
writes material new code in **exactly two** — L4 (the Prometheus forge) and L5
(the governance package) — plus the three net-new _contracts_ in
`libs/contracts/src/v9` that the whole stack speaks. L1, L2, and L3 are
_consumed_: the model plane through injected seams, the agent loop by attested
reuse, the capability tools by direct import. L6 is the open build. That
distribution is the architecture working as designed — the new code is
concentrated where the product's identity lives (_forge_ and _govern_ a grounded
lesson), and absent everywhere the platform already had a better answer.

```mermaid
flowchart TB
    subgraph L6["L6 Delivery & Experience — CONSUMES + open build"]
      EXP["libs/v9/experience view-models<br/>(rendered app = largest net-new)"]
    end
    subgraph L5["L5 Governance plane — V9 NET-NEW CODE"]
      GOV["@oshun/v9-governance<br/>AgentRun DAG · budget inheritance · kill switches<br/>replay · entitlements · seven gates"]
    end
    subgraph L4["L4 Production orchestration — V9 NET-NEW CODE"]
      PROM["@oshun/v9-prometheus forgeLesson<br/>self-contained HTN planner (no @yemaya import)"]
    end
    subgraph L3["L3 Capability tools — CONSUMES by direct import"]
      CAP["@mnemosyne/core · @sophia/semantic-search<br/>@kalika/* · @nyx/* &nbsp;(MCP substrate exists, unused by V9)"]
    end
    subgraph L2["L2 Agent runtime — CONSUMES, spawns NO new loop"]
      IRIS["@iris/agents-core AgenticLoop<br/>max-iter 24 · budget meter · explicit terminations"]
    end
    subgraph L1["L1 Model plane — CONSUMES via injected seams only"]
      MODEL["@iris/model-routing · @nous/*<br/>(no @iris/@nous import in libs/v9)"]
    end
    L6 --> L5 --> L4 --> L3 --> L2 --> L1
    PROM -. "injected LessonWriter (Stage 3)" .-> IRIS
    GOV -. "confirmConsumesSharedLoop → files F2/A2 gap if not unified" .-> IRIS
```

## The design rules that make this SOTA, not merely consolidated

The monolith is explicit that stacking six layers is not, by itself, an
achievement — a stack can be a pile. Four rules (inherited from the platform
report and specialized for learning, §1) are what make it an architecture, and
each has a real anchor in the layers above:

- **Mandatory gates before any human gate.** Everything generated passes
  grounding + accuracy + policy + canon checks before a human is asked to
  review, enforced at L5. The block is hard, not advisory: `forgeLesson` returns
  `blocked` with no artifact when any gate fails (`pipeline.ts:235`).
- **Agents are products with visible DAGs, cost ledgers, and replay.** Not a
  metaphor — the L5 registration _is_ a DAG of the pipeline stages, the
  `BudgetMeter` in the L2 loop is the cost ledger, and the replay manifest names
  the reproducibility fields (`agent-family.ts:100`).
- **Determinism where it matters.** A lesson is a reproducible artifact: same
  inputs + seed ⇒ same artifact and the same hashes, which is simultaneously a
  provenance guarantee and the cost lever behind L4's profile-class cache.
- **Champion–challenger everything.** The cross-cutting package carries the
  champion–challenger and anti-metric machinery so a new generation strategy is
  measured against the incumbent before it ships.

## Edge cases and failure modes specific to the layering

The layered design has its own failure surface — distinct from the per-subsystem
failures the [overview](./overview.md) catalogs — and the system is built to
report rather than fabricate at each seam:

- **Substrate not yet unified.** If the platform's single-agentic-substrate
  consolidation is incomplete, L5 does not assert it is done; it files the
  `F2`/`A2` gap (`iris-loop.ts:49`) and the `ok`/`gapFiled` verdict reflects
  reality.
- **Missing model plane.** With no `LessonWriter` injected (no L1 provider
  wired), Stage 3 throws `LessonWriterNotConfiguredError` (`write.ts:37`) — the
  forge fails loud rather than emitting an ungrounded lesson.
- **Budget exhaustion mid-run.** The L2 loop terminates with the explicit
  `budget_exceeded` status and a `BudgetViolation` payload; it does not return a
  partial answer dressed as complete.
- **Over-allocated envelope.** A registration whose per-stage caps exceed the
  inherited ceiling fails `validateBudgetInheritance` (`agent-family.ts:111`)
  before any run starts.
- **Capability-shape drift.** Because L3 is consumed by direct import rather
  than a schema-described MCP boundary, a breaking change in a substrate is
  caught at _compile time_ by V9's type-checker — the trade-off opposite to the
  runtime-only failure of the one structural adapter noted in the subsystem map.

## Related

- Section hub: [../V9_ARCHITECTURE.md](../V9_ARCHITECTURE.md) (§1 the six-layer
  stack, §8 the Bellona non-dependency, §9 governance)
- [./overview.md](./overview.md) — the productization thesis and the flow
- [./subsystem-map-and-reuse-ledger.md](./subsystem-map-and-reuse-ledger.md) —
  the vertical reuse audit (real import / structural adapter / injected
  boundary)
- [./prometheus-lesson-pipeline.md](./prometheus-lesson-pipeline.md) — L4 in
  depth
- [./seven-gates-and-aletheia.md](./seven-gates-and-aletheia.md) — the L5 gate
  plane and the two gate framings
- [./delivery-and-cross-cutting.md](./delivery-and-cross-cutting.md) — L6, the
  full governance/cross-cutting libraries, determinism, cost
- [./atlas-knowledge-graph.md](./atlas-knowledge-graph.md),
  [./hephaestus-explorables.md](./hephaestus-explorables.md),
  [./lesson-artifact.md](./lesson-artifact.md) — the subsystems the layers carry
