Grand Diomande Research · Full HTML Reader

Mac4 Codex Handoff — 2026-04-26 night

You're picking up LUME on Mac4 in steady-state product-build mode. The Saturday demo is past. The current live state is a Duncan-lite proof: real Femto raw depth + audio sidecar + shader dissolve + 26K-particle code-driven overlay + purple grid tunnel, all running together in Unity right now. See `lume-mac4-live-demo-state.md` in `[home-path]` for that snapshot.

Embodied Trajectory Systems technical note backlog reference score 22 .md

Full Public Reader

# Mac4 Codex Handoff — 2026-04-26 night
## Goal: turn the live demo into a Duncan-modes picker app

You're picking up LUME on Mac4 in steady-state product-build mode. The Saturday demo
is past. The current live state is a Duncan-lite proof: real Femto raw depth + audio
sidecar + shader dissolve + 26K-particle code-driven overlay + purple grid tunnel,
all running together in Unity right now. See `lume-mac4-live-demo-state.md` in
`[home-path]` for that snapshot.

This handoff is about the next jump: making the running application feel like the
operator console Duncan teases in his E588 / E588+ reels — where a hidden
backtick-toggled panel lets you flip through named visual modes ("Maximalism",
"Dissolving Clones", "Frozen Sim Buffers", "Kelp Audio Reaction", "Pinscreen",
"Logo Testing", etc.) without touching the Unity Editor. We have everything we
need on disk to do this. Most of the foundation is already shipped. The work is
fill-in-the-blanks plus a real UI pass.

---

What the user actually wants

A runtime picker UX inside the running LUME app. Not a Unity Editor inspector
list. A real polished panel that:

- Lists Duncan's named visual modes by name (Maximalism, Kelp, Frozen Forms 1–9,
Logo Testing 1–5, Motion Sparks 1–4, Pinscreen, Depth Spawn, Wobbly Lads,
Blobby Guys, etc.).
- Shows the audio-coupling family for each (4-band EQ rules, position-not-force,
EQ before auto-gain — see playbook).
- Lets the operator switch instantly during a live session.
- Optionally auto-cycles on a BPM divisor (already wired in `LumeVfxEditor`).
- Persists last selection per install (use the `LumeCalibrationPanel` JSON
pattern at `Application.persistentDataPath/lume-calibration.json` — extend it
or add a sibling `lume-picker.json`).

Think of it as the difference between "an Editor-time list of ScriptableObjects"
and "a runtime control surface a human flips through during a show." The latter
is what we want. Duncan calls his version the "VFX Editor" + a separate
"Settings" menu — we can collapse to one for now.

---

What's already on disk (DO NOT REBUILD)

Preset infrastructure (scaffolded, empty)

`Assets/Scripts/Vfx/`:
- `LumeVfxPreset.cs` — particle params (intensity, density, count 100–200000,
gravity, initialVelocity, lifetime, spawnRate, baseColor, particleTex,
materialOverride). `[CreateAssetMenu(menuName = "LUME/VFX Preset")]`.
- `LumeAvatarPreset.cs`
- `LumeLightingPreset.cs`
- `LumeEnvironmentPreset.cs`
- `LumeFluidSimPreset.cs`

All 5 are `ScriptableObject` with `[CreateAssetMenu]`. Editor-time you can
right-click → Create → LUME → ... → fills in fields. Read each one before
adding fields — they may already cover everything Duncan named in his playbook.

Editor / operator panel (built, empty)

`Assets/Scripts/Vfx/LumeVfxEditor.cs`:
- `[DisallowMultipleComponent] MonoBehaviour`.
- Procedural Canvas built on Awake, hidden by default, backtick toggle.
- 6 `Dropdown` slots: vfx01, vfx02, avatar, lighting, environment, fluidSim.
- AutoCycle toggle that switches VFX01 every `autoCycleBpmDivisor` bars when
`LumeRuntime.currentBpm > 0`.
- `pointRenderer` MaterialPropertyBlock target for `_BaseColor`.
- The 5 preset Lists are public + serialized — populate via Inspector
drag-drop OR via `Resources.LoadAll` at Awake.

This is good Wave-1 scaffolding. The procedural Canvas is functional but UGLY.
It is explicitly labeled as "Wave 2 GUI authoring can replace it with a
hand-designed prefab if desired." That moment is now.

Scene patch sidecar

`Assets/Scenes/LumeMain.duncan-track4.scene-patch.md` — read this for the
intended scene topology around the editor.

Duncan corpus

`Reference/Duncan/`:
- `INDEX.md` — 83-row table, newest first, with each reel's named mode in the
caption column ("Wide FoV vs Narrow FoV", "Maximalism", "Dissolving Clones",
"Slime Freeze", "Blobby Guys", "Combo Test", "Frozen Sim Buffers 1-5",
"Kelp 1-5", "Frozen Forms 1-9", "Logo Testing 1-5", "Motion Sparks 1-4",
"Depth Particles Fluid Sim Presets", etc.).
- `reels/` — 248 files (.mp4 symlinks + .json sidecars + .txt captions). Zero
disk cost (symlinks).
- `analyses/` — 69 Gemini visual analysis markdown files (`E###-<shortcode>.md`
format). These are your ground truth for concrete preset values: each one
describes color palette, particle behavior, audio coupling, motion language.

Plus the playbook synthesis already lives in memory:
- `[home-path]` (v2 master)
- `lume-duncan-playbook-chunk-{DV-DU,DT-DS,DR-DQ}.md` (3 verbatim source chunks)
- `DUNCAN-GAP-ANALYSIS.md` (16-row Duncan-vs-LUME with status + Wave 5 priority)

The v2 playbook explicitly lists:
- 9 VFX Editor slots
- 15 enums
- 6 named FluidSim presets
- 4-EQ-band audio rules
- Inspector dump (IOR=1.33, Translucency=0.003, Emissions Scale 0–0.05)
- HOLOVIS commercial-install brand context

---

What's actually missing — the work

Stream A: content extraction (preset corpus)

For each named Duncan mode in `Reference/Duncan/INDEX.md` that has a matching
`analyses/E###-*.md` file:

1. Read the analysis. Extract: dominant color palette, particle count
estimate, motion family (drift/swarm/strip/mesh/blob/pinscreen),
audio-reactive channel mapping (which EQ band drives what), lifetime feel
(snappy / floaty / frozen), and any explicit Inspector params Duncan
showed.
2. Generate a `LumeVfxPreset` `.asset` file at
`Assets/Resources/LumePresets/Vfx/<E###-<slug>>.asset` with concrete numeric
values. Slug = lowercase-kebab of the named mode (e.g. `e598-dissolving-clones`,
`e549-kelp-feet-back-on-ground`, `e544-blocky-pinscreen`).
3. Group by family — when a mode is part of a series (Frozen Forms 1–9, Logo
Testing 1–5, Kelp 1–5), emit the series as `LumeFluidSimPreset` /
`LumeEnvironmentPreset` / `LumeAvatarPreset` where appropriate. The
playbook's 6 named FluidSim presets and 15 enums tell you the right
bucketing.
4. Write a content manifest at `Assets/Resources/LumePresets/MANIFEST.md`
that lists every preset file with its source reel, family, and one-line
description. This is what the picker will display.

You do NOT need to be perfect or watch every reel — the analyses are good
enough. Where an analysis is missing (`— ` in the INDEX Analysis column),
fall back to the caption + the playbook chunks. Don't fabricate. If a mode
genuinely lacks data, mark it as `// TODO needs reel rewatch` in the
generated asset and move on.

Target: at least 25 concrete preset assets across the 5 families covering
the most-cited Duncan modes. The Wave-5 priority order from
`DUNCAN-GAP-ANALYSIS.md` is your sequencing guide:
1. impulse channel (already shipped — `LumeTransientForcePusher.cs`)
2. calibration UI (already shipped — `LumeCalibrationPanel.cs`)
3. fluid sim (NOT shipped — see Stream C below)
4. SuperHot motion-gate (already shipped — `LumeMotionGate.cs`)
5. marching cubes (NOT shipped)

Stream B: real picker UX (replace procedural Canvas)

Replace `LumeVfxEditor`'s procedural Canvas with a designed runtime panel.
Two acceptable paths — pick the one that lets you ship in this session:

Path 1 — IMGUI (fastest). Mirror `LumeCalibrationPanel.cs`'s pattern.
Bind to F1 (NOT backtick — backtick conflicts with Unity console). Show a
left-anchored panel with mode-family tabs (VFX / Avatar / Lighting /
Environment / FluidSim). Each tab is a vertical scroll list of mode names
+ tiny preview color swatch. Click → `SwitchVfx01` etc. Bottom row: "Auto-
cycle on/off", "BPM divisor: [4][8][16][32]", "Lock to current". This gets
you a real, polished operator surface in ~200 lines and zero prefabs.

Path 2 — uGUI prefab. Author a real prefab with TextMeshPro, custom
fonts (from `Packages` / Resources), per-family color theming, and a
search box. Save at `Assets/UI/LumeVfxPicker.prefab`. This is the
"production" path. Takes longer because Unity GUI authoring without
sitting in the Editor is painful, but doable in batchmode via
`PrefabUtility.SaveAsPrefabAsset` + procedural construction (look at how
`LumeBootstrapTunnelScene.cs` and `LumeVfxGraphBootstrap.cs` do code-only
scene/asset construction).

Either path: persist last selection per family to
`Application.persistentDataPath/lume-picker.json`. Load on enable, save
on disable + on selection change. Re-use the JSON helper pattern from
`LumeCalibrationPanel.cs` if it has one — if not, vanilla
`JsonUtility.ToJson` + `File.WriteAllText` is fine.

Hard requirements for the picker:
- Toggle key NOT backtick (use F1). Document the keybind in
`ARCHITECTURE.md`.
- Hidden by default.
- Survives `LumeWaveAutoWire` re-runs (component is idempotent).
- Does not block the depth/overlay/tunnel renderers when visible — must be
drawn in screen-space overlay canvas above everything.
- No hard dependency on `pointRenderer` — if null, panel still toggles +
switches presets, color application is a no-op (consistent with
`LumeVfxEditor`'s "silent skip" pattern).

Stream C: optional but high-leverage — fluid sim

If Streams A+B finish and there's time, port Keijiro `StableFluids` into
LUME proper. The playbook + gap-analysis make this the next-most-painful
hole. Three deliverables:

1. `Assets/Compute/LumeFluidSim.compute` — 2D Eulerian fluid sim, RGB advect,
fed by `_AudioLevels` (position not force, per E512 — read the playbook).
2. `Assets/Scripts/LumeFluidSim.cs` — `[DefaultExecutionOrder(180)]`, runs
between optical-flow (0) and audio-receiver (200). Publishes
`_FluidVelocity` global texture for shaders to sample.
3. `LumeFluidSimPreset.asset` files for the 6 named families from playbook v2.

Don't ship a half-fluid-sim. If Streams A+B + tests don't fit, mark this
"deferred to next session" and finish what you started.

Stream D: tests + commit + sync

- Add Python tests for any new wire-format edges (none expected — picker is
pure-Unity).
- Add Unity edit-mode tests for the picker:
- `Assets/Scripts/Editor/Tests/LumeVfxPickerTests.cs` — verify
`Resources.LoadAll<LumeVfxPreset>` returns ≥ N assets, picker survives
instantiate/destroy, JSON round-trip, family switch fires
`MaterialPropertyBlock` update.
- Run `pytest -q` in `software/demo/`. 37 fast tests should stay green.
Add to count if you ship new wire stuff.
- Commit with messages following the pattern in `git log` (e.g. `feat(lume):
duncan modes picker — runtime panel + 25 preset assets`).
- Sync to Mac1 if Tailscale recovers — `tailscale status`, then rsync. If
flaking, just commit on Mac4 main and surface that in the session-end
report.

---

Reading order — do this BEFORE touching code

1. `lume-mac4-live-demo-state.md` (memory) — what was just shipped
2. `ARCHITECTURE.md` (project root) — canonical 10-component model
3. `MAC5-CODEX-HANDOFF-2026-04-26.md` (project root) — prior handoff
4. `CODEX-CONTEXT.md` + `CODEX-PLAN.md` (project root) — origin + plan
5. `Reference/Duncan/INDEX.md` (project) — full 83-reel table
6. `[home-path]` (v2 master playbook)
7. `[home-path]` (newest reels source chunk)
8. `Assets/Scripts/Vfx/LumeVfxEditor.cs` — the existing scaffold you're extending
9. `Assets/Scripts/Vfx/LumeVfxPreset.cs` (and the 4 sibling preset SOs)
10. `Assets/Scripts/LumeCalibrationPanel.cs` — UX + JSON-persistence pattern to mirror
11. `Assets/Scripts/LumeWaveAutoWire.cs` — make sure your picker plugs into Auto-Wire

12. Sample 5–10 random analyses files from `Reference/Duncan/analyses/` to
calibrate your sense of how rich the Gemini analyses are. E598 (Dissolving
Clones), E568 (SuperHot Cubes), E549 (Kelp 4 of 5), E545 (Pinscreen), E535
(Particle Motion Kick) are good representative samples.

---

Don't touch

- `software/demo/pointcloud_pub.py` (don't-touch from Wave 2)
- `Assets/Scripts/LumeUdpReceiver.cs` (wire format dispatcher)
- `Assets/Scripts/LumeAudioReactor.cs` (Wave 1 fallback)
- `Assets/Scripts/LumeFlowParticleOverlay.cs` and the matching shader/material
— these are TEMPORARY substitutes for the unauthored `.vfx` graph and must
stay until the real `.vfx` is built. Don't delete; the comment in the file
explicitly labels it as the temporary path.
- The 4 wire-format magic bytes (LUME 0x4C554D45, LUMD 0x4C554D44,
LUMF 0x4C554D46, reserved LUMC 0x4C554D43). Pinned by golden tests.
- Mega/Bolt CAD (`hardware/cad/`) — different workstream, Mac1 territory.
- The active tmux feeds `lume-real-d` and `lume-audio` — don't kill them
while testing. Use `unity -batchmode` for compile checks instead of
forcing live-Unity restart cycles.

---

Verification before you call it done

1. Live state still healthy: `tmux ls | grep lume` shows both feeds, Unity
logs show all 4 "drawing" lines (point renderer / grid tunnel / flow
particle overlay / audio receiver). `health-check.sh` passes.
2. `pytest -q` in `software/demo/` — 37+ fast tests green.
3. Unity batchmode compile clean: `Unity -batchmode -projectPath . -quit
-logFile -` returns 0. (Adjust path to local Unity install.)
4. Picker manual smoke (you'll need to ask Mohamed to do this in front of
Mac4, OR record a screencap if you have GUI access via Tailscale +
screen share):
- Run scene → press F1 → panel appears.
- Switch through 3 different VFX presets — color/material visibly changes.
- Toggle auto-cycle on, set BPM via the audio sidecar, watch it cycle.
- Quit → relaunch → last selection persisted.
5. Commit SHAs listed in session-end report.

---

Session-end report template

## What I verified live
- (tmux feeds, Unity log lines, test counts, batchmode compile result)

## What I built
- Stream A: N preset assets at <paths>, manifest at <path>
- Stream B: <picker path>, <toggle key>, <persistence file>
- Stream C: <fluid sim status — done / partial / deferred>
- Stream D: <test additions, total counts>

## What I committed (SHAs + branches)
- <sha> on main: <subject>
- <sha> on main: <subject>

## Mac1 sync status
- (success | rsync command for next session if Tailscale flaking)

## Still unfinished
- (list, with reasons; no completion theater; flag any temporary paths
  with their upgrade requirement)

## Pickup recipe for next session
- (concrete commands, file paths, keybinds)

---

Why this matters

The Saturday demo gave us proof-of-concept. The K11 + Bolt arrive Apr 27 and
we move into product-build. The picker is the operator's actual hands-on
surface for the running install — without it, switching modes means closing
Unity, editing Inspector, restarting. With it, LUME starts to feel like
HOLOVIS-class commercial-install software instead of a research demo.

We have the corpus, we have the scaffolding, we have the live data path.
This session is filling in the middle.

Promotion Decision

Keep in the searchable backlog until it intersects a live paper or system.

Source Anchor

lume-commerce/viz/lume-pcloud/MAC4-CODEX-HANDOFF-2026-04-26-night.md

Detected Structure

Method · Code Anchors · Architecture