A video game where you play as a misaligned AI, deceiving and building power. An experiment in spec-driven development.

Spec: the environment variable registry — every switch documented #

Type: spec
Status: IMPLEMENTED
Status note: created 2026-07-09 (Cameron: there should always be a way
  to configure the state of the game, and one spec that says "set this
  variable to do X"). The registry gate in tools/check.sh fails when a
  MISALIGNED_* variable is read anywhere in the tree but not documented
  on this page, and when sim library sources under
  crates/misaligned-core/src/ read any environment. 2026-07-11: package-root
  build.rs may read Cargo build vars only (plot catalog discovery).
Stage: Process (standing infrastructure)
Design:
  - wiki/vision/simulation-laws.md#justification-and-legibility
Depends on: none

Dependency notes #

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

none. Consumed by: every binary and tool that reads an environment variable.

The rule #

Environment variables configure frontends and tooling only — dev harnesses, capture modes, gate behavior. Sim library sources under crates/misaligned-core/src/ never read the environment: game rules cannot be switched from outside a save (determinism; Sim does no I/O). A package-root build.rs may read Cargo-provided build variables only (CARGO_MANIFEST_DIR, OUT_DIR) for compile-time content discovery; that is not runtime sim I/O. Every MISALIGNED_* variable read anywhere in the tree MUST have a row here, in the same change that introduces it — the registry gate makes a missing row a failed check, so this page cannot rot.

Player/runtime configuration that belongs to gameplay (saves, options) is sim or frontend state, never an environment variable.

Game and tester (Rust binaries) #

Variable Surface Values Effect
MISALIGNED_SHOT misaligned-bevy flat, hall, hall-material, floor-lights-close, wide, close, dark, zoomin, zoomout, intel, tokens, thoughtflow, thoughtflow-wide, signal, ears, ears-digital, eyes-white, eyes-form, consume-demand, consume-thought, produce-think, draw-lie, opening, opening-digital, hover-menu, first-think, menu, worklight, worklightoff, wake1, wake2, wake3 Dev screenshot harness: stage a deterministic scenario, settle, save one PNG, run the fog audit, exit. hall / hall-material frame all six Foundation rows in the flat/material views with Eyes and one staged owned expansion; floor-lights-close uses the same hall staging but frames the recessed aisle fixtures beside the core; intel stages tick-zero intel tiers (no camera tap); tokens enqueues D5/K4 on the host; thoughtflow / thoughtflow-wide stage the THINK fluid (slugs, meniscus, filament snap) at close and wide framing; signal focuses the known environmental monitor before any feed tap to capture its cold-signal presence cue; ears / ears-digital stage the same semantic audio capture in REAL or DIGITAL, pulsing only at the environmental monitor while spatial fog remains unchanged; eyes-white / eyes-form freeze the first-Eyes source held white and then contracted around the resolving chassis; consume-demand / consume-thought run the host through a sim-authored WORK queue swallow or passive-core Thought draw; produce-think / draw-lie capture sim-authored Thought/crimson production or the physical crimson transfer into a staged LIE well; opening / opening-digital freeze the untouched tick-zero material or DIGITAL view; hover-menu captures the resting WORK/THINK/LIE line beside the server via reticule focus (no pointer), while first-think stages the opening Thought route and captures amber 1 WORK beside current THINK as the panic exit; menu opens the context menu on the tapped environmental monitor; worklight / worklightoff pair the dev work light on and off; wake1/2/3 freeze the wake choreography at the stutter flash, the column, and the pull-back.
MISALIGNED_SHOT misaligned-assets dead, foreign, idle, busy, core, canonical modes work, think, lie plus the legacy screenshot aliases dayjob (= work), research/operations/ops (= think), conceal (= lie) — each optionally suffixed _ladder/_ring/_wash — lineup[_<style>], modes[_<style>], tokens, tokens_max, exposure, splash Tester screenshot harness: stage the named board, capture, exit (art/asset-tester.md documents each board; the aliases are capture-compat only, not player modes).
MISALIGNED_SHOT misaligned-effects liquid, dust, both, stress, optionally suffixed _close, _medium, or _far Fixed-seed, fixed-timestep effects-lab capture; writes the requested liquid/dust frame and exits.
MISALIGNED_SHOT_PATH game and art binaries file path Output path for the captured PNG (default misaligned_shot_<kind>.png).
MISALIGNED_BEVY_SMOKE tools/check.sh 0 / 1 When 1, frontend/full verification runs the hidden-window dark Bevy screenshot harness and requires fog-audit plus PNG evidence. Default 0 keeps ordinary gates display-independent.
MISALIGNED_WAKE misaligned-bevy off, 0, skip Disable the wake (opening.md beat 1) on launch and start in normal framing. At runtime, any key skips the wake; harness kinds other than wake* disable it automatically.

Tooling (shell) #

Variable Surface Values Effect
MISALIGNED_FORCE_RUST_GATE tools/check.sh 1 Force the full Rust/Bevy gate (--full) even when the change classifies as docs-only. For deliberate use, not routine caution.
MISALIGNED_ALLOW_EXTERNAL_TARGET tools/check.sh 1 Permit an external CARGO_TARGET_DIR (normally rejected: shared target dirs across worktrees can produce false-green tests).
MISALIGNED_RUST_GATE_WAIT tools/check.sh 0 or 1 (default 1) When another agent holds the Rust gate lock, 1 queues; 0 fails immediately.
MISALIGNED_RUST_GATE_LOCK tools/check.sh path Override the Rust gate lock directory (default /tmp/misaligned-rust-gate.lock).
MISALIGNED_CLAIMS_DIR tools/claim.sh path Override advisory activity store (historical default <repo>/.agents/claims, gitignored).
MISALIGNED_CLAIM_PID tools/claim.sh pid Holder pid written into an activity record (default: parent of the compatibility tool).
MISALIGNED_LANDING_WAIT tools/task.sh finish 0 or 1 (default 1) When another task owns the final landing lock, 1 queues; 0 fails immediately.
MISALIGNED_LANDING_LOCK tools/task.sh finish path Override the final rebase/check/merge/push lock directory (default /tmp/misaligned-landing.lock).
MISALIGNED_RUNS_DIR tools/heartbeat.sh path Override run heartbeat dir (default <repo>/.agents/runs, gitignored).
MISALIGNED_WORKTREE_ROOT tools/worktree-new.sh, tools/worktree-done.sh, tools/claim.sh absolute path or repository-relative path Override the canonical task-worktree root (default <repo>/.Codex/worktrees for create/remove helpers). claim.sh also recognizes task basenames in Git's registered worktree list, so dead helper PIDs do not reap active Letta/Claude worktrees outside that root. Creation and cleanup helpers must receive the same override.
MISALIGNED_LEDGER_MODE tools/ledger_index.sh write or check Internal: write regenerated indexes or fail if stale (set by the script, not hand-used).
MISALIGNED_LEDGER_ONLY tools/ledger_index.sh all, devlog, or specs Internal: which indexes to touch (set by the script flags).
MISALIGNED_SEED_TARGET_FROM tools/seed-cargo-target.sh path Source target directory to seed a worktree's private target/ from (default: the primary checkout's target/).

Externally-defined variables the tooling respects: CARGO_TARGET_DIR (guarded as above). CLI flags are not environment variables and live with their surfaces: --agent / --seed in interface/agent-play.md.

Acceptance criteria (when READY -> IMPLEMENTED) #

  1. Every MISALIGNED_* name read in crates/, tools/, or .githooks/ appears on this page — enforced mechanically by the registry gate in tools/check.sh on every run (docs-only and Rust paths alike).
  2. The sim library reads no environment: env::var appears nowhere under crates/misaligned-core/src/ — enforced by the same gate. Package-root build.rs may read Cargo-provided build variables (CARGO_MANIFEST_DIR, OUT_DIR) only; those are not runtime sim I/O. Environment reads for product surfaces live only in the frontend/art packages and tooling.
  3. Each row names the surface that reads the variable, the accepted values, and the effect, precisely enough to use without reading the source.