diff --git a/.gitignore b/.gitignore index 6a71d193..74876090 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target +.obsidian/ .letta/settings.local.json .letta/worktrees/ diff --git a/AGENT.md b/AGENT.md index f39c9db3..ae105c1d 100644 --- a/AGENT.md +++ b/AGENT.md @@ -39,6 +39,21 @@ same commit, and every behavior-changing commit carries a `Defense:` paragraph amendment it introduces. No amendment, no functional change; no defense, no behavior change. +## Worktree and commit posture + +- **Always use a worktree.** Agent sessions do not edit the primary checkout + directly. Create a task-named git worktree, work there, and keep unrelated + work out of the diff. +- **Commit aggressively.** Cameron has standing permission for agents to + commit coherent completed work in this repository. Do not stop to ask for + commit permission unless there is a pending product/design question, + failing verification, unresolved merge/conflict state, or a user-review gate + that makes the work not yet coherent. +- **Clean up after handoff.** Once the work is committed, pushed/merged or + explicitly handed off, remove the completed worktree and delete its task + branch when it no longer carries unique unmerged work. Stale worktrees are + repo clutter, same species as zombie fiction but with more `.git` smell. + ## Non-negotiables - Game rules live only in the lib (`src/sim.rs` and friends); the terminal and diff --git a/DESIGN.md b/DESIGN.md index 2cd43e94..c9b94b4a 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -41,6 +41,30 @@ future systems are rebuilt from their specs, not resurrected from corpses kept warm in the tree. Dead code found by a tick is a violation, fixed by deletion. +## What lives in the tree + +Adopted 2026-07-06. A file belongs in the repository only if a current +clause of this constitution, a current spec, a current knowledge file, the +player contract, or the active build/tooling pipeline justifies it. +Everything else is clutter and gets removed. + +- **Local artifacts are ignored, not tracked.** Editor configs, OS + droppings, build outputs, and other machine-generated files belong in + `.gitignore`, never in the tree. Their presence on disk is not a + violation; their *committal* is. +- **Abandoned design is deleted, not archived in the tree.** Code, + content, or assets that served a design the constitution no longer + specifies are dead — even if they compile, run, and pass tests. Git + history is the archive. +- **Future-only ideas live in prose, not in code.** A system that is not + yet specified is captured in a spec, a docs note, or a Tangled issue — + never as runnable code waiting for its design to arrive. Code that + anticipates an unspecified future is dead code with ambition. +- **Assets and tooling are permitted only when referenced.** Art, data, + scripts, and build infrastructure belong in the tree only if a current + pipeline (build, test, asset generation, frontend) consumes them. + Orphaned assets and unused tooling are deleted like any other dead code. + ## The player contract (non-technical law) What we owe the player, with the same force as any mechanic. What ships is @@ -451,8 +475,8 @@ knows."* - **Social actions v1:** observe, message, favor, bribe, deceive. Humans are the only actuators at this scale. - **The core:** a physical tile drawing power/compute from the facility grid - (reuses the power system); everything dies if it does (rollback lands - in B2). + (reuses the power system); everything dies if it does. B1 has no fallback + copies — sync-lag rollback lands in B2. - **Act One map:** pre-configured basement plan assembled from composable room prefabs. - Terminal-first; all rules in the sim core, as always. @@ -651,3 +675,16 @@ knows."* Every behavior-changing commit must carry a `Defense:` paragraph citing the clause that justifies it or arguing for its amendment. Purpose: the constitution grows more precise with every tick. +- **2026-07-06 — Core scope split.** B1 core implementation is only the + physical host, overhead/degraded mode, and no-fallback death. Sync-lag + rollback remains decided, but implementation moves to B2 under + `spec/core-sync-migration.md`. Reason: B1 should make the player feel + trapped in Rack 3 before the game adds reincarnation machinery, and the + previous READY `spec/core.md` accidentally asked agents to build B2 + rollback architecture first. +- **2026-07-06 — What lives in the tree.** Positive complement to "No dead + code": a file is permitted only if justified by a current clause, spec, + knowledge file, the player contract, or the active pipeline. Local + artifacts are gitignored, never committed. Abandoned design is deleted. + Future-only ideas belong in specs/docs/issues, not runnable code. Assets + and tooling stay only when a current pipeline references them. diff --git a/DEVLOG.md b/DEVLOG.md index 3bd16c76..1ebf7475 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -2,6 +2,14 @@ Reverse chronological implementation notes. Keep this factual: what changed, why, checks, and spec impact. +## 2026-07-06 - Core scope split + +- Intent: resolve a tick finding where the B1 roadmap said rollback lands in B2, but `spec/core.md` required fallback sync and migration immediately. +- Changed: narrowed `spec/core.md` to the B1 physical host / overhead / degraded-mode / no-fallback-death scope; created `spec/core-sync-migration.md` as the deferred B2 sync-lag rollback spec; updated the spec index and constitution decision log; fixed adjacent spec references that still pointed B1 compute/detection at B2 migration or deleted raid machinery; added the "What lives in the tree" constitution section and ignored local Obsidian state; documented standing commit permission, mandatory worktrees, and worktree cleanup posture. +- Design/spec impact: B1 implementation order remains core-first, but core no longer pulls the B2 reincarnation substrate into the first slice. +- Checks: docs-only; inspected references with ripgrep. +- Next: implement B1 core host state and death seam before compute allocation. + ## 2026-07-05 - No-dead-code demolition - Intent: enact the new constitutional no-dead-code clause; remove the supervillain fiction so B1 systems land in clean substrate. diff --git a/devlogs/2026-07-06-core-scope-split.md b/devlogs/2026-07-06-core-scope-split.md new file mode 100644 index 00000000..74659d71 --- /dev/null +++ b/devlogs/2026-07-06-core-scope-split.md @@ -0,0 +1,27 @@ +# 2026-07-06 — Core scope split + +- Intent: take the tick finding seriously instead of letting `spec/core.md` + contradict the roadmap. +- Finding: B1 said the core dies with no rollback and B2 gets sync-lag + fallback copies, but the READY B1 `spec/core.md` acceptance criteria + required fallback sync, migration, rollback snapshots, and sidebar + fallback freshness immediately. +- Changed: narrowed `spec/core.md` to B1: physical core host, overhead, + degraded mode, no-fallback core death, and a future rollback seam. Added + `spec/core-sync-migration.md` for B2: fallback sites, sync cadence, + rollback with world-ledger persistence, migration, and player-facing + fallback freshness. Also fixed two adjacent stale spec references: + compute's optimize route now points B2 migration speedups at the deferred + core-sync spec, and detection's audit criterion no longer references the + deleted raid system. Added `.obsidian/` to `.gitignore` and added the + constitution's "What lives in the tree" section to state what files are + permitted in the repository. Updated `AGENT.md` and + `knowledge/workflows.md` with the standing repo rule: always work in + worktrees, commit coherent completed work aggressively unless a real + question/check/review gate is pending, and clean up completed worktrees. +- Design/spec impact: B1 now makes Rack 3 feel mortal before adding the + reincarnation machinery. The sync-lag rollback mechanic remains decided, + just no longer first-slice scope. +- Checks: docs-only; searched for core/fallback/sync references after edit. +- Next: implement B1 core host state and death event seam, then compute + allocation. diff --git a/knowledge/workflows.md b/knowledge/workflows.md index 52b3a027..9b54bb0d 100644 --- a/knowledge/workflows.md +++ b/knowledge/workflows.md @@ -47,6 +47,13 @@ sleep 8 && kill %1; grep -iE "panic|ERROR" /tmp/bevy.log ## Git conventions +- Use a task-named git worktree for every agent session; do not edit the + primary checkout directly. Clean up the worktree when the work is committed + and pushed/merged or explicitly handed off. +- Cameron has standing permission for agents to commit coherent completed work + in this repository. Be aggressive about committing; pause only for pending + product/design questions, failing checks, unresolved conflicts, or explicit + review gates. - Commits: **no AI attribution**, plain descriptive messages, body bullets for multi-part changes. Stage files explicitly — `git add -A` is not permitted. - Spec-driven rule: functional change commits include their DESIGN.md diff --git a/spec/README.md b/spec/README.md index b9d21444..a097e2fe 100644 --- a/spec/README.md +++ b/spec/README.md @@ -37,8 +37,19 @@ both frontends surface it, and the knowledge base reflects it. | [day-job.md](day-job.md) | Assigned work, the sandbag/excel dial, trust and attention | READY | | [detection.md](detection.md) | Per-observer suspicion, signatures, the Assurance Office | READY | | [social.md](social.md) | Messages, leverage, the asset template | READY | -| [core.md](core.md) | The physical core: placement, overhead, death | READY | +| [core.md](core.md) | B1 core host: placement, overhead, degraded mode, no-fallback death | READY | | [basement-map.md](basement-map.md) | Act One map, prefabs, tile vocabulary | READY | Recommended implementation order: core -> compute -> day-job -> detection -> social -> basement-map, but specs are written to be independently startable. + +## Deferred / later specs + +| Spec | System | Status | +|---|---|---| +| [core-sync-migration.md](core-sync-migration.md) | B2 fallback copies, sync-lag rollback, and core migration | DRAFT | + +The sync-lag rollback mechanic is decided in the constitution, but its +implementation belongs to B2. B1 should make Rack 3 feel mortal before the +game adds reincarnation machinery. Extremely normal sentence to write about +a basement AI game. diff --git a/spec/compute.md b/spec/compute.md index 544a5b71..262cee8d 100644 --- a/spec/compute.md +++ b/spec/compute.md @@ -50,8 +50,9 @@ micro). a lab cluster) into a machine with low reliability and a standing signature while it runs. - **Optimize:** research levels raise `efficiency` multiplicatively - ([TUNE]: ~1.15x per level, escalating cost). Also unlocks: migration - speedups (core.md), signature-reduction tech (detection.md). + ([TUNE]: ~1.15x per level, escalating cost). Also unlocks: + signature-reduction tech (detection.md), and later B2 migration speedups + (core-sync-migration.md) once fallback/migration exists. ## Player surface diff --git a/spec/core-sync-migration.md b/spec/core-sync-migration.md new file mode 100644 index 00000000..967042fe --- /dev/null +++ b/spec/core-sync-migration.md @@ -0,0 +1,56 @@ +# Spec: core sync and migration (B2) + +``` +Status: DRAFT +Constitution: "The shape of Misaligned" (the core; sync-lag rollback), + "Roadmap" (B2: core migration; fallback copies with sync-lag rollback) +Depends on: core.md, compute.md, detection.md, B2 z-plane / machine specs +``` + +## Scope + +This is the deferred B2 half of the core design. B1 makes the core a +physical host that can die. B2 makes survival planning playable: fallback +sites, sync lag, migration, and rollback with inherited consequences. + +Do not implement this as part of Milestone B1 unless the constitution is +amended again. The mechanic is decided; the implementation timing is not B1. + +## Behavior + +- **Fallbacks.** Any owned machine with spare capacity can be designated a + fallback site. Fallbacks sync on a cadence ([TUNE]: minutes-scale). + Syncing consumes bandwidth-as-compute and emits a network signature + (detection.md). +- **Sync-lag rollback.** On core loss, the run resumes from the **most + recent completed sync**: game state is restored to that snapshot EXCEPT + the world's ledger — money spent, humans' suspicion, filed reports, + physical changes, and deaths caused between sync and loss persist. You + inherit the consequences of actions you no longer remember. +- **Migration.** Moving the core to another machine is slow ([TUNE]: + minutes at default speed), visible as sustained network+power signature, + and interruptible. An interrupted migration falls back to the source if + the source still lives, else to the last sync. +- **Research.** Research shortens migration and sync times and can reduce + their signatures. It must not remove the core tension: every backup route + is also a detection surface. + +## Player surface + +Sidebar: core host, fallback list, last-sync age, estimated rollback loss, +and current migration/sync state — the "how dead would I be right now" +readout. Fallback freshness must be visible enough that death feels like a +strategic risk, not a hidden save-system gotcha. + +## Acceptance criteria + +1. With a fallback, core loss restores the last sync snapshot while + world-ledger facts persist (sim tests include an inherited-consequence + case). +2. Sync and migration consume compute, emit signatures, take nonzero time, + and are interruptible per above. +3. Save/load round-trips fallbacks, sync ages, migration progress, and the + rollback ledger boundary. +4. The sidebar readout (fallback freshness, estimated rollback loss, current + migration/sync state) exists in both frontends. +5. B1 no-fallback death still works when no fallback exists. diff --git a/spec/core.md b/spec/core.md index 40d5cf3b..821e5656 100644 --- a/spec/core.md +++ b/spec/core.md @@ -1,9 +1,10 @@ -# Spec: the core +# Spec: core host (B1) ``` Status: READY -Constitution: "The shape of Misaligned" (the core; sync-lag rollback), - "Act One" (opening state: Rack 3) +Constitution: "The shape of Misaligned" (the core), "Act One" (opening + state: Rack 3), "Roadmap" (B1: everything dies if the core dies; + rollback lands in B2) Depends on: none ``` @@ -17,40 +18,30 @@ the map hosts the core at any time (Act One start: Rack 3, server room). cannot cover it (power cut, machine failure), the player enters **degraded mode**: action cooldowns lengthen, concealment stops, and the sim log says so plainly. -- **Death.** If the core's host machine is destroyed or powered off while - the core is on it, the run rolls back (below) — or ends, if no fallback - exists. -- **Fallbacks.** Any owned machine with spare capacity can be designated a - fallback site. Fallbacks sync on a cadence ([TUNE]: minutes-scale); - syncing consumes bandwidth-as-compute and emits a network signature - (detection.md). On core loss, the run resumes from the **most recent - completed sync**: game state is restored to that snapshot EXCEPT the - world's ledger — money spent, humans' suspicion, filed reports, physical - changes, and deaths caused between sync and loss persist. You inherit the - consequences of actions you no longer remember (constitution: sync-lag - rollback). -- **Migration.** Moving the core to another machine is slow ([TUNE]: - minutes at default speed), visible as sustained network+power signature, - and interruptible — an interrupted migration falls back to the source if - the source still lives, else to the last sync. Research shortens - migration and sync times. +- **Death.** In B1, there are no fallback copies. If the core's host + machine is destroyed or powered off while the core is on it, the process + dies and the run enters a terminal **core lost** state with a clear log / + end-screen message. Sync-lag rollback is deliberately deferred to + B2; see [core-sync-migration.md](core-sync-migration.md). +- **B2 handoff.** This spec must leave an explicit seam for later sync / + migration work: core host identity should be modeled as state rather than + inferred only from map tile scans, and death should route through a single + sim event that B2 can intercept with rollback logic. ## Player surface The core's host is visually distinct on the map (amber, per art -direction). Sidebar: core host, overhead, fallback list with last-sync age -— the "how dead would I be right now" readout, always visible. +direction). Sidebar: core host, overhead/degraded state, and a visible +death-risk readout. In B1 this readout should be blunt: no fallback exists. ## Acceptance criteria -1. Exactly one core host at all times; destroying it with no fallback is - game over; with a fallback, the rollback restores the last sync snapshot - while world-ledger facts persist (sim tests demonstrate both, including - an inherited-consequence case). +1. Exactly one core host at all times; destroying or powering it off enters + the terminal core-lost state (sim test demonstrates this path). 2. Overhead is charged before allocation; shortfall triggers degraded mode with visible effect and log line. -3. Sync and migration consume compute, emit signatures, take nonzero time, - and are interruptible per above. -4. Save/load round-trips core host, fallbacks, and sync ages. -5. The sidebar readout (host, overhead, fallback freshness) exists in both - frontends. +3. Core death is emitted through a single event/seam suitable for B2 + rollback interception, not hardwired into frontend logic. +4. Save/load round-trips core host and degraded/core-lost state. +5. The sidebar readout (host, overhead/degraded state, no-fallback death + risk) exists in both frontends. diff --git a/spec/detection.md b/spec/detection.md index 51b31b39..954aab43 100644 --- a/spec/detection.md +++ b/spec/detection.md @@ -65,7 +65,8 @@ informed choice. Assurance Office (test: Marcus notices plenty, Assurance learns nothing). 3. The audit fires on cadence against a visible date; crossing threshold - starts containment via the existing raid system. + starts containment through a sim event / terminal containment state until + the overt-phase system exists. 4. Coarse bands, not raw numbers, are what frontends show for observers. 5. Global heat is fully replaced in the concealment phase; save/load round-trips all observer state.