Cipher Voice — Post-v0.1 Integration Plan
docs/architecture/adr/ADR-0015-cipher-line-auxiliary-display.md— authoritative hardware + FFI decision.docs/architecture/KN-86-CIPHER-LINE-Grammar-Framework.md— authoritative engine spec (event stream, memory store, five modes, mode selector, grammar s-exp, coherence stack, NoshAPI primitives).docs/architecture/KN-86-Capability-Model-Spec.md— Cipher Voice section + Universal Deck State schema.CLAUDE.mdCanonical Hardware Specification — CIPHER-LINE hardware values; Spec Hygiene Rule 6 (OLED-exclusive with one sanctioned Null exception).docs/plans/post-v0.1/2026-04-21-mission-board.md— companion plan this doc wires into.docs/plans/post-v0.1/2026-04-21-dev-repl.md,2026-04-21-nemacs.md— companion plans for REPL and editor wiring.- Predecessor:
docs/_archive/plans/post-v0.1/2026-04-21-cipher-voice.md— archived v1 (pre-ADR-0015 grammar engine design, superseded 2026-04-24). Retained as design history only.
Hardware spec: See CLAUDE.md Canonical Hardware Specification. This plan does not restate CIPHER-LINE row geometry, panel size, or font values — consult the Grammar Framework §2 and CLAUDE.md for those.
What this document is
Section titled “What this document is”This is a post-v0.1 planning document for the cross-capability integration work that follows once ADR-0015 lands its firmware bring-up (F1–F7 in the ADR) and the CIPHER-LINE Grammar Framework’s engine ships.
It is NOT:
- A grammar engine spec. That’s
docs/architecture/KN-86-CIPHER-LINE-Grammar-Framework.md. - A hardware or FFI spec. That’s ADR-0015.
- An architectural decision. The architecture is decided.
This plan answers a narrower question: once the Cipher voice is rendering on CIPHER-LINE per the Grammar Framework, what integration work is queued across Mission Board, the dev REPL, nEmacs, and companion subsystems? Each section below is a PR-sized slice of work with acceptance criteria, scoped to agents who own those surfaces.
The archived v1 of this doc (now at docs/_archive/plans/post-v0.1/2026-04-21-cipher-voice.md) spent most of its pages designing the grammar engine on the assumption Cipher rendered on the 80×25 main grid across five zones. That engine design is superseded; the Grammar Framework is the authoritative replacement. The genuinely still-useful content in v1 was the cross-capability integration thinking — that is what this v2 preserves and cleans up.
1. Scope boundary — firmware, cartridges, and this plan
Section titled “1. Scope boundary — firmware, cartridges, and this plan”Before delegating integration work to other subsystems, we restate the boundary ADR-0015 and the Grammar Framework already enforce. This plan NEVER revisits these — it only wires them to companion subsystems.
Firmware (nOSh) owns — already specified, do not re-design:
- The Cipher engine (event stream, memory store, five modes, mode selector, grammar expansion, coherence stack). See Grammar Framework §§3–9.
- CIPHER-LINE rendering (the 4-row OLED surface — Row 1 status strip, Rows 2–3 Cipher scrollback, Row 4 contextual). See ADR-0015 §2 and Grammar Framework §2.
- The NoshAPI FFI (
cipher-emit,cipher-push-event,cipher-extend-grammar,cipher-set-mode-weights,aux-*family). See Grammar Framework §11 (authoritative signatures) and ADR-0015 §4 (eight new primitives, NoshAPI 54 → 62). - The
cart-capabilitiesallowlist that gates Null’scipher-main-grid-escape. See ADR-0015 §3a. - Universal Deck State fields for Cipher:
coherence_stack(50 B),event_ring(1280 B),cipher_mode_weights(4 B), plus the existingcipher_seed[4]LFSR. See ADR-0015 §6 and Grammar Framework §9.
Cartridges own — already specified:
- Their
cipher-grammarblock in the.kn86container (vocabulary pools, production fragments, new non-terminals, mode biases, style deltas, event-type registrations, cart-scoped affect tags). See Grammar Framework §10. - Pushing events via
cipher-push-event. See Grammar Framework §11. - Null uniquely: main-grid Cipher passages via
cipher-emit-main-grid, authorized by thecipher-main-grid-escapecapability. See ADR-0015 §3a and Grammar Framework §2 (sanctioned exception).
This plan owns — the integration surface:
- Wiring Mission Board events into the Cipher event stream (Section 2).
- Wiring the dev REPL’s read-only introspection + tutorial hooks (Section 3).
- Wiring nEmacs’s predictive palette and editing-session ambient behavior (Section 4).
- Tracking cross-cutting follow-ups that don’t belong to any single agent (Section 5).
- Open questions that need Josh’s disposition before work begins (Section 6).
No new Cipher engine design decisions live here. If you find yourself proposing one, stop — it belongs in an ADR or in the Grammar Framework, not in a post-v0.1 plan.
2. Mission Board → Cipher integration
Section titled “2. Mission Board → Cipher integration”Companion plan: docs/plans/post-v0.1/2026-04-21-mission-board.md §Cross-capability hooks → Cipher voice.
The Mission Board is the highest-traffic Cipher consumer. Per ADR-0015, Cipher no longer renders on the MISSIONS tab — there is no Row 20–22 commentary strip, no per-contract annotation block on the main grid. Instead, mission board events push into the Cipher event stream; the nOSh runtime generator decides when and how to speak on CIPHER-LINE Rows 2–3.
2.1 Event mapping
Section titled “2.1 Event mapping”The mission-board plan already emits these events on the nOSh topic bus. This plan commits them into the Cipher engine’s event stream via cipher-push-event from the nOSh runtime side (Cipher’s events are firmware-pushed, tagged :firmware; the Grammar Framework §3 baseline event types accommodate all of these without extension).
| Mission-board event | Cipher event type | Default affect | Beat transition |
|---|---|---|---|
mission_board_refreshed | :observation | :routine | — (beat stays) |
mission_highlight_changed | :observation | :routine | — |
mission_bid | :action | :routine | — |
mission_accepted | :mission-start | :routine | nOSh runtime sets beat to :mission-brief |
mission_required_cartridge_missing | :anomaly | :anomalous | — |
mission_suspended_resume_available | :phase-advance | :significant | nOSh runtime sets beat to :phase-transition |
| Mission Board entry (first tab switch per power cycle) | :observation | :routine | nOSh runtime sets beat to :bare-deck → :mission-brief |
Cipher will often be silent in response (silent mode is first-class per Grammar Framework §5.5). That is correct; it matches the cockpit-voice-recorder aesthetic §1 of the Grammar Framework codifies. The operator does not need Cipher to narrate every board-refresh tick.
2.2 Work items
Section titled “2.2 Work items”- GWP-TBD (Firmware, post-ADR-0015 bring-up) — Wire Mission Board event bus into
cipher-push-eventwith the mapping above. Acceptance: Mission Board events show up in the Cipher event stream debug overlay (F12) with correct:type/:affect/:tag=:firmware. Cipher engine consumes them; CIPHER-LINE Rows 2–3 respond according to the Grammar Framework’s mode selector. No main-grid Cipher rendering anywhere. - GWP-TBD (Gameplay Design) — Author a small nOSh-baseline
cipher-grammarextension for mission-flavored vocabulary (:subject,:object,:verb-presententries for contracts, threats, payouts) so that Mission Board events produce readable fragments even without a domain cartridge loaded. Lives in the nOSh baseline grammar, not in any cartridge. Acceptance: with no cart inserted, amission_highlight_changedtick renders a comprehensible fragment likecontract. waiting.rather than a bare slot fallback. - GWP-TBD (QA) — Golden-file regression. Given a fixed Mission Board event sequence and a fixed
cipher_seed, the CIPHER-LINE output must be deterministic per Grammar Framework §6 Determinism. Test matrix: at least one sequence covering board refresh, highlight change, bid, accept, and the resume path.
2.3 Explicitly out of scope for this plan
Section titled “2.3 Explicitly out of scope for this plan”- Cipher commentary on specific contracts (threat-bracket flavor, payout-tier flavor, domain-tag flavor). That flavor is captured in the Grammar Framework’s mode selector biases and in each cartridge’s
cipher-grammarblock, not in the integration plan. - Any notion of a Mission Board “Cipher annotation rail” on the main grid. That is retired per ADR-0015.
3. dev REPL → Cipher integration
Section titled “3. dev REPL → Cipher integration”Companion plan: docs/plans/post-v0.1/2026-04-21-dev-repl.md.
The dev REPL (ADR-0002) gives the operator a player-facing Lisp shell with read-only NoshAPI access. For Cipher, the REPL is an inspection and teaching surface — never a mutation surface without explicit operator consent.
3.1 REPL primitives
Section titled “3.1 REPL primitives”The Grammar Framework’s NoshAPI primitives (§11) already exist. The REPL exposes a small read-only subset for introspection.
| REPL primitive | Delegates to | Mutation? | Purpose |
|---|---|---|---|
(cipher-stack-head N) | Grammar Framework §9 Stack Operations | No | Read last N coherence-stack entries. Null uses the same primitive for its Cipher Analysis subpanel. |
(cipher-memory-peek) | Read-only snapshot of memory-store state | No | Returns a list of current memory-store entries (event-type, tag, approximate age, current weight). For tutorial and debug only. |
(cipher-beat) | Read-only access to current firmware beat | No | Returns the current beat keyword (:bare-deck, :active-hack, etc.) so operators can see what mode-selector distribution is active. |
(cipher-sample passage-hint) | Scratch LFSR variant | No | Preview what Cipher might say next tick without consuming the real seed. Uses a scratch LFSR derived from cipher_seed. Tutorial-friendly. |
Explicitly NOT exposed to the REPL:
cipher-emit(writes CIPHER-LINE; mutation).cipher-push-event(mutates event stream; writeable only from the active cart or nOSh runtime subsystems, not from the REPL, to prevent tutorial programs from rewriting Cipher’s memory).cipher-extend-grammar,cipher-set-mode-weights(mutate live grammar / bias tables).- Any
aux-*primitive that takes a row. The REPL doesn’t get to paint CIPHER-LINE.
3.2 Tutorial hooks
Section titled “3.2 Tutorial hooks”The first-boot REPL tutorial (ADR-0002) gains a three-step Cipher lesson:
(cipher-beat)— observe that the engine has a context.(cipher-stack-head 3)— observe the last three things Cipher said (or silence markers).(cipher-sample :observe)— preview an observation without consuming the seed.
The lesson teaches read-vs-mutate as a concept; Cipher is a natural teaching case because cipher-sample and cipher-emit are visibly different verbs on the same voice.
3.3 Work items
Section titled “3.3 Work items”- GWP-TBD (Firmware) — Implement the four REPL-scoped read primitives above. Acceptance: calling any of them from the REPL returns a well-formed value and does NOT advance
cipher_seed, push into the event stream, or push into the coherence stack. - GWP-TBD (Gameplay Design) — Author the three-step tutorial lesson. Acceptance: first-boot operators see the lesson, complete it without any Cipher state mutation, and the post-lesson
cipher_seedequals the pre-lessoncipher_seed. - GWP-TBD (QA) — Tutorial regression. The lesson must be idempotent against
cipher_seed,coherence_stack,memory_store— run it, run it again, the state is bit-identical.
4. nEmacs → Cipher integration
Section titled “4. nEmacs → Cipher integration”Companion plan: docs/plans/post-v0.1/2026-04-21-nemacs.md.
nEmacs (ADR-0008) is the structural editor. Its predictive palette uses cartridge vocabulary the same way Cipher does — this is a shared-data opportunity, not a duplication.
4.1 Shared vocabulary frame
Section titled “4.1 Shared vocabulary frame”ADR-0008 boosts predictive palette ranking for tokens in the currently-loaded cartridge’s vocabulary. The Grammar Framework §10 already defines vocabulary as part of the cipher-grammar block. nEmacs and the Cipher engine consume the same vocabulary frame — the cart’s cipher-grammar :vocabulary pools.
Concretely, the nOSh runtime publishes a vocab_frame_updated event on cart-load and cart-eject. Both Cipher and nEmacs subscribe. This keeps them in lockstep — whatever words a cartridge teaches the editor are the same words Cipher might speak.
This is not a new design decision (the Grammar Framework already makes vocabulary data, not code). It is a statement that the integration is free if we wire it correctly, and a reminder not to create a second vocabulary table for nEmacs.
4.2 Editing-session ambient behavior
Section titled “4.2 Editing-session ambient behavior”There is no ambient Cipher whisper on the main grid inside nEmacs. Per Spec Hygiene Rule 6, Cipher does not render glyphs on the 80×25 main grid (the one sanctioned exception is Null’s escape — nEmacs is not Null). Any ambient Cipher behavior during editing sessions happens on CIPHER-LINE, using the normal mode selector and the normal beat (editing sessions run against :bare-deck or :mission-brief, not a bespoke :editor-open beat).
If the experience with shipping v0.1 reveals that CIPHER-LINE goes too quiet during long editing sessions, the fix is a bias adjustment (push a per-cartridge :mode-biases entry for the active beat that raises drift slightly), not a new rendering zone.
4.3 Work items
Section titled “4.3 Work items”- GWP-TBD (Firmware) — Publish
vocab_frame_updatedon cart-load and cart-eject. Acceptance: nEmacs’s palette invalidates its cache on each event; Cipher’s active grammar refreshes on each event. Both consume the samevocab_frame_hash. - GWP-TBD (nEmacs agent) — Subscribe to
vocab_frame_updated; use the emitted frame as the sole vocabulary source for palette ranking. Acceptance: when a cart swaps, nEmacs’s top-ranked palette entries change within one frame. - GWP-TBD (Playtest / QA) — Post-v0.1 telemetry or playtest observation: is CIPHER-LINE too quiet during extended editor sessions? If yes, file a small bias-tuning task; if no, do nothing. Do not preemptively add editor-specific beats.
5. Cross-cutting follow-ups (not owned by a single companion plan)
Section titled “5. Cross-cutting follow-ups (not owned by a single companion plan)”These are items that don’t fit cleanly into Mission Board, REPL, or nEmacs plans but are in-scope for the Cipher voice area.
5.1 Legacy field names vs. Grammar Framework schema
Section titled “5.1 Legacy field names vs. Grammar Framework schema”The predecessor v1 of this doc referenced a cipher_seed[4] LFSR as the single randomness source. The Grammar Framework §6 Computation and ADR-0015 §6 confirm this is still correct — cipher_seed[4] is the one LFSR, advanced per mode selection and per slot fill. The new event_ring (1280 B) and coherence_stack (~272 B reserved, 265 B used) and cipher_mode_weights (4 B) are additive fields, not a replacement. No work item — just a note so a future reader doesn’t think the LFSR model was displaced.
5.2 Null’s main-grid escape — tooling parity
Section titled “5.2 Null’s main-grid escape — tooling parity”Null is the one cartridge authorized to render Cipher on the main grid (ADR-0015 §3a, Grammar Framework §2). The voice heuristic still applies: Null’s main-grid passages are chains of clipped fragments joined by punctuation and line breaks, not conversational sentences. This is an authoring discipline, not a runtime constraint — firmware will render whatever cipher-emit-main-grid is given.
- GWP-TBD (QA) — Add a Null-specific voice-heuristic check to the gameplay-spec review pass. Any proposed Null main-grid passage must pass §1 of the Grammar Framework (under eight words per clause, drops articles/connectives, etc.) before it ships.
5.3 Debrief / phase-completion Cipher on CIPHER-LINE
Section titled “5.3 Debrief / phase-completion Cipher on CIPHER-LINE”The phase-completion moment used to trigger a full-screen debrief modal with main-grid Cipher text. Per ADR-0015 it now fires as a standard event (:result-success or :result-failure) that produces a CIPHER-LINE utterance at whatever mode the selector picks — typically annotate or reflect under :debrief beat (Grammar Framework §6 beat table). There is no main-grid debrief modal for Cipher; whatever cartridge-side outcome UI a module wants post-phase is cartridge content on the main grid, Cipher commentary on CIPHER-LINE.
No work item — this is a restatement for the post-v0.1 reader who remembers the old debrief-modal design.
5.4 Emulator parity
Section titled “5.4 Emulator parity”ADR-0015 follow-on F1 creates kn86-emulator/src/oled.c for the CIPHER-LINE SDL2 render surface. This plan depends on that landing before any of the above work items can be QA’d end-to-end on the emulator. Tracked in the ADR; not duplicated here.
6. Open questions
Section titled “6. Open questions”Each of these blocks some sub-item above and needs Josh’s disposition (as PM) before the agent picks it up. None require re-opening ADR-0015 or the Grammar Framework.
-
Should
cipher-samplefrom the REPL be unrestricted, or gated by operator consent on first use? The primitive is read-only and doesn’t touchcipher_seed, so there’s no memory-rewrite risk. The concern is narrative spoilers —cipher-sample :reflectcould surface a memory a first-time operator isn’t ready to see. Proposal: unrestricted; Cipher fragments are terse enough that spoilers are not a real risk. PM to confirm. -
Per-cartridge
:mode-biasesand:style-deltasauthoring quality bar. Grammar Framework §10 caps biases at ±0.20 and deltas at ±64. But a cart that maxes out both on every beat will drown out the nOSh runtime-default voice. Do we need a QA checklist that flags a cart’s grammar block for review if it approaches the caps? Proposal: yes — QA agent adds “Cipher grammar balance” to the gameplay-spec Round 2 review pass. PM to confirm QA scope change. -
Cipher commentary on
mission_required_cartridge_missing. Should the nOSh-baseline grammar include an “insert the module” fragment, or stay silent and let the main-grid error message carry the load? Proposal: baseline silent; modules that want a voice line on this event can register it via their owncipher-grammar. PM to confirm. -
Tutorial lesson order. The three-step REPL Cipher lesson §3.2 assumes it comes AFTER the operator has loaded at least one cartridge (so the coherence stack and memory store have content to introspect). Is that a hard sequencing constraint, or do we ship a “demo state” the tutorial injects into the memory store and coherence stack? Proposal: hard constraint — the tutorial is gated on “at least one cart has been loaded this session.” Gameplay Design agent to confirm with first-boot flow.
-
Null-specific QA pass (§5.2). Does the Null gameplay spec’s current voice-heuristic compliance ship as-is, or does it need a revision pass against the Grammar Framework §1 heuristic before v0.1 closes? Proposal: a short Null-specific compliance review, same template as the other Round 2 reviews. PM to schedule with QA.
End of plan.