# KAIVERSE WORLD-RENDER PLAN

**Status:** Investigation + design (READ-ONLY pass — no code changed).
**Author context:** produced against real files under `C:\KAI` at Codex **v9.10.130**.
**Owner ask:** make the KAIVERSE a *real rendered world* — textured planets the agents actually
move through — grounded in the owner's **own** texture assets and in **real** chat/Codex
content, not hallucinated. Rendering must be performant (distance-based LOD, crisp textures,
camera effects). Isolated from Leo's fragile audio path — this is dashboard/rendering + data.

---

## TL;DR — the three headline findings

1. **The textures exist and are already wired.** They live in **`C:\KAI\textures\`** — a full set
   of 2048×1024 equirectangular planet maps (albedo + normal + height + cloud) keyed by agent
   name, with 4K originals in `_orig_4k\`, plus ground PBR sets in `textures\ground\`. They are
   real NASA-derived maps from Solar System Scope (CC BY 4.0), credited in `textures\CREDITS.txt`.
   `kaiverse.js` **already loads them** onto each agent body (sRGB + anisotropy + normal + height +
   clouds). So "planets aren't rendered" is not quite the situation — **the agent-planets ARE
   textured and drawn today.**

2. **The gap is not rendering — it's the WORLD MODEL and MOVEMENT.** `shared/kaiverse-world.mjs`
   defines 6 named worlds with `moveAgent`/`residents`, but it has **zero importers** — it is a
   finished place-model that nothing renders or drives. And each agent's spatial `position {x,y,z}`
   in `simulation.mjs` is **dead — permanently `0,0,0`**; only a coarse `location` *string* updates
   (from the clock). So when Leo "moves," nothing on the map moves because (a) the worlds aren't
   drawn and (b) there is no live position feeding the renderer.

3. **Grounding data is real and queryable.** `transcripts.db` (24.7 MB) exposes an FTS5 table
   `transcript_fts(speaker, user_id, content, context, channel_id, timestamp)` — every real thing
   said in chat, full-text searchable. Plus `The KAI Codex.md`. A planet can be populated with real
   quotes by a **single deterministic rule** (e.g. `speaker = <agent>` or `channel_id = <world>`) —
   no fabrication needed.

**So the realistic v1 is: wire the existing 6-world model + a real agent position onto the
already-textured planet renderer, and hang real transcript/Codex lines off each body.** Full
"perceptual AI generation" of worlds is a much larger, separate effort (scope note at the end).

---

## ASSET INVENTORY (the load-bearing finding)

### Primary: `C:\KAI\textures\` — planet surface maps (THE ones to use)

Per-planet equirectangular set, one per agent name. Verified dimensions:

| Layer | File pattern | Size | Format | Notes |
|---|---|---|---|---|
| Albedo / color | `<name>.jpg` | 2048×1024 | sRGB JPG | equirectangular (2:1) |
| Normal | `<name>_normal.jpg` | 2048×1024 | JPG | GL-convention relief |
| Height / displacement | `<name>_height.jpg` | 2048×1024 | JPG | drives GPU displacement |
| Clouds (alpha) | `<name>_clouds.png` | 1024×512 | PNG w/ alpha | only some planets |
| 4K originals | `_orig_4k\<name>.jpg`, `_orig_4k\<name>_normal.jpg` | 4096×2048 | JPG | master source for a hi-LOD tier |
| Pre-boost | `_preboost\<name>.jpg` | (subset) | JPG | pre-contrast versions |

**Planet ↔ agent ↔ body mapping** (from `textures\CREDITS.txt`, authoritative):

| Texture name | Real body | KAIVERSE agent |
|---|---|---|
| `default` | Earth | (Oracle / home / fallback) |
| `kai` | Jupiter | KAI (core intelligence) |
| `leo` | Mars | Leo |
| `gemini` | Venus | Gemini |
| `claudey` | Neptune | Claudey |
| `x` | Moon | X |
| `groq` | Uranus | Groq |
| `analyst` | Mercury | Analyst |
| `researcher` | Makemake | Researcher |
| `kaicoder` | Ceres | Kai Coder |

Names present: `analyst, claudey, default, gemini, groq, kai, kaicoder, leo, researcher, x`
(10 planets). Clouds exist for: claudey, default, gemini, groq, kaicoder, leo.
**License:** Solar System Scope, CC BY 4.0 — attribution string is in `CREDITS.txt`; keep it
surfaced somewhere in the UI/credits.

### Secondary: `C:\KAI\textures\ground\` — surface/terrain PBR (for landing/close LOD)

`ground037`, `ground054`, `rock020`, `snow004` — each with `_diffuse.jpg`, `_disp.jpg`,
`_nor_gl.jpg` at 1024×1024. These are the tileable materials for a walk-on / descent surface,
not planet-from-orbit maps.

### Other image locations (context, mostly NOT planet art)

- `C:\KAI\kaiverse_assets\ground\` — duplicate ground set (Ground029/037, Rock023, single PNG each). Redundant with `textures\ground\`.
- `C:\KAI\oracle\img\` — 9 **2D bot avatars** (`kai.png`, `leo.png`, …) for the dashboard UI, not sphere maps.
- `C:\KAI\kaiverse_app\` — a **separate/older copy** of `kaiverse.js` + `kaiverse-graphics.js` + `image1.png`, `image 2.png`. Parallel app, not the live dashboard renderer. Don't confuse with the root files.
- `C:\KAI\kai-icon.png` — app icon.
- Everything under `bitnet/`, `BitNet-main/`, `OpenJarvis-main/`, `hyperprobe-main/`, `logs/rf_camera/`, `node_modules/` — third-party/log noise, **not KAIVERSE art.**

**No dedicated skybox / starfield image asset was found.** The current sky is procedural
(shaders in `kaiverse.js` / `kaiverse-graphics.js`). If the owner wants a real skybox/HDRI, that
is a *new* asset to source — flagged as an OWNER DECISION below.

---

## WHAT THE KAIVERSE RENDERS TODAY

**Tech:** Three.js **r128** (CDN) + postprocessing (EffectComposer, UnrealBloom, SSAO, shader
passes — all r128 example modules from unpkg). Rendered into `<canvas id="kv-canvas">` in
`oracle.html` (~line 1809). The 3D code lives in **`C:\KAI\kaiverse.js`** (~348 KB, ~5500 lines);
graphics/shaders in `kaiverse-graphics.js` (~9 KB).

**Serving (important for asset paths):** `tools/oracle-discord/command-center-server.mjs`
(the :3001 dashboard server) serves:
- `/` → `c:\KAI\oracle.html` (line 4458)
- `/kaiverse.js`, `/kaiverse-graphics.js`, `/kaiverse_worker.js`, `/three-gltfloader-r128.js`,
  `/oracle-kv-mobile.js/.css` → allowlisted from `C:\KAI\` root (line ~4409)
- `/textures/<file>` → `C:\KAI\textures\<file>` (line ~4392), content-types png/webp/jpeg
- `/kaiverse-wasm/pkg/…` → WASM (line ~4429)

> ⚠️ **Serving gotcha (Phase A dependency):** the `/textures/` handler *sanitizes the name with*
> `replace(/[^a-zA-Z0-9_.-]/g,'')`, which **strips `/`**. So `/textures/ground/xxx.jpg` and
> `/textures/_orig_4k/xxx.jpg` collapse to `groundxxx.jpg` / `_orig_4kxxx.jpg` and **won't
> resolve.** Subfolder textures are currently *not servable*. Any plan that uses the 4K masters or
> ground PBR needs either a flat copy in `textures\` or a one-line server change to allow a single
> safe subpath. (Server change = restart via `Start-Dashboard.ps1`.)

**Scene graph (built in `nsBuildGraph`, `kaiverse.js` ~line 185–290):**
- **CORE** — glowing sun at origin (`id:'core'`, line 211), the KAI/Oracle lattice root.
- **10 AGENT bodies** — the roster (`AGENTS`) placed on a golden-ratio ecliptic disc orbiting the
  core: `baseR = (150000 + i*180000) * SP`, gentle inclination, slow Kepler-ish orbits
  (line ~216–231). These are the "planets."
- **ENGINE** body (Rust core), **PROVIDER** bodies as distant stars, a **CHANNELS** body.
- **`cosmosPlanets`** — rare *procedural* full-mesh worlds scattered far out (line ~870 / ~1543),
  independent of the texture files.
- **First-person flight camera** (`nsUpdateCamera`, WASD + mouse-look + scroll throttle) — **do not
  touch its movement math** (hard rule; a chase-cam rewrite broke it once).

**Texturing (already implemented, `kaiverse.js` ~line 2663–2681):** for every body of kind
`bot`/`core`/`engine`, it derives `tname = name.toLowerCase().replace(/[^a-z0-9]+/g,'')`
("Kai Coder" → `kaicoder`) and `TextureLoader.load`s:
`/textures/<tname>.jpg` (albedo, `sRGBEncoding`, `anisotropy = maxAnisotropy`), `_normal.jpg`
(→ `material.normalMap`), `_height.jpg` (cached for displacement), `_clouds.png` (cached for a
cloud shell). Falls back silently to procedural if a file is missing.

**Existing LOD / perf machinery (reuse it, don't reinvent):**
- `lodReg()` / `nsUpdateFieldLOD()` (line ~1950–2051) — opacity-fade streaming for far fields.
- `nsUpdateBodyLOD()` (line ~3704) — halo-vs-body read by distance.
- "PLANET DESCENT LOD" (line ~3762) and shader `lodScale` (line ~4056) — detail ramps on approach.
- Renderer already sets `sRGBEncoding` output + ACES tone mapping + exposure (line ~494).

**Bottom line:** the renderer draws textured agent-planets with orbits, atmosphere, bloom, and a
descent-LOD scaffold **today**. What it does **not** do: render the 6 named *worlds*, reflect a
*real* agent position, or show *grounded content* on a body.

---

## THE WORLD MODEL — `shared/kaiverse-world.mjs`

Six templates (`WORLD_TEMPLATES`, line 6–43). All metadata is real and already written:

| World (id/name) | environment | gravity | aesthetic (abridged) | features |
|---|---|---|---|---|
| **Nexus Prime** | Digital Core | 1.0 | Sleek futuristic city, floating platforms, data streams. KAI's throne/core. | Lattice Core, Data Streams, Command Center |
| **Terra Familiar** | Natural | 1.0 | Earth-like — nature, houses, streets. Home. | Houses, Parks, Streets |
| **Neon Grid** | Cyberpunk | 1.2 | Tron/cyberpunk — glowing circuits, digital rain, grid floors. | Data Grid, Industrial Forges, Neon Towers |
| **Aether Wilds** | Alien | 0.8 | Crystalline formations, floating islands, bioluminescent flora. | Floating Islands, Crystals, Bioluminescence |
| **The Forge** | Volcanic/Industrial | 1.5 | Rocky, industrial, volcanic — heavy computation. | Volcanoes, Anvils, Lava flows |
| **Void Archive** | Space/Library | 0.5 | Vast library floating in space — knowledge/memories. | Floating Bookshelves, Constellations, Memory Orbs |

- `Kaiverse` class: `worlds` Map; `createWorld`, `getWorld`, `getAgentWorld(name)` (line 123),
  `moveAgent(name, toWorldId)` (line 132), `residents[]` per world.
- Persisted to `state/kaiverse/universe.json` (`save`/`load`). Default init creates 3
  (Nexus Prime, Terra Familiar, Neon Grid).
- Portal economics: `KaiverseLaws.travelCost` (fixed 5.0 energy to jump).
- **Zero importers** — confirmed in `LEO-EMBODIMENT-PLAN.md` (line 49): nothing in `shared/`,
  `bots/`, or `*.mjs` imports it. It is unwired.

**Reconciliation the owner must decide (see OWNER DECISIONS):** there are *two* "planet" concepts
that don't currently line up —
- **Agent-planets** (10, texture-backed: kai/leo/gemini… = Jupiter/Mars/Venus…), which is what the
  renderer draws now, and
- **Named worlds** (6, theme-backed: Nexus Prime, The Forge…), which is the movement/residency
  model.
The textures are keyed to *agents*, not to *worlds*. So we either (a) render the **6 worlds** as
planets and assign each a texture, or (b) keep rendering the **10 agent-planets** and treat the 6
worlds as *districts/regions on/near them*. This choice drives Phases B–D.

---

## AGENT POSITION — how "real movement" is (and isn't) available

- Leo owns a live `sim = new AgentSimulation(...)` (`bots/leo.mjs:418`), from
  `shared/simulation.mjs`.
- `sim.state.location` — a **string** label, updated by `tick()` **from clock hours only**:
  `"Offline" | "The Lattice" | "Industrial_Core" | "Social_Lattice"` (simulation.mjs ~line 352–404).
- `sim.state.position {x,y,z}` and `rotation` — **present but dead: initialized `0,0,0` and never
  reassigned** (confirmed in `LEO-EMBODIMENT-PLAN.md:31`). No spatial coordinate is produced today.
- The named-place model (`kaiverse-world.mjs` `getAgentWorld`/`moveAgent`) is the *intended* source
  of "which world is this agent in," but nothing calls it.

**Consequence:** to make movement *real*, we need a single authoritative "where is agent X"
signal. The cheapest honest version is **named-world residency** (`getAgentWorld`) surfaced to the
renderer — *not* a fabricated `{x,y,z}`. A true spatial position is a later upgrade. This matches
the embodiment plan's own recommendation (line 149): "build the minimal version first (named
locations + a home), defer the spatial map."

---

## GROUNDING DATA — real content, queryable, no fabrication

### Source 1 — `tools/oracle-discord/transcripts.db` (24.7 MB)

Schema (from `shared/transcript-memory.mjs`):
- **`transcript_fts`** (FTS5 virtual table): `speaker`, `user_id`, `content`, `context`,
  `channel_id`, `timestamp`. Full-text searchable — this is *every real message*.
- **`message_meta`**: `fts_rowid`, `channel_id`, `timestamp`, `phi_g`, `coherence`,
  `contradiction`, `learned_by_kai` — per-message cognition scores (use to rank "best"/"most
  interesting" lines).
- **`entity_facts`**: extracted subject/relation facts (does/doesnt/says/fact).
- Already exposed over HTTP: `GET /api/transcripts?channel=<id|all>&limit=200` (command-center-server).

### Source 2 — `The KAI Codex.md` (v9.10.130)

Canonical manual. Structured as a masthead table + `## CHANGELOG - vX.Y.Z` blocks + named plan
sections. Grounding = pull real CHANGELOG entries / section text (by heading), each traceable to a
line/version.

### The association rule (deterministic, auditable)

Every surfaced item must trace to a **real row/line**. Two clean rules, pick per the render model:

- **Agent-planet model:** `SELECT content, timestamp, channel_id FROM transcript_fts WHERE
  speaker = '<AgentName>' ORDER BY timestamp DESC` → real things *that agent* actually said →
  shown on that agent's planet. Optionally rank by joining `message_meta.phi_g/coherence`.
- **Named-world model:** map each world → a channel_id (or a topic keyword set), then
  `… WHERE channel_id = '<world channel>'` or `… WHERE transcript_fts MATCH '<world topics>'`.
- **Codex overlay:** attach Codex CHANGELOG/section lines whose heading matches the
  agent/world/topic. Store the source (version + heading, or fts rowid + timestamp) alongside each
  item so any card can show "source: transcript 2026-06-30 #channel" or "source: Codex v9.10.x".

No item is generated — each is a stored row or a Codex line, with its provenance carried through.

---

# PHASED BUILD PLAN

Each phase: real-file anchor → proposed change + where → perf/memory → risk → dependencies.
All edits are **surgical and flag-gated** per the project hard rules. **Nothing here touches
`nsUpdateCamera` movement or Leo's audio path.**

## Phase A — ASSET PIPELINE (make the real textures load crisply & cheaply)

**Real-file anchor:** `C:\KAI\textures\` (+ `_orig_4k\`, `ground\`); loader at `kaiverse.js`
~2663–2681; server texture route `command-center-server.mjs` ~4392.

**Proposed changes / where:**
1. **Texture manifest** — add a small map (top of `kaiverse.js`, near the roster) of
   `agent → { albedo, normal, height, clouds }` filenames, driven by `CREDITS.txt`. Makes the
   asset↔body binding explicit instead of string-derived (`tname`), and lets `default`/Earth be
   assigned to Oracle/home deliberately.
2. **Crisp filtering** (extend the existing loader callbacks, don't rewrite): set
   `texture.generateMipmaps = true`, `minFilter = LinearMipmapLinearFilter`,
   `magFilter = LinearFilter`, keep `anisotropy = renderer.capabilities.getMaxAnisotropy()`,
   `wrapS = RepeatWrapping` (equirect longitude wrap), `colorSpace/encoding = sRGB` for albedo only
   (normals/height stay linear). The 2048×1024 maps are power-of-two → mipmaps are free and fix
   shimmering at distance. (Anisotropy + sRGB are already set; this adds the mip chain + correct
   linear space for normal/height.)
3. **LOD texture tiers by camera distance** — 3 tiers: far = no surface map (existing halo/impostor
   from `nsUpdateBodyLOD`), mid = 2048 working set (current `textures\`), near/descent = 4K master
   from `_orig_4k\`. Load the 4K tier **lazily** only when the body enters the descent band
   (`nsUpdateFieldLOD`/descent-LOD already computes proximity), and **dispose** it on exit
   (`texture.dispose()`) to cap VRAM.
4. **Serving fix for masters** (dependency): either copy the needed `_orig_4k` files flat into
   `textures\` (no server change), or make a one-line allowance in the `/textures/` route for a
   single safe subpath. Prefer the flat copy for v1 (zero server risk).

**Perf/memory:** working set = 10 planets × (albedo+normal+height ≈ 3×~0.5 MB decoded to ~8–12 MB
GPU each mip-chained) → keep the **4K tier lazy** (only 1–2 loaded at once). Budget target: full
scene < ~256 MB texture VRAM. Frustum culling and draw-call reduction already exist for fields;
planets are few (≤10) so draw calls are not the bottleneck — **texture memory is**, hence the lazy
4K + dispose discipline. Clouds are a separate transparent shell (extra draw) — gate behind the
descent band too.

**Risk:** low–medium. Mip/filter tweaks are additive and reversible. The only server-adjacent risk
is the subpath serving change (mitigated by the flat-copy option).
**Depends on:** nothing. This is the foundation for B.

## Phase B — PLANET RENDERING (draw the worlds as textured planets)

**Real-file anchor:** `nsBuildGraph` node build `kaiverse.js` ~185–290; texture apply ~2663;
LOD `nsUpdateBodyLOD`/descent-LOD ~3704/3762; world data `kaiverse-world.mjs`.

**Two build options (OWNER DECISION drives which):**
- **B1 (smallest, recommended v1):** keep the **10 agent-planets** exactly as rendered, and simply
  make them read from the Phase-A manifest with proper LOD + a **selectable/labeled** identity so
  each is unmistakably "a place." Add per-planet name/aesthetic labels sourced from either the
  agent roster or, if using the world overlay, the matching `WORLD_TEMPLATES` entry. This ships a
  "real rendered world" with near-zero new geometry.
- **B2 (bigger):** render the **6 named worlds** as their own textured planets. Requires assigning
  each world a texture (worlds ≠ agent names, so pick from the 10 maps, e.g. Terra Familiar→
  `default`/Earth, The Forge→`kai`/Jupiter or a lava-leaning map, Void Archive→`x`/Moon, etc.) and
  giving each a stable orbital slot. Reuse the same `add()` + texture loader path — do **not** add a
  second renderer.

**Camera effects (reuse existing):** bloom/SSAO already present; add (flag-gated) a subtle
per-planet approach effect using the existing descent-LOD proximity value — atmosphere rim fade +
exposure lift on descent. **No changes to `nsUpdateCamera`.** A render-only 3rd-person ship layer is
allowed *only* via the existing `nsPlayerShipPre/Post` pattern if desired — out of scope for v1.

**Perf/memory:** ≤10 (B1) or +6 (B2) textured spheres; geometry is cheap. Displacement from
`_height` is GPU-side and already LOD-scaled by the shader `lodScale`. Keep displacement **off**
until the mid/near band. Reuse frustum culling; no new draw-call hotspots.

**Risk:** medium — this is *visual* work, which the hard rules say must be **eyeball-iterated with
the owner** (ship one knob, owner flies + screenshots, tune). Never blind-batch visual changes.
B2 adds the world↔texture assignment risk (arbitrary until owner picks).
**Depends on:** A (manifest + LOD tiers). Blocks D (a body must exist to move to).

## Phase C — GROUNDED CONTENT (real quotes/Codex lines on each planet)

**Real-file anchor:** `transcripts.db` (`transcript_fts`, `message_meta`); `The KAI Codex.md`;
existing HTTP `GET /api/transcripts` in `command-center-server.mjs`.

**Proposed changes / where:**
1. **Server:** add a read-only endpoint, e.g. `GET /api/kaiverse/planet-content?body=<agent|world>&limit=N`
   in `command-center-server.mjs`, that runs the association query (Phase-A rule) against
   `transcript_fts` (+ optional `message_meta` ranking by `phi_g`/`coherence`) and appends matching
   Codex lines. Returns `{ items: [{ text, source, timestamp }] }`. Read-only, cache like the
   existing `/api/transcripts` 6 s TTL. Restart via `Start-Dashboard.ps1`.
2. **Client:** on planet **hover/click** in `kaiverse.js` (there is already a hit-sphere + selection
   path), fetch that body's content and show real lines in the existing info panel/overlay. Each
   card shows its **provenance** (channel + date, or Codex version + heading).

**Perf/memory:** trivial — a handful of indexed FTS reads per selection, cached. No render cost.
**Risk:** low. The only correctness rule: **every card must carry a real source**; if a query
returns nothing, show "no grounded content yet," never a generated filler line.
**Depends on:** B (a selectable body) + the transcripts.db association rule. **Isolated from Leo's
audio path** — it only *reads* the DB Leo also writes; no shared runtime.

## Phase D — REAL MOVEMENT (reflect the agent's actual position)

**Real-file anchor:** `kaiverse-world.mjs` `moveAgent`/`getAgentWorld` (line 132/123);
`simulation.mjs` `state.location`/dead `position` (line ~202/352); `LEO-EMBODIMENT-PLAN.md`
(v9.10.129/130) — the sibling plan that already scopes wiring `sim` ↔ `kaiverse-world`.

**Proposed changes / where:**
1. **Single source of truth for "where":** wire `kaiverse-world.moveAgent`/`getAgentWorld` into the
   agent lifecycle so residency is real (this is exactly the LEO-EMBODIMENT-PLAN work — align with
   it, don't duplicate). Persisted already to `state/kaiverse/universe.json`.
2. **Expose it:** `GET /api/kaiverse/positions` in `command-center-server.mjs` → for each agent,
   `{ agent, worldId, locationLabel }` from `getAgentWorld` + `sim.state.location`. Read-only.
3. **Render the marker:** in `kaiverse.js`, poll that endpoint (reuse the existing vitals poll
   cadence) and place/animate each agent's **marker at the body it currently resides on/near** — a
   real, data-driven position. When residency changes, tween the marker between bodies so movement
   is *shown*, not claimed.
4. **Defer true spatial `{x,y,z}`** until the owner wants intra-world coordinates — per the
   embodiment plan's "minimal first" recommendation. v1 movement = which planet you're on.

**Perf/memory:** negligible — a small JSON poll + a tween. No new textures.
**Risk:** medium — depends on the embodiment wiring landing; if `moveAgent` isn't driven yet,
markers just reflect `sim.state.location` mapped to a body (still real, coarser).
**Depends on:** B (bodies to stand on), and coordinates with `LEO-EMBODIMENT-PLAN.md`. **Must not
touch Leo's audio/voice code** — only the sim's *state read* and the world model.

---

## KEY OWNER DECISIONS

1. **Which "planet" is the world?** Render the **10 agent-planets** (B1, smallest, already
   textured) or the **6 named worlds** (B2, needs world→texture assignments)? Or agent-planets
   *with* the 6 worlds as districts on them? — This single choice shapes B, C, D.
2. **How many planets to start with?** Recommend **start with the ~4 primary agents** (KAI, Leo,
   Gemini, Groq — the ones with public chat + clouds) to iterate the LOD/texture loop cheaply,
   then scale to all 10.
3. **Content association rule:** ground each planet **by speaker** (things *that agent* said) or
   **by channel/topic** (things said *about/in* that world)? Recommend **by speaker** for v1 — it's
   the most defensible and needs no channel↔world mapping.
4. **How much content per planet?** e.g. top 10 by recency, or top 10 by `phi_g`/coherence
   ("most coherent/important")? Recommend a small ranked set (10) with a "load more."
5. **3D globes vs stylized map?** Recommend **keep the existing 3D globes** (textures already fit
   them); a flat map would throw away the working renderer.
6. **Skybox:** procedural (current) is fine for v1. A real HDRI/skybox is a *new asset to source* —
   only if the owner wants it.
7. **Serving the 4K masters:** flat-copy into `textures\` (zero server risk) vs a one-line
   `/textures/` subpath allowance? Recommend **flat-copy** for v1.

---

## HONEST SCOPE NOTE

**Realistic v1 with existing assets (weeks, not months):** the planets are *already textured and
rendered*. v1 = (A) crisp mip/LOD texture loading from the real `textures\` set, (B) make the
bodies unmistakable labeled "places" with approach camera effects, (C) hang **real** transcript +
Codex lines off each via a read-only endpoint, (D) reflect **real residency** (which planet an
agent is on) so movement is *shown*. This uses only files that exist today and is fully isolated
from Leo's audio path.

**What v1 is NOT:** true intra-world spatial coordinates for every agent, walk-on planet surfaces
using the ground PBR, gas-giant band shaders / volumetric clouds you fly into (those are Tier
1.5–2 of the visual-overhaul goal doc and are eyeball-iterated separately), and — the big one —
**"perceptual AI generation"** of worlds (agents generating/altering their environment from
scratch). That last item is a substantially larger, separate track (new generation pipeline,
storage, and validation) and should not be conflated with "render the real textures I already
have." The owner's core ask — *a real place the agents move through, grounded in his own textures
and real words* — is achievable now by wiring what already exists.

---

## FILE ANCHOR INDEX (quick reference)

| Concern | File / path | Line(s) |
|---|---|---|
| Planet textures | `C:\KAI\textures\` (`<name>.jpg/_normal/_height/_clouds`, `_orig_4k\`, `ground\`, `CREDITS.txt`) | — |
| Renderer | `C:\KAI\kaiverse.js` (Three.js r128) | node build ~185–290; texture load ~2663–2681 |
| LOD machinery | `kaiverse.js` | `lodReg`/`nsUpdateFieldLOD` ~1950–2051; `nsUpdateBodyLOD` ~3704; descent-LOD ~3762; shader `lodScale` ~4056 |
| Canvas / three includes | `C:\KAI\oracle.html` | `<canvas id="kv-canvas">` ~1809; three r128 CDN ~2309 |
| Static serving | `tools/oracle-discord/command-center-server.mjs` | `/textures/` ~4392; `/kaiverse.js` allowlist ~4409; dashboard ~4458 |
| World model | `tools/oracle-discord/shared/kaiverse-world.mjs` | templates 6–43; `moveAgent` 132; `getAgentWorld` 123 |
| Agent sim / position | `tools/oracle-discord/shared/simulation.mjs` | `position` ~202 (dead); `location` tick ~343–404 |
| Leo sim instance | `tools/oracle-discord/bots/leo.mjs` | 418 |
| Transcripts DB | `tools/oracle-discord/transcripts.db` (schema in `shared/transcript-memory.mjs`) | `transcript_fts` 36–43; `message_meta` 64; `entity_facts` 83 |
| Codex | `C:\KAI\The KAI Codex.md` | masthead (v9.10.130) + CHANGELOG blocks |
| Sibling plan | `C:\KAI\LEO-EMBODIMENT-PLAN.md` | sim↔world wiring (Phase D alignment) |
