Skip to content

Universal Deck State

The persistent identity of the deck. Lives in the device’s own flash memory (not on any cartridge), is read into SRAM on boot, is shared across every cartridge, and persists across power cycles.

  • orchestration.md — the runtime that owns and mutates this struct.
  • cartridge-lifecycle.md — when deck-state fields get touched on cart insert / swap / removal.
  • cipher-voice.md — the engine that reads coherence_stack, event_ring, cipher_mode_weights.
  • adr/ADR-0011 — flash partition layout and update path.
  • adr/ADR-0015 — the source for the CIPHER-LINE additions (coherence_stack, event_ring, cipher_mode_weights).
  • adr/ADR-0019 — confirms Universal Deck State stays on the device’s microSD; per-cart save data lives on the cartridge’s SD.

typedef struct {
char operator_handle[12]; /* Chosen alias — set on first boot, changeable via SYS */
int32_t credit_balance; /* Universal currency (¤), pooled across all modules */
uint16_t reputation; /* Cumulative standing — accrues from all mission completions */
uint32_t cartridge_history; /* Bitfield: which capability modules have ever been loaded */
uint8_t lambda_slots[256]; /* 8 × 32-step macro recordings */
uint8_t quote_slots[32]; /* 8 × 4-byte Cell ID references */
uint8_t phase_chain_len; /* Current length of active phase chain data */
uint8_t phase_chain[256]; /* Variable-length multi-phase mission continuity state */
uint8_t cipher_seed[4]; /* Current LFSR state for Cipher voice generation */
uint8_t coherence_stack[400]; /* 5-slot ring of recent Cipher utterances (ADR-0015) —
per slot: 64-byte UTF-8 fragment text (≤2 rows of 32
chars, matching CIPHER-LINE scrollback pair) + 4-byte
timestamp + 1-byte mode + 2-byte affect flags + 1-byte
weight + 8-byte alignment padding = 80 bytes/slot.
Text is retained so the generator can chain
("sector nine. sector nine was louder."), not just
deduplicate. Persists across cartridge swaps. */
uint8_t event_ring[1280]; /* 128-slot decay-weighted event pool (ADR-0015) —
per slot: 4-byte keyword hash + 4-byte payload hash
+ 1-byte decay counter + 1-byte stickiness flags.
Fed by cipher-push-event and nOSh runtime event sources. */
uint8_t cipher_mode_weights[5]; /* Cartridge-tunable Cipher mode weights, one byte per
mode (observe / annotate / reflect / drift / silent;
ADR-0015) — overlays reputation-tier defaults; reset
to defaults at cart-unload. */
uint8_t reserved[16]; /* Expansion */
} DeckState;

Size note. With the ADR-0015 additions, DeckState grows by 1,685 bytes (400 + 1,280 + 5). Total struct size is ~2,272 bytes before alignment padding — well inside the 4 KB dedicated deck-state flash region described under Persistence, so no wear-leveling or partition change is required to absorb the growth. ~1,800 bytes of headroom remain for future fields.


operator_handle — The operator’s chosen name. Displayed on the boot screen, transmitted during link handshakes, embedded in provenance chain entries. Set during first boot; changeable via SYS menu but the change is recorded in the provenance chain of every cartridge subsequently loaded.

credit_balance — The universal economy. Credits (¤) are earned by completing mission phases and spent on tool acquisition, contract bids, and capability upgrades. One currency, shared across all modules. A payout from an ICE Breaker penetration funds a Black Ledger audit tool purchase.

reputation — Cumulative standing. Increases on successful mission completion; decreases on mission abandonment and failed submissions. Higher reputation unlocks higher-threat contracts on the mission board, reduces maintenance costs on surveillance implants, and improves linked play matchmaking priority. Reputation is domain-agnostic — the deck’s reputation reflects the operator’s total career, not performance in one module.

cartridge_history — A 32-bit bitfield. Each bit corresponds to a capability module. The bit is set the first time that module is loaded into this deck. It is never cleared. The mission board reads this bitfield to determine which contract templates to generate and which cross-program integration features to enable. This is the architectural backbone of the capability curve. The 32-bit width supports up to 32 modules — sufficient for the 14-module launch library plus 18 future expansion slots (including community-created content via the Relay module).

lambda_slots / quote_slots — nOSh runtime managed macro and bookmark systems. These persist across cartridge swaps within a session but are volatile across power cycles (stored in SRAM, not flash). Lambda recordings are key sequences; quote slots are Cell ID references. Both work identically regardless of which cartridge is loaded.

phase_chain — Variable-length serialized state for multi-phase missions (up to 256 bytes, current length tracked by phase_chain_len). When a mission spans multiple capability domains and requires cartridge swaps, the phase chain records which phases are complete, what the next required capability is, and any intermediate state (extracted data hashes, threat modifiers, partial payouts, evidence chains, contact positions). The 256-byte maximum accommodates 3–4 phase chains with full intermediate state — sufficient for the most ambitious cross-domain missions the library envisions. The nOSh runtime manages this — cartridges cannot write to the phase chain directly.

cipher_seed — The current state of the LFSR used by the Cipher voice. Advances on every Cipher text generation event. The voice’s output is deterministic given the seed and the deck state — two decks with identical state produce identical Cipher text.

coherence_stack (ADR-0015) — A 5-slot ring of the most recent Cipher utterances spoken on the CIPHER-LINE auxiliary display. Each slot is 80 bytes: 64 bytes of UTF-8 fragment text (up to two 32-char rows, matching the CIPHER-LINE scrollback pair), 4 bytes of timestamp, 1 byte of mode (observe / annotate / reflect / drift / silent), 2 bytes of affect flags, 1 byte of recency weight, and 8 bytes of alignment padding — 400 bytes total. Text is retained, not just hashed, because the Grammar Framework’s coherence-chaining mechanic needs the previous fragment verbatim (e.g., “this corridor. same hum as sector nine. sector nine was louder.”). The Cipher generator reads this ring both to avoid obvious repetition across cartridges — ICE Breaker and Cipher Garden should not debrief a phase with identical phrasing — and to feed chaining. The ring persists across cartridge swaps so coherence holds across Hot Swap boundaries. Stickiness is time-delta-based; decay probabilities are nOSh runtime tuning knobs and are not exposed through the FFI. nOSh runtime owned — cartridges never write this field.

event_ring (ADR-0015) — A 128-slot decay-weighted event pool, fed by the cartridge-facing primitive cipher-push-event and by runtime-internal event sources (mission-board activity, phase transitions, power events). Each slot holds a 4-byte keyword hash, a 4-byte payload hash, a 1-byte decay counter, and 1 byte of stickiness flags, for 1,280 bytes total (128 × 10). Events decay every 15 seconds of wall-clock time: normal events by 1 per tick, :significant events by 1 every 3 ticks, :anomalous events by 1 every 10 ticks. An event at decay 0 is reaped. The Cipher generator weights an event by decay / max_decay when producing utterances, so newer events dominate. nOSh runtime owned — cartridges push events through the FFI but do not read or write the ring directly.

cipher_mode_weights (ADR-0015) — 5 bytes of cartridge-tunable mode weights, one byte for each of the five canonical modes defined in the Grammar Framework: observe, annotate, reflect, drift, silent. Each byte is a 0–255 weight added to the base reputation-tier weights for that mode; the mode selector draws from the summed distribution per utterance tick. Set by cipher-set-mode-weights from cartridge Lisp; reset to the reputation-tier defaults at cart-unload. A cartridge biases without overriding — a Legend-tier operator’s silent-heavy Cipher cannot be forced verbose by a cartridge cranking observe, only nudged toward the edges of the tier’s existing envelope. silent is first-class; a cart can legitimately weight it above all others for a tense beat, and the absence of utterance matters as much as the presence. nOSh runtime owned persistence; cartridge-tunable through the FFI.


The Universal Deck State is written to flash on:

  • Explicit save (SYS → Save)
  • Mission phase completion
  • Cartridge swap (phase chain serialization) — see cartridge-lifecycle.md for the ordering
  • Power-off detection (low-voltage interrupt)

Flash wear-leveling is handled by the nOSh runtime. The deck state occupies a dedicated 4 KB region with rotating write pages.