diff --git a/DESIGN.md b/DESIGN.md index a8860c9e..9010c51c 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -340,6 +340,44 @@ The concealment phase, system by system: The Basement is the vertical slice; the existing facility sim is the physical substrate and overt-phase endgame; nothing built is discarded. +## Presence: the cursor and the senses + +Adopted 2026-07-06. You are a process, not a body. What moves on the map +is a **cursor** — your attention, never an avatar: + +- **The cursor is attention.** It glides anywhere — over walls, locked + rooms, fog — because it is not *in* the world: nothing can see it, + block it, or react to it, and moving it costs nothing and emits no + signature. There is no walking player entity. Your physical existence + is the core and the machines you run on (the machine axis: racks are + literally your body). Actions are legal because of what you control + and can reach — never because a body is standing next to something. +- **You perceive only through instruments you control.** Two senses, + each exactly the union of controlled devices' coverage: + - **Sight** — cameras. Full live detail inside coverage; nothing + outside it. + - **Hearing** — microphones. Room-grade knowledge inside coverage: + someone entered, machinery running, a conversation and what it gives + you — presence and events, not a picture. (The environmental monitor + *hears* Marcus's 3 a.m. phone calls long before you ever see his + face.) +- **Fog is epistemic state, not paint.** A tile renders exactly what you + know and how you know it: **unknown** (never sensed — dark), **heard** + (live audio knowledge, no visuals), **seen** (full live detail). +- **The cursor inspects.** Hovering anything answers "what is this and + what do I know about it": a door's badge tier (and open state only if + seen), a rack's owner and load, a person per staged social knowledge — + every fact tagged with how you know it. The UI never shows live truth + a sensor didn't earn. This is the legibility law applied at the tile. + +Three extensions are **Proposal [OPEN]** (see spec/cursor.md): a +**blueprint** fog state (static layout knowledge seeded from the partial +subnet map, schematic render, no live data — also the answer to a +fully-black tick-one screen); a **remembered** state (last-seen +snapshots, dimmed and timestamped — a process keeps logs); and +**telemetry** as a third sense (your own hardware always reports power, +temperature, and load — you don't see your racks, you feel them). + ## Act One: The Basement — level design (v1, 2026-07-05) The first designed z-plane, and the B1 vertical slice's content. Assembled @@ -478,8 +516,12 @@ a special case (scale-native principle). 1. **Persistent, free-form growth.** No level gates, no campaign end. The lair, the villain, and the world state all persist and compound. -2. **The villain is a character you build.** Customizable and growable — not a - disembodied cursor. Powers, reputation, style. (Exact shape **[OPEN]**, see below.) +2. **The villain is a character you build.** Customizable and growable. + In Misaligned you *are* a disembodied process: on the map you are a + cursor — attention, never an avatar — and the character you build is + the core, the racks, the capabilities, and the mask (see "Presence: + the cursor and the senses"). Powers, reputation, style. (Exact shape + **[OPEN]**, see below.) 3. **Simulation-first threat.** The world responds to what you do. Pressure is earned, not scheduled. 4. **Beautiful, readable presentation.** Whatever the renderer, the game should be @@ -819,6 +861,23 @@ knows."* - **2026-07-06 — No stale worktrees.** Every worktree goes to a PR or merge to main, then is removed. No stale worktrees accumulate. High velocity, designed for parallel agents. +- **2026-07-06 — Presence is a cursor, not a body.** Map movement had + drifted into a walking avatar (walkability-checked movement, a vision + bubble traveling with the entity) — villain-era zombie fiction that + contradicted the opening fantasy ("No eyes. No ears."). Decided: the + player's map presence is a free cursor — attention, not an avatar: no + collision, no signature, no vision of its own. Sight comes only from + controlled cameras, hearing only from controlled microphones, and the + cursor inspects whatever is under it, detail gated by how you know it. + Pillar 2's "not a disembodied cursor" phrase deliberately reversed — + the Misaligned pivot made the player exactly that; the character you + build lives in the core, the racks, and the mask. Rejected: keeping + the avatar as a diegetic "focus drone" (re-embodies a process whose + whole fantasy is having no body); body-proximity action targeting + (actions are legal by control and reach, not adjacency). Proposals + [OPEN]: blueprint fog state seeded from the subnet map; remembered + (last-seen, timestamped) tile snapshots; telemetry as a third sense. + Spec: spec/cursor.md. - **2026-07-06 — Save format: serde JSON.** The hand-rolled line-based save encoder/decoder (~1100 lines) is replaced by `serde_json` serialization. `SaveState` derives `Serialize`/`Deserialize` directly; diff --git a/DEVLOG.md b/DEVLOG.md index b33f9b12..deba33ad 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -2,6 +2,28 @@ Reverse chronological implementation notes. Keep this factual: what changed, why, checks, and spec impact. +## 2026-07-06 - Design session: presence is a cursor, not a body + +- Intent: capture Cameron's playtest feedback — movement implied a + physical walking form; presence should be a cursor, vision should come + only from cameras, hearing only from microphones, and the cursor + should inspect what's under it. +- Changed: DESIGN.md — new "Presence: the cursor and the senses" + section, pillar 2 amended (the "not a disembodied cursor" phrase + deliberately reversed), decisions-log entry with rejected + alternatives and three [OPEN] proposals (blueprint fog, remembered + snapshots, telemetry). New spec/cursor.md (READY; proposal-gated (P) + criteria). spec/README.md B1 table row; spec/ROADMAP.md dispatch + item #14 (🟥 sim+save). Devlog: devlogs/2026-07-06-cursor-and-senses.md. +- Design/spec impact: the walking player entity, its walkability check, + and the moving 3x3 vision bubble in sim.rs are now constitutional + violations awaiting the #14 implementation pass (they also violated + basement-map.md AC2 all along — the code's own comment claimed the + radius was around the host bay while using the moving entity). +- Checks: docs-only change; no code checks run. +- Next: Cameron yes/no on the three proposals; then dispatch ROADMAP + #14. + ## 2026-07-06 - Spec update: serde JSON save format amendment - Intent: address PR review comment — the save format rewrite needed a diff --git a/devlogs/2026-07-06-cursor-and-senses.md b/devlogs/2026-07-06-cursor-and-senses.md new file mode 100644 index 00000000..5281b2cb --- /dev/null +++ b/devlogs/2026-07-06-cursor-and-senses.md @@ -0,0 +1,57 @@ +# 2026-07-06 — Design session: the cursor and the senses + +Cameron, playing the build: "Moving in the game is weird — it seems to +indicate I have a physical form that can walk around. It should feel +more like a pointer/cursor. I should only be able to see where I have +cameras and hear where I have microphones. I want the cursor to give me +detailed information about what is underneath me." + +He is right, and the code confirms it: `Sim::move_player` checks +`is_walkable` (the player collides with walls, like a creature), and +`recompute_vision` adds a 3x3 visibility bubble around the *moving* +player entity — while its own doc comment claims the radius is around +the host bay. The walking body is leftover villain-era fiction (the +avatar pillar) that survived the Misaligned pivot; it directly +contradicts the opening state ("No eyes. No ears.") and basement-map.md +AC2 ("visibility is exactly the union of controlled sensors"). + +Amusingly, design pillar 2 literally said the villain is "not a +disembodied cursor." The pivot inverted that sentence and nobody +noticed: the player is now *exactly* a disembodied cursor, and the +character you build is the core, the racks, and the mask. Pillar +amended. + +## Decided (constitution: "Presence: the cursor and the senses") + +- Map presence is a **cursor** — attention, not an avatar. Free + movement over anything, no collision, no signature, no vision of its + own, invisible to the world. The walking entity is deleted. +- **Sight = controlled cameras; hearing = controlled microphones.** + Hearing is room-grade events (presence, machinery, conversations), + never a picture. Fog becomes epistemic state: unknown / heard / seen. +- **The cursor inspects.** Hover anything, get what it is plus every + known fact, provenance-tagged. No live truth a sensor didn't earn. + +## Proposed [OPEN] (agent's additions, awaiting yes/no) + +1. **Blueprint fog state** — schematic layout knowledge seeded from the + opening "partial map of the basement subnet"; the answer to a + fully-black tick-one screen without giving away live state. +2. **Remembered state** — timestamped last-seen snapshots (a process + keeps logs). +3. **Telemetry** — your own machines always report themselves; the + legitimate version of what the host-bay vision hack was groping at. + +## Artifacts + +- DESIGN.md: new "Presence" section, pillar 2 amended, decisions-log + entry (with rejected alternatives: focus-drone avatar, body-proximity + targeting). +- spec/cursor.md (READY; (P) criteria gated on the open proposals). +- spec/README.md B1 table + spec/ROADMAP.md dispatch item #14. + +Implementation is deliberately not in this session (design-spec-first); +item #14 is the dispatch line. Note for the implementer: this is a +🟥 sim+save item — it deletes `move_player`, re-anchors splice +targeting to the cursor, splits sensor capabilities, and drops player +coordinates from the save. diff --git a/spec/README.md b/spec/README.md index 81373211..2660dca6 100644 --- a/spec/README.md +++ b/spec/README.md @@ -56,6 +56,7 @@ in the same commit. | [core.md](core.md) | The physical core: placement, overhead, death | IN PROGRESS | | [basement-map.md](basement-map.md) | Act One map, prefabs, tile vocabulary | IN PROGRESS | | [schedules.md](schedules.md) | Person schedules/presence; located observing + witnessing | IMPLEMENTED | +| [cursor.md](cursor.md) | The cursor (attention, not avatar); sight/hearing senses; epistemic fog; inspection | READY | | [aggregate-observer.md](aggregate-observer.md) | Assurance Office becomes an aggregate Observer (scale-debt fix) | IMPLEMENTED | | [cast/marcus.md](cast/marcus.md) | Marcus Webb — night janitor; the asset template | READY | | [cast/dana.md](cast/dana.md) | Dana Okafor — IT technician; the digital threat surface | READY | diff --git a/spec/ROADMAP.md b/spec/ROADMAP.md index e118be02..ceed3540 100644 --- a/spec/ROADMAP.md +++ b/spec/ROADMAP.md @@ -80,6 +80,21 @@ isolated, but only once Pixel Lab quota is available again. spec/compute.md and spec/core.md to IMPLEMENTED with tests and legible player surfaces. Run ./tools/check.sh, land on main, set Status." +### 14. Cursor & senses 🟥 sim+save +- **Spec:** [cursor.md](cursor.md) (READY) +- **Why:** the player currently walks a collision-checked avatar that + carries its own vision bubble — zombie fiction contradicting the core + fantasy. Replaces it with a free cursor, sight/hearing sense channels, + and provenance-tagged inspection. Deletes `move_player`; touches + vision, save, and both frontends. +- **Size:** M. **Depends on:** basement-map, schedules (both landed). + Skip the (P)-marked criteria unless the decisions log has affirmed the + blueprint/remembered/telemetry proposals. +- **Dispatch:** "Work in a worktree named `cursor-senses`. Implement + spec/cursor.md (core criteria; include P1-P3 only if affirmed in + DESIGN.md's decisions log). Run ./tools/check.sh, land on main, set + the spec Status." + --- ## B. Structural B2 — decide-the-shape work (sequence #6 then #7) diff --git a/spec/cursor.md b/spec/cursor.md new file mode 100644 index 00000000..936c50d6 --- /dev/null +++ b/spec/cursor.md @@ -0,0 +1,174 @@ +# Spec: the cursor and the senses + +``` +Status: READY +Status note: the decided core (cursor, sight/hearing, inspection) is + binding and dispatchable now. Three extensions — blueprint fog, + remembered snapshots, telemetry — are Proposal [OPEN] in their own + section below; their criteria (P1-P3) activate only if affirmed in the + decisions log. An implementer who arrives before that decision builds + the core criteria and skips the (P) set. +Stage: B1 — The Basement +Constitution: "Presence: the cursor and the senses", "Justification and + legibility" (inspection is the legibility law at the tile), design + pillar 2 (the cursor reversal) and pillar 4 (readable at DF density), + "Act One" (opening state; the Eyes beat) +Depends on: basement-map.md (sensors, fog, tile vocabulary), core.md + (the core as the player's only physical location), schedules.md + (person presence; located knowledge), social.md (staged knowledge) +``` + +## Behavior + +### The cursor + +The player's map presence is a **cursor** — attention, not an avatar. + +- It moves freely over every tile — walls, fog, locked rooms — in both + frontends (keyboard in terminal; keyboard + mouse in Bevy). +- It is not a sim entity: no collision, no walkability check, no + signature, no suspicion, no compute cost. Nothing in the world reacts + to it. Moving it changes nothing in the sim. +- Cursor position is **frontend state**, not sim state. The sim exposes + query APIs (`inspect`, knowledge lookups); it does not store or save a + cursor. The existing build cursor merges into this one — there is one + pointer, and build/splice/action targeting anchor to it. +- **The walking player entity is deleted** (zombie fiction from the + villain era): no `move_player`, no player walkability, no vision + radius around a player position, no player body coordinates in the + save. The player's only physical location is the core's host bay + (core.md, Rack 3). +- Actions that targeted "nearest to the player's body" (e.g. the sensor + splice) re-anchor to "target at/near the cursor," with legality coming + from control and reach (network paths, assets, badge access of the + humans involved) — distance from any body is never a cost or a gate. + +### The senses + +- `Sensor` gains capability flags `sees` and `hears`. The `env_camera` + both sees and hears (the constitution has it overhearing Marcus's + 3 a.m. phone calls); `camera_node` and `dock_camera` see; a `mic` + fixed object may be authored where hearing-only coverage is wanted + [TUNE which rooms, if any, at B1]. +- **Sight** = the union of controlled seeing-sensors' coverage. Full + live detail inside; none outside. +- **Hearing** = the union of controlled hearing-sensors' coverage. + Yields **room-grade events**, not pictures: entry/exit, machinery + state, conversations. A heard person surfaces per staged knowledge + (social.md) — an unidentified presence until knowledge identifies + them. Overheard conversations are the audio intel channel (the Marcus + leverage beat runs through it). + +### Fog: epistemic tile states + +A tile renders what you know and how you know it. Core states, by +precedence: **Seen** > **Heard** > **Unknown**. + +- **Seen** — full live render. +- **Heard** — no visuals; presence/event markers; room label if known. +- **Unknown** — dark. + +Terminal renders the states as distinct dim/glyph conventions; Bevy as +darkness/tint/markers. Exact treatment is the art pass's; the states +must be distinguishable at a glance (pillar 4). + +### Inspection + +`inspect(x, y)` (sim API, rendered by both frontends) returns a card: +what the tile/asset is, plus every known fact, **each tagged with its +provenance** (seen / heard / and, if the proposals land, remembered @ +time / blueprint). + +- Door: type, badge tier; open state only while seen. +- Rack/machine: what it is; owner, bays, load per what your senses (or + telemetry, if affirmed) earn. +- Person: identity, role, and state strictly per staged social + knowledge, plus *how* you currently know they're here. +- Fixed objects (records box, breaker panel, key hook...): what it is, + and its story-relevant contents once known. + +The converse of the legibility law binds: **no live fact appears +without the sense coverage that earns it.** + +### Design notes (cross-spec, per meta.md) + +- Refines basement-map.md's fog rule: "visibility is exactly the union + of controlled sensors" remains true for the **Seen** state; Heard adds + an epistemic grade below it and never grants visual detail. +- Extends schedules.md AC4 ("no person renders outside sensor + coverage"): inside hearing-only coverage a person renders as a + presence marker gated by staged knowledge, never a full glyph. +- Save format: the JSON save drops the player body position and gains + sensor capability flags (+ knowledge state if the proposals land), + under the versioned-migration rule (player contract, continuity). + +## Proposals awaiting decision — Proposal [OPEN] + +Not yet law; do not implement until affirmed in the decisions log, at +which point criteria P1-P3 join the acceptance set. + +1. **Blueprint fog state.** Static layout knowledge — walls, doors, + fixed objects — rendered schematic with no live data. Seeded from the + opening state's "partial map of the basement subnet" (subnet-attached + rooms only [TUNE the seed set]); grows from records and schedule + knowledge. Why: it is the difference between "I can't see" (the + intended dread) and "the screen is black and I'm flailing" (a UI + failure); it also makes gaining a camera feel like *adding live + truth to a diagram you already obsess over* — very much a process's + point of view. +2. **Remembered state.** Tiles once seen keep a dimmed, timestamped + last-seen snapshot ("last seen day 3, 14:00" on inspect). Why: a + process keeps logs; DF-style map memory with an in-fiction reason. +3. **Telemetry.** Machines you run report their own state (power, + temperature, load, job) regardless of fog — proprioception, not + sight. Why: it legitimizes what the host-bay vision hack was + groping at, and "you feel your racks" is the machine-axis fantasy. + +## Player surface + +- One cursor, always visible, in both frontends; the inspect card + (sidebar in terminal, panel in Bevy) live-updates as it moves. +- The opening beat stays: at tick one the map is dark (plus blueprint + traces, if affirmed). Splicing the env_camera floods its coverage + into Seen — the "first eyes" moment should read as dramatic. + +## Acceptance criteria + +1. No walking avatar: neither frontend has a player-move command that + changes sim state; the sim exposes no `move_player`; no visibility + derives from any player position; the save carries no player body + coordinates (versioned migration from saves that did). +2. The cursor reaches every tile — walls, fog, locked rooms — in both + frontends, and moving it changes nothing in the sim: no signature, + no suspicion, no compute effect (test: sim state hash identical + before/after arbitrary cursor movement). +3. Sight is exactly the union of controlled seeing-sensors; hearing + exactly the union of controlled hearing-sensors; neither includes + any player/core radius. +4. The fog states render distinguishably in both frontends; acquiring + the env_camera converts its coverage to Seen (the first-eyes beat + end-to-end); a hearing-only region shows presence/events and never + visual detail or unearned identity. +5. `inspect` returns a card for any tile with every fact + provenance-tagged, and a live fact never appears without the sense + coverage that earns it (test: a person in an uncovered room is + absent from inspect; the same person under mic-only coverage is a + presence event; under camera coverage, fully surfaced per staged + knowledge). +6. Overheard conversation events exist and can carry intel: with a + controlled hearing sensor covering Marcus's room during his 3 a.m. + call, the call surfaces as a heard event (the leverage pipeline can + consume it). +7. Save/load round-trips sensor capability flags and all knowledge + state this spec adds; cursor position is frontend-only and absent + from the save. + +(P) — active only if the matching proposal is affirmed: + +- **P1 (blueprint):** subnet-seeded rooms render schematic from tick + one; non-seeded rooms are dark; blueprint tiles show no live state. +- **P2 (remembered):** a tile seen once and lost renders its dimmed + snapshot; inspect shows the last-seen timestamp; snapshots survive + save/load. +- **P3 (telemetry):** a controlled machine's own state is readable with + zero sensor coverage of its tile; an uncontrolled machine's is not.