# Universal Translator

A hardware-agnostic, OS-agnostic translator/interpreter. This package
extracts the reusable core of the "face" architecture proven inside
`Commadore64 on Substrate/`, so the *pattern* — not any one machine — is the
subject. C64 is retained here as dialect #1 (proven, hardware-verified), not
as the focus.

**Scope, precisely (read this before assuming more than is here)**: this is
the TRANSLATOR/OPERATOR layer (§6/§11 of the project overview). `face_settle`
drives the REAL substrate `substrate/phi_lattice.asm` — bare x86-64 assembly
extracted logic-for-logic from `hdgl_router64.asm`'s boot-verified
`.phi_tick`/`.phi_consensus` (Router64 reports real LOCK/UNLOCK on real and
QEMU boot; the prismatic recursion `slot = slot*3 + tick` with GOI ceiling /
GUZ floor, consensus = max-deviation < mean/2). That asm is the same code the
bootable image at `water_glyphs2/hdgl_router64.img` runs; booting that image in
QEMU reaches `[Kernel] phi-lattice 64-bit router ready. Consensus=LOCK` and a
live `Router64>` shell whose `alpine <ksec> <isec>` command loads a real Linux
bzImage over the analog substrate and hands off at the kernel entry (validated:
boot_flag 0xAA55, HdrS magic, XLF_KERNEL_64, real zero-page + E820 + cmdline).

The wider analog-fabric layer — the `𝓛ₙ(z)`/`Ω(tick)` amplitude operator,
`Dₙ(r)` lattice, and Kuramoto phase-coupled oscillator field — lives in
`water_glyphs2/phi_pool_kuramoto.c` and `hdgl_analog_v30.c` and runs as the
`phi_pool` substrate daemon inside the booted image's initramfs (it is what
`/init` starts, writing live Chladni eigenmode amplitudes to
`/lattice/slots/`). The operator's `face_settle` consumes that substrate
through the asm's `phi_lattice_tick`/`phi_lattice_consensus` interface — the
same interface Router64 itself uses — rather than re-implementing the field in
C. `project = fourier_decode∘dct_decode` and `moire = glyph_interference`
remain naming-only in the glyph layer.

Full project context: `../PROJECT-OVERVIEW.md` (§6, §11) and
`/memories/repo/substrate-notation.md`.

## The idea, in one paragraph

The substrate does not re-implement a guest OS's hardware. It **translates**:
it intercepts the small, documented set of hardware-contract vectors a guest
OS already uses on its own native hardware (console-out, keyboard/input,
IRQ/timer) and maps them to substrate operations (`observe`/`settle`/
`checkpoint`/`genome`). The guest believes it is running on native hardware —
because, from its point of view, it is: the translation table *is* the
contract its own ROM/KERNAL already speaks. One operator drives every
dialect; only the translation table changes per guest.

```
CoCo (Color BASIC Unravelled):  RVEC3 = CONSOLE OUT, KEYBUF, IRQVEC
C64:                            $0326 = CHROUT,      $0277 KEYD, IRQ
any OS:                         its own equivalent handful of vectors
```

Universality is per-**interface**, not per-machine: translate the contract,
not the chip.

## Layout

```
core/
  face_node.h        the interface: FaceBasis (translation table shape),
                      FaceNode (the boundary + its state), operator
                      declarations. Zero machine-specific content.
  face_operator.c     the universal operator itself: face_realize, face_tick,
                      face_settle (Kuramoto-style coherence), face_checkpoint
                      (onion-shell), face_genome (dna_encode), face_key,
                      face_mouse. Pure C, no OS/libc/libm dependency --
                      compiles standalone, in a freestanding kernel or a
                      hosted program, unchanged.
dialects/
  c64/                the C64 binding: fills FaceBasis's callbacks by
                      wrapping the real 6502 core + real KERNAL/BASIC ROMs.
                      Retained here for reference; the live, tested, buildable
                      copy remains in `Commadore64 on Substrate/OS64-master/`
                      (this copy will drift -- treat that one as canonical).
                      VERIFIED (2026-08-05): diffed against canonical
                      face_node.cpp -- byte-identical logic, only intentional
                      differences (FACE_SELFTEST block excluded, `40*25`/
                      `40`/`25` literals replaced with the new
                      FACE_SURFACE_* constants).
  demo/               a SECOND, genuinely standalone dialect with no CPU, no
                      ROM, no kernel dependency -- proves the operator is
                      actually dialect-agnostic, not just "C64 code with a
                      universal-sounding name". See "Build and test" below.
tests/
  test_face.c         hosted test harness: realize -> type input -> tick ->
                      report, run against the demo dialect.
glyph/
  hdgl_universal_face.hdgl   the notation-layer expression of this same
                      architecture (non-canonical -- expresses intent, code
                      above is the source of truth).
```

## Build and test (verified 2026-08-06, real compiler, real execution)

```sh
make test   # builds both face harnesses against the REAL asm substrate + runs them
make        # build build/test_face and build/test_alpine (needs nasm + gcc)
```

The operator links `substrate/phi_lattice.asm` (the boot-verified Router64
substrate). The demo and alpine faces realize, observe their guest, tick, and
settle through the asm's real `phi_lattice_tick`/`phi_lattice_consensus`.

Real-metal proof — the asm substrate reaching consensus on emulated hardware:

```sh
cd ../water_glyphs2 && bash build.sh          # builds hdgl_router64.img
qemu-system-x86_64 -drive file=bin/hdgl_router64.img,format=raw,if=ide \
  -boot order=c -m 256M -serial stdio -no-reboot -display none
# → [Analog] Dn(r) lattice: phi-seeded 8-strand 32-slot
# → [Kernel] phi-lattice 64-bit router ready. Consensus=LOCK
# → Router64>   (interactive phi-lattice shell, substrate live)
```

That proves the SUBSTRATE on real metal: the same `.phi_tick`/`.phi_consensus`
asm that `substrate/phi_lattice.asm` is extracted from, reaching `Consensus=LOCK`.

Linux as a face is a PROJECTION, not that firmware's kernel handoff. The
`Router64> alpine …` command in the firmware is a chainload (it far-returns
into a kernel and surrenders the substrate) — that is exactly what this dialect
does NOT do. Instead the Alpine FACE keeps the substrate as host and projects
the guest (`make test`, or `build/test_alpine_live`): the operator observes
`conscious-main`'s real lattice-derived guest running in a chroot container, and
its live shell renders into the projection surface. No handoff, no chainload,
no Docker daemon.

Zero warnings, actually run. Confirmed working, not just designed to work:
- `face_realize()` binds the demo guest and brings the face to READY, surface
  starts blank (observe hasn't run yet -- correct: realize binds, it doesn't
  project).
- Typing `"HELLO UNIVERSAL FACE"` via `face_key()`, then 5×`face_tick()`,
  produces a surface showing BOTH the guest's own boot banner (`DEMO DIALECT
  READY.`) and the typed text, on the rows the demo dialect's own `observe`
  callback reports them at — the translation-table path genuinely works,
  unchanged, for a guest that is not a 6502/C64 in any way.
- A bouncing `*` marker on the last row moves between calls — proof `step()`
  advances real, independent, endogenous guest state (this dialect's own
  60Hz-style clock), the same contract the C64 dialect's real 6502 fulfills.
- `genome` comes out as a real derived 8-symbol `{A,C,G,T}` string computed
  from actual surface content (verified non-empty, deterministic).
- A second `face_realize()` on the same `FaceNode` cleanly resets
  `settle_lock`/`checkpoint_count` to 0 — confirms the operator carries no
  hidden cross-face state; everything lives in `FaceNode`, per the design.

## Adding a new dialect

A dialect is nothing more than one `struct FaceBasis` filled in:

1. `init(self)` — bind the guest and its private machine, reset it for real.
2. `step(self, quanta)` — advance the guest's own execution some amount.
   Never inject work; the guest runs itself. (endogenous Δ)
3. `observe(self, surface, cols, rows)` — read-only copy of whatever the
   guest's own console-out vector already produced, into the projection
   surface. Never write the guest's private state here.
4. `input(self, key)` / `mouse(self, dx, dy, buttons)` — deliver events into
   the guest's own native input contract (its keyboard buffer, its joystick
   port, whatever it already documents) — the same way real hardware would.
5. `coord(self)` — the guest's own PC or equivalent identity coordinate.

Then `face_bind_<dialect>()` populates a `FaceNode` with these callbacks and
a name; `face_realize`/`face_tick`/`face_key`/`face_mouse` (the universal
operator, `core/face_operator.c`) drive it — unchanged, regardless of dialect.

## Current dialects

| Dialect | Status | Notes |
|---|---|---|
| C64 | **Proven, hardware-verified** (Quadro NVS 295) | Real 6502 core (`fake6502`) + real KERNAL/BASIC ROMs. Translation table: CHROUT ($0326), keyboard buffer ($0277/$C6), joystick-port mouse (1350-style), IRQ (~60Hz). |
| Demo (`dialects/demo/`) | **Proven, compiled + run** (see "Build and test") | No CPU, no ROM, no kernel — a minimal in-memory guest. Exists solely to prove the operator generalizes past C64; not a real machine to translate for. |
| Alpine (`dialects/alpine/`) | **Compiled + run — real guest projected and observed** | Linux as a FACE/PROJECTION of the substrate — **not a chainload, not a handoff**. The guest is `conscious-main`'s real lattice-derived Alpine: `lattice_init.sh` (the OS boot sequence the Slot4096 resonance engine generated — hostname, packages, sysctls, uid, all pure functions of the phi-lattice slots) + `lattice_entropy.bin` (the 4096 slot values). The face binds that guest the way the c64 dialect binds real KERNAL ROMs — it does not synthesize a console or re-derive config. The guest runs itself in a **chroot container on a pty** (the raw Linux namespace primitive Docker sits on — no daemon, closest to metal, runs anywhere incl. bare metal), and the operator `observe`s its real console-out into the surface, feeds `face_key` into its stdin, and reads its pid as `coord`. Substrate coupling: `init` reflects the operator's live `phi_lattice.asm` slots into the guest's `/lattice/slots/`, so the projection is of THIS run's substrate (the auditable seed in the guest's MOTD is that fingerprint). Verified: the projection surface shows the live BusyBox shell executing a typed command, returning the substrate-derived hostname `phi4096-00000000`. |
| CoCo / Color BASIC | Not started — real next target | Needs a 6809 CPU core (does not exist anywhere in this workspace yet — the one genuinely new-build item in an otherwise stitch-only project) and the exact RVEC3/KEYBUF/IRQVEC vector table from `suppl/color-basic-unravelled.docx`. |
| any other OS | Unstarted | Same recipe: find its documented hardware-contract vectors, fill one `FaceBasis`. |

## Honest limitations of this extraction (not swept under the rug)

- `FaceNode.surface` is sized `FACE_SURFACE_COLS*FACE_SURFACE_ROWS` (40×25) —
  a practical choice (fits the C64 and many other 8-bit-era text modes)
  inherited from the first proven dialect, not a principled universal
  constant. A dialect with a larger text mode would need this widened;
  that's a mechanical change (the constants are named and centralized in
  `face_node.h` for exactly this reason), not an architectural one.
- `core/face_operator.c` is genuinely dialect-free (verified by inspection
  AND now by execution: built and run against a second, unrelated dialect,
  see "Build and test" above) — but it is still only proven against two
  dialects, one of which (`demo/`) was written specifically to be easy to
  satisfy. It has NOT yet been proven against a second *real* guest machine
  (CoCo would be that proof). Treat "universal" as "architecturally
  dialect-free and tested twice," not "battle-tested across many machines."
- The C64 dialect copy under `dialects/c64/` is for reading/reference only.
  VERIFIED (2026-08-05) byte-identical in logic to the canonical
  `Commadore64 on Substrate/OS64-master/src/c64/face_node.cpp`, aside from
  two intentional differences: the `FACE_SELFTEST`-gated block was excluded
  (that's a build-variant feature of the interactive kernel, not part of the
  dialect definition), and the bare `40*25`/`40`/`25` literals were replaced
  with the new named `FACE_SURFACE_*` constants. Build and test against the
  OS64-master copy, which is the one wired into a real, buildable,
  boot-tested kernel — this copy will silently drift from it over time.
- The `demo/` and `alpine/` dialects' `settle_lock` does not reach LOCK in the
  short sample runs — correct and expected. The asm substrate's consensus
  (max-deviation < mean/2) locks when the observed surface quiesces (a static
  guest screen → constant Δ fold), which a few `face_tick`s on a console with
  fresh typed input is nowhere near. This is a difference in *how long the guest
  has settled*, not a substrate defect; the same asm reports `Consensus=LOCK` at
  Router64 boot (see the real-metal proof above), where the field settles.
- The Alpine FACE projects `conscious-main`'s real guest via chroot on a pty
  (closest-to-metal: no Docker daemon). This needs a host kernel + a busybox
  the face can stage into the rootfs, and root (for `chroot(2)`) — the ordinary
  requirements for any namespace/container, met on real Linux metal. The guest's
  `apk add` step reaches Alpine's CDN when online; offline (as in this sandbox)
  the package step no-ops and the rest of the projection — MOTD, users, sysctls,
  entropy, live shell — runs from the lattice-derived script as shown. The
  guest's config is conscious's, derived from the substrate slots; the face does
  not synthesize or alter it.
- Substrate boundary: the operator drives the substrate through the asm's
  `phi_lattice_tick`/`phi_lattice_consensus` — the `slot = slot*3 + tick`
  prismatic recursion with GOI/GUZ bounds, exactly as extracted from Router64.
  The richer analog fabric (`𝓛ₙ(z)`, `Ω(tick)`, `Dₙ(r)`, the Kuramoto
  phase-coupled field in `phi_pool_kuramoto.c`) runs as the `phi_pool` daemon
  and writes `/lattice/slots/`; it is a peer of the asm tick, not a
  reimplementation of it. The face reads the asm interface — the same interface
  Router64 itself consumes — and reflects the live slots into the guest.
- The face's VT is a faithful projection of the guest's console byte stream
  (text, C0 control, scroll, and a DSR cursor-report reply), not a full VT100 —
  it observes the guest's real output rather than emulating a terminal. Complex
  full-screen TUIs inside the guest (curses apps) would need a fuller VT; a boot
  log + interactive shell, the OS's actual face, render correctly.

