# The merge — substrate owns the loop, C64 is a face

## What you asked for, and what this is

Keep both lineages, merged, keyboard snappy like the old OS64-faces version.
Done WITHOUT surgery — by moving one loop boundary, not rebuilding anything.

## The insight

The old version is snappy because the SUBSTRATE owns the loop and everything
(including input) is a face stepped one small quantum per tick — the poll sits
in the fast outer loop. Our version was laggy because the C64 emulator owned the
loop and ran 200,000 instructions between polls.

The C64 already exposed `face_tick_steps(face, quantum)` — it was already a face
shape. So the merge is: the substrate orbit owns `while(true)`; each iteration
ticks tau, RE-SETTLES Omega = Fix(T) = phi, polls the keyboard ONCE (snappy),
steps the C64 face ONE small quantum (12000), and steps all other faces. The
C64's 6502 / observation / KERNAL injection / shift keys are byte-for-byte
unchanged. Snappiness falls out for free: poll every ~12k quantum instead of
every 200k batch (~16x sooner).

## Faithful to OS64-faces (hdgl_faces.img)

- substrate.cpp: tau ticks; Omega = Fix(T) = phi RE-SETTLED every tick by
  iterating T(X)=1+1/X (nothing stored that can be derived). Verified on host:
  S is perturbed each tick (alive, Delta!=0) yet Omega = 1.6180339887498948
  every tick, |Omega - phi| = 0, Lambda=39 iterations of real convergence.
- phi_fold privacy: face token = phi_fold(genome ^ session ^ id), disjoint per
  face, different every boot (session from RDTSC). Verified: distinct tokens.
- face table + face_step_all(): every face advances ONE quantum per tick,
  genuinely interleaved — exactly orbit_loop + face_step_all in the reference.
- The C64 is registered as a face, NOT the loop owner. It is one face among many.

## Verified

- Boots to real BASIC; typed (fast, 0.12s gaps) PRINT 1234 -> 1234, no drops.
- Shift keys work ($ ( ) " * : etc. reach BASIC — the symbols now type).
- Full source tree rebuilds clean with substrate.o added.

## Still additive (faces/observers, NOT surgery) — next

- VIC color observe (POKE53280/53281 -> visible border/background).
- Font glyphs for symbols ($ ( ) " are currently blank bitmaps in diagfont.h,
  so shifted symbols type into BASIC but render blank — a font fill, not logic.
- fib phi-ladder face (unbounded ratio, exact-integer readout dropping at limb
  width) + count/hello faces, registered alongside the C64 face.
