# Delivery, Direction & Operations

Ariadne mints a mystery in two halves — a symbolic skeleton that Clew proposes
and Minos _proves_ uniquely solvable, and an experienced surface that Anansesɛm
and Loom realize into prose, art, voice, and living suspects. This page is about
the **last mile and the run time**: the three subsystems that carry a verified,
realized case the rest of the way to a player and keep the whole thing operable.
**Daedalus** is the compiler — it lowers a proven case into the _exact_ V5 data
structures the shipping detective game already reads, so the playable game needs
no rewrite. **Theseus** is the automated playtester — an autonomous solver that
_plays the compiled case_ to prove its fairness survived the compile, then
grades it on an eight-dimension quality panel and decides, all-or-nothing,
whether it may ship. **The Oracle** is the drama manager — it models each
player, paces difficulty into their flow channel, and keeps a warm queue of
verified cases minting against a bounded budget, so the Bureau Case Board is
never empty and never bankrupts itself.

The throughline is the solve-first thesis read from the delivery side: _fairness
and quality are properties the system proves in game data, not attestations it
hopes for._ Daedalus refuses to compile a case Minos did not pass; Theseus
refuses to publish a case it cannot itself solve in the compiled structs; the
Oracle refuses to mint past its budget ceiling. Each refusal is specific,
located, and tested. The realization half they depend on is its own page,
[./realization-and-living-suspects.md](./realization-and-living-suspects.md),
and the disciplines that wrap _every_ case — budget, journal, determinism,
provenance, localization — are
[./cross-cutting-pipeline-and-localization.md](./cross-cutting-pipeline-and-localization.md).
For the feature map this page belongs to, see
[../V8_features.md](../V8_features.md).

## What ships, honestly

- **Daedalus's compile is real, deterministic, and tested.** `compileCase`
  (`libs/yemaya/case-compiler/src/compile.ts:59`) lowers a verified
  `MysterySession` + ground truth into the `FV5*` Mind-Palace structs and a v2
  `cold_cases_manifest.json`; the CLI test forges a real case from seed 5 and
  proves the emitted manifest validates
  (`apps/v8/daedalus-compiler/src/cli.test.ts:9`). On a publish it runs the
  **authoritative** `validate-cold-cases.py --generated` as a build gate
  (`compile.ts:108`).
- **Theseus is equally real.** Its solver reasons over the _compiled_ structs,
  not the IR (`libs/yemaya/case-eval/src/solver.ts:30`); G4 in-game solvability
  is proven to **fail** when a required edge is dropped (`eval.test.ts:67`); the
  diagnostic judge's PCA aggregation is a genuine power-iteration eigenvector,
  not a mean (`pca.ts:40`); a wired LLM judge that throws **propagates** rather
  than being swallowed (`eval.test.ts:108`). The platform seven-gate suite
  (`libs/v8/case-gates`) and the C2PA-stamping bundle forge
  (`libs/v8/case-bundle`) are real and spec-anchored too.
- **The honest seams are seams, not fabrications.** The LLM judge is an injected
  `JudgeFn` that _refines_ deterministic heuristic scores; absent, the heuristic
  still grades from real case structure (`judge.ts:158`). The media providers in
  the bundle forge are injected `CaseMediaGenerator` boundaries — an absent
  provider yields a `not-configured` slot, never a fabricated asset
  (`case-bundle.ts:262`).
- **The Oracle is real and green, but a library, not yet a wired run time.**
  `@yemaya/case-director` is fully implemented — a genuine online-rating player
  model, streak-aware pacing, a budget-throttled mint queue, deterministic
  placement, a seasonal calendar — with **33 passing tests across five files**.
  But **no run-time app imports it yet**: the Loom service's
  `POST /v8/cases/mint` mints from a `CaseSpec` the _caller_ supplies
  (`apps/v8/loom-service/src/server.ts:43`). Treat its decision logic as tested,
  not as a director already steering a shipped game.
- **Two divergences from the architecture prose, labeled.** The compiler app is
  `apps/v8/daedalus-compiler` (a thin CLI wrapper); the compile _core_ lives in
  `@yemaya/case-compiler` so libs and apps import it without a lib↔app
  dependency (`daedalus-compiler/src/index.ts:7`), and the "runtime relay" is
  really the separate `apps/v8/loom-service`. And the shipping V5
  deduction-`Kind` enum is only `'Authored' | 'Weak'` — there is no `Generated`
  value — so the compiler maps confidence to those two real values rather than
  inventing a third.

## Daedalus — compiling a proof into the shipping game

Daedalus's contract is narrow and strict: turn a `MysterySession` Minos
_already_ proved (plus an optional `AssetManifest`) into a `CompiledCase` — the
`FV5*` structs, the v2 manifest, and a resolved asset bundle. Because the output
is V5's _existing_ authored-case format, the game's deduction UI, interrogation
rig, and world streaming consume a generated case unchanged; the
backward-compatible v2 schema still validates the 25 hand-authored launch packs
and only _adds_ a generation-provenance block.

### The one-command local pipeline

The CLI is the whole offline pipeline in a single invocation
(`apps/v8/daedalus-compiler/src/cli.ts:55`):

```
daedalus --seed 42 --cell Period --difficulty standard --suspects 4 --out ./out
```

`runCli` builds a `CaseSpec` from the flags (difficulty drives the bands, so
`standard` ⇒ 4 suspects, 11 clues, `cli.ts:38`), calls Clew's
`generateCaseSync`, then Minos's `verifyCase`. It prints the verdict and
**refuses to compile a case that failed verification**, returning exit code 1
(`cli.ts:85`); only on a green verdict does it compile to
`<caseId>.compiled.json` and `.manifest.json`.

### The FV5 mapping

`compileCase` builds a shared context, then runs four deterministic mappers — no
randomness, no LLM. **Evidence**: one `FV5MindPalaceEvidenceNode` per clue,
carrying a `t+NN%` fiction timestamp (which Theseus reads to score pacing), a
`bFalseLead` flag mirroring `isRedHerring`, and an `Image` bound to the
generated asset when the manifest has one. **Deductions**: the culprit chain
pairs the incrimination clues in surfacing order (means → opportunity → motive →
broken alibi) with confidence climbing toward the alibi flaw, and each
herring↔clearance pair links a refuted red herring to its suspect's clearance;
`Kind` is `Authored` at high confidence else `Weak` — the two real V5 values.
**Accusations**: the culprit's outcome is `Rating: 'Brilliant'` carrying the
culprit chain's edge ids as `RequiredEdgeIds` (the spine Theseus G4 walks), and
each innocent gets a plausible-wrong outcome — the wrongful-conviction hook
Palimpsest's write-back later seizes.

A final guard: `resolveBundle` **throws** if any `FSoftObjectPath` the structs
reference is unresolved (`compile.ts:91`) — a case cannot compile pointing at
art that does not exist.

### Draft vs. release, and the Python build gate

The draft-vs-release distinction is load-bearing. A standalone compile is a
**draft**: Minos's G1–G3 are proven here, but G4–G7 (Theseus, safety, canon) are
downstream, so a bare invocation labels it a draft and **skips the Python build
gate** unless `--release` is passed with every gate asserted green (`cli.ts:95`,
`compile.ts:108`). A draft produces exactly the structs Theseus needs to _play_
the case without pretending it cleared gates it has not run. The honest seam:
the CLI does not itself run Theseus — `--release` _asserts_ G4–G7; the genuine
verdicts are computed by `@yemaya/case-eval` and supplied by the full publish
path (the Loom service), not synthesized by the compiler.

On a publish, two gates bite. The in-process `validateGeneratedManifest` mirrors
the Python validator — ≥3 evidence nodes, ≥2 deduction pairs, no duplicate ids,
a provenance block citing a verifier report and C2PA root, **and every release
gate green**; a draft filters not-yet-green release-gate problems out, a publish
does not (`compile.ts:100`). Then `runPythonBuildGate` runs
`validate-cold-cases.py --generated`, throwing `CompileError` on a non-zero exit
(`compile.ts:125`).

## Theseus — proving the case is good enough to ship

Theseus (`@yemaya/case-eval`) answers V8's version of V2's shipping question —
_how do you know a generated case is good enough to ship?_ — with proofs in game
data. Its defining choice: it reasons over the **compiled** `FV5*` data, not the
IR. Minos proved the IR admits a unique solution; Theseus proves that property
_survived the compile_, catching a dropped edge, a mis-bound node, or a herring
that lost its clearance — losses an IR-level proof structurally cannot see.

### The autonomous solver and G4 in-game solvability

`solveCompiledCase(compiled, skill)` (`solver.ts:30`) is a deterministic graph
solver. It scores each suspect by the confidence of the deduction edges
converging on them; a herring↔clearance edge **refutes** (subtracts), modeling
"looked guilty, then cleared" (`solver.ts:63`). The `skill ∈ [0,1]` parameter is
a confidence floor — `(1−skill)·0.6` — so a low-skill solver ignores buried
chains and may miss the answer. It accuses the highest positive-net suspect and
reports `decisive` only when the margin over the runner-up is ≥ 0.5
(`solver.ts:88`). The full-skill solver is authoritative; an LLM "detective" is
an optional realism layer, never required to prove solvability.

`checkInGameSolvable(compiled)` is the end-to-end proof: it finds the
`Brilliant` outcome and demands the solver accuses _that_ culprit, decisively,
with **every** `RequiredEdgeIds` edge present and _walkable_ (both endpoints
resolving to real evidence nodes). The teeth are in the test — remove one
required edge from a verified case and G4 flips to `false` (`eval.test.ts:67`),
the exact compile-loss class this gate exists to catch.

### The eight-dimension judge diagnostic and G5 calibration

`scoreHeuristic` (`judge.ts:81`) grades eight rubric dimensions — coherence,
surprise, fairness-feel, pacing, character, prose, voice-fit,
difficulty-accuracy — each from **real structure**, never a random number.
Coherence runs the solver (culprit + decisive ⇒ 0.9); surprise peaks at a ~⅓
red-herring density; pacing is `1 − normalized std-dev` of the evidence staging
gaps. An injected `JudgeFn` may refine any subset, and a judge that throws
**propagates** (`judge.ts:158`). `judgePanel` learns weights across a batch via
real PCA — `pca1Weights` mean-centers the score matrix, builds the covariance,
and takes its top eigenvector by power iteration (`pca.ts:40`) — with a default
pass threshold of 0.6.

The heuristic and PCA outputs remain diagnostics. G5 requires independently
calibrated human-aligned judge evidence bound to the exact artifact, with
licensed gold, current approval, bias probes, held-out champion/challenger
evidence, and a clean contamination analysis (`calibratedG5EvidenceProblems`,
`release.ts`). A high diagnostic score cannot satisfy G5 by itself.

`calibrateDifficulty` (`calibration.ts:24`) runs Theseus at five skill levels
(`0.2 … 1.0`) to estimate a solve-rate, then reports the empirical difficulty
`1 − solveRate` and the `drift` from Minos's a-priori grade — a case the
strongest solver cannot crack is mis-graded; one every weak solver cracks is
easier than its grade claims. That drift is the signal _designed to feed the
Oracle's player model_, though the write-back wire is still spec.
`runRegressionCorpus` (`corpus.ts:26`) anchors the suite: every corpus case must
be G4-solved _and_ judged above threshold — V5's 25 authored cases are the
intended golden fixtures once cooked.

## Operating a case end-to-end: the Loom relay and the two gate framings

At run time the UE5 client never holds provider keys — it reaches everything
through the **Loom relay** (`apps/v8/loom-service`), and `POST /v8/cases/mint`
runs the full pipeline and returns the compiled pack _only_ if all eight
`ReleaseDecision` gates pass: HTTP 200 with the manifest, or 422 with the
blocking reasons (`server.ts:40`). `runPipeline` (`pipeline.ts:127`) is the
composition that ties the last mile together — Minos verify (G1–G3) →
narrative/asset realize → Daedalus **draft-compile** → Theseus G4 + calibrated
G5 → G6 safety + G7 canon → G8 preregistered human-quality launch evidence →
`decideRelease`, and only on an all-green decision a **publish re-compile** with
the Python validator enforced (the diagram below).

```mermaid
flowchart TD
  PLAYER["V5/V6 player at the Bureau Case Board"]
  subgraph oracle["Oracle — @yemaya/case-director (real lib · not yet wired)"]
    PM["player model (Elo skill)"]
    PACE["pacer: flow nudge + anti-repetition + canon weave"]
    MQ["mint-ahead queue (budget-throttled)"]
    PM --> PACE --> MQ
  end
  PLAYER -. "accusation outcome" .-> PM
  MQ -. "CaseSpec (warm)" .-> LOOM
  PLAYER -->|"POST /v8/cases/mint { spec }"| LOOM
  subgraph loom["Loom relay — apps/v8/loom-service · runPipeline"]
    direction TB
    GEN["Clew + Minos: verify G1–G3"]
    DRAFT["Daedalus DRAFT compile → FV5 structs (skipPythonGate)"]
    THE["Theseus: G4 in-game solvable · diagnostic judge"]
    G5["G5 calibrated human-aligned judge evidence"]
    SAFE["G6 safety (fail-loud) · G7 canon"]
    HUMAN["G8 preregistered human-quality launch evidence"]
    DEC{"decideRelease — all 8 green?"}
    PUB["Daedalus PUBLISH compile → v2 manifest + validate-cold-cases.py"]
    GEN --> DRAFT --> THE --> G5 --> SAFE --> HUMAN --> DEC
    DEC -- "no" --> BLK["422 + blockingReasons · nothing cached"]
    DEC -- "yes" --> PUB
  end
  PUB -->|"200 + cold_cases_manifest.json"| PLAYER
```

One thing to internalize before reading any gate code: **V8 has a seven-gate
platform suite and a distinct eight-gate pipeline release decision.** The
runtime Loom pipeline uses the **Theseus `ReleaseDecision`** framing
(`release.ts:40`), ordered by the _pipeline stage_ that produces each verdict;
`decideRelease` publishes only when all eight pass and attaches a specific
blocking reason per failure (`eval.test.ts:179` confirms a single failing G6
blocks). The **platform suite** `@oshun/v8-case-gates` is a different numbering,
ordered by _kind of check_, and registers seven `GateDefinition`s on the shared
`@oshun/content-release-gates` service — **composed, not forked**:

| #   | Theseus `ReleaseDecision` (`case-eval/src/release.ts`) | Platform suite (`@oshun/v8-case-gates`, `case-gates/src/index.ts`) |
| --- | ------------------------------------------------------ | ------------------------------------------------------------------ |
| G1  | Minos formal uniqueness                                | fair-play (every solution clue presented before the reveal)        |
| G2  | deductive completeness                                 | solvability (the CSP proved one solution)                          |
| G3  | fair-play + mechanic balance                           | clue-grounding (every cited clue exists)                           |
| G4  | **Theseus** in-game solvable                           | suspect voice-distinctiveness                                      |
| G5  | calibrated human-aligned judge evidence                | misdirection (≥1 herring, ≤ max — fair, not a maze)                |
| G6  | Sekhmet safety                                         | prose quality                                                      |
| G7  | canon consistency                                      | content safety                                                     |
| G8  | preregistered human-quality launch evidence            | —                                                                  |

`evaluateV8Case` (`case-gates/src/index.ts:183`) returns `cleared` only when all
seven pass. The `case-bundle` forge is where that suite earns its keep:
`forgeCaseBundle` proves uniqueness _before any generation_ (throwing
`CaseNotSolvableError`, `case-bundle.ts:237`), fails loud with no prose writer,
C2PA-stamps each produced asset with a verifiable Ed25519 manifest, and runs the
assembled case through `evaluateV8Case`, leaving `blocked: true` on any failure.
Its spec proves no media is generated for an unsolvable skeleton and that
tampering any signed field flips verification to false.

## Oracle — directing which labyrinth a player meets next

The Oracle's job is to keep one player in their **flow channel** — cases neither
trivial nor impossible — while honoring their taste, avoiding repetition,
weaving their open story threads back in, and never letting the mint bill run
away. It is real, tested decision logic, though no runtime app has wired it in
yet, and this section is honest about that boundary.

### Player model, pacing, and the mint-ahead queue

`updateFromOutcome` (`player-model.ts:139`) is a genuine Elo-style update, not a
moving average of a label. Each finished case carries an `actual` score in
`[0,1]` (`wrong`→0, `partial`→0.45, `correct`→0.8, `brilliant`→1), and the model
nudges the skill estimate by `K · (actual − expected)` where `expected` is the
Elo logistic against the difficulty's implied rating. The `K`-factor _decays_
with evidence — `0.12 + 0.4/(1+n)` runs from 0.52 on a player's first case to a
~0.12 asymptote — so provisional ratings find a player fast and settled ones
don't tank on one bad night. The model also keeps theme/cell taste counters and
weight-sorted **open threads** (e.g. "wrongly accused Dockhand Mara, now freed")
that pacing weaves into the next case's `priorOutcomeHooks`.

The pacer's `nextCaseSpec` reconciles three pressures into one deterministic
`CaseSpec`: difficulty tracks skill but is **nudged by the recent streak** (one
band up after strong solves, down after weak ones); **anti-repetition** drops
every theme and cell used in the last _K_ cases; and **canon weaving** writes
the strongest open thread into the spec. `MintQueue.refill`
(`mint-queue.ts:131`) keeps _N_ verified cases warm per `(player, cell)` lane so
a player at the Case Board never waits on the pipeline — real water-mark
scheduling against a live budget: it **reserves the per-request cost before
emitting** (`DEFAULT_MINT_COST` = 4000 tokens, 3 asset-jobs), and the first
reservation the budget cannot grant stops the refill short, leaving the lane
partially warm with `budgetLimited` set. The Oracle thus throttles its own mint
rate against the remaining envelope.

### Placement, seasonal cadence, and the honest boundary

`placeCase` decides where a verified case surfaces, in priority order: a
**commissioned** case is always honored directly; otherwise, if an active world
location matches the spec and has a present NPC to carry the hook, the case is
seeded **ambient** into the living world; else it falls back to the **bureau
Case Board**. `buildSeasonCalendar` replaces V5's authored weekly packs with a
generated drop calendar — dated drops a week apart, difficulty escalating across
the season, the cell rotating — and it never reads a clock, so a season is
reproducible from its id. The honest boundary is the wire: `placeCase` reads a
`WorldState` interface, but the _live_ NPC-schedule injection and the in-engine
Case Board that consume its decision are the UE5 plugin — the external
remainder.

## How a case fails to ship — refusals

The layer is built to _refuse_ rather than fabricate, each refusal specific and
located:

- **In-game solvability lost** → a compile that drops a required edge, mis-binds
  a node, or strips a herring's clearance makes G4 return `pass: false`;
  `decideRelease` refuses to publish (`eval.test.ts:67`).
- **G5 calibration absent or invalid** → a passing heuristic/PCA aggregate
  cannot publish without exact-artifact, current, independently calibrated
  human-aligned judge evidence; the platform-suite parallels are low voice, low
  prose, or unsafe content.
- **Under-determined skeleton** → caught _before_ any generation in the bundle
  forge (`CaseNotSolvableError`); in the suite it fails G2 solvability.
- **A non-green release gate at compile** → a draft tolerates it; a publish does
  not — `validateGeneratedManifest` then the Python gate reject the pack
  (`compile.ts:100`, `:108`).
- **Mint budget exhausted** → `MintQueue.refill` stops short with
  `budgetLimited: true` rather than overrunning.
- **Honest absences** → no `python3` keeps a draft buildable while labeling it a
  draft; an absent media provider yields a `not-configured` slot; a wired LLM
  judge that errors is propagated, not swallowed.

On any of these the case does not ship — nothing is published or cached — and
the failing gate's reason is the signal a Clew repair pass or a human reviewer
acts on.

## Related

- [./realization-and-living-suspects.md](./realization-and-living-suspects.md) —
  the writers' room, asset fabric, and Ori suspects whose trees and manifest
  Daedalus folds into the V5 pack.
- [./cross-cutting-pipeline-and-localization.md](./cross-cutting-pipeline-and-localization.md)
  — the budget, journal, determinism, provenance, and localization disciplines
  the Loom pipeline threads through every mint.
- [../architecture/daedalus-compiler-and-theseus-eval.md](../architecture/daedalus-compiler-and-theseus-eval.md)
  — the architecture companion: the deep compile target and Theseus eval path,
  gate by gate.
- [../architecture/oracle-director-cross-cutting-and-deployment.md](../architecture/oracle-director-cross-cutting-and-deployment.md)
  — the Oracle, the cross-cutting spine, and the deployment shape in depth.
- Hub: [../V8_features.md](../V8_features.md) · Architecture spec:
  [../V8_ARCHITECTURE.md](../V8_ARCHITECTURE.md).
