Skip to content

The KN-86 Deckline — Definitive Guide

platform — fiction, hardware, nOSh runtime, cartridge authoring, player- facing Lisp, economy, modules, build/test, and the decisions behind each. Authoring contract: Every normative claim cites an ADR or a source spec under docs/. Where source docs disagree, this guide flags the conflict in Appendix B rather than silently picking a reading.


The KN-86 is a fictional 1988 “Personal Cyberspace Terminal” from Kinoshita Electronics, reconstructed as a real product in 2026. It is simultaneously:

  • A desktop emulator (SDL2, C11) — the primary development environment.
  • A prototype handheld (Raspberry Pi Zero 2 W + Elecrow 7” IPS, 1024×600) — hardware spec complete.

Both targets share the same nOSh C API, the same Lisp-authored cartridge grammar, the same capability model, and the same .kn86 binary format. See docs/KN-86-Platform-Design-Master-Index.md for the index of all platform docs.

The device ships with a 30-key Lisp-flavored keyboard, an amber Elecrow 7” IPS display (1024×600 pixels, 80 columns × 25 rows text grid at ~12×24 pixels per character, #E6A020 on black), a YM2149-family PSG, and a 14-module capability library distributed across six in-fiction publishers. Players register an operator handle, accept contracts from a nOSh-runtime-owned mission board, and assemble capability stacks — often by physically swapping cartridges mid-mission — to complete multi-phase campaigns and earn credits and reputation.


Positioning statement (from docs/marketing/KN-86-Marketing-Plan.md):

In 1988, Kinoshita Electronics released a Personal Cyberspace Terminal that thought in lists. It was never real — until now.

The KN-86 is not a retro homage to a machine that existed. It is a counterfactual: a serious answer to “what if a consumer handheld had been designed in 1988 around Lisp and cyberpunk operator fiction instead of sprites-and-jumping?” The fiction sells the product; the capability model and the Lisp authoring layer make that fiction mechanically load-bearing.

Product intents:

  1. A plausible 1988 artifact — tactile amber LCD, chunky MX/Choc switches, PSG audio, provenance tokens on the back of cartridges.
  2. A real Lisp machine for the palm — cartridges are Lisp; players who want to can script missions and edit code on the device (ADR-0002).
  3. A capability platform, not a cartridge catalog — missions compose across cartridges (ADR-0001 capability model); hot-swap is designed, not tolerated.

TargetSoCRAM / FlashDisplayStatus
Desktop emulatorx86_64 / arm64host1024×600 SDL window (80×25 text grid, default 3× scale)building
PrototypeRPi Zero 2 W (ARM Cortex-A53)512 MB / SDElecrow 7” IPS (1024×600)spec complete

See docs/hardware/KN-86-Pi-Zero-Build-Specification.md for the platform details and docs/hardware/KN-86-Pi-Zero-Sourcing-Guide.md for sourcing. (The earlier KN-86-Modern-Build-Specification.md targeted the dropped Pico 2 / RP2350 build and is archived at docs/_archive/hardware/KN-86-Modern-Build-Specification.md.)

2.2 Prototype target: Pi Zero 2 W + Elecrow 7”

Section titled “2.2 Prototype target: Pi Zero 2 W + Elecrow 7””

The Raspberry Pi Zero 2 W paired with the Elecrow 7” IPS display provides a cost-effective validation platform. The prototype shares the same software stack (nOSh, cartridge grammar, capability model) as the desktop emulator. Hardware-specific differences (GPIO, display driver, power management) are abstracted by the HAL layer. This target validates nOSh runtime behavior and player experience before committing to production mass manufacturing.

Elecrow 7” IPS panel, 1024×600 pixels, HDMI input. Logical presentation is 80 columns × 25 text rows. The nOSh runtime owns row 0 (status) and row 24 (action bar); cartridges own rows 1–23. The amber aesthetic (#E6A020) is achieved in the emulator via SDL; on the prototype, color mapping is handled by the display driver. See docs/ui-design/KN-86-UI-Design-System.md for the five screen patterns (Full List Browser, Split Pane, Full Grid, Status Dashboard, Detail Inspector) and docs/ui-design/KN-86-Input-System-Architecture.md for the 30-key layout.

30-key layout arranged as an 8×4 matrix (32 intersections, 30 populated). Kailh Choc v1 White/Jade switches with MBK low-profile keycaps; UV-printed legends. GPIO budget is exactly 30 pins with a 74HC595 shift register expanding the column select — any further expansion forces a redesign. Matrix scan runs at 1 kHz via PIO with 10 ms debounce.

The six Lisp primitive keys (CAR, CDR, CONS, NIL, ATOM, EQ) and four action keys (EVAL, QUOTE, LAMBDA, APPLY) are load-bearing across every module; their semantics are fixed in the Lisp Paradigm Revisions spec (docs/game-design/KN-86-Lisp-Paradigm-Revisions.md) and are what lets cartridges share a single cognitive grammar.

emu2149 software-emulated YM2149 running on Core 1; PCM output via I2S to a MAX98357A DAC/amplifier. Three tone channels + noise + envelope, 14 registers. PSG register state is exposed to the F12 debug overlay in the emulator. A forthcoming PCM Voice Bark addendum (not yet read into this draft) layers short sampled barks over the PSG bed for Cipher voice.


Part 3 — nOSh: the nOSh runtime orchestrator

Section titled “Part 3 — nOSh: the nOSh runtime orchestrator”

The nOSh runtime is called nOSh. Under the capability model (ADR-0001, Capability Model Spec), nOSh owns:

  • the mission board — generating contracts from cartridge templates seeded by deck state;
  • the economy — credits, reputation, tier gating, payouts;
  • the phase chain — ordered sequence of capability-domain requirements for multi-phase missions;
  • the Cipher voice — grammar-engine narrator that draws domain vocabulary from whichever cartridge is inserted;
  • Universal Deck State — 64-byte struct persisted to flash, shared across every cartridge.

Cartridges are capability modules, not standalone programs: they contribute code, mission templates, behavior tables, generation data, domain vocabulary, and per-cartridge save slots — but nOSh stays in charge of the meta-loop.

From the Bare Deck Terminal spec and the Capability Model spec, Deck State is a 64-byte SRAM struct persisted to flash:

  • operator_handle[12] — player handle, entered on first boot.
  • credit_balance (int32) — earned currency.
  • reputation (uint16) — career reputation.
  • cartridge_history — bitfield of cartridges ever inserted. Reconciliation flag: uint16 in Bare Deck spec, uint32 in Capability Model spec. Appendix B.
  • lambda_slots[256] — 8 recorded procedures × 32 steps each.
  • quote_slots[32] — named constants.
  • phase_chain[N] — current multi-phase contract’s ordered phase list. Reconciliation flag: Bare Deck says 16 bytes; Capability Model says 256 bytes. Appendix B.
  • cipher_seed[4] — RNG seed for Cipher voice determinism.

First boot: operator handle entry (typed on the Lisp keyboard, stored in deck state). Subsequent boots: Cipher greeting keyed on reputation tier, then the Bare Deck terminal with five tabs — STATUS, CIPHER, LAMBDA, LINK, SYS. Inserting a cartridge brings up its module UI; removing it returns to the Bare Deck.

The mission board is the nOSh runtime’s primary surface. It generates candidate contracts by sampling cartridge-provided templates, filtering by the operator’s reputation tier, and seeding with deck state (so a given operator sees a coherent mission space, not pure randomness). Selecting a multi-phase contract commits its phase chain to deck state; each phase is a capability-domain requirement that may need a different cartridge inserted to satisfy. The Hot Swap — physically swapping cartridges mid-mission in ~5 seconds — is a designed mechanic, not a tolerated quirk (see ICE Breaker gameplay spec).

Cipher is nOSh’s in-fiction narrator. The voice is a nOSh runtime grammar engine; the cartridges contribute domain vocabulary tables. Cipher is verbose at low reputation (Apprentice / Trainee) and silent at Legend. Templates and vocabulary tables live in the Capability Model spec.


ADR-0004 selected Fe as the embedded Lisp VM. Fe is ~800 LOC, 20–25 KB compiled, arena-allocated (no GC — allocation is a bump pointer, and per-handler resets release everything), and measures 2–6 ms typical handler latency in our benchmarks. The comparative table in ADR-0004:

OptionCode sizeRAM floorGCHandler latencyEffort
uLisp40–50 KB≥ 16 KBmark-sweepvariable, pauseslow
Fe20–25 KB≤ 8 KBarena2–6 mslow
Custom VM20–28 KB≤ 8 KBarena1–4 ms (target)2–3 wk

Fe wins on certainty: we avoid GC pauses entirely by designing around arena reset boundaries (handler entry/exit), we keep the memory budget firmly inside the device’s working RAM, and we do not burn 2–3 sprint-weeks writing a VM when Fe already meets the envelope.

Memory budget (from ADR-0001):

BudgetLimit
VM flash≤ 48 KB
VM SRAM floor≤ 8 KB
Per-cartridge arena16–32 KB
REPL arena24 KB
nEmacs editor16 KB

Part 5 — The NoshAPI FFI surface (ADR-0005)

Section titled “Part 5 — The NoshAPI FFI surface (ADR-0005)”

Fe handlers in a cartridge can only call into the nOSh runtime through the enumerated NoshAPI FFI — 54 primitives across three visibility tiers:

  • All-carts tier — display primitives, sound, cell pool ops, LFSR (deterministic randomness), version metadata. Every cartridge has access.
  • Mission-context tier — economy (award credits, record reputation events), navigation (open/close subviews), deck-state reads and bounded writes, save-slot access. Available only inside a mission handler.
  • REPL read-only tier — read-only projections of deck state and the cartridge catalog, exposed to the player-facing REPL and nEmacs; no writes, no side effects.

The full vtable is declared in the Capability Model spec under “Cartridge Code Execution Model” — fields for display, sound, economy, navigation, cell pool, LFSR, deck state, save, and version. Treating the FFI as an enumerated surface (not “anything the cartridge can link against”) is what lets nOSh maintain invariants like “no cartridge can forge reputation” or “no cartridge can read another cartridge’s save slot.” See the NoshAPI Versioning Policy spec (not yet deep-read into this draft) for how the vtable evolves.


Part 6 — Cartridge format v2.0 (ADR-0006)

Section titled “Part 6 — Cartridge format v2.0 (ADR-0006)”

ADR-0006 defines cartridge format v2.0: an 80-byte header followed by Fe bytecode, followed by tagged static data, closed by a CRC-32. The header carries format version, capability bits, publisher ID, API-version requirement, bytecode length, static-data length, and an Ed25519 signature slot. Loader verifies CRC, then API-version compatibility, then signature (for signed carts); any failure rejects the cartridge without mutating deck state.

Static data now carries an optional CART_CAPABILITIES subsection (added 2026-04-24; see ADR-0006 §Cart-Capabilities Block) holding the cart’s requested capability keywords. The nOSh runtime validates the block at cart-load against a baked-in allowlist and rejects unauthorized declarations with :capability-not-granted on Row 24. Null’s cipher-main-grid-escape is the v0.1 sanctioned exception.

Reconciliation flag: the emulator’s types.h currently declares a 256-byte CartridgeHeader matching the pre-capability v1.4 format; this is ahead of the runtime migration to v2.0. Appendix B.


Part 7 — Player-facing Lisp (ADR-0002, ADR-0007, ADR-0008, ADR-0009)

Section titled “Part 7 — Player-facing Lisp (ADR-0002, ADR-0007, ADR-0008, ADR-0009)”

ADR-0002 is the umbrella decision: the player can see and write Lisp. It expands into three sub-decisions:

  • REPL ships at launch — 24 KB arena, 32-expression history, tutorial mode, REPL read-only FFI tier. See ADR-0002.
  • nEmacs is the structural on-device editor — ships post-launch (ADR-0008). Structural editing grammar: CAR descends, CDR siblings, CONS opens an 8-token palette, NIL deletes, QUOTE grabs, EVAL confirms, LAMBDA toggles literal mode. The editor reuses the same 30 keys as gameplay, which is what makes it tractable on the form-factor.
  • Token prediction v1 (ADR-0009) ranks the CONS palette by domain boost (+5 for in-cartridge tokens), local boost (+3 for tokens used in the current buffer), recency (0–10), popularity (0–4), and a semantic bonus (+1). Measured at ~1–2 ms on target hardware — invisible to the player.
  • Scripted missions (ADR-0007) exist — cartridges can ship Lisp-authored missions alongside or in place of handler-defined ones — but they are always optional on the main campaign path. A player who never writes or reads Lisp must still be able to complete every campaign.

Cartridge handlers dispatch through a tagged union: a cell-pool entry’s handler field is either a C function pointer (for the few nOSh-runtime-owned built-ins) or a Fe lambda reference. Runtime treats both identically at the cell contract; the author cannot tell the difference at the FFI boundary. This is why “C grammar retained as runtime contract” is consistent with “Lisp is the sole authoring language”: the surface (nosh_cart.h) is Lisp; the underlying cell semantics (CAR/CDR/ handlers) are still the same C ABI as before.


Part 8 — Fe Lisp on the KN-86: a cartridge-programmer primer

Section titled “Part 8 — Fe Lisp on the KN-86: a cartridge-programmer primer”

This part is a practical primer on how Lisp actually lives on the KN-86. It covers the Fe dialect, the cartridge source shape, the FFI wrapping of C primitives, the player-facing REPL, and the memory model. Canonical references: ADR-0001 (Lisp substrate), ADR-0004 (Fe VM selection), ADR-0005 (FFI enumeration — 54 primitives), ADR-0010 (ICE Breaker reference cartridge), ADR-0002 / ADR-0008 / ADR-0009 (player-facing REPL, nEmacs, token prediction).

The original C grammar (nosh_cart.h) was a three-layer stack: macro authoring surface, nosh_runtime.c dispatcher + cell-pool + nav-stack, and nosh_stdlib.c helpers (draw, SFX, LFSR, list ops). That spec is marked SUPERSEDED by ADR-0001, but only the authoring layer has changed. Post-ADR-0001:

  • Authoring surface: Fe Lisp source (.lsp), compiled to Fe bytecode, packaged into a .kn86 cartridge (ADR-0006 v2.0 format).
  • Runtime contract: unchanged — same cells, same handler slots, same nav stack. What used to be C function pointers in handler slots are now Fe lambda references; dispatch is tagged-union (ADR-0001).
  • Standard library: unchanged C implementation; exposed to Fe via the enumerated NoshAPI FFI (ADR-0005).

Fe is an ~800-LOC embedded Lisp implementation: s-expression syntax, lexical scope, first-class lambdas, tail-call support, no garbage collector. Memory comes from an arena that the cartridge owns; allocation is a bump pointer. When the arena is reset — at phase boundaries by default — everything allocated since the last reset is freed in O(1). There is no free, no mark-sweep pause, no fragmentation. The tradeoff is discipline: cartridges must not hold references across arena resets. Per-cartridge arena is 16–32 KB (ADR-0001 memory budget); the player-facing REPL gets an additional 24 KB arena; nEmacs gets 16 KB. Handler latency targets 2–6 ms typical on device (ADR-0004 / docs/architecture/fe-vm-benchmark-results.md).

Syntax conventions: cartridge Lisp uses kebab-case (drill-into, sound-tone), while the C side uses snake_case (nosh_drill_into, nosh_sound_tone); the FFI binding translates at the boundary.

A cartridge .lsp file has a small number of top-level forms. Each maps directly to a runtime construct (pulled from ADR-0010):

  • (deck-title "Name" :id ... :class ... :version ... :publisher ... :capability-bit N) — one per cartridge. Sets the boot banner, the capability bit in Deck State’s cartridge_history, and the mission- generation class filter.
  • (defcell TYPE (:fields ...) (:handlers ...)) — declares a cell type. :fields is a typed slot list ((name :string 24), (threat :u8)). :handlers is a table keyed by input-event name (car, cdr, eval, info, quote, lambda, nil, atom, eq, apply) and valued with (lambda (self) ...). Missing handlers are a no-op at dispatch — silence is a valid UX for “not applicable here.”
  • (defmission "NAME" :threat-range :base-payout :phases :class :generator-phase N (lambda (threat rep) ...)) — declares a mission template the nOSh runtime mission board can instantiate. Generators are pure functions over (threat, reputation) that return a cell graph.
  • (defdomain MODULE (:vocabulary ...)) — the Cipher voice vocabulary for this cartridge. Words become available to both Cipher narration and the token-prediction palette (ADR-0009).
  • (defn NAME (ARGS) BODY) — cartridge-local helpers and phase hooks (on-phase-1-complete, on-mission-success, on-mission-failure).
  • (defn cart-init () ...) — called once on cartridge load; seeds the LFSR, registers mission templates, sets the capability bit, emits the Cipher greeting.
  • (defstruct cart-state ...) + (defn cart-save ...) + (defn cart-load ...) — per-cartridge save slot; serialization format is ADR-0006 tagged static data, one slot per cartridge.

8.4 The NoshAPI FFI (what cartridges can call)

Section titled “8.4 The NoshAPI FFI (what cartridges can call)”

Cartridges reach the nOSh runtime only through the enumerated NoshAPI. Fifty-four primitives across three visibility tiers (ADR-0005). The pattern is identical for every primitive: Fe marshals arguments, the runtime validates range/type, the C function runs, and any out-of-range condition raises a keyword-tagged error (:out-of-range, :invalid-register, :pool-exhausted, etc.). Silent clamping is the current policy for display/sound (defensive); hard errors for structural operations (cell/nav/mission).

Tier 1 — All-carts (available in any handler, any time):

Display / text (80×25 cell grid): text-clear, text-putc, text-puts, text-printf, text-scroll, text-cursor, text-invert. Display / graphics (960×600 bitmap, per ADR-0014): gfx-clear, gfx-pixel, gfx-line, gfx-rect, gfx-circle, gfx-blit. Display mode control: split-view, display-mode. Sound / PSG raw: psg-write, psg-read (14 registers, 0–255). Sound / high-level: sound-tone (ch freq vol), sound-noise, sound-envelope, sound-silence. Sound / SFX: sfx-keyclick, sfx-boot, sfx-select, sfx-confirm, sfx-error, sfx-alert. Cell pool: spawn-cell 'type-symbol, destroy-cell. Navigation stack (depth ≤ 32): drill-into, navigate-back, current-cell, set-root, next-sibling, prev-sibling. List ops over sibling chains: list-push, list-get, list-length, is-leaf, link-cells, unlink-cell. Procedural generation: lfsr-seed, lfsr-next, lfsr-range min max, lfsr-shuffle (see ADR-0005 “Known Unknowns” — shuffle API is still open). Deck state (read-only in Tier 1): deck-state (→ record with :handle, :credits, :reputation, :cartridge-history, :phase-chain), plus accessors get-handle, get-credits, get-reputation, has-capability N. Stdlib draw helpers: draw-threat-bar, draw-progress-bar, draw-bordered-box.

Tier 2 — Mission-context (only inside an active phase handler; calling outside raises :not-in-mission):

phase-advance, mission-complete, award-credits amount, modify-reputation delta, set-phase-data key value, get-phase-data key, set-capability bit.

This is the tier that can change the world. The enumerated nature of the surface is the whole point of ADR-0005: a cartridge cannot forge reputation, cannot write another cartridge’s save slot, cannot edit the phase chain outside of phase boundaries, and cannot issue display or sound writes while the nOSh runtime owns the foreground.

Tier 3 — REPL read-only (ADR-0002, player-facing REPL):

display-mode, get-handle, get-credits, get-reputation, has-capability, current-cell, list-get, list-length, is-leaf, deck-state, lfsr-seed, lfsr-next, lfsr-range. All mutations — text-*, gfx-*, sound-*, spawn-cell, drill-into, phase-*, mission-complete, award-credits, modify-reputation, set-capability — are forbidden from the REPL. Exploration without corruption is the design.

The FFI binder does the conversions (ADR-0005 §Type Mapping):

CFeNotes
voidnilhandlers that return nothing
bool#t / #ftrue / false literals
uint8/16/32_tintegerrange-checked on the C side
int8/16/32_tintegersigned; range-checked
float / doubleunsupported in MVPdeferred to a later phase
const char *stringnull-term guaranteed by the C side
CellBase *cell (opaque)passed by handle, not inspected directly
DeckState *deck-state recordaccessed via get-* functions

No floats in MVP. Integer math is fixed-point where needed (percentages × 100, fractions × 256). Handlers that would “naturally” want a float (positioning, volume ramp) use integer Q8.8 or similar.

When an input event fires (say the player hits CAR while focused on a contract cell), the runtime looks up the cell’s car handler slot. The slot carries a tagged union: either a C function pointer (for nOSh-runtime-owned cells) or a Fe lambda reference (for cartridge cells). The runtime treats both identically — same args, same return contract, same 5 ms target / 10 ms ceiling for handler latency. Missing slots are a silent no-op. This is what makes “Lisp authoring over C runtime contract” coherent: the contract is the cell, not the language.

The REPL (ADR-0002) ships day one. It lives in Bare Deck (tab assignment TBD — see Open Questions). Its sandbox is the 24 KB REPL arena and the Tier 3 FFI subset; it can inspect the deck, run procedural generation, evaluate pure functions, and poke around a cartridge’s declared domain vocabulary, but it cannot write to the display, emit sound, spawn cells, or change credits / reputation. History is 32 expressions. Tutorial mode walks newcomers through (+ 1 2)(list 1 2 3)(map (lambda (x) (* x x)) '(1 2 3))(get-reputation) and up.

nEmacs (ADR-0008) is the post-launch on-device structural editor. The grammar uses the same 30 keys gameplay uses, so no extra muscle memory is needed: CAR descends into a form, CDR moves to the next sibling, CONS opens an 8-token palette (ranked by ADR-0009’s domain/local/recency/popularity formula), NIL deletes, QUOTE grabs a form, EVAL confirms, LAMBDA toggles literal mode. The editor’s 16 KB arena hosts the edit buffer; saving commits to the per-deck snippet library. Scripted missions (ADR-0007) are always optional on the main campaign path — a player who never opens the editor must be able to complete every campaign.

Token prediction v1 (ADR-0009) ranks the CONS palette: `score = DOMAIN_BOOST(5 if in-cartridge) + LOCAL_BOOST(3 if in buffer)

  • recency(0–10) + popularity(0–4) + semantic_bonus(1)`. Measured at ~1–2 ms on target hardware — invisible.

Cartridges live inside three nested allocation scopes:

  1. Cartridge load scope (root arena, 16–32 KB). Allocated once at cart insertion; holds deck-title, registered cell types, mission templates, domain vocabulary, cart-state. Freed on eject.
  2. Mission scope (sub-arena inside the root). Allocated when a contract is accepted; holds generated cell graphs, phase data, runtime state. Freed at mission-complete or abort.
  3. Phase scope (sub-arena inside mission). Allocated at phase entry; freed at phase-advance. This is the natural reset point for per-handler garbage — design your intermediate computations to live here.

The design rule: do not stash a cell reference across a scope boundary you did not allocate it in. In practice this almost never matters because the cell pool itself is stable for the mission’s lifetime; it is transient intermediate data (temporary lists, match results, Cipher lines under construction) that lives in the phase arena and must not be retained.

The smallest useful cartridge skeleton:

(deck-title "Example Cart v1.0"
(:id example)
(:version "1.0")
(:publisher "Kinoshita Demo")
(:capability-bit 0x0F))
(defcell greeter
(:fields (name :string 24))
(:handlers
(car (lambda (self) (text-puts 0 0 (name self))))
(eval (lambda (self) (sfx-confirm)
(award-credits 10)))))
(defn cart-init ()
(let ((g (spawn-cell 'greeter)))
(set-root g)
(sfx-boot)
(cipher-narrate "Example deck armed.")))

Full worked reference: ADR-0010’s icebreaker.lsp sketch (cell types, mission templates with phase-1 and phase-2 generators, Cipher vocabulary, save/load). Treat ADR-0010 as the canonical example for how a real cartridge composes all of these forms.

8.10 What cartridge authors don’t have (yet)

Section titled “8.10 What cartridge authors don’t have (yet)”

Worth being explicit about the MVP envelope:

  • No floats / doubles in FFI.
  • No direct mutation of C arrays from Fe (the lfsr-shuffle API is an open question — see ADR-0005 §Known Unknowns).
  • No dynamic loading of additional Fe modules — everything the cart needs ships inside its .kn86.
  • No networking from cartridge Lisp (Relay owns update flow; the link-protocol UART is mediated by the nOSh runtime per Capability Model spec).
  • No direct access to another cartridge’s save slot — per-cart isolation is enforced at the FFI layer.
  • No float-based audio envelopes; use PSG register writes or the high-level sound-tone / sound-envelope primitives.

These are the ADR-0005 Tier 1 / Tier 2 surface’s hard edges. When a future capability warrants expansion, the NoshAPI Versioning Policy (docs/architecture/KN-86-NoshAPI-Versioning.md) is how we grow the surface without breaking existing cartridges.


Full ASCII layout and per-key semantics live in docs/ui-design/KN-86-Input-System-Architecture.md. Summary:

  • Primitive keys (load-bearing cross-cartridge semantics): CAR, CDR, CONS, NIL, ATOM, EQ.
  • Action keys (cognitive roles): EVAL (confirm/run), QUOTE (grab/ reference), LAMBDA (record/literal-mode), APPLY (invoke slot).
  • Navigation & text — the remaining 20 keys cover digits, cursor movement, escape/back, tab switching, cart-specific function keys.

Production event model: 1 kHz PIO scan, 10 ms debounce, hold detection for key-repeat and long-press. Event queue is drained on the main loop tick. Emulator mirrors via SDL scancode → KN86_KEY_* mapping in input.c.


Five canonical screen patterns, all defined in docs/ui-design/KN-86-UI- Design-System.md:

  • Full List Browser — flat list, one row per item, right-aligned meta.
  • Split Pane — left list, right detail; CAR/CDR navigates.
  • Full Grid — 2D grid (e.g., NeonGrid, Black Ledger).
  • Status Dashboard — multi-region status readouts.
  • Detail Inspector — single-entity deep view with field rows.

The nOSh runtime owns status row 0 (handle, credits, reputation tier, cart name) and action row 24 (context-aware key hints). Cartridges own rows 1–23.


With no cartridge inserted, the device boots to Bare Deck — five tabs (STATUS, CIPHER, LAMBDA, LINK, SYS) providing operator status, Cipher voice playback, lambda-slot management, link-protocol (UART) session control, and system administration. Bare Deck is also where the REPL (ADR-0002) lives at launch, inside the LAMBDA or SYS tab (specific tab assignment TBD — see open questions in the outline).


Credit scaling (from Master Index payout table):

TierPayout range
T150–100 ¤
T2100–250 ¤
T3250–600 ¤
T4600–1,400 ¤
T51,400–3,000 ¤
T63,000–6,400 ¤

Multi-phase bonuses: +40% (2 phases), +50% (3 phases), +60% (4+).

Reputation tiers: Apprentice 0–4, Trainee 5–14, Specialist 15–24, Expert 25–49, Master 50–99, Legend 100+. Tier gates which archetypes and threat levels the mission board offers.

Detailed phase-by-phase in docs/architecture/KN-86-Campaign-Economy- Spec.md: Corporate Espionage, Maritime Intelligence, Signal Hunt, Supply Chain Sabotage, Strategic Takeover, Full Operation, Counter- Intelligence, Vault Deep Dig, Linked Cooperative. Each archetype specifies input → output → duration → threat → payout per phase, so the mission board can compose them deterministically from deck state.

12.3 The 14×14 cross-module interaction matrix

Section titled “12.3 The 14×14 cross-module interaction matrix”

The Master Index carries the canonical interaction matrix — which pairs of modules reinforce each other, which are neutral, which conflict. This is what makes “multi-phase spans capability domains” more than a label: the matrix encodes designed synergies such as ICE Breaker + Depthcharge (network intrusion → physical recovery) or NeonGrid + ICE Breaker (grid reconnaissance → targeted intrusion).


Six categories, six in-fiction publishers. Canonical module reference card (Master Index):

#ModuleCapabilityPublisherCategoryBit
1ICE BREAKERNetwork IntrusionZaibatsu DigitalOperations0x01
2NeonGridGrid TraversalEdgeware SystemsNavigation0x02
3Black LedgerForensic AuditBureau 9 TechCommerce0x03
4DepthchargeMaritime ReconCascade / PR DynamicsOperations0x04
5ShellfireEW / FrequencyZaibatsu DigitalOperations0x05
6TakezoTactical AnalysisTakezo InstituteStrategy0x06
7SynthFenceMarket OperationsMeridian SystemsCommerce0x07
8DriftSignal TrackPR DynamicsNavigation0x08
9PathfinderRoute PlanningPR DynamicsNavigation0x09
10NodespaceNet StrategyKōji InteractiveStrategy0x0A
11The VaultKnowledge BaseKōji InteractiveKnowledge0x0B
12Cipher GardenCryptanalysisZaibatsu DigitalStrategy0x0C
13NullIntrospectionnOSh RuntimeSystem0x0D
14RelaynOSh runtime DistributionnOSh RuntimeSystem0x0E

Categories by count: Operations 4 (ICE BREAKER, Depthcharge, Shellfire, Takezo-adjacent), Navigation 3 (NeonGrid, Drift, Pathfinder), Commerce 2 (Black Ledger, SynthFence), Strategy 2–3 (Nodespace, Cipher Garden, Takezo — see reconciliation note below), Knowledge 1 (The Vault), System 2 (Null, Relay).

Reconciliation flag: the Master Index’s category-rollup says System = 1 (Relay only) but the module reference card lists both Null and Relay as System. Going with the ref card (System 2).

Four-phase release:

  • Phase 1 — Day 1 launch: ICE BREAKER, NeonGrid, Black Ledger, Depthcharge.
  • Phase 2 — Q3 2026: Shellfire, Nodespace, The Vault, Cipher Garden.
  • Phase 3 — Q1 2027: SynthFence, Drift, Pathfinder, Takezo.
  • Phase 4 — Q2 2027: Null, Relay (meta / system layer).

See docs/game-design/KN-86-Launch-Titles-Capability-Model.md for launch-title capability profiles and docs/game-design/KN-86-Launch- Titles-Traditional-Gaming-Model.md for the game-design bible. See docs/game-design/KN-86-Launch-Titles-Capability- Model.md for their capability profiles and docs/game-design/KN-86- Launch-Titles-Traditional-Gaming-Model.md for the game-design bible.

Each capsule below draws from the module’s gameplay spec under docs/gameplay-specs/. Capsules are deliberately short; the specs are canonical.

0x01 — ICE BREAKER (Zaibatsu Digital, Operations). Network intrusion tempo-sport. Atomic unit: OODA loop, 2–5 s early / 0.5–2 s expert. Four parallel systems (network, toolkit, threat, sound). Six tool archetypes CRACK / MIRROR / SPIKE / CLOAK / SIPHON / GHOST, combinable via CONS. Hot Swap is designed, not tolerated. ADR-0010 reference implementation for the Lisp re-expression.

0x02 — NeonGrid (Edgeware Systems, Navigation). Navigation pedagogy that graduates into a persistent precision gym. 16×10 → 20×15 procedural grids, checkpoints, sentry patrols. Loop: OBSERVE–LEARN–EXECUTE–VERIFY, 5–15 s per decision. Metric is precision, not speed; mastery ceiling is eyes-closed audio-only traversal. Teaches the Lisp grammar through embodied practice (CAR/CDR/NIL/ATOM/EQ become muscle memory).

0x03 — Black Ledger (Bureau 9 Tech, Commerce). Investigative deduction engine. Loop: SCAN–ASSESS–TRACE–EXPOSE, minute-scale. Signature mechanic is move-limited investigation: finite CAR drills, QUOTE flags, EQ comparisons, CONS linkages. Suspicious transactions carry distinct microtonal signatures on Voice 2 — fraud is audible before it is visible. Hot-swap partner for ICE BREAKER on Corporate Espionage campaigns.

0x04 — Depthcharge (Cascade / PR Dynamics, Operations). Listening game. Remote-pilot a submersible drone; the Deckline is the drone’s panel, the PSG is its sonar. Slower OODA (10–30 s early, 5–15 s expert). Active-vs-passive sonar is the central tension; depth is risk/reward. Headphones mandatory — sound IS the game.

0x05 — Shellfire (Zaibatsu Digital, Operations). Real-time frequency management. Three PSG voices ARE three RF bands. OODA 6–8 s early, 3–4 s expert. Core skill is reading the jamming tempo — when peaks arrive, when extraction windows open. Zaibatsu’s expert-skewed second title; audio-only mastery is a real endgame.

0x06 — Takezo (Takezo Institute, Strategy). The anti-tempo cartridge. Turn-based pattern analysis on 5×5 → 11×11 territory grids with an AI opponent scaling novice → master. Loop: OBSERVE–ANALYZE– COMMIT–REFLECT, unlimited time per turn. Named for Musashi; philosophy made playable.

0x07 — SynthFence (Meridian Systems, Commerce). Market-as-adversary trading system. OODA tempo belongs to the market, not the operator — hesitation is cost. Bid/ask spreads, margin, volatility, regulatory forced-closure. Voice 1 market mood, Voice 2 position health, Voice 3 regulatory threat. Pairs with Black Ledger (laundering) and ICE BREAKER (market sabotage).

0x08 — Drift (PR Dynamics, Navigation). Signal triangulation as geometric real-time sport. Three antennas, three bearings, one hidden RF source; intercept before the transmission window closes. OODA 8–12 s per cycle. The game is about angles and distances; the signal is a pretext. Audio-only triangulation is an emergent endgame.

0x09 — Pathfinder (PR Dynamics, Navigation). Two-phase: turn-based planning (unlimited time; design route, allocate fuel, pre-stage countermeasures) followed by real-time execution (3–5 s OODA; convoy health, route collisions, adaptive replanning). Teaches that no plan survives contact with the world but a well-designed plan survives longer.

0x0A — Nodespace (Kōji Interactive, Strategy). Go-like territorial control on abstract node networks, 20–100 turns per contract. Edges = supply lines; control through majority ownership + fortification. AI personalities scale Aggressive → Adaptive → Asymmetric. Zero time pressure; counterweight to all the tempo modules.

0x0B — The Vault (Kōji Interactive, Knowledge). Not a game — a library with gameplay embedded in research structure. Loop: BROWSE → DISCOVER → CONNECT → PROFILE. Six knowledge domains gated by a knowledge_index stat in Deck State; that stat is read by every other module, so Vault research produces intel bonuses and payout multipliers platform-wide. Passive enhancement through active participation.

0x0C — Cipher Garden (Zaibatsu Digital, Strategy). Cryptographic laboratory. Loop mirrors OODA but at 30 s – 2 min per hypothesis cycle. Teaches frequency distributions, repeating-pattern detection, and the statistical signatures of real language. Pairs with ICE BREAKER in the Counter-Intelligence campaign (extract → decrypt) and unlocks encrypted entries in The Vault.

0x0D — Null (nOSh Runtime, System). Self-reflection tool, not a game. Loop: BROWSE → ANALYZE → COMPARE → OPTIMIZE. Career dashboards, per-module stats, Cipher commentary on the operator’s own patterns, leaderboards, generated OPTIMIZATION CHALLENGE bounties on the mission board. Transforms the deck from playstation to personal operating system.

0x0E — Relay (nOSh Runtime, System). Platform maintenance engine. Four phases: SCAN → EVALUATE → APPLY → VERIFY. Receives signed system image updates (ADR-0003), new Cipher passages, rebalance patches, community- submitted puzzles. Relay is what makes the single-cartridge-slot device infinite: post-launch content ships through the same VM and the same tiered FFI as cartridges themselves.

The canonical publisher set (per the module reference card): Zaibatsu Digital (ICE BREAKER, Shellfire, Cipher Garden — operations & cryptanalysis), Edgeware Systems (NeonGrid — grid/spatial), Bureau 9 Tech (Black Ledger — forensic commerce), Cascade / PR Dynamics (Depthcharge — maritime), Takezo Institute (Takezo — tactical analysis), Meridian Systems (SynthFence — market operations), PR Dynamics (Drift, Pathfinder — navigation), Kōji Interactive (Nodespace, The Vault — strategy & knowledge), plus the in-universe nOSh Runtime first-party label for Null and Relay. The loading- screen fiction lives in the Capability Model spec.

Reconciliation note: an earlier outline carried “Cipher Garden” as a possible publisher; it is in fact module #12 (Cryptanalysis), published by Zaibatsu Digital. The canonical publisher set (per module reference card) is: Zaibatsu Digital, Edgeware Systems, Bureau 9 Tech, Cascade / PR Dynamics, Takezo Institute, Meridian Systems, Kōji Interactive, plus the in-universe “nOSh Runtime” first-party label for Null and Relay — seven distinct external publishers.


Part 14 — System image updates (ADR-0011)

Section titled “Part 14 — System image updates (ADR-0011)”

A/B slot architecture on the SD card: bootfs A/B + rootfs A/B + shared deck-state partition. Updates arrive as .kn86fw payloads (header defined in tools/kn86fw/format/kn86fw.h — magic, format version, nOSh runtime version, payload SHA-256, nOSh version, min bootloader version) and are written to the inactive slot. The device exposes that inactive slot as a USB mass-storage drive via g_mass_storage, so the desktop Tauri flasher (or a raw drag-drop fallback) writes the image and reboots the device under Pi firmware tryboot. If the new slot fails to hit the boot-success sentinel within 60 seconds, tryboot reverts to the previous slot automatically on next power cycle. The attention gesture to enter updater mode at boot is SYS+LINK held for ~1.5 s, detected by an early-boot daemon after the USB HID keyboard enumerates but before nOSh launches. Migration scripts for deck-state schema evolution ship as Fe bytecode embedded in the update payload — they run under the same VM as cartridges and use the same FFI tier they would need, so there is no second runtime to maintain.


brew install cmake sdl2 # macOS prerequisites
cd kn86-emulator
mkdir build && cd build
cmake .. && make

Artifact: build/bin/kn86emu. Args: --scale N (default 3), --keymap PATH, --state-dir DIR, --no-save. Positional arg loads a .kn86 cartridge on boot.

Single-threaded SDL2 app with a global SystemState (g_state in main.c). Source layout:

  • display.c — 1024×600 physical display, 80×25 text mode, text / bitmap / split modes, amber #E6A020.
  • font.c — 8×8 monospace bitmap font.
  • input.c — SDL scancode → KN86_KEY_* mapping, event queue, hold detection.
  • psg.c — YM2149 PSG emulator, 14 registers.
  • sound.c — 44.1 kHz mono PCM via SDL audio callback.
  • cartridge.c.kn86 loader (dlopen during desktop dev).
  • nosh.c — unified nOSh API wrapper.
  • debug.c — F12 overlay (PSG registers, display mode, FPS).
  • nosh_runtime.c, nosh_stdlib.c — runtime and standard library, shared contract with the production nOSh runtime.
  • bare_deck.c — 1367 LOC, the Bare Deck terminal + tabs.
  • deck.c — Universal Deck State serialization.
  • types.h — all shared types.

30 files in src/, 14 test binaries in tests/, ~4,231 LOC total.

cd kn86-emulator/build && ctest

Suites: test_cell_pool, test_nav_stack, test_lfsr, test_input_dispatch, test_list_ops, test_deck_state. Static analysis: scan-build make and cppcheck --enable=all src/.

C11, 4-space indent, ~100-char line length, /* */ comments (not //). New source files must be added to the SOURCES list in CMakeLists.txt.


#TitleStatusOne-line rationale
0001Embedded Lisp as cartridge scriptingAcceptedLisp is the authoring surface; C runtime stays as contract.
0002Player-facing Lisp (REPL / nEmacs / scripted missions)AcceptedMakes the Lisp-machine promise mechanically real.
0003nOSh runtime update mechanism (Pico 2)ArchivedSuperseded by ADR-0011 after Pico 2 target was dropped.
0004Bytecode VM selection (Fe)Accepted20–25 KB, arena, 2–6 ms — fits budget without custom work.
0005NoshAPI FFI surface (54 prims)AcceptedEnumerated, tiered surface preserves nOSh runtime invariants.
0006Cartridge format v2.0Accepted80-B header + bytecode + tagged data + CRC-32 + Ed25519.
0007Lisp-scripted mission FFI & contractAcceptedOptional on main path; identical dispatch contract.
0008nEmacs structural editor UXAcceptedReuses 30-key grammar; post-launch.
0009Token prediction v1 rankingAcceptedDomain+local+recency+popularity; ~1–2 ms on target.
0010ICE Breaker Lisp re-expressionAcceptedReference implementation for the Lisp authoring surface.
0011Pi Zero 2 W system image update systemDraftg_mass_storage + A/B tryboot + Tauri flasher + SYS+LINK.

TopicSource
All ADRsdocs/architecture/adr/
Capability model, FFI vtable, publishersdocs/architecture/KN-86-Capability-Model-Spec.md
Cartridge grammar (superseded, retained as runtime contract)docs/architecture/KN-86-Cartridge-Grammar-Spec.md
Campaign archetypes & economydocs/architecture/KN-86-Campaign-Economy-Spec.md
Hardware, BOM, platform comparisondocs/hardware/KN-86-Pi-Zero-Build-Specification.md (earlier Pico-era spec archived at docs/_archive/hardware/KN-86-Modern-Build-Specification.md)
Sourcingdocs/hardware/KN-86-Pi-Zero-Sourcing-Guide.md (earlier Pico-era guide archived at docs/_archive/hardware/KN-86-Sourcing-Guide.md)
UI / screen patternsdocs/ui-design/KN-86-UI-Design-System.md
30-key input layout & event modeldocs/ui-design/KN-86-Input-System-Architecture.md
Bare Deck terminaldocs/ui-design/KN-86-Bare-Deck-Terminal-Spec.md
Launch titles — capability profiledocs/game-design/KN-86-Launch-Titles-Capability-Model.md
Launch titles — game design bibledocs/game-design/KN-86-Launch-Titles-Traditional-Gaming-Model.md
Lisp key semantics across modulesdocs/game-design/KN-86-Lisp-Paradigm-Revisions.md
Per-module gameplay specsdocs/gameplay-specs/
Round 1 / Round 2 design reviewsdocs/reviews/
Marketing, positioning, GTMdocs/marketing/KN-86-Marketing-Plan.md
Expert evaluation & 90-day sprintdocs/business/KN-86-Product-Evaluation.md
Master indexdocs/KN-86-Platform-Design-Master-Index.md

Appendix B — Known inconsistencies (reconciled 2026-04-16)

Section titled “Appendix B — Known inconsistencies (reconciled 2026-04-16)”
  1. Display geometry. RECONCILED. Canonical spec per ADR-0014 (docs/architecture/adr/ADR-0014-display-profile-redesign.md): Elecrow 7” IPS (1024×600) with a 960×600 logical framebuffer, 80×25 character grid at a 12×24 physical cell, integer scale = 1, 32 px horizontal letterbox per side, zero vertical letterbox. Stale references to 640×192, 640×200, 80×24, or the earlier “~12×24 / non-integer horizontal accepted” prose have been purged (2026-04-16 pass + ADR-0014 cleanup).
  2. cartridge_history width. Bare Deck spec: uint16. Capability Model spec: uint32. With 14 launch modules and room for expansion, uint32 is the safer canonical choice.
  3. phase_chain length. Bare Deck spec: 16 bytes. Capability Model spec: 256 bytes. Reconcile against actual worst-case archetype (longest campaign × phase encoding size).
  4. Cartridge header format. Emulator types.h declares a 256-byte v1.4-era header; ADR-0006 ratifies an 80-byte v2.0 header. Migration work item.
  5. System-category count. Master Index category rollup shows System = 1 (Relay only); module reference card lists both Null and Relay as System. Reference card is canonical (System = 2).
  6. Cartridge Grammar Spec status. Marked SUPERSEDED by ADR-0001 but retained for runtime contract details. Add a prominent banner pointing Lisp authoring questions to ADR-0001 and keeping the runtime/stdlib sections as canonical.

Appendix C — Emulator file inventory (snapshot)

Section titled “Appendix C — Emulator file inventory (snapshot)”

~4,231 LOC across 30 files in kn86-emulator/src/. Largest files: bare_deck.c 1367, main.c 374, nosh_runtime.c 324, deck.c 298, nosh_stdlib.c 295, psg.c 276, display.c 273. 14 test binaries in tests/ (cell pool, nav stack, LFSR, input dispatch, list ops, deck state, + 8 more).


  1. REPL tab placement in Bare Deck (LAMBDA vs SYS vs its own tab).
  2. Canonical phase_chain encoding & length cap.
  3. Cartridge header migration plan v1.4 → v2.0 (emulator + any existing test carts).
  4. Confirm category rollup for Takezo (Operations rollup says 4 incl. Takezo; module reference card puts Takezo in Strategy). Likely a stale Master Index rollup — reference card wins.
  5. Order-of-operations for the 4-phase launch beyond Phase 1.

Pass 1 (2026-04-15, self-review). Scope: accuracy, completeness, readability.

  • Accuracy. Every normative claim now traces to an ADR or a spec under docs/. Module reference table was reconciled against the Master Index card — names, publishers, capability bits, and categories match. Part 13 capsules were written from each module’s own gameplay spec under docs/gameplay-specs/. Early-draft speculation about non-existent modules (Blacksite / Compass / Wayfinder / Overwatch / Pact / Archive / Maintenance) was removed; the real library is ICE BREAKER, NeonGrid, Black Ledger, Depthcharge, Shellfire, Takezo, SynthFence, Drift, Pathfinder, Nodespace, The Vault, Cipher Garden, Null, Relay. “Cipher Garden” is module 0x0C, not a publisher.
  • Completeness. All 14 launch modules (plus THRESHOLD launch-adjacent = 14 + 1) have capsules; all 10 ADRs have decision-log rows; all five screen patterns, the 30-key layout by category, all three compile targets, all canonical publishers (plus the in-universe nOSh Runtime first-party label), the full credit/ reputation table, the four-phase release schedule, and the Universal Deck State struct are covered.
  • Readability. Prose-first; tables only where they compact information (hardware targets, memory budgets, VM options, credit tiers, module reference, decision log, source-of-truth index).
  • Known gaps (carried to next pass): deeper per-module write-ups beyond capsules; NoshAPI Versioning Policy deep-read (for Part 5); Prototype Architecture deep-read (for Part 2 RPi Zero target); Round-1 / Round-2 review findings for design-rationale callouts.

End of Draft 1. Maintained as a living document — update in place as reconciliation items in Appendix B are closed in the source specs.