A video game where you play as a misaligned AI, deceiving and building power. An experiment in spec-driven development. forked from cameron.stream/misaligned
misaligned wiki interface terminal.md
13 kB · 228 lines

Spec: the terminal frontend #

Type: spec
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.
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

Dependency notes #

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. Individual system specs own what is shown; this spec owns how the terminal presents and drives it.

Why this spec exists #

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.

Look #

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
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.

Glyph vocabulary #

  • 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.
  • 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.

Layout #

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.
  • 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 anchor's available actions. There are no modal panel-open keys; status that used to live in People/Reach/Finance/Research panels lives on the rail, and their verbs live on the host rack, device tiles, and the switch.
  • Modal panels (People t, Reach r, Finance e) are centered framed boxes: ┌─ TITLE ─…┐ border in chrome, ├──┤ dividers, column headers in chrome caps. Panels are status and selection only: the people panel shows trace debt, per-person raw recording counts, watch state, and latest-intel provenance when known; the finance panel shows known accounts, known flows, slush balance, hidden-count summaries, and positions. Verbs live on the context menu — Enter (or a) opens it on the panel's selection.
  • Context menu — a compact overlay anchored at the cursor (or the open panel's selection), listing the focused anchor's available actions.

Feel #

  • 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.

Act #

  • 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 action surface: it renders Sim::available_actions for the focused anchor, one row per verb as verb · cost · [band]; disabled rows are dimmed and carry their reason; automate affordances (scheme policies, a per-person watch) render as indented child rows in place. Persistent settings, scheme state, and policy rows carry [control] and amber-dim; 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; only globals (pause, speed, save/load) 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.

Verification #

Headless: agent-mode smoke run (wiki/process/workflows.md), asserting the plain-text playing frame, people panel, 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.

Acceptance criteria #

  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; earned off-map people are reachable through the host-rack context menu (wiki/mechanics/schedules.md criteria 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.