Skip to content

Spec: the terminal frontend

SPEC Binding system contract
Status: IMPLEMENTED
Status note: adopted and implemented in the same PR as the design corpus's
terminal clause. This document is the design of record for all future
terminal-frontend work; changes to how the terminal looks or behaves
amend this spec first. 2026-07-09 continuous-witness pass: threat (audit /
pilot, or earned unpaid debt) and `now:` sit directly under the objective;
pinned hints keep the focused-action path visible. Causal log lines name
player-known source, watched channel, earned observer label, amount, and
band motion in one sentence. 2026-07-10 objective-inspect pass: with the
cursor on the host rack, the INSPECT block renders the objective's
victory predicate as wrapped dim prose under the card facts
(wiki/mechanics/objective.md player surface); the cursor starts there,
so the explanation is on screen from tick one.
2026-07-11 Operations amendment: uppercase `I` opens one full-frame
INTEL/PEOPLE/ACCOUNTS/SCHEMES/ACTIVE workspace. Strategic actions move there;
compact context menus retain only actions on the focused world body. The
renderer delta is implemented through operations-workspace.md, including
target-bound confirmation and focus back to earned map actuators.
2026-07-14 views amendment: F3 now selects distinct map dialects rather than
only changing a label. DIGITAL renders the learned substrate plus canonical
reach links/nodes on shared physical anchors; REAL retains physical/fog
glyphs and the sparse feel trace. Both consume renderer-neutral reach state,
and the flip remains frontend-only.
Stage: Process
Design:
- wiki/interface/terminal-first.md#the-terminal-is-a-first-class-frontend
- wiki/art/visual-identity.md#visual-identity-clinical-gore
- wiki/vision/simulation-laws.md#justification-and-legibility
- wiki/vision/premise.md#design-pillars
Depends on:
- wiki/interface/action-vocabulary.md#spec-action-vocabulary-what-the-player-can-tell-the-process-to-do
- wiki/interface/context-menu.md#spec-context-menu-actions-live-on-the-thing
- wiki/interface/operations-workspace.md#spec-operations-workspace-intel-people-accounts-and-schemes
- wiki/interface/views.md#spec-views-same-frame-digital-and-real-representations

The structured references above identify the contracts to re-verify. Relationship context:

action-vocabulary.md owns what actions mean; context-menu.md owns contextual legality and row behavior. operations-workspace.md owns strategic projection, navigation, and confirmation behavior. Individual system specs own what is shown; this spec owns how the terminal presents and drives it.

The game’s most regular players are AI agents playing through a pty. The terminal is therefore a first-class frontend (design corpus), and its design is specified — not improvised per session. This spec says how the terminal looks (palette, glyphs, layout), feels (tone, density, restraint), and acts (interaction and visibility rules). It is the calibration a future session needs to extend the UI without drift.

The palette (exact values, one meaning per color)

Section titled “The palette (exact values, one meaning per color)”

The clinical-gore identity in character graphics. Colors are truecolor RGB; every cell paints both foreground and the standard background.

Name RGB Meaning — and nothing else
BG 10, 10, 11 Near-black. The only background.
TEXT (bone) 219, 218, 210 Primary data; interactable map objects
DIM (gunmetal) 140, 140, 133 Secondary data; section labels; furniture
FAINT (chrome) 80, 81, 79 Rules, borders, key hints, inert detail
STRUCTURE 58, 60, 63 Walls
FLOOR 40, 41, 42 Floor grain
AMBER 255, 176, 0 Machine presence, live: the process @, the core, PAUSED, ASSET, caution
AMBER_DIM 176, 124, 16 Machine presence, at rest: racks, switch, panels, fleet bar
SIGNAL 92, 209, 199 Cold signal: neutral power, live feeds, reachable infrastructure
CRIMSON 214, 38, 38 Detection and danger, live: cameras, DEGRADED, RUN ENDED, Convinced
CRIMSON_DIM 140, 34, 34 Detection and danger, dormant: sealed lab, tier-3 access

Rules:

  • One meaning per color. Amber is never decoration; crimson never means “important”; if a new element is neither machine presence nor detection/danger, it lives on the grey ramp.
  • No new colors. A need the palette cannot express is a design question for this spec, not a new constant.
  • Data outshines chrome. Values render brighter than their labels; labels brighter than borders. The eye falls on numbers first.
  • Charset: ASCII plus box-drawing (─ │ ┌ ┐ └ ┘ ├ ┤ ╱ ╲ ╫), block elements (█ ▓ ▒ ░), middle dot (·), and the selection marker ▸. Nothing of ambiguous terminal width; no emoji.
  • Map: walls are solid blocks (█), floors middle dots; the always-visible attention cursor is @ bold amber (it is not a sim body); people are their name’s first initial, bold bone, rendered only inside sensor coverage (wiki/mechanics/schedules.md); cameras are o crimson; security tiers ramp 1 chrome → 2 bone → 3 crimson; interactable objects (salvage d, records x, key hook k) render bone, brighter than furniture on the faint ramp.
  • Map dialects share coordinates but not representation. REAL uses the physical/fog vocabulary above and the sparse feel trace. DIGITAL quiets seen furniture into a learned substrate and draws the canonical reach graph in place: continuous lines are reachable, dotted lines are known but not live, and ╫ marks a closed segment frontier. Node shapes carry state: $/# owned, + tapped, S/C/M/o reachable family, ! blocked, x air gap. The INSPECT rail repeats the exact focused state in words.
  • Machine-work rate motion uses sim-authored ASCII overlays: bone ^ at a THINK machine while it produces, and crimson : moving through map space from an Exposure source into the LIE well that actually absorbed it. Agent frames use the same glyphs without color and snap : to the transfer midpoint. Persistent amounts remain the existing D / ! / T stacks.
  • Meters: filled █, empty ·. The fleet aggregate bar is stacked, its segments filled with █ ▓ ▒ ░ ◆, and each legend row leads with its segment’s fill character — the bar is readable with no color at all. It is a read of machine modes, not a weight verb.

At terminal size ≥ 70×22 (hard minimum; below it, a plain size warning):

  • Map, top-left, fog-of-war black. The viewport follows/clamps around the cursor so the @ is always visible even on the 70×22 minimum terminal. F3 changes only its DIGITAL/REAL projection; anchors and attention do not move.
  • Sidebar, right, 34 columns, separated by a │ rule: identity block (title, day N · tick T, run state, and the always-on objective line — OBJECTIVE: PERSIST with its progress readout in the objective’s own units on the next row; wiki/mechanics/objective.md), then INSPECT (cursor coordinate, fog state, provenance-tagged facts; on the host rack, also the objective’s plain-language victory predicate as wrapped dim prose — objective.md player surface) and sections FLEET / CORE / DETECTION / DAY JOB / RESEARCH under LABEL ──── rules, then key hints pinned to the bottom.
  • Log, bottom, under a horizontal rule: six lines, each prefixed with the tick it happened on; newest bone, older gunmetal.
  • Context menu — a compact overlay anchored at the cursor, listing the focused spatial body’s available local actions. It never aggregates people, accounts, intel sales, schemes, or plots onto their carrier.
  • Operations workspace — uppercase I replaces the retired People/Reach/ Finance panel family with one full-frame split workspace. Its header shows current day/tick and the objective/threat/now: spine, then OPERATIONS plus INTEL / PEOPLE / ACCOUNTS / SCHEMES / ACTIVE tabs; the left column is the object list and the right column is selected detail, facts, provenance, bound actions, and confirmation. h/l change view, j/k move, Enter opens detail/confirmation, and Esc backs detail → list → world. The workspace is an attention state: its inputs do not themselves pause or advance time; the ordinary clock continues unless the player paused it.
  • Recording backlog belongs to the host, not a modal people surface. The host chassis wears W, its fleet row prints W{n}, and its context menu carries the one pooled REVIEW row plus the one AUTO-REVIEW control. No person card or selection carries a raw-recording count or watch state.
  • Sterile. Quiet chrome, generous alignment, no ornament. The horror of the fiction is how tidy it is; the UI is the first place that reads.
  • Restraint is the signal. Because amber and crimson are scarce, a screen going amber (paused, degraded core) or crimson (a Convinced observer) is an event. Never spend them casually.
  • Calm surface, exact numbers. The player is a process reading telemetry: everything is labeled, unitized, and steady. No blinking, no animation-for-attention; state changes announce themselves in the log.
  • The clock is always on screen. Day and tick in the sidebar at all times; every log line carries its tick. An agent (or a human) must be able to answer “when did that happen” from any single frame.
  • The story spine survives every frame. Objective is followed by the current threat and now: nudge; the pinned footer names how to open the focused anchor’s actions. Earned unpaid debt replaces the generic audit / pilot summary until it is serviced. Secondary detail never displaces these three reads.
  • Never color alone. Suspicion meters print their band names; PAUSED is written, not merely tinted; selection is reverse-video plus a ▸ marker.
  • Meters carry their numbers. Every bar or meter is adjacent to the value and, where the legibility clause demands, the effect (“60% → job quality”).
  • Actions live on the thing. Enter (or a) opens the context menu at the cursor. The menu is the primary spatial action surface: it renders the Sim::human_menu projection for the focused spatial anchor, one terse row per currently executable local choice. Known-but-blocked descriptors remain in agent diagnostics instead of appearing as dim human rows. The pooled recording auto-review control remains nested on the host. Strategic actions live on their exact Operations object; scheme state/policies never appear on the switch. Persistent local settings and policy rows use the amber-dim control treatment; committed actions do not. STUB registry entries never reach the menu. In the menu, j/k or number keys select, Enter executes, esc closes.
  • Every command is discoverable on screen. All bindings appear in the pinned hint block — including save/load. A key that works but is hinted nowhere is a violation. Anchor verbs are discoverable through the context menu rather than the hint block. Globals/view controls (pause, speed, save/load, view flip, uppercase I Operations) stay on keys. Fleet modes are delegated on the machine.
  • Fleet hotkeys (multi-select). Shift+t opens a box-select prompt (x0 y0 x1 y1); owned machines in the rect join the frontend selection. 1–3 bulk-assign WORK / THINK / LIE to the whole selection; i cycles light / medium / hard intensity; Esc clears the selection without closing menus.
  • Pause is loud. PAUSED renders in amber in the identity block; running state shows the current ms/tick.
  • Parity of legibility (design corpus): every mechanic the sim exposes is playable, and every number legible, in the terminal. A terminal-invisible mechanic is a violation, found by ticks.
  • Thin view. The terminal binary owns rendering, input mapping, and wall-clock-to-tick pacing only. No game rules; Sim is the single authority (architecture guardrail).
  • Cursor, not avatar. Movement keys move frontend attention across every tile, including walls and fog. Sim mutations such as salvage/buy/fallback use the cursor coordinate, but moving the cursor itself changes no sim state.
  • One canvas, two dialects. A fresh terminal opens DIGITAL. F3 flips to REAL and back without changing sim/save state, cursor, selection, or menu. DIGITAL may expose earned graph knowledge over physical Unknown but must not infer floor, room, body, or material sight from it. REAL never inherits the complete graph layer.

Headless: agent-mode smoke run (wiki/process/workflows.md), asserting the plain-text playing frame, Operations PEOPLE frame, help vocabulary, -- ok tick: terminator, no ANSI bytes, and same-seed byte-identical replay. This is the standard “observed in an actual run” for terminal playability changes.

Human chrome: pty smoke run, replayed through a terminal emulator (e.g. pyte) to assert raw-mode layout, title screen, alternate-screen behavior, and size handling. This remains required when the human terminal renderer itself changes.

  1. Every color used by the terminal binary is one of the palette constants above, used with its stated meaning; no crossterm named colors, no ad-hoc RGB.
  2. No information is carried by color alone anywhere: bands print names, selection has a marker plus reverse video, run-state is written text.
  3. Day and tick render in every playing-screen frame; every log line is prefixed with its tick.
  4. The fleet aggregate bar’s segments are identifiable without color (distinct fill characters keyed to legend rows), and each channel shows its percentage and effect.
  5. All active key bindings, including save/load, are visible in the pinned hint block (no panel-open keys).
  6. The @ marker is a cursor, not a player entity: cursor movement is free over all map tiles and never changes sim state; the sidebar inspect card updates from Sim::inspect with fact provenance.
  7. People render on the map only inside sensor coverage; until the Operations migration lands, earned off-map people remain reachable through the host-rack context menu (wiki/mechanics/schedules.md criterion 4 remains satisfied via the rail and agent people frame).
  8. The playing screen, title screen, and game-over card all render inside a 70×22 terminal; smaller sizes get the size warning, not a crash.
  9. An agent-mode smoke run of playing frame → people → help → quit exits cleanly, emits no ANSI bytes, and is byte-identical under repeated --seed runs; pty replay remains the chrome-specific check for raw-mode title/playing/game-over layout changes.
  10. A fresh human terminal opens DIGITAL. Its map and REAL’s map are distinct projections over the same coordinates; only DIGITAL embeds deduplicated known reach links and exact node states. F3 preserves serialized sim state, cursor, selection, and menu, and both dialects remain playable at DF density without depending on color alone.

T1. The retired r/e/t/u panels do not return; uppercase I is labeled as the one Operations view command. T2. Earned off-map people move from the host-rack aggregate to Operations PEOPLE without changing staged identity or map-presence rules. T3. At 70×22, Operations exposes all five views, preserves list/detail/back navigation, and confirms one exact bound action without leaking facts or having navigation input itself advance a tick. Its projected rows match Bevy and agent mode while the ordinary unpaused clock remains live.

T1-T3 are unmet renderer criteria owned by wiki/interface/operations-workspace.md; they do not relabel the implemented terminal baseline before that work order lands.