Ariadne · Architecture

V8 Architecture — Ariadne: The Self-Authoring Detective Universe

The runtime, package, and integration architecture behind Ariadne — the self-authoring detective universe. How the systems fit together, communicate, and scale.

6sections9 minread

On this page

Status: technical design for V8. Date: 2026-06-04. Pairs with V8_features.md (product), V8_GAP_ANALYSIS.md (what's missing), V8_SOTA_RESEARCH.md (external grounding), V8_TODOS.md (execution backlog). Cross-ref convention: features§"<anchor>"V8_features.md; sota§NV8_SOTA_RESEARCH.md; gap§NV8_GAP_ANALYSIS.md; v5§… → V5 docs/source.


This architecture reference has been decomposed into focused pages under architecture/. This file remains the canonical hub (every section heading is preserved, so existing arch§"…" anchors keep resolving); the in-depth, code-grounded companion pages live under architecture/. Start at the architecture page index. The product feature map is in V8_features.md / features/.

1. Architectural thesis#

The LLM proposes; a constraint solver disposes. A fair, solvable mystery has a symbolic skeleton (ground truth + clue logic + uniqueness proof) that must be verifiable, and an experienced surface (prose, dialogue, art, voice) that LLM agents realize from that skeleton. V8 keeps these two layers strictly separated. The skeleton is authoritative and machine-checked; the surface is generated, graded, and regenerated on failure.

This is the single decision that makes everything else fall out. It directly implements the solve-first, constraint-verified approach from sota§1 and avoids the freestyle-LLM failure mode (rambling, contradictions, unsolvable "gotchas").

V8 runs as a backend service ("the Loom service", a new app under apps/v8/) that the V5/V6 UE5 client reaches only through a relay (never direct provider calls — sota§4, UnrealGenAISupport's explicit production warning). Output lands in V5's existing authored case format, so the shipping game is unchanged.


2. Pipeline overview (the eleven stages)#

text
 ┌────────────────────────────── Ariadne / the Loom service (apps/v8) ─────────────────────────────┐
 │                                                                                                   │
 │  0 SEED ───► 1 GROUND TRUTH ───► 2 CLUE DERIVATION ───► 3 VERIFY ──(fail→repair)──┐               │
 │  Oracle/      Clew (solve-first)   Clew (backward)        Minos (CSP/ASP+fairplay) │               │
 │  Showrunner   + Palimpsest canon   derive clues+herrings  unique-solution proof    │               │
 │                                                                          (pass)    ▼               │
 │  4 COMPILE-IR ───► 5 NARRATIVE REALIZE ───► 6 ASSET REALIZE ───► 7 EVAL ──(fail→repair/HITL)──┐    │
 │  MysterySession IR  Anansesɛm writers'room   Loom→Isis jobs       Theseus solve + judge       │    │
 │  (validator schema) (CreativeAgents)         + Ori suspects       8-dim + safety(Sekhmet)     │    │
 │                                                                                     (pass)     ▼    │
 │  8 COMPILE-GAME ───► 9 PUBLISH/DELIVER ───────────────────────────────────────► 10 DIRECT       │    │
 │  Daedalus: FV5* +     Daedalus relay: stream pack+assets to UE5;                  Oracle: place   │    │
 │  cold_cases_manifest  ACE/Inworld live interrogation at runtime                   in open world  │    │
 │                                                                                                   │
 │  11 CROSS-CUTTING: budget · HITL · provenance(C2PA) · determinism/replay · canon write-back ·     │
 │     multiplayer sync · localization · accessibility · telemetry/evals                             │
 └───────────────────────────────────────────────────────────────────────────────────────────────────┘

Stages 0–8 are offline (case minted ahead of need or on commission); stage 9–10 include the runtime path (live interrogation, on-demand minting). The pipeline is a yemaya StateGraph/WorkflowBuilder graph (gap§1C) with conditional repair edges.


3. The canonical data contracts#

V8 introduces three intermediate representations and compiles to one existing target. Keeping these explicit is what lets independent agents/teams work in parallel.

3.1 CaseSpec (input to the pipeline) — new, libs/yemaya/case-engine#

ts
interface CaseSpec {
  caseId: string; // deterministic from seed
  seed: number; // reproducibility (sota: determinism)
  cell: EV5Cell; // 'Period'(Vice Squad) | 'Urban' | … (mirror V5 enum)
  era: string; // '1947-LA' etc — selects canon slice
  difficulty: 'intro' | 'standard' | 'hard' | 'fiendish';
  targetSuspects: number; // 3..7
  targetClues: number; // derived band per difficulty
  themeTags: string[]; // 'arson','warehouse-district',...
  castConstraints?: {
    // canon reuse
    requiredCharacterIds?: string[]; // recurring NPCs / prior-case figures
    requiredLocationIds?: string[];
    priorOutcomeHooks?: string[]; // e.g. wrongful-conviction from case #7
  };
  lengthMinutesVO: number; // maps to FV5ColdCasePackDefinition.VoiceOverMinutes
  commissionedBy?: string; // player/creator id (Commission Studio)
}

3.2 CaseGroundTruth (Stage 1–3 internal) — new, libs/yemaya/case-engine#

The symbolic skeleton. Never shown to the player. This is the constraint network from sota§1 (EXAG backward-generation + CSP).

ts
interface CaseGroundTruth {
  victim: CharacterRef;
  culprit: CharacterRef;                 // the unique answer
  means: { weaponId: string; access: AccessFact[] };
  motive: { kind: 'financial'|'revenge'|'jealousy'|'cover-up'|…; evidenceVars: string[] };
  opportunity: { windowStart: TimeFix; windowEnd: TimeFix; place: LocationId };
  timeline: TimelineEvent[];             // every character's movements; conflict-detected
  facts: GroundTruthFact[];              // atomic propositions (who/where/when/what)
  alibis: Alibi[];                       // innocents verifiable; culprit's has a flaw
  constraints: ConstraintClause[];       // CSP/ASP clauses linking facts→suspects
}

3.3 MysterySession IR (Stage 2 output, Stage 3 gate input) — EXISTING#

The pipeline's pivot point is the existing validator schema, so the existing Knox/Van-Dine checker grades V8 output unchanged (libs/yemaya/agents/src/quality-assurance/mystery-fairness-validator.ts:508):

ts
interface MysterySession {
  // existing — DO NOT redefine; import it
  clues: Map<ClueId, Clue>; // Clue{ type, visibility, importance,
  //   introducedAt, pointsTo[], eliminates[],
  //   isRedHerring, redHerringFairness }
  solutions: Map<SolutionId, Solution>; // Solution{ culprit, method, motive,
  //   requiredClues[], deductionPath[] }
  characters: Map<string, MysteryCharacter>;
  timeline: StoryTimeline;
  config: MysteryFairnessConfig;
}

Clew's job is to produce a MysterySession; today only validators consume one (gap§1A). The Solution.deductionPath IS Ariadne's thread (the Clew).

3.4 Compile target (Stage 8) — EXISTING V5 structs + manifest#

Daedalus emits exactly what V5's human Case Author tool emits, so cases drop into the shipping game (gap§1B):

  • FV5MindPalaceEvidenceNode (V5MindPalaceTypes.h:33) ← each Clue
  • FV5MindPalaceDeductionEdge (:72) ← each deductionPath step (sets Kind=Authored-equivalent Generated, Confidence, bCrossEra)
  • FV5MindPalaceAccusationOutcome (:117) ← culprit + each plausible-wrong accusation (Rating, OutcomeBranch)
  • FV5ColdCasePackDefinition (V5DetectiveColdCasesTypes.h:17) ← the pack header
  • cold_cases_manifest.json (schemaVersion:1, packs[].mindPalace.{evidenceNodeIds[],deductionPairIds[]}) validated by V5/tools/cold-cases/validate-cold-cases.py — V8 adds a generatedBy, seed, provenanceC2PA, and assetManifestId field (schemaVersion bump to 2, backward-compatible).

4. Subsystem designs#

4.1 Clew — Generative Case Engine (libs/yemaya/case-engine)#

Stage 1 (ground truth, solve-first). A Truth-Weaver CreativeAgent + symbolic builder. Procedure (EXAG, sota§1):

  1. Pick victim/culprit/means/motive/opportunity from the canon slice (Palimpsest) under CaseSpec constraints. LLM proposes a dramatically interesting configuration; the builder commits it as GroundTruthFacts.
  2. Generate every character's timeline; run conflict detection (no person in two places at once; culprit present at scene in the window).
  3. Emit constraints: ConstraintClause[] — the CSP/ASP encoding where the culprit variable is the unknown.

Stage 2 (clue derivation, backward). A Clue-Smith agent + derivation pass:

  1. For each GroundTruthFact that distinguishes the culprit, derive one or more Clues (physical/forensic/testimony/timeline-inconsistency/relationship), each with pointsTo[]/eliminates[] set to solution variables — the clue inventory tied to solution variables (sota§1).
  2. Generate red herrings: each must be fairly refutable — there must exist an available clue that eliminates it (redHerringFairness). Uniqueness enforcement = generate contradictory evidence that rules out every non-culprit.
  3. Set visibility/introducedAt to stage revelation (fair gradual disclosure).
  4. Assemble the MysterySession IR (§3.3).

Implements CreativeAgent base (base-creative.ts:140), uses llmProvider.complete(); structured output validated against the IR schema.

4.2 Minos — Solvability & Fair-Play Verifier (libs/yemaya/case-verifier)#

The gate. Three checks, all must pass:

  1. Formal uniqueness (CSP/ASP). Compile MysterySession + CaseGroundTruth.constraints into a constraint program (use clingo/ASP or a TS CSP lib via a sidecar) and prove: with only player-available clues (visibility ≠ withheld), the culprit is the only satisfying model. If a second suspect satisfies → fail (under-constrained). If zero satisfy → fail (over-constrained/unsolvable). (sota§1, AAAI-2007 unique-solution guarantee.)
  2. Deductive completeness. Every step in Solution.deductionPath is supported by clues introduced before it (no forward references; no external knowledge).
  3. Fair-play. Run the existing analyzeFairness(sessionId) (Knox/Van-Dine, mystery-fairness-validator.ts:1825) and investigation-mechanic-balance-analyzer. Require rating ∈ {exemplary, fair} and zero broken/unfair violations.

Repair loop: on failure, return the specific violation set to Clew, which regenerates only the offending clues/herrings (critique-revise, sota§2). Bounded retries (default 3) then escalate to HITL (yemaya hitl).

4.3 Palimpsest — Canon & Continuity Graph (libs/yemaya/canon-graph)#

  • A knowledge graph (people, places, factions, timelines, prior-case outcomes, open threads) persisted in Postgres + pgvector (already in docker infra) with a graph overlay (Neo4j optional profile already exists).
  • SCORE-style dynamic state tracking + hierarchical prior-case summaries + hybrid (TF-IDF + embedding) retrieval (sota§3).
  • Reuses/absorbs the existing libs/yemaya/canon-enforcement lib.
  • Every stage that generates reads a retrieved canon context; Stage 11 writes the case outcome back (the world remembers — features§"3").

4.4 Anansesɛm — Writers' Room (libs/yemaya/case-writers-room)#

The narrative realization DAG, built on yemaya WorkflowBuilder/StateGraph: Showrunner → {StoryDirector, CharacterWriter, DialogueWriter, Cinematographer, SoundDesigner} → Integrator. Realizes the verified skeleton into: scene descriptions, interrogation dialogue trees (with V5's 12 facial-tell beats), partner banter, briefings, era voice. All grounded by the Palimpsest canon graph (@yemaya/canon-graph — hybrid TF-IDF + feature-hashing-embedding retrieval over the canon graph's nodes, with 1-hop sub-graph continuity-constraint grounding; the "graph-RAG" of sota§3) so it cannot contradict canon. Reuses the existing CreativeAgent specialists (gap§1C); promotes the integration adapters from type-stubs to live calls.

4.5 Loom — Asset Realization Fabric (libs/yemaya/case-assets)#

Per-case asset plan → Isis jobs via IsisClient.submitBatch() / submitAndWait() (libs/isis/client): | Asset | Provider (existing) | Bind to | |---|---|---| | Crime-scene env + 3D props | Hunyuan3D/Meshy (3d) | FSoftObjectPath in evidence nodes / level | | Suspect portraits, MetaHuman params | Stability/Flux (image) | character cards | | Document/photo evidence | Stability (image) | FV5MindPalaceEvidenceNode.Image | | Case music + stings | Suno (music) | pack audio | | Full VO for every line | ElevenLabs (tts) | VoiceLineCount/VoiceOverMinutes | | Flashback/CCTV clips (opt) | LTX (video) | cutscene refs | Retrieve-then-generate (sota§2, RPGAgent): reuse cached/library assets via semantic tags before minting new ones (cost control). Results → asset manifest (URLs/ids from JobOutput.files[].url).

4.6 Ori-Detective — Living Suspects (libs/yemaya/case-suspects + V6 bridge)#

Each suspect gets a V6 Ori (memory stream / reflection / planning, sota§2 Generative Agents) seeded with the case ground truth (what they know, hide, lie about). At runtime, Hathor DialogueGenerator.generateResponse() + NVIDIA ACE/Inworld drive live, lip-synced interrogation (sota§4). The Ori enforces alibi consistency and fair lying (every lie catchable by a clue the game gives). Innocents and the culprit share the same machinery — only their ground-truth facts differ.

4.7 Daedalus — Case Compiler & Runtime Bridge (apps/v8/daedalus + UE plugin)#

  • Compiler (Stage 8): MysterySession + asset manifest → FV5* structs → cold_cases_manifest.json pack; runs validate-cold-cases.py as a build gate.
  • Runtime relay (Stage 9): new BFF routes (/v8/cases/*) the UE5 client calls to request/stream cases on demand. The client never holds provider keys (sota§4). A thin UE5 plugin (V8/ue/Plugins/V8_Ariadne_CaseClient) following the UnrealGenAISupport async-delegate pattern fetches packs + asset bundles and registers them with the existing cold-cases plugin.
  • Live interrogation transport: ACE/Inworld session brokering, audio + viseme stream to MetaHuman (Audio2Face/NeuroSync).

4.8 Theseus — Automated Playtester & Eval (libs/yemaya/case-eval)#

  • Solver agent: an autonomous LLM detective (sota§1, Digital Detectives) that plays the compiled case against V5's data model — collects clues, attempts deductions on the actual FV5MindPalaceDeductionEdge set, makes an accusation. Must reach the intended culprit via a Brilliant-eligible path. This is the end-to-end solvability proof in game data, not just the IR.
  • Judge panel: LLM-as-judge 8-dimension rubric (coherence, surprise, fairness-feel, pacing, character, prose, voice-fit, difficulty-accuracy), PCA-aggregated (sota§5). Threshold-gated.
  • Difficulty calibration: vary solver "skill" to estimate solve-rate; map to CaseSpec.difficulty; feed back to Oracle's player model.

4.9 Oracle — Open-World Case Director (libs/yemaya/case-director)#

Drama/experience manager (sota§1 drama mgr): maintains a player model (skill, pacing, preferences, open canon threads), decides which minted cases surface on the Bureau Case Board, which seed as ambient open-world mysteries, and when. Owns the mint-ahead queue (keep N cases warm per player/cell) within budget.


5. Cross-cutting concerns (Stage 11)#

  • Budget/cost: every stage reports tokens/job-cost to yemaya budget-management; Oracle throttles mint rate; Loom prefers retrieve-over-mint. Hard ceiling per case; over-budget → degrade (fewer bespoke assets) not fail.
  • HITL: yemaya hitl review queue for: repair-loop escalations, commissioned cases, flagged content. Reviewers see the ground truth + Minos report.
  • Provenance: every generated asset C2PA-signed (V3 C2PA_EVERY_EXPORT.md); manifest records seed, model versions, provider job ids.
  • Safety: V7 Sekhmet scans all generated text/art/audio before publish (CSAM/abuse/defamation/IP); Oracle won't surface unscanned cases.
  • Determinism/replay: (seed, model-versions, canon-snapshot-hash) fully determines a case; the pipeline journals each stage for audit and reproduction.
  • Multiplayer canon: co-op cases share one canon snapshot; outcome write-back is leader-arbitrated through V5 online services.
  • Localization/accessibility: VO + text generated per locale (extend V6/V7 loc); accessibility pass (captions, colorblind-safe evidence cues, difficulty assists) per V6 accessibility.
  • Telemetry/evals: case solve-rates, accusation-rating distributions, abandon-points stream to Maat-style dashboards; adversarial case-quality eval gates run in CI (extend V7 ADVERSARIAL_EVAL_GATES.md).

6. Deployment shape#

  • New app apps/v8/loom-service (the orchestrator BFF; TS/Nest, reuses yemaya agents) + apps/v8/daedalus-compiler (case→V5 build) + a clingo/ASP sidecar for Minos.
  • New libs under libs/yemaya/: case-engine (Clew), case-verifier (Minos), canon-graph (Palimpsest), case-writers-room (Anansesɛm), case-assets (Loom), case-suspects (Ori-Detective), case-eval (Theseus), case-director (Oracle), case-contracts (shared types + the V5 compile target schema).
  • New UE plugin V8/ue/Plugins/V8_Ariadne_CaseClient (runtime fetch + ACE/Inworld interrogation), depending only on V5MindPalace/V5DetectiveColdCases modules.
  • Infra: Postgres+pgvector (have), Redis event bus (have), object store for generated assets (MinIO have / S3 prod), optional Neo4j (have, profile).
  • Models: Claude/GPT for agents (have via isis/lilith providers); ACE/Inworld for runtime NPCs (new creds: OSHUN_INWORLD_* / OSHUN_NVIDIA_ACE_*).

All of section 6 is enumerated as tasks in V8_TODOS.md.