# The Soulful Braid, the Agora Commons, and Explainer Films

These three features are V9's "Phase-2 delight & depth" layer
(`V9_ARCHITECTURE.md` §3 P2): the part that turns a correct, grounded lesson
into something a learner _wants_ — an experience with an emotional shape, a way
for creators to author and share their own journeys, and a watch-don't-poke
explainer film when the learner would rather sit back. All three live in a
single library, `@oshun/v9-theia` (`libs/v9/theia/src`), alongside the
wonder-director itself; the package is named for Theia, the Titaness of sight
and the "wonder director" who orchestrates awe. The library is small and dense —
six source files, one ~9 KB spec — and every function in it composes a _real_
substrate: the live Atlas graph (`@oshun/v9-atlas`), the real Mnemosyne mastery
ladder (`@mnemosyne/core`), and the V9 contract vocabulary (`@oshun/contracts`).
What it does _not_ do is fabricate the parts it cannot compute: the avatar/face
runtime, the headless widget browser, and the Manim renderer are all expressed
as typed, fail-loud _boundaries_ that a real service plugs into. This is the
feature-side companion to the section hub —
[../V9_features.md](../V9_features.md).

The through-line connecting the braid, the commons, and the films is the same
idea Theia exists to serve: _a lesson never dead-ends_. The emotional arc closes
on the next question; Agora lets a learner-turned-creator pin that next question
into a publishable journey; and the explainer film is just another shareable
social object minted from a verified lesson. Everything here is downstream of
the [Prometheus lesson forge](./prometheus-lesson-forge.md) and the
[Atlas](./atlas-wonder-resolution.md), and gated by the same
[seven gates](./subsystem-map-and-gates.md) every lesson passes before a learner
sees it.

## What ships, honestly

The **logic** in `@oshun/v9-theia` is real and tested — all six modules,
exercised by `theia.spec.ts` (the spec covers thread continuation, the emotional
arc, surprise-me, the widget verifier's ship/block/fail-loud paths, the Manim
self-repair loop, the HITL state machine + budget, Agora authoring + share
objects, and Chiron-full memory + personas). The functions are not CRUD: they
walk the real Atlas edge set, index into the real six-level Dreyfus mastery
ladder, parse outputs through the real `V9ExplorableSchema`, and compute real
sha256 provenance hashes.

What is **boundary / injected** (real interface, no production adapter wired in
this package): the `HeadlessWidgetRunner` that proves a generated widget reaches
its success state, the `ManimRenderer` that renders the film, and — for
Chiron-full — the embodied face + emotion-recognition runtime (Psyche). For the
Manim renderer specifically, the _other half_ already exists: a genuine 436-line
Python render service at
`services/metis/src/metis/media/manim_render_service.py` invokes the `manim` CLI
in a sandboxed subprocess (rlimits, wall-clock timeout, session isolation) and
returns structured `{syntax,runtime,timeout,unknown}` failures whose data model
"mirrors the TS `ManimRenderRequest` contract" (`manim_render_helpers.py`). The
missing piece is the TS↔Python adapter; each half is real, the bridge is not yet
in code.

What is **spec / aspirational at this seam**: Agora's `buildShareableObject`
imports nothing from V7 **Mawu** distribution or **Sekhmet** safety — it builds
an OpenGraph-ready share _descriptor_ with a templated `metis.oshun/share/...`
URL; the actual safety-gated publish ride is the design's promise, not this
function's behavior. And critically, **no production code imports
`@oshun/v9-theia` yet** — a repo-wide grep for the package turns up only its own
spec. The V9 [experience layer](./threads-and-mastery-loop.md) ships its _own_
simpler thread and surprise-me (`libs/v9/experience/src/lesson-player.ts` reads
a precomputed `thread.nextWonders` off the lesson artifact;
`wonder-front-door.ts` does an adjacency-based "surprise me"). Theia is the
richer, graph-driven version of those ideas, fully built and tested, awaiting
wiring into the runtime. Where this page says "Theia threads across the Atlas,"
read it as "the tested library does this; the running player does not call it
yet." Honest "built-but-unwired" beats fake "shipped."

## The soulful braid — Theia's emotional arc and thread continuation

The "soulful braid" the design asks for — science set beside the human, awe set
beside understanding — is, at the code level, three small orchestration
functions in `theia.ts`.

### Thread continuation (`nextWonders`)

`nextWonders(atlas, from, max = 3)` answers "what better question does this
concept open?" by walking the real Atlas edge set in a fixed priority order
(`theia.ts:17`):

```ts
const THREAD_EDGE_PRIORITY = ['enables', 'bridges', 'specializes', 'related'];
```

Of the nine `V9ConceptEdgeType` values in the contract (`prerequisite`,
`related`, `part_of`, `generalizes`, `specializes`, `enables`, `conflicts`,
`complements`, `bridges`), the thread deliberately uses only four — and they are
the _forward_ ones. It never threads back into a `prerequisite` (that is
remediation, not a next wonder), never offers a `conflicts` edge as a thread,
and prioritizes `enables` (this unlocks that) over `bridges` (a cross-axis jump)
over `specializes` over a loose `related`. The function throws on an unknown
source concept, dedups by target id, and slices to `max`. The spec pins the
priority behavior precisely: an `enables` edge to "Age of the universe" beats a
`related` edge to "Cosmic microwave background," so the Olbers'-paradox thread
proposes the age of the universe _first_ (`theia.spec.ts:59`).

The `bridges` edge is where the braid lives structurally. The contract defines
it as "a cross-axis thread, e.g. cosmology ↔ deep-time" (`concept-graph.ts:87`),
and V9 organizes reality along seven **wonder axes** — `cosmos`, `laws`, `mind`,
`meaning`, `deep-time`, `living-world`, `made-world` (`primitives.ts:42`). A
`bridges` edge from a `cosmos` node to a `meaning` or `mind` node _is_ the
"science next to the human" juxtaposition, and because `bridges` sits second in
the thread priority, Theia will surface it. What is **not** in this package is
the curated content that fills those bridge edges — the meditation session
beside the neuroscience-of-attention thread, the Hathor myth beside the
cosmology lesson, the Nisaba source text beside it. Those are design promises;
the structural seam (the bridge edge + its place in the thread priority) is what
ships today.

### The emotional arc (`orchestrateEmotionalArc`)

The arc tags a lesson's narrative beats with one of four emotions —
`awe → curiosity → understanding → anticipation` — by pattern (`theia.ts:63`):
the opening beat (or any `/hook/i`) is **awe**, a `/why it matters|connect/i`
beat is **understanding**, a `/next question|the next/i` beat is
**anticipation**, the last beat defaults to anticipation, and everything between
is **curiosity**.

This looks like a toy until you read what produces the beats. The Prometheus
planner emits exactly this phrasing (`libs/v9/prometheus/src/plan.ts`):

```ts
const beats = [
  `Hook: ${input.wonder}`,
  ...claims.map((c, i) => `Establish[${i}]: ${c.text}`),
  'Why it matters: connect the established facts back to the wonder.',
  'The next question: open the thread to the next, better wonder.',
];
```

The arc's regexes are tuned to the forge's beat vocabulary: `Hook:` → awe,
`Why it matters: connect` → understanding, `The next question:` → anticipation.
So even though `@oshun/v9-theia` does not yet import the planner, the two were
written to compose — the arc is designed to run over a real Prometheus lesson
plan, opening on awe and closing on the next question. (The shared default
persona `chiron:warm-generalist` is the same constant on both sides — `plan.ts`
and Agora's `toPrometheusDirectives` — another deliberate alignment.)

### Surprise me (`surpriseMe`)

`surpriseMe(atlas, masteryMap, max = 1)` finds "a wonder you didn't know you
had, from the frontier of what you almost know." For every concept the learner
has _not_ mastered but which has at least one prerequisite, it computes
`readiness = masteredPrereqs / totalPrereqs`, keeps the ones with
`0 < readiness ≤ 1`, sorts descending, and returns the top `max`. "Mastered"
here means the learner's level is `≥ intermediate` —
`MASTERED_FLOOR = MASTERY_LEVELS.indexOf('intermediate')` (index 2 of the
six-level Dreyfus ladder
`novice, beginner, intermediate, advanced, expert, master`,
`libs/mnemosyne/core/src/types.ts:154`). The prerequisite set comes from the
real Atlas, which delegates closure to the Mnemosyne `KnowledgeGraph` rather
than reimplementing it (`atlas-store.ts:146`). The spec drives a learner who has
mastered "Light" toward "Olbers' paradox" at `readiness === 1` — every
prerequisite satisfied, the highest-readiness unexplored frontier
(`theia.spec.ts:75`).

## The Agora commons — author, then share

Agora (`agora.ts`) is the creator loop: a learner or educator steers the forge
to author a guided journey, and the result becomes a shareable social object —
the free-tier growth lever the product analysis calls for.

### Authoring a journey (`GuidedJourneySpec` → directives)

A creator's choices are a `GuidedJourneySpec`:
`{ creatorId, topic, tone, depth, audience }`, where
`tone ∈ {playful, rigorous, poetic, socratic}`,
`depth ∈ {intro, standard, deep}`, and
`audience ∈ {kids, teens, adults, experts}`. `validateJourneySpec` enforces two
real rules: a topic under three trimmed characters is rejected, and **`deep`
depth for a `kids` audience is refused** — a small but genuine
age-appropriateness guard at authoring time, before anything reaches the forge.

`toPrometheusDirectives` maps the authoring intent onto forge directives:

| Depth      | `maxConcepts` | `targetSuccess` |
| ---------- | ------------- | --------------- |
| `intro`    | 3             | 0.80            |
| `standard` | 6             | 0.75            |
| `deep`     | 12            | 0.70            |

The `targetSuccess` is a flow-band target, and note the direction: a _deeper_
journey aims at a _lower_ predicted success rate (0.70), i.e. it is allowed to
be harder — that is the difficulty-in-the-flow-channel idea expressed as a
number. The `personaHint` maps tone to a Chiron persona ref (`chiron:playful`,
`chiron:rigorous`, `chiron:poetic`), with `socratic` collapsing to the warm
generalist (`chiron:warm-generalist`). Be precise about what this is: the
emitted `PrometheusDirectives`
(`{ topic, targetSuccess, maxConcepts, personaHint }`) is _not_ the same shape
as the forge's `LessonPlanInput` (`{ wonder, conceptSet, groundTruth, ... }`).
It is an authoring-intent object — a structural seam that a forge front-door
would consume to drive planning and ground-truth assembly — not a literal call
into `planLesson`. See the
[Prometheus lesson forge](./prometheus-lesson-forge.md) for what the directives
would steer.

### The shareable object (`buildShareableObject`)

`buildShareableObject` mints a `ShareableObject` for either kind of social
artifact — `explorable` or `explainer-film` — carrying
`{ kind, lessonId, conceptId, title, url, ogDescription }`. The `url` is a
deterministic `https://metis.oshun/share/<kind>/<encoded-lessonId>` and the
`ogDescription` is a templated OpenGraph card line ("Explore … — a grounded,
interactive … from Metis"). This is honestly a _descriptor builder_: the
function produces the metadata an OG card or a deep link needs, and nothing
more. The module header describes publishing as riding "V7 Mawu distribution +
Sekhmet (the injected boundary)," but the code imports neither — the safety
review and the distribution ride are the design's promise, layered on by
[governance and boundaries](./governance-and-boundaries.md), not behavior in
this function.

## On-demand explainer films — the Manim self-repair driver

`manim.ts` is the precise-STEM explainer-film driver: a NotebookLM-style video
overview, but _computed-correct_, because it renders only from a **verified
Kalika derivation**, never from prose.

`renderExplainerFilm(request, renderer?, options)` takes a `ManimRenderRequest`
(`{ conceptId, title, derivation: string[] }`) and:

1. **Fails loud** with `ManimNotConfiguredError` if no renderer is wired — it
   will not silently no-op.
2. **Refuses an empty derivation** — "refusing to render an explainer film from
   an empty (unverified) derivation." No verified math, no film. This is the
   anti-fabrication contract at the film boundary.
3. Runs a **self-repair loop** up to `maxAttempts` (default 3), passing the
   1-based `attempt` count into `renderer.render(request, attempt)` so a render
   service can _see_ how many times it has failed and self-correct — the
   reliability pattern the 2026 Manim-from-LLM literature requires
   (`V9_SOTA_RESEARCH.md` §2).
4. On success, computes a **C2PA content hash** — `sha256` over
   `[conceptId, derivation, assetRef]` — binding the film to the exact verified
   derivation that produced it, and returns
   `{ rendered: true, film: { assetRef, attempts, c2paContentHash } }`.
5. On exhaustion returns `{ rendered: false, attempts, lastError }` — a
   structured failure, never a thrown crash mid-loop.

The spec exercises all four edges: retry-then-succeed (attempt 2 wins,
`calls === 2`), give-up-after-`maxAttempts`, refuse-empty-derivation, and
fail-loud-with-no-renderer (`theia.spec.ts:127`).

The `ManimRenderer` is the injected boundary, and its real counterpart already
exists in Python. `ManimRenderService` (`manim_render_service.py`) discovers a
`manim` binary (via PATH or the repo-local `services/metis/.venv-manim`), builds
a `manim render` argv (`build_render_command`), runs it in a forked subprocess
with CPU and address-space rlimits and a wall-clock ceiling
(`with_timeout_ceiling`), classifies any non-success into a structured
`RenderError` of kind `syntax | runtime | timeout | unknown`, and locates the
produced video artifact (`locate_video_artifact`) — even treating "returncode 0
but no artifact" as a failure ("the render lied about success"). The helpers
module states outright that `RenderJob` "mirrors the TS `ManimRenderRequest`
contract," so the two halves were co-designed. What is missing is the adapter
that implements the TS `ManimRenderer` interface by calling this service over
HTTP or subprocess; until it exists, `renderExplainerFilm` is real, the Python
renderer is real, but the end-to-end TS render is unwired.

A word on C2PA: the hash computed here is real and is the determinism/provenance
binding (gate **G7**) a C2PA manifest would carry, but this driver does not
_sign_ a manifest — that cryptographic step is the V3 C2PA remainder. The
explorable provenance contract makes the distinction explicit: `c2paSigned`
defaults to `false` (`explorable.ts:95`) and only flips true once a real signer
runs.

### Generative widgets — the same discipline, for ideas without a kernel

For concepts with no computed kernel, Prometheus can generate a runnable web
widget; `generative-widgets.ts` is the verifier that decides whether it may
ship. `verifyGenerativeWidget(spec, runner?)` fails loud without a
`HeadlessWidgetRunner`, then runs the widget headlessly and **blocks** it unless
it both _compiles_ and _reaches its declared success state_. Only on a
demonstrated success does it parse a real `V9Explorable` through
`V9ExplorableSchema` with `kind: 'generative-widget'`,
`successState.reachable: true` (plus the runner's evidence string), a grounding
pin (`sourceId: 'iris:widget-gen'`, `credibility: 0.6`), and a provenance block
(`contentHash = sha256(code)`, `c2paSigned: false`). This is the contract's
bright line at work: `reachable` "is set true only after the success state was
actually demonstrated … never asserted blind" (`explorable.ts:73`), and
`isV9ExplorableShippable` returns exactly `successState.reachable`. A
generated-but-unverified widget never ships — and the `HeadlessWidgetRunner` has
no production implementation anywhere yet, so this verification logic is real
and tested but not yet running against a real browser. The explorable runtime
that hosts the shipped widget lives next door in
[Chiron and Hephaestus](./chiron-and-hephaestus.md).

## Mid-pipeline control: HITL and the per-step budget

`hitl.ts` is the human-in-the-loop control plane the forge runs under.
`HitlSession` is a real state machine over
`running | paused | redirected | resumed | failed | recovered`: you may `pause`
only from `running`/`resumed`; `redirect(direction)` only from `paused` and only
with a non-empty direction (this is regenerate-with-direction); `resume` from
`paused`/`redirected`; and `recover` only from `failed`, where
`checkpoint-restore` returns the latest `HitlCheckpoint` and `replan` returns
`null` (start the stage fresh). Illegal transitions throw rather than silently
passing. `enforceStepBudget(spent, stepCap, requested)` is the cost guard: it
rejects a negative request, allows a step only if `spent + requested ≤ stepCap`,
and reports the `remaining` budget. Together these are the seam the platform
Yemaya HITL fix plugs into — a pipeline that can be paused, steered, resumed,
budget-capped, and recovered from a checkpoint mid-flight.

## Chiron-full: cross-session memory and grounded historical personas

`chiron-full.ts` is the glue that complements the base Chiron persona library
(`@oshun/v9-chiron`: `getChironPersona`, integrity modes, delivery). It does two
things, both pure logic.

**Cross-session memory.** `buildSessionMemory(traces)` partitions the learner's
concept traces into `struggledConcepts` (mastery `≤ beginner`) and
`masteredConcepts` (mastery `≥ advanced`) — note these floors differ from
surprise-me's `intermediate` floor, because "open the session on it" and "ready
for the frontier" are different bars. `chironOpeningLine(memory)` then opens a
returning learner on what was tricky last time ("Last time, _Tensor calculus_
was tricky — want to revisit it before we go further?"), or acknowledges
progress, or falls back to a warm "What are you wondering about today?". This is
the Mnemosyne trace projected into Chiron's opening turn.

**Grounded historical personas.** `buildHistoricalPersona` enforces the
anti-fabrication and consent rules for "Chiron as a historical figure." It
**throws `UngroundedPersonaError` if there is no Nisaba source pin** (no
invented personal claims — the persona may say nothing the sources don't
ground), always attaches a `reconstructionLabel` ("Reconstruction of _X_,
bounded by historical sources — not the real person."), and **refuses a
living-voice persona without a consent record** (the V3 voice-clone registry /
Sekhmet gate). The embodied face and emotion recognition (Psyche) is the
provider-gated runtime remainder; this module ships the memory and
persona-safety logic only. The full mentor surface — voice, face, integrity
modes, Socratic dialogue — is documented in
[Chiron and Hephaestus](./chiron-and-hephaestus.md).

## How it fits together

The diagram below traces a creator's authoring choice through the forge and out
to the two shareable artifacts, marking which seams are real-and-tested (solid)
and which are injected boundaries (dashed):

```mermaid
flowchart TD
  A[Creator: GuidedJourneySpec<br/>topic · tone · depth · audience] -->|validateJourneySpec| B{ok?}
  B -->|kids+deep / topic<3 → reject| X[blocked at authoring]
  B -->|ok| C[toPrometheusDirectives<br/>maxConcepts · targetSuccess · personaHint]
  C -.authoring-intent seam.-> D[Prometheus forge<br/>plan · ground-truth · gates G1–G7]
  D --> E[orchestrateEmotionalArc<br/>awe→curiosity→understanding→anticipation]
  D --> F[nextWonders / surpriseMe<br/>thread across the Atlas]
  D --> G[verifyGenerativeWidget]
  D --> H[renderExplainerFilm<br/>self-repair loop ≤3]
  G -.HeadlessWidgetRunner.-> G2[(headless browser<br/>boundary)]
  H -.ManimRenderer.-> H2[(Metis manim service<br/>real Python, unwired)]
  G --> I[V9Explorable<br/>reachable=true]
  H --> J[ExplainerFilm<br/>c2paContentHash]
  I --> K[buildShareableObject]
  J --> K
  K -.Mawu + Sekhmet.-> L[(safety-gated publish<br/>boundary)]
```

The solid edges are the tested logic in `@oshun/v9-theia`; the dashed edges are
the three boundaries — the headless widget runner, the Manim render service
(real, but unbridged), and the Mawu/Sekhmet publish ride — that a running V9
supplies.

## Related

- [Overview](./overview.md) and the section hub
  [../V9_features.md](../V9_features.md)
- [Subsystem map and the seven gates](./subsystem-map-and-gates.md) — where G4
  (solvability), G5 (delight), and G7 (provenance) bite on widgets and films
- [Atlas and wonder resolution](./atlas-wonder-resolution.md) — the graph
  `nextWonders` / `surpriseMe` walk, and the `bridges` edge behind the braid
- [Prometheus lesson forge](./prometheus-lesson-forge.md) — what Agora's
  directives steer and the beats the emotional arc runs over
- [Chiron and Hephaestus](./chiron-and-hephaestus.md) — the embodied mentor and
  the explorable runtime hosting verified widgets
- [Threads and the mastery loop](./threads-and-mastery-loop.md) — the experience
  layer's own thread/surprise, and where Theia's graph-driven version would wire
- [Governance and boundaries](./governance-and-boundaries.md) — Sekhmet safety,
  the V3 C2PA signer, and the voice-clone consent registry
