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) #
- Every
MISALIGNED_*name read incrates/,tools/, or.githooks/appears on this page — enforced mechanically by the registry gate intools/check.shon every run (docs-only and Rust paths alike). - The sim library reads no environment:
env::varappears nowhere undercrates/misaligned-core/src/— enforced by the same gate. Package-rootbuild.rsmay 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. - Each row names the surface that reads the variable, the accepted values, and the effect, precisely enough to use without reading the source.