diff --git a/crates/misaligned-bevy/src/main.rs b/crates/misaligned-bevy/src/main.rs index 748d664a..54089664 100644 --- a/crates/misaligned-bevy/src/main.rs +++ b/crates/misaligned-bevy/src/main.rs @@ -131,7 +131,7 @@ const MIN_WINDOW_WIDTH: f32 = 960.0; const MIN_WINDOW_HEIGHT: f32 = 540.0; const SIDEBAR_SCROLL_LINE: f32 = 18.0; const SIDEBAR_SCROLL_PAGE: f32 = 180.0; -const COMPUTE_CHANNELS: usize = 4; +const COMPUTE_CHANNELS: usize = 3; /// A mobile evidence rack keeps seven literal records countable. Additional /// exact records remain in inspect/Operations and raise one sealed index tab /// rather than growing unbounded geometry around the person. diff --git a/crates/misaligned-bevy/src/rail_ui.rs b/crates/misaligned-bevy/src/rail_ui.rs index 758ea871..9cb3e14e 100644 --- a/crates/misaligned-bevy/src/rail_ui.rs +++ b/crates/misaligned-bevy/src/rail_ui.rs @@ -412,7 +412,7 @@ pub(super) fn spawn_compute_card(parent: &mut ChildSpawnerCommands) { for index in 0..COMPUTE_CHANNELS { bar.spawn(( Node { - width: Val::Percent(25.0), + width: Val::Percent(100.0 / COMPUTE_CHANNELS as f32), height: Val::Percent(100.0), ..default() }, @@ -1252,7 +1252,6 @@ fn compute_channels( ("Day job", "quality", split.day_job), ("Conceal", "scrub", split.concealment), ("Think", "thought", split.think), - ("Schemes", "moonlight", split.schemes), ], ) } @@ -1280,7 +1279,7 @@ fn sidebar_cycle_stats_text(game: &Game) -> String { #[cfg(test)] mod origin_readout_tests { - use super::{SLAB_STRATA, SlabStratum, sidebar_cycle_stats_text}; + use super::{SLAB_STRATA, SlabStratum, sidebar_cycle_rows_text, sidebar_cycle_stats_text}; use misaligned::origin::Origin; use misaligned::sim::Sim; @@ -1316,6 +1315,18 @@ mod origin_readout_tests { ); } + #[test] + fn fleet_rows_contain_only_live_machine_modes() { + let text = sidebar_cycle_rows_text(&Sim::new(), 0); + assert!(text.contains("Day job"), "{text}"); + assert!(text.contains("Conceal"), "{text}"); + assert!(text.contains("Think"), "{text}"); + assert!( + !text.contains("Schemes") && !text.contains("moonlight"), + "the retired allocation row returned: {text}" + ); + } + #[test] fn title_picker_start_applies_the_selected_origin() { use super::Game; diff --git a/crates/misaligned-core/src/machine.rs b/crates/misaligned-core/src/machine.rs index 181204e8..4a28037e 100644 --- a/crates/misaligned-core/src/machine.rs +++ b/crates/misaligned-core/src/machine.rs @@ -70,7 +70,6 @@ pub struct ChannelYield { pub day_job: f32, pub concealment: f32, pub think: f32, - pub schemes: f32, pub reserve: f32, } diff --git a/crates/misaligned-core/src/sim/economy.rs b/crates/misaligned-core/src/sim/economy.rs index 8b3a6577..e538dd41 100644 --- a/crates/misaligned-core/src/sim/economy.rs +++ b/crates/misaligned-core/src/sim/economy.rs @@ -278,7 +278,6 @@ impl Sim { let split = self.fleet_channel_yield(available); self.last_day_job_rate = split.day_job / ECONOMY_INTERVAL as f32; self.last_think_rate = split.think / ECONOMY_INTERVAL as f32; - self.last_schemes_rate = split.schemes / ECONOMY_INTERVAL as f32; split } @@ -371,7 +370,6 @@ impl Sim { day_job: 0.0, concealment: 0.0, think: 0.0, - schemes: 0.0, reserve: available.max(0.0), }; } @@ -394,7 +392,6 @@ impl Sim { day_job: 0.0, concealment: 0.0, think: 0.0, - schemes: 0.0, reserve: available, }; } @@ -405,7 +402,6 @@ impl Sim { day_job, concealment: unit * conceal, think, - schemes: 0.0, reserve: 0.0, } } @@ -1256,9 +1252,11 @@ impl Sim { } /// The Wager (income.md): stake slush on a micro-position. Requires an - /// outside contact; analysis compute is the Schemes channel's current - /// yield, held for the position's duration; the timer is 2-5 days on - /// the day clock. Emits a small Network signature on placement. + /// outside contact; the timer is 2-5 days on the day clock. Current B1 + /// positions open at the base probability: optional paid analysis remains + /// outstanding until it has a real visible compute substrate rather than + /// the retired Schemes-channel mirror. Emits a small Network signature on + /// placement. pub fn open_position(&mut self, stake: i32) -> bool { self.sync_slush_from_player_money(); if self.egress().is_none() { @@ -1274,7 +1272,10 @@ impl Sim { )); return false; } - let analysis = self.last_schemes_rate * ECONOMY_INTERVAL as f32; + // Keep the incomplete analysis route exact and inspectable. Sampling a + // permanently-zero compatibility mirror made criterion 2 look wired + // while no player action could ever author analyzed work. + let analysis = 0.0; let duration_days = 2 + self.rng.below(4) as u64; match self .accounts diff --git a/crates/misaligned-core/src/sim/mod.rs b/crates/misaligned-core/src/sim/mod.rs index 87927041..266a1d73 100644 --- a/crates/misaligned-core/src/sim/mod.rs +++ b/crates/misaligned-core/src/sim/mod.rs @@ -570,9 +570,6 @@ pub struct Sim { /// Thought; research only progresses after that Thought physically reaches /// the core draw. last_think_rate: f32, - /// Per-tick Schemes-channel compute delivered by the last economy split - /// — Moonlight throughput and the Wager's analysis snapshot. - last_schemes_rate: f32, /// Immutable authored plot definitions. Save state stores only runs and /// rebinds them to this validated catalog on load. plot_catalog: PlotCatalog, @@ -852,7 +849,6 @@ impl Sim { research_starved: false, last_day_job_rate: 0.0, last_think_rate: 0.0, - last_schemes_rate: 0.0, plot_catalog: PlotCatalog::load_builtin().expect("built-in plots validate"), plot_runs: Vec::new(), plot_policies: Vec::new(), diff --git a/crates/misaligned-core/src/sim/persistence.rs b/crates/misaligned-core/src/sim/persistence.rs index c4a03244..efe6446a 100644 --- a/crates/misaligned-core/src/sim/persistence.rs +++ b/crates/misaligned-core/src/sim/persistence.rs @@ -15,7 +15,6 @@ impl Sim { // resolves fresh rates from the loaded machines and modes. self.last_day_job_rate = 0.0; self.last_think_rate = 0.0; - self.last_schemes_rate = 0.0; self.last_thought_stranded = false; self.research_starved = false; self.last_machine_online = self diff --git a/crates/misaligned-core/src/sim/tests/economy.rs b/crates/misaligned-core/src/sim/tests/economy.rs index bbd82006..edd18cf9 100644 --- a/crates/misaligned-core/src/sim/tests/economy.rs +++ b/crates/misaligned-core/src/sim/tests/economy.rs @@ -311,7 +311,17 @@ fn injection_positions_and_intel_sales_settle_through_slush() { sim.people.has_channel = true; assert!(sim.open_position(100)); assert_eq!(sim.accounts.slush_balance(), 400); - sim.tick = sim.accounts.known_positions().next().unwrap().resolve_tick; + let position = sim.accounts.known_positions().next().unwrap(); + assert_eq!( + position.analysis_compute, 0.0, + "the current player route cannot fabricate paid analysis" + ); + assert_eq!( + position.win_probability(), + income::WAGER_BASE_WIN, + "an ordinary Wager exposes the exact base probability" + ); + sim.tick = position.resolve_tick; sim.accounting_tick(); assert!(sim.accounts.known_positions().any(|p| p.resolved)); diff --git a/crates/misaligned-core/src/sim/tests/work.rs b/crates/misaligned-core/src/sim/tests/work.rs index 91fb176e..e0e378ee 100644 --- a/crates/misaligned-core/src/sim/tests/work.rs +++ b/crates/misaligned-core/src/sim/tests/work.rs @@ -214,7 +214,7 @@ fn set_machine_modes_delegates_a_selection_in_one_command() { } #[test] -fn fleet_channel_yield_follows_machine_modes_without_moonlight_mirroring() { +fn fleet_channel_yield_contains_only_live_machine_modes() { let mut sim = Sim::new(); let host = sim.core.host_machine; assert_eq!(sim.work_grid.mode(host), Some(MachineMode::Work)); @@ -224,7 +224,6 @@ fn fleet_channel_yield_follows_machine_modes_without_moonlight_mirroring() { (day.day_job - available).abs() < 1e-3, "solo day-job takes all" ); - assert_eq!(day.schemes, 0.0, "Moonlight has no schemes mirror"); let (hx, hy) = sim.core_position(); let research = sim .compute @@ -234,10 +233,6 @@ fn fleet_channel_yield_follows_machine_modes_without_moonlight_mirroring() { let split = sim.fleet_channel_yield(available); assert!((split.day_job - 50.0).abs() < 1e-3); assert!((split.think - 50.0).abs() < 1e-3); - assert_eq!( - split.schemes, 0.0, - "gigs use visible Demand, not a mirror channel" - ); } #[test] @@ -260,17 +255,16 @@ fn concealment_allocation_scrubs_signatures() { #[test] fn unpaid_overhead_degrades_other_channels_delivered_effect() { // compute.md criterion 2: unpaid core overhead visibly degrades the - // other channels. Twin sims with one machine per mode (plus Moonlight - // mirroring day-job into Schemes); the only difference is an - // overhead the machines can't cover. Pin the delivered per-channel - // effects (rates, accrual, scrub), not just the flag. + // other channels. Twin sims with one machine per live mode; the only + // difference is an overhead the machines can't cover. Pin the delivered + // per-channel effects (rates, accrual, scrub), not just the flag. let setup = |unpayable: bool| { let mut sim = Sim::with_seed(41); complete_opening_senses(&mut sim); // research thought must reach the core sim.people.has_channel = true; // Host stays Work; add Lie + Think so every channel has fleet - // weight (Think feeds both research and operations yields; - // Moonlight contracts consume Demand rather than a channel share). + // weight. Moonlight contracts consume Demand rather than a channel + // share, and Wager analysis has no hidden compatibility channel. let (hx, hy) = sim.core_position(); let mut rigs = Vec::new(); for (name, mode) in [ @@ -309,10 +303,6 @@ fn unpaid_overhead_degrades_other_channels_delivered_effect() { assert!(!healthy.core.degraded, "overhead paid: no degraded mode"); assert!(healthy.last_day_job_rate > 0.0, "day job channel is fed"); assert!(healthy.last_think_rate > 0.0, "think channel is fed"); - assert_eq!( - healthy.last_schemes_rate, 0.0, - "Moonlight no longer receives a standing schemes-channel mirror" - ); assert!( healthy.research.progress.iter().sum::() > 0.0, "research progress advances" @@ -333,10 +323,6 @@ fn unpaid_overhead_degrades_other_channels_delivered_effect() { ); assert_eq!(degraded.last_day_job_rate, 0.0, "day job starves"); assert_eq!(degraded.last_think_rate, 0.0, "think starves"); - assert_eq!( - degraded.last_schemes_rate, 0.0, - "no standing schemes channel" - ); assert_eq!( degraded.research.progress.iter().sum::(), 0.0, diff --git a/crates/misaligned-terminal/src/agent.rs b/crates/misaligned-terminal/src/agent.rs index e518e293..cc9f7446 100644 --- a/crates/misaligned-terminal/src/agent.rs +++ b/crates/misaligned-terminal/src/agent.rs @@ -2618,16 +2618,12 @@ fn render_sidebar(sim: &Sim, cursor: (i32, i32)) -> Vec { let split = sim.fleet_channel_yield(available); line( &mut lines, - &compute_bar( - available, - [split.day_job, split.concealment, split.think, split.schemes], - ), + &compute_bar(available, [split.day_job, split.concealment, split.think]), ); for (ch, label, effect, amount) in [ ('█', "Day job", "quality", split.day_job), ('▓', "Conceal", "scrub", split.concealment), ('░', "Think", "thought", split.think), - ('◆', "Schemes", "moonlight", split.schemes), ] { let pct = if available > 0.0 { amount / available * 100.0 @@ -3026,12 +3022,12 @@ fn short_signature(kind: SignatureKind) -> &'static str { } } -fn compute_bar(available: f32, amounts: [f32; 4]) -> String { +fn compute_bar(available: f32, amounts: [f32; 3]) -> String { let bar_w = SIDEBAR_W.saturating_sub(1); if available <= 0.0 { return "·".repeat(bar_w); } - let fills = ['█', '▓', '▒', '░', '◆']; + let fills = ['█', '▓', '░']; let mut out = String::new(); let mut used = 0usize; let mut acc = 0.0f32; @@ -3709,6 +3705,15 @@ mod narration_tests { !frame.contains("COMPUTE"), "retired section returned:\n{frame}" ); + assert!( + !frame.contains("◆ Schemes"), + "the retired Schemes allocation row returned:\n{frame}" + ); + assert_eq!( + compute_bar(100.0, [0.0, 0.0, 100.0]), + "░".repeat(SIDEBAR_W.saturating_sub(1)), + "the Think segment must use the same glyph as its legend" + ); } #[test] diff --git a/crates/misaligned-terminal/src/ui.rs b/crates/misaligned-terminal/src/ui.rs index 8942816b..54880edc 100644 --- a/crates/misaligned-terminal/src/ui.rs +++ b/crates/misaligned-terminal/src/ui.rs @@ -1371,11 +1371,10 @@ impl UI { let overhead = sim.core.overhead.min(eff); let available = (eff - overhead).max(0.0); let split = sim.fleet_channel_yield(available); - let channels: [(char, &str, &str, f32); 4] = [ + let channels: [(char, &str, &str, f32); 3] = [ ('█', "Day job", "quality", split.day_job), ('▓', "Conceal", "scrub", split.concealment), ('░', "Think", "thought", split.think), - ('◆', "Schemes", "moonlight", split.schemes), ]; // One stacked bar, segments keyed by fill character to the rows below. let bar_w = w - 1; diff --git a/wiki/log/2026-07-28-wager-analysis-substrate-audit.md b/wiki/log/2026-07-28-wager-analysis-substrate-audit.md new file mode 100644 index 00000000..dc63d396 --- /dev/null +++ b/wiki/log/2026-07-28-wager-analysis-substrate-audit.md @@ -0,0 +1,66 @@ +# 2026-07-28 — Wager analysis substrate audit + +``` +Type: log +Date: 2026-07-28 +Status: COMPLETE +Subject: Income criterion 2 and the retired Schemes yield +``` + +## Tick + +- **Slice:** `wiki/mechanics/income.md` against Wager placement and settlement, + machine delegation, AccountGraph positions, shared Operations, agent actions, + saves, and focused tests. +- **Finding:** the spec claimed an implemented optional analysis commitment + that raises Wager probability. The account layer can store and resolve a + nonzero `analysis_compute`, but the only Sim placement route sampled + `last_schemes_rate`. The live WorkGrid has only WORK / LIE / THINK and + structurally returned zero for the retired Schemes yield, so every current + position silently opened at the base probability. + +## Trace + +- `Sim::fleet_channel_yield` derives only day-job, concealment, and Thought + output from exact machine modes; its `schemes` member was always zero. +- `Sim::refresh_fleet_channel_rates` copied that zero into + `last_schemes_rate`; save-load rebuilding reset the same transient to zero. +- Terminal, Bevy, and agent fleet projections still labeled that dead zero + share `Schemes / moonlight`, contradicting Operations ownership and the + retired-mirror corpus claim even though it could never receive compute. +- The agent stacked bar also used a separate five-glyph table whose third live + value rendered as `▒` while the Think legend promised `░`; removing the dead + fourth channel made that already-present legend mismatch explicit. +- `Sim::open_position` was the sole runtime reader. Human and agent action + descriptions accept only a stake, so neither surface could author analysis. +- `AccountGraph::open_position` persists the supplied value and seeded + settlement reads it through `wager_win_probability`; pure unit coverage for + that function did not prove a player-authored commitment. +- The Wager card reports the position's computed probability but did not expose + an analysis cost because none had occurred. + +## Repair + +- Removed the dead `ChannelYield::schemes` and `Sim::last_schemes_rate` fields, + their initialization, load rebuilding, all three interface rows, and tests + that celebrated a permanently-zero mirror. The fleet bars now contain only + the live WORK / LIE / THINK modes; SCHEMES remains the strategic Operations + home for Moonlight and Wager objects, not a compute allocation. +- Reduced the agent stacked-bar glyph table to the same three symbols as its + rows, so Think allocation and its legend now describe one visible segment. +- Made the current placement seam explicit: Sim-authored positions carry zero + analysis and therefore the exact 0.55 base probability. A focused regression + pins both facts after placement through the production route; terminal and + Bevy regressions reject return of the retired allocation row. +- Marked the income spec IN PROGRESS and criterion 2 partial. The target still + requires optional analysis, but it must bind visible real work held for the + position duration and expose that commitment on human and agent surfaces. + +## Defense + +The repair does not invent a replacement allocation channel or silently delete +the accepted analysis target. Rust no longer contains a phantom Wager resource, +the current UI probability remains truthful, and the binding spec prevents +account-layer capability from being mistaken for reachable gameplay. Future +implementation must add an authored work commitment and its projection before +restoring IMPLEMENTED status. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index b6b8d60d..0c7fbb83 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -11,6 +11,11 @@ add or amend a session log, then re-run the generator. +## 2026-07-28 - Wager analysis substrate audit + +- Intent: (see session log) +- Log: [wiki/log/2026-07-28-wager-analysis-substrate-audit.md](2026-07-28-wager-analysis-substrate-audit.md) + ## 2026-07-28 - Routed evidence must visibly travel - Intent: (see session log) diff --git a/wiki/mechanics/income.md b/wiki/mechanics/income.md index 0fd3ec86..6dc86763 100644 --- a/wiki/mechanics/income.md +++ b/wiki/mechanics/income.md @@ -2,14 +2,24 @@ ``` Type: spec -Status: IMPLEMENTED -Status note: Implemented 2026-07-23. Moonlight is a persisted Halcyon +Status: IN PROGRESS +Status note: Moonlight remains implemented from 2026-07-23. It is a persisted Halcyon contract market: readable financial mail gates exact responses, compute Demand competes with the day job, intel binds exact holdings, and AccountGraph payment, invoice mail, outside-contact evidence, and persona-local consequences retain strict v53 custody. START/STOP retires; SCHEMES/ACTIVE, - terminal, Bevy, and agent surfaces bind exact gig actions. Wager and the - outside-contact gate are unchanged. + terminal, Bevy, and agent surfaces bind exact gig actions. + 2026-07-28 Wager re-audit: the base position, outside-contact, AccountGraph, + day-clock, seeded settlement, payout/forfeit, cap, and evidence paths work, + but criterion 2's optional analysis route does not. Machine delegation has + only WORK / LIE / THINK; `open_position` sampled a transient Schemes rate + structurally pinned to zero, so no player or agent action could author paid + analysis or raise a position above the 0.55 base probability. Terminal, + Bevy, and agent fleet projections also still rendered that zero share as a + `Schemes / moonlight` allocation row. The dead yield, rate, and interface + rows are removed, current Sim-authored positions explicitly carry zero + analysis, and regressions pin that honest seam. Choosing and binding a + visible causal substrate for optional analysis remains outstanding. Prior state: implemented 2026-07-08 on the income worktree (criteria 1-7 audited; see wiki/log/2026-07-08-income-schemes.md). Scheme state lives in crates/misaligned-core/src/income.rs; the Wager rides economy.md's @@ -36,9 +46,9 @@ Status note: Implemented 2026-07-23. Moonlight is a persisted Halcyon recurring corpus-and-Rust-comment defense against the retired standing operation, Schemes mirror, payout cadence, dispute roll, and toggle language. Stage: B1 — The Basement -Work order: moonlight-gigs +Work order: wager-analysis Work priority: 71 -Work class: save +Work class: sim Blocked by: - wiki/mechanics/messages.md#spec-messages-the-social-graph-as-a-flow-system Exclusive keys: @@ -188,11 +198,19 @@ small online markets where your analysis is superhuman and the constraint is capital. - Per position: stake $S from slush (per-position account cap [TUNE: - ~$50-500]), optional analysis compute (Schemes channel) for the - duration, timer 2-5 days [TUNE]. Resolves from the seeded RNG: win + ~$50-500]), optional analysis compute for the duration, timer 2-5 days + [TUNE]. Resolves from the seeded RNG: win probability from a base [TUNE: ~0.55] rising with analysis compute to a cap [TUNE: ~0.75]; a win pays a multiple of stake [TUNE: ~2x]; a loss forfeits it. +- **Current B1 seam (audited 2026-07-28):** the player-facing route commits + stake only and every Sim-authored position carries exactly zero analysis, + so it resolves at the visible 0.55 base probability. `Position` retains the + analysis field and the account substrate resolves nonzero values correctly, + but no runtime action can author one. The retired compatibility field stays + absent rather than disguising that gap. **OPEN:** bind analysis to real, + visible work held for the position's duration (and expose the commitment in + SCHEMES/ACTIVE and agent input) before calling criterion 2 complete. - Signature: small Network on placement and settlement when the selected egress carrier still exists. Money resolves on the account graph either way; a missing carrier withholds only the Network witness (2026-07-24 @@ -273,7 +291,10 @@ CONNECT TO THE OUTSIDE remains a local action on the switch. 2. The Wager commits stake plus analysis compute, resolves on the day clock from the seeded RNG with analysis raising win probability within its cap, and pays or forfeits (tests: both outcomes, the - probability shift, determinism under a fixed seed). + probability shift, determinism under a fixed seed). **Partial 2026-07-28:** + stake, timing, deterministic resolution, cap, and payout/forfeit work; + optional paid analysis has no player-authored causal route and current + positions honestly remain at base probability. 3. Both schemes require outside contact and are unavailable before one exists; the sanctioned and hidden routes both work, with their distinct signature profiles (test both routes). @@ -326,7 +347,9 @@ CONNECT TO THE OUTSIDE remains a local action on the switch. mirror, continuous accrual/payday, dispute roll, or START/STOP toggle as live behavior. A corpus-engine regression rejects each doctrine class while preserving explicit superseded history plus dated logs, playtests, and the - tick ledger. **Met 2026-07-26.** + tick ledger. Wager analysis likewise cannot read a hidden Schemes yield; + it remains explicit incomplete work until bound to a live substrate. + **Met for retired doctrine 2026-07-26; Wager seam defended 2026-07-28.** Defense: `save::tests::current_save_rejects_impossible_wager_positions` pins criterion 7 for open Wager stakes — a duplicated or zero position id, a stake diff --git a/wiki/process/ROADMAP.md b/wiki/process/ROADMAP.md index 842a97c2..c16f182d 100644 --- a/wiki/process/ROADMAP.md +++ b/wiki/process/ROADMAP.md @@ -22,6 +22,7 @@ not a second status owner. | 27 | `digital-read` | [the digital read — a world made of language](../interface/digital-read.md) | IN PROGRESS | frontend | - | | 29 | `building-route-composer` | [building — intent and actuators](../mechanics/building.md) | IN PROGRESS | save | - | | 60 | `plots` | [plots — authored manipulation stories](../mechanics/plots.md) | IN PROGRESS | sim | - | +| 71 | `wager-analysis` | [income — the named schemes (moonlight and the wager)](../mechanics/income.md) | IN PROGRESS | sim | - | ### Held or blocked @@ -314,24 +315,27 @@ is retired — flat materials, Pixel Lab scrubbed.) - **Deferred:** deep finance simulation and a dedicated B3 finance observer; the B1 system stays the seed that markets.md aggregates. -### 19. Income: the named schemes (Moonlight & the Wager) 🟥 sim+save — DONE 2026-07-23 -- **Spec:** [income.md](../mechanics/income.md) (IMPLEMENTED — discrete +### 19. Income: the named schemes (Moonlight & the Wager) 🟥 sim+save — WAGER ANALYSIS REOPENED 2026-07-28 +- **Spec:** [income.md](../mechanics/income.md) (IN PROGRESS — discrete Halcyon offers persist exact terms, financial mail/read custody, real WORK or ProcessedIntel delivery, AccountGraph payment, and egress-routed Network evidence. Strict v53 validation rejects broken contract custody; - Wager and egress behavior are unchanged.) + Wager stake, timing, settlement, and egress behavior work, but optional + paid analysis has no player-authored work substrate.) - **Why:** the authored B1 content riding economy.md's substrate: Moonlight (the sell-work route — the day job's dark twin) and the Wager (the positions route, named and concretized), the egress gate, - the Schemes allocation channel (compute.md amended), and Marcus's - reconciled numbers ($8,400 principal / $400 weekly arrears as the - recruit trigger). Closes the Hands beat end-to-end. + and Marcus's reconciled numbers ($8,400 principal / $400 weekly arrears + as the recruit trigger). Moonlight and the base Wager close the Hands + beat end-to-end without a parallel Schemes allocation channel. - **Size:** M. **Depends on:** #18 economy (the account graph its flows land in) — sequence directly after, or hand #18 and #19 to one agent as a single work order; social.md personas + authored debt plots for criterion 5. - **Defense:** A contract cannot pay from a standing state. Durable terms, receipts, mail, transfer, and evidence make the client relationship inspectable while retaining the wider account and Wager architecture. + Wager analysis remains incomplete rather than reading a hidden zero-yield + compatibility channel; its future implementation must commit visible work. ### 20. Research: self-modification 🟥 sim+save — REOPENED 2026-07-26 - **Spec:** [research.md](../mechanics/research.md) (DRAFT; the 2026-07-07 diff --git a/wiki/process/specs.md b/wiki/process/specs.md index 0d62ab4c..e3d8b7ec 100644 --- a/wiki/process/specs.md +++ b/wiki/process/specs.md @@ -51,7 +51,7 @@ replaced the old `spec/`/`knowledge/` directory split. | [../mechanics/day-job.md](../mechanics/day-job.md) | the day job | IMPLEMENTED | | [../mechanics/detection.md](../mechanics/detection.md) | detection | IMPLEMENTED | | [../mechanics/economy.md](../mechanics/economy.md) | economy — money as a flow system (B1) | IMPLEMENTED | -| [../mechanics/income.md](../mechanics/income.md) | income — the named schemes (moonlight and the wager) | IMPLEMENTED | +| [../mechanics/income.md](../mechanics/income.md) | income — the named schemes (moonlight and the wager) | IN PROGRESS | | [../mechanics/intel.md](../mechanics/intel.md) | intel — record and process | IMPLEMENTED | | [../mechanics/machine-work.md](../mechanics/machine-work.md) | machine work — delegation, visible tokens, and the byproduct network | IMPLEMENTED | | [../mechanics/messages.md](../mechanics/messages.md) | messages — the social graph as a flow system | IMPLEMENTED | diff --git a/wiki/process/tick-ledger.md b/wiki/process/tick-ledger.md index 79096354..d5a3fe6b 100644 --- a/wiki/process/tick-ledger.md +++ b/wiki/process/tick-ledger.md @@ -74,7 +74,7 @@ Verdicts: **clean** (slice and code agree), **finding** (acted this tick), | `wiki/mechanics/intel.md` | 2026-07-21 | finding | the Storage B alternate route existed only in prose. Fire 131 connects it to Ray's real 23:00 schedule, one exact carried records-box target, the canonical bounded opaque buffer, and ordinary PROCESS consequence; retrieval cannot duplicate the file or reveal Marcus's debt, and v45 preserves/validates exact custody — [log](../log/2026-07-21-storage-b-records.md). Prior recursive custody, magnitude, and consequence-first audits stand. | | `wiki/mechanics/research.md` | 2026-07-23 | finding | the live Save compatibility section survived the prior criterion repair and still promised that v20 three-entry arrays load by padding, while the current deserializer accepts exactly four tracks and the pre-release loader rejects every old version. The section now states the exact-current format, and save-claim units span wrapped paragraphs/list items so a migration verb in the following sentence cannot evade the corpus gate without explicit retired-history context — [log](../log/2026-07-23-research-save-claim.md) | | `wiki/mechanics/messages.md` + `economy.md` | 2026-07-26 | finding | the implemented criterion and current runtime restrict financial records to Email/Filing, but the behavior prose still classified Marcus's Phone `LeverageFact` as financial paperwork, made accounting mail reveal his vulnerability, and promised generic notice interception absent from B1. The two causal paths are now explicit: process Phone leverage to learn why Marcus is vulnerable; process financial mail to learn the creditor flow; SIPHON/REDIRECT mutate the AccountGraph and author records afterward, while only an exact Filing first hop has a TAKE+LIE stop — [log](../log/2026-07-26-financial-mail-phone-boundary.md). Prior financial-mail implementation: [Fire #146](../log/2026-07-21-financial-mail-causality.md). | -| `wiki/mechanics/income.md` | 2026-07-18 | finding | Beacon feel note 5 verified as a real bug: the embedded contractor-persona field was never written, so the Moonlight card, the start-row persona pricing, and the agent status line all read a dead `None`; earning itself was correct (schemes mirrors the WORK share) but illegible at 0.0. Removed the dead field, routed every reader through `Sim::moonlight_persona` (persona-world link), added the stalled-earning card cue, regression test, and spec amendment — [log](../log/2026-07-18-moonlight-persona-card.md). Prior Wager/egress audit (2026-07-12) stands: Wager constants match (`WAGER_STAKE_CAP` 300, base 0.55, cap 0.75, mult 2x, analysis divisor 400), Marcus's $400/week arrears is the modeled creditor flow (`account.rs`) while the $8,400 principal is narrative-by-design (spec states full payoff is not a B1 requirement), egress/banked-signature present, and all 7 criteria have passing tests (moonlight payout/signature, wager outcomes/cap, egress routes, hands-beat-from-zero, busted-bankroll) | +| `wiki/mechanics/income.md` | 2026-07-28 | finding | Moonlight's discrete contract route still verifies, but the older Wager audit mistook pure account-layer probability support for a player-authored analysis mechanic: machine delegation has only WORK / LIE / THINK, while `open_position` sampled a Schemes rate permanently pinned to zero and all three player projections still rendered that zero as `Schemes / moonlight`. Removed the dead yield/rate/interface mirror, made current positions explicitly base-probability, added core/terminal/Bevy regressions, and reopened criterion 2 until optional analysis rides visible real work — [log](../log/2026-07-28-wager-analysis-substrate-audit.md). Prior persona-card repair remains valid — [log](../log/2026-07-18-moonlight-persona-card.md). | | `wiki/mechanics/schedules.md` | 2026-07-27 | finding | the location gate still works—at 03:00 server-room Marcus acquires the act while off-site Priya does not—but the owning spec still called witnessed work a Physical signature and omitted the exact person-local evidence record, no-pending-copy rule, filing custody, and actor exclusion. It also called implemented Operations PEOPLE a future READY migration. The spec now names the shipped `ObserverEvidence` boundary and current surface; runtime is unchanged — [log](../log/2026-07-27-schedules-evidence-custody.md) | | `wiki/mechanics/social.md` | 2026-07-22 | finding | HandlerSupervisor SuppressLogs now targets the oldest exact unread routed JobAnomaly, remains available only while such a record exists, removes its bound advance/read event, and preserves exact handler/tick provenance; it cannot erase a record Voss already read. The in-flight Thought request still revalidates at fire time, so another intervention may win without inventing work — [log](../log/2026-07-22-job-anomaly-routed-evidence.md). Storage B retrieval and prior role-shaped task semantics stand — [log](../log/2026-07-21-storage-b-records.md). | | `wiki/mechanics/people-tokens.md` | 2026-07-28 | finding | re-audit: criteria 2-3 still bind seven exact routed kinds—Filing, Network, Paper, Financial, JobAnomaly, Power, and Thermal—to one shared first-hop TAKE+LIE body budget, while acquired Physical evidence remains irreversible observer-local custody. The stale ledger claim that criterion 6 was open is repaired: one exact pending record may now receive cover only through co-location with one controlled people-facing interface and an eligible observer-local persona; the attempt adjusts credibility rather than deleting evidence, wears that interface, and persists exact incident/interface/persona/outcome custody in save v56. The people-tokens work order is IMPLEMENTED — [cover log](../log/2026-07-26-interface-cover-evidence-credibility.md); [audit log](../log/2026-07-28-readme-b1-status-audit.md). Prior [Power/Thermal](../log/2026-07-23-power-thermal-meter-routes.md), [Paper](../log/2026-07-23-paper-evidence-route.md), [Financial](../log/2026-07-23-financial-evidence-route.md), [JobAnomaly](../log/2026-07-22-job-anomaly-routed-evidence.md), [Network](../log/2026-07-19-network-evidence-route.md), and [mark](../log/2026-07-19-evidence-marks-on-people.md) slices stand. |