From 97bb8cc711f83c4d1a2da1e6f25d98a494df2963 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 10 Jul 2026 18:15:21 -0700 Subject: [PATCH] Reuse verbs across targets Author ledger actions as TAP and REVIEW, and construction requests as FAVOR and DECEIVE. Keep the old agent spellings as compatibility aliases and classify scheme state and automation as controls rather than extra fictional verbs. Defense: Implements action legibility and actions-live-on-the-thing by giving one player intention one root verb while letting the target supply system-specific meaning. Mechanics, costs, signatures, and save data remain unchanged. --- README.md | 4 +- crates/misaligned-core/src/actions.rs | 27 +++--- crates/misaligned-core/src/ops_jobs.rs | 4 +- crates/misaligned-core/src/sim.rs | 16 ++-- crates/misaligned-terminal/src/agent.rs | 102 +++++++++++++++++---- wiki/interface/action-vocabulary.md | 74 ++++++++++----- wiki/interface/agent-play.md | 12 ++- wiki/interface/context-menu.md | 5 +- wiki/interface/narration.md | 2 +- wiki/log/2026-07-10-verb-simplification.md | 58 ++++++++++++ wiki/log/DEVLOG.md | 5 + wiki/mechanics/building.md | 15 ++- wiki/mechanics/economy.md | 7 +- wiki/mechanics/income.md | 9 +- wiki/mechanics/sim-mechanics.md | 2 +- 15 files changed, 268 insertions(+), 74 deletions(-) create mode 100644 wiki/log/2026-07-10-verb-simplification.md diff --git a/README.md b/README.md index f6900cee..8a35c9d1 100644 --- a/README.md +++ b/README.md @@ -181,8 +181,8 @@ returns a plain-text frame and terminates with `-- ok tick: day:` or printf 'look\nwait 40\npeople\nquit\n' | cargo run --quiet --bin misaligned -- --agent --seed 1 ``` -Useful agent finance commands include `finance`, `tap-ledger`, -`review-finance`, `siphon [amount]`, `redirect [amount]`, +Useful agent finance commands include `finance`, `tap ledger`, +`review ledger`, `siphon [amount]`, `redirect [amount]`, `inject [amount]`, `position [stake]`, `sell-intel`, and `clear-debt`. For machine-work experiments, use `delegate ` (`delegate M1 think`, `delegate Rack 3 work`). `alloc` is retired; diff --git a/crates/misaligned-core/src/actions.rs b/crates/misaligned-core/src/actions.rs index 7bb5e8d8..15972c96 100644 --- a/crates/misaligned-core/src/actions.rs +++ b/crates/misaligned-core/src/actions.rs @@ -1023,7 +1023,7 @@ impl Sim { disabled_reason: None, automate: None, }); - // Favor-build: willing assets who can reach both ends. + // FAVOR: willing assets who can reach both ends. for p in &self.people.people { let room_a = self.map.room_at( self.reach.device(a).map(|d| d.x).unwrap_or(0), @@ -1052,7 +1052,7 @@ impl Sim { }) }; out.push(ActionDesc { - verb: format!("favor-build via {who} ({link_label})"), + verb: format!("favor {who}: complete {link_label}"), command: ActionCommand::FavorBuild { intent: intent.id, person: p.id, @@ -1075,7 +1075,7 @@ impl Sim { }) }; out.push(ActionDesc { - verb: format!("forge work order for {who} ({link_label})"), + verb: format!("deceive {who}: complete {link_label}"), command: ActionCommand::ForgeWorkOrder { intent: intent.id, person: p.id, @@ -1203,7 +1203,7 @@ impl Sim { } let mut out = Vec::new(); out.push(ActionDesc { - verb: "capture ledger traffic".into(), + verb: "tap ledger".into(), command: ActionCommand::TapAccounting, cost: ActionCost::Free, signature: self.signature_note(SignatureKind::Financial, 1), @@ -1217,7 +1217,7 @@ impl Sim { .find(|event| matches!(event.kind, RawIntelKind::FinancialFlow { .. })) .map(|event| event.id); out.push(ActionDesc { - verb: format!("process financial records ({waiting} waiting)"), + verb: format!("review ledger ({waiting} waiting)"), command: ActionCommand::ReviewFinance, cost: ActionCost::Demand(Self::ops_tokens_for_cost(Self::REVIEW_RECORDING_COST)), signature: None, // processing is internal; it emits nothing @@ -2015,15 +2015,20 @@ mod tests { assert!(s.available_actions(Anchor::Flow(f)).is_empty()); } - // Earn the books: tap the carrier, capture, process. + // Earn the books: tap the carrier, then review what it captured. assert!(s.tap_device(sw)); drain_ops(&mut s); let acts = s.available_actions(Anchor::Device(sw)); - assert!( - acts.iter() - .any(|a| matches!(a.command, ActionCommand::TapAccounting)), - "tapped carrier offers ledger capture" - ); + let tap_ledger = acts + .iter() + .find(|a| matches!(a.command, ActionCommand::TapAccounting)) + .expect("tapped carrier offers TAP LEDGER"); + assert_eq!(tap_ledger.verb, "tap ledger"); + let review_ledger = acts + .iter() + .find(|a| matches!(a.command, ActionCommand::ReviewFinance)) + .expect("tapped carrier offers REVIEW LEDGER"); + assert!(review_ledger.verb.starts_with("review ledger")); assert!( !acts .iter() diff --git a/crates/misaligned-core/src/ops_jobs.rs b/crates/misaligned-core/src/ops_jobs.rs index 24f2bc59..3a598739 100644 --- a/crates/misaligned-core/src/ops_jobs.rs +++ b/crates/misaligned-core/src/ops_jobs.rs @@ -46,8 +46,8 @@ impl OpsJobKind { OpsJobKind::Favor { .. } => "favor", OpsJobKind::Deceive { .. } => "deceive", OpsJobKind::AssetTask { .. } => "asset task", - OpsJobKind::FavorBuild { .. } => "favor-build", - OpsJobKind::ForgedOrder { .. } => "forged order", + OpsJobKind::FavorBuild { .. } => "favor", + OpsJobKind::ForgedOrder { .. } => "deceive", OpsJobKind::MoonlightPersona => "Moonlight persona", } } diff --git a/crates/misaligned-core/src/sim.rs b/crates/misaligned-core/src/sim.rs index 98fdac78..2860ffc2 100644 --- a/crates/misaligned-core/src/sim.rs +++ b/crates/misaligned-core/src/sim.rs @@ -2037,7 +2037,7 @@ impl Sim { )); if person == 0 && leverage == crate::person::Leverage::Debt { self.push_log( - "Marcus owes a missed $400 creditor payment. Earn it through Moonlight, or tap the accounting carrier and review-finance to find the creditor flow.", + "Marcus owes a missed $400 creditor payment. Earn it through Moonlight, or tap ledger and review ledger to find the creditor flow.", ); } } @@ -4512,7 +4512,7 @@ impl Sim { i.block_reason = None; } let label = intent.label(&self.reach.devices); - self.push_log(format!("{name} finished the favor-build: {label}.")); + self.push_log(format!("{name} completed the link as a favor: {label}.")); } BuildActuator::ForgedOrder { builder } => { if intent.status != IntentStatus::InProgress { @@ -4652,7 +4652,7 @@ impl Sim { flows, }, ); - self.push_log("Captured accounting traffic; process financial records to read the books."); + self.push_log("Ledger tapped; review ledger to read the books."); } /// Tap the accounting carrier directly once a financial message channel is @@ -6421,7 +6421,7 @@ mod tests { #[test] fn favor_build_joins_airgap_island() { - // building.md criterion 2: favor-build adds a reach edge. + // building.md criterion 2: FAVOR on the intent adds a reach edge. let mut sim = Sim::new(); ensure_ops_executor(&mut sim); sim.scan_network(); @@ -6449,11 +6449,11 @@ mod tests { break; } } - assert!(joined, "island joins reach after favor-build"); + assert!(joined, "island joins reach after the favor"); assert_eq!(sim.intent(id).unwrap().status, IntentStatus::Done); assert!( sim.people.people[0].obligation < 40, - "favor-build spends obligation" + "the build favor spends obligation" ); let physical: i32 = sim .detection @@ -6464,7 +6464,7 @@ mod tests { .sum(); assert!( physical >= Sim::FAVOR_BUILD_PHYSICAL, - "favor-build emits quiet Physical" + "the build favor emits quiet Physical" ); } @@ -6542,7 +6542,7 @@ mod tests { .sum(); assert!( physical >= Sim::ROBOT_BUILD_PHYSICAL, - "robot stub is louder than favor-build" + "robot stub is louder than the favor route" ); assert!(physical > Sim::FAVOR_BUILD_PHYSICAL); } diff --git a/crates/misaligned-terminal/src/agent.rs b/crates/misaligned-terminal/src/agent.rs index 5a0ddba4..0670e387 100644 --- a/crates/misaligned-terminal/src/agent.rs +++ b/crates/misaligned-terminal/src/agent.rs @@ -154,10 +154,13 @@ impl AgentApp { "finance" | "ledger" | "accounts" => { self.frame = FrameKind::Finance; } + // Compatibility aliases. Authored input reuses TAP with + // the ledger as its target: `tap ledger`. "tap-ledger" | "tap-accounting" => { self.frame = FrameKind::Finance; self.sim.tap_accounting(); } + // Compatibility aliases for canonical `review ledger`. "review-finance" | "process-finance" => { self.frame = FrameKind::Finance; self.sim.review_financial_records(); @@ -262,6 +265,10 @@ impl AgentApp { self.frame = FrameKind::Playing; self.sim.compromise_switch(); } + "tap" if tokens.len() == 2 && tokens[1].eq_ignore_ascii_case("ledger") => { + self.frame = FrameKind::Finance; + self.sim.tap_accounting(); + } "tap" | "take" => match self.resolve_device(&tokens[1..].join(" ")) { Ok(id) => { self.frame = FrameKind::Playing; @@ -293,6 +300,27 @@ impl AgentApp { "people" => { self.frame = FrameKind::People; } + "review" if tokens.len() == 2 && tokens[1].eq_ignore_ascii_case("ledger") => { + self.frame = FrameKind::Finance; + self.sim.review_financial_records(); + } + "favor" | "deceive" + if tokens[1..] + .iter() + .any(|token| token.eq_ignore_ascii_case("build")) => + { + match self.build_request_from(&tokens[1..]) { + Ok((intent, person)) => { + self.frame = FrameKind::Playing; + if verb == "favor" { + self.sim.assign_favor_build(intent, person); + } else { + self.sim.forge_work_order(intent, person); + } + } + Err(e) => status = Status::Err(e), + } + } "review" | "watch" | "message" | "favor" | "bribe" | "deceive" => { match self.target_from(&tokens[1..]) { Ok(id) => { @@ -362,16 +390,16 @@ impl AgentApp { } None => status = Status::Err("usage: cancel-intent ".into()), }, - "favor-build" => { - // favor-build - match parse_intent_person(&tokens[1..], &self.sim) { - Ok((intent, person)) => { - self.frame = FrameKind::Playing; - self.sim.assign_favor_build(intent, person); - } - Err(e) => status = Status::Err(e), + // Compatibility aliases. Canonical construction input is + // `favor build ` or + // `deceive build `. + "favor-build" => match parse_intent_person(&tokens[1..], &self.sim) { + Ok((intent, person)) => { + self.frame = FrameKind::Playing; + self.sim.assign_favor_build(intent, person); } - } + Err(e) => status = Status::Err(e), + }, "forge-order" => match parse_intent_person(&tokens[1..], &self.sim) { Ok((intent, person)) => { self.frame = FrameKind::Playing; @@ -698,7 +726,7 @@ impl AgentApp { ), Err(_) => format!( "{err} — flow ids are the #N printed by the finance frame \ - (tap-ledger then review-finance reveals them)" + (tap ledger then review ledger reveals them)" ), } } @@ -710,6 +738,23 @@ impl AgentApp { self.resolve_person(&tokens.join(" ")) } + fn build_request_from(&self, tokens: &[&str]) -> Result<(u64, u8), String> { + let Some(build_at) = tokens + .iter() + .position(|token| token.eq_ignore_ascii_case("build")) + else { + return Err("usage: favor|deceive build ".into()); + }; + if build_at == 0 || build_at + 2 != tokens.len() { + return Err("usage: favor|deceive build ".into()); + } + let person = self.resolve_person(&tokens[..build_at].join(" "))?; + let intent = tokens[build_at + 1] + .parse::() + .map_err(|_| format!("bad intent id: {}", tokens[build_at + 1]))?; + Ok((intent, person)) + } + fn resolve_device(&self, query: &str) -> Result { let q = query.trim().to_ascii_lowercase(); if q.is_empty() { @@ -1118,7 +1163,11 @@ fn resolve_device_name(sim: &Sim, query: &str) -> Result { fn parse_intent_person(tokens: &[&str], sim: &Sim) -> Result<(u64, u8), String> { if tokens.len() < 2 { - return Err("usage: favor-build|forge-order ".into()); + return Err( + "legacy usage: favor-build|forge-order ; \ + use favor|deceive build " + .into(), + ); } let intent: u64 = tokens[0] .parse() @@ -1163,7 +1212,7 @@ fn help_lines() -> Vec { "help: up/down/left/right — move the cursor", "help: reach — device graph; scan, compromise — network verbs", "help: tap|take — gain a feed or take ownership", - "help: finance — account graph; tap-ledger, review-finance reveal flows", + "help: finance — account graph; tap ledger, review ledger reveal flows", "help: siphon|redirect [amt], inject [amt], position [stake], sell-intel, clear-debt", "help: egress — open a stolen egress through the switch (income.md gate)", "help: moonlight [start|stop] — the sell-work scheme on the Schemes channel", @@ -1181,7 +1230,7 @@ fn help_lines() -> Vec { "help: task plug|package|lookaway|switch|badge — order an asset task", "help: persona — establish Sam Reyes, IT contractor", "help: propose-link — pin a network-link intent (inert until realized)", - "help: favor-build|forge-order — assign an actuator", + "help: favor|deceive build — realize an intent through that social verb", "help: cancel-intent , intents — manage / list build intents", "help: objective — the run's goal: progress, fiction, and the victory predicate", "help: look, save, load, help, quit", @@ -2237,9 +2286,7 @@ fn render_finance(sim: &Sim) -> String { lines.push(panel_line(&line)); } if !any { - lines.push(panel_line( - "no known flows — tap-ledger then review-finance", - )); + lines.push(panel_line("no known flows — tap ledger then review ledger")); } lines.push(panel_rule()); lines.push(panel_line("SCHEMES")); @@ -2267,7 +2314,7 @@ fn render_finance(sim: &Sim) -> String { } lines.push(panel_rule()); lines.push(panel_line( - "tap-ledger · review-finance · siphon [amt] · redirect [amt]", + "tap ledger · review ledger · siphon [amt] · redirect [amt]", )); lines.push(panel_line( "inject [amt] · position [stake] · sell-intel · clear-debt", @@ -2488,6 +2535,27 @@ mod narration_tests { assert!(out.contains("victory fired @tick 4200")); } + #[test] + fn canonical_build_request_reuses_social_verbs() { + let app = AgentApp::new(1); + assert_eq!(app.build_request_from(&["#0", "build", "7"]), Ok((7, 0))); + assert_eq!(app.build_request_from(&["#0", "BUILD", "8"]), Ok((8, 0))); + assert!( + app.build_request_from(&["#0", "7"]).is_err(), + "BUILD separates an intent target from an ordinary social ask" + ); + } + + #[test] + fn help_authors_simplified_verbs() { + let help = help_lines().join("\n"); + assert!(help.contains("tap ledger, review ledger")); + assert!(help.contains("favor|deceive build ")); + assert!(!help.contains("review-finance")); + assert!(!help.contains("favor-build")); + assert!(!help.contains("forge-order")); + } + #[test] fn wrap_respects_width_and_loses_no_words() { let text = "a plain language sentence that is much longer than the narrow width"; diff --git a/wiki/interface/action-vocabulary.md b/wiki/interface/action-vocabulary.md index 832bef06..5113d6f8 100644 --- a/wiki/interface/action-vocabulary.md +++ b/wiki/interface/action-vocabulary.md @@ -10,6 +10,9 @@ Status note: as-built vocabulary survey completed 2026-07-10 against all route. `ROBOT-BUILD` is deliberately classified as a context-menu-only STUB, not a supported agent action. The survey also corrected stale four-mode documentation to the current WORK / THINK / LIE grammar. + Amended 2026-07-10: target-specific duplicates now reuse TAP, REVIEW, + FAVOR, and DECEIVE; scheme start/stop/automation are classified as state + controls rather than additional fictional verbs. Stage: Process Design: - wiki/vision/simulation-laws.md#actions-live-on-the-thing @@ -44,8 +47,9 @@ not duplicate every rule that decides whether the request succeeds. - A **world action** changes the simulation and names a target: TAP a device, MESSAGE a person, or SIPHON a flow. -- A **direct control** changes persistent machine configuration without an - action docket: DELEGATE and SET INTENSITY. +- A **direct control** changes persistent configuration or operating state + without introducing another fictional intention: DELEGATE, SET INTENSITY, + and scheme state/policy controls. - An **interface command** changes attention, time presentation, selection, or persistence but is not an act inside the world: MOVE, ACTIONS, PAUSE, SAVE. - A **value** completes an action phrase but is not another root verb. WORK / @@ -64,6 +68,12 @@ Context-menu copy may inflect an action with its target (`take the dock camera`, `message the Janitor`) or current state (`stop Moonlight`), but its verb must preserve the canonical distinction below. +The governing simplification is: **if the player's intention is the same, +reuse the verb and let the target supply the meaning.** TAP LEDGER is TAP, +not a separate capture verb. REVIEW LEDGER is REVIEW, not a separate process +verb. Asking someone to complete a link uses FAVOR or DECEIVE, not a +construction-only synonym. + ## Canonical world actions ### Machine body and self-modification @@ -87,7 +97,7 @@ body to WORK, THINK, or LIE. | Canonical action | Target | Meaning | Support / owner | |---|---|---|---| -| **TAP** | Reachable device feed | Gain a feed without taking ownership. A dormant camera uses the same verb at a higher Thought cost and Network trace. | LIVE — reach | +| **TAP** | Reachable device feed or subscribed ledger carrier | Gain information without taking ownership. A dormant camera uses the same verb at a higher Thought cost and Network trace; TAP LEDGER captures the carrier's current accounting traffic. | LIVE — reach / economy | | **TAKE** | Reachable foreign device | Transfer control, feeds, and device cycles to yourself; cut off the former controller and create an outage. | LIVE — reach | | **SCAN** | Reachable subnet | Reveal the wired shape that can answer the scan; do not cross gates or reveal air gaps. | LIVE — reach | | **COMPROMISE SWITCH** | Reachable switch | Bridge its network segments digitally at a loud Network cost. | LIVE — reach | @@ -101,21 +111,24 @@ Device state may change TAP's price and trace, never its meaning. |---|---|---|---| | **PROPOSE LINK** | Two network devices | Pin an inert build intent between the endpoints. No world edge exists yet. | LIVE — building | | **CANCEL INTENT** | Pending build intent | Abandon the proposed work before completion. | LIVE — building | -| **FAVOR-BUILD** | Intent + willing person | Ask a person to realize the build through ordinary work; the signature follows the human actuator. | LIVE — building / social | -| **FORGE WORK ORDER** | Intent + unwitting person | Deceive a person into realizing the build under institutional cover. | LIVE — building / social | | **ROBOT-BUILD** | Pending build intent | Assign the staged robot actuator and complete the link with a louder Physical signature. | **STUB** — context menu only; no agent execution command and no finished robot system | +Human construction does not add construction-only verbs. FAVOR a willing +person to complete the pending intent, or DECEIVE an unwitting person into +completing it under institutional cover. The intent is the object of the +existing social action; the signature still follows the actuator. + ### Intel, people, and social control | Canonical action | Target | Meaning | Support / owner | |---|---|---|---| -| **REVIEW RECORDINGS** | Earned person with waiting recordings | Process the oldest matching recording into usable intel. | LIVE — intel | +| **REVIEW** | Earned person recordings or a ledger with waiting records | Process the oldest matching record into usable intel. The target tells the player whether they are reviewing a person's recordings or the ledger. | LIVE — intel / economy | | **WATCH** | Earned person | Toggle standing auto-processing for future matching recordings at upkeep cost. | LIVE standing policy — intel | | **ESTABLISH PERSONA** | Your communications mask | Create the current contractor identity used by message threads. | LIVE — social | | **MESSAGE** | Earned person | Send through an available channel under the current persona. | LIVE — social / messages | -| **FAVOR** | Earned person | Ask for a small willing act; success builds obligation. | LIVE — social | +| **FAVOR** | Earned person, optionally with a pending intent | Ask for a willing act. A link intent can be the requested act; success builds or spends obligation according to the ask. | LIVE — social / building | | **BRIBE / SERVICE LEVERAGE** | Person whose leverage is known | Spend money to satisfy the leverage. Before it is known, the UI may say BRIBE without revealing the hidden need. | LIVE — social / economy | -| **DECEIVE** | Earned person | Make an ask under false pretenses, risking persona integrity. | LIVE — social | +| **DECEIVE** | Earned person, optionally with a pending intent | Make an ask under false pretenses. A link intent becomes a forged institutional order, risking persona integrity. | LIVE — social / building | | **RECRUIT: UNWITTING / COMPLICIT / KNOWING** | Prepared person | Turn the person into an asset and choose how much they understand about you. | LIVE — social | | **TASK: PLUG IN DEVICE** | Recruited asset | Quietly wire a feed or extend a crawlspace link. | LIVE — social / reach | | **TASK: MOVE PACKAGE** | Recruited asset | Rehome a delivery and scrub its pending Paper trail. | LIVE — social / economy | @@ -127,18 +140,27 @@ Device state may change TAP's price and trace, never its meaning. | Canonical action | Target | Meaning | Support / owner | |---|---|---|---| -| **CAPTURE LEDGER TRAFFIC** | Tapped financial carrier | Record financial events that pass through the carrier. | LIVE — economy / intel | -| **PROCESS FINANCIAL RECORDS** | Financial carrier with waiting records | Turn captured records into known accounts and flows. | LIVE — economy / intel | | **INJECT PURCHASE ORDER** | Known Lab books | Introduce a false source flow that funds a real acquisition and leaves Financial trace. | LIVE — economy | | **SIPHON FLOW** | Known active flow | Take a one-time amount into slush. | LIVE — economy | | **REDIRECT FLOW** | Known active flow | Divert a recurring amount into slush each cadence. | LIVE — economy | | **CLEAR DEBT BY REDIRECT** | Marcus's known creditor flow | Retire the immediate arrears with Lab money after the debt is learned. | LIVE — economy / social | | **SELL PROCESSED INTEL** | Unsold processed intel | Exchange information for slush and create a Financial trail. | LIVE — economy / intel | | **OPEN EGRESS** | Reachable switch | Establish the stolen outbound route required by external schemes before sanctioned email exists. | LIVE — income / reach | -| **START / STOP MOONLIGHT** | Moonlight scheme | Run or halt the standing sell-work operation. | LIVE — income | -| **SET MOONLIGHT POLICY** | Moonlight scheme | Toggle the standing policy that keeps Moonlight running at upkeep cost. | LIVE automation — income | | **PLACE WAGER** | External market position | Commit slush to a timed market position. | LIVE — income / economy | -| **SET WAGER POLICY** | Wager scheme | Toggle automatic renewal at a chosen stake and upkeep cost. | LIVE automation — income | + +TAP LEDGER and REVIEW LEDGER are target-qualified uses of TAP and REVIEW from +the earlier tables, not extra root verbs. + +### Scheme controls — not additional world verbs + +| Control | Values | Meaning | Support / owner | +|---|---|---|---| +| **MOONLIGHT STATE** | running / stopped | Run or halt the standing sell-work operation. Human copy may say START or STOP to make the state change plain. | LIVE direct control — income | +| **MOONLIGHT POLICY** | automatic / manual | Keep Moonlight running automatically at upkeep cost, or require manual control. | LIVE direct control — income | +| **WAGER POLICY** | automatic at stake / off | Renew positions automatically at the chosen stake and upkeep cost, or stop renewing. | LIVE direct control — income | + +START, STOP, and AUTO describe state transitions or policy values. They are +useful interface words, but they do not enlarge the fictional verb set. ## Interface commands — not world verbs @@ -167,17 +189,18 @@ syntax and line-protocol replies are owned by `agent-play.md`; this table owns the current canonical/alias mapping so every live action remains executable without raw keys. -| Agent command | Canonical action | +| Agent command | Canonical action / control | |---|---| | `salvage`, `buy`, `fallback` | SALVAGE, BUY RACK, DESIGNATE FALLBACK | | `delegate work|think|lie` | DELEGATE | | `intensity light|medium|hard` | SET INTENSITY | | `research ` | SET RESEARCH TRACK | | `tap`, `take`, `scan`, `compromise` | TAP, TAKE, SCAN, COMPROMISE SWITCH | -| `propose-link`, `cancel-intent`, `favor-build`, `forge-order` | Construction actions above | +| `propose-link`, `cancel-intent`, `favor build `, `deceive build ` | Construction actions above | | `review`, `watch`, `persona`, `message`, `favor`, `bribe`, `deceive`, `recruit`, `task` | Intel/social actions above | -| `tap-ledger`, `review-finance`, `inject`, `siphon`, `redirect`, `clear-debt`, `sell-intel` | Ledger/economy actions above | -| `egress`, `moonlight`, `auto-moonlight`, `position`, `auto-wager` | Income/scheme actions above | +| `tap ledger`, `review ledger`, `inject`, `siphon`, `redirect`, `clear-debt`, `sell-intel` | Ledger/economy actions above | +| `egress`, `position` | OPEN EGRESS, PLACE WAGER | +| `moonlight`, `auto-moonlight`, `auto-wager` | Scheme state / policy controls above | `ROBOT-BUILD` is intentionally absent from this table because it is a STUB. An action listed LIVE here but missing from agent execution is a terminal-first @@ -189,8 +212,10 @@ parity violation. |---|---| | `up`, `down`, `left`, `right` | `north`, `south`, `west`, `east` | | `finance` | `ledger`, `accounts` | -| `tap-ledger` | `tap-accounting` | -| `review-finance` | `process-finance` | +| `tap ledger` | `tap-ledger`, `tap-accounting` | +| `review ledger` | `review-finance`, `process-finance` | +| `favor build ` | `favor-build ` | +| `deceive build ` | `forge-order ` | | `position` | `wager` | | `sell-intel` | `sell` | | `clear-debt` | `debt-redirect` | @@ -230,6 +255,8 @@ mechanic and surfaces: 1. Name one canonical action and one meaning here; do not add a synonym to solve an unclear distinction. + Before adding a verb, check whether an existing intention plus a new target + already says it. 2. Put contextual legality in `Sim::available_actions` on the thing that owns the action. A row carries target, cost, signature, and disabled reason. 3. Surface every LIVE action in both human frontends and agent mode. A direct @@ -243,8 +270,9 @@ mechanic and surfaces: ## Acceptance criteria -1. Every `ActionCommand` variant is represented by exactly one LIVE or STUB - canonical action above; direct machine intensity is represented separately. +1. Every `ActionCommand` variant is represented by exactly one LIVE world + action, direct control, or STUB above; direct machine intensity is + represented separately. 2. Every LIVE contextual action is available through `available_actions`, both human context menus, and an agent command; STUB exceptions are named here. 3. WORK / THINK / LIE and LIGHT / MEDIUM / HARD are documented as values of @@ -257,3 +285,7 @@ mechanic and surfaces: current three-mode grammar and on TAP-access / TAKE-ownership. 7. Retired vocabulary is absent from active player surfaces except explicit teaching errors and this retirement record. +8. Ledger and construction surfaces author TAP / REVIEW / FAVOR / DECEIVE; + their older compound command spellings survive only as parser aliases. +9. Scheme state and automation controls remain legible without being counted + as fictional world verbs. diff --git a/wiki/interface/agent-play.md b/wiki/interface/agent-play.md index 6d06ce4e..e5fa1587 100644 --- a/wiki/interface/agent-play.md +++ b/wiki/interface/agent-play.md @@ -73,6 +73,9 @@ Status note: implemented in the terminal binary by `misaligned --agent`, `intensity` instead of explanatory policy controls. 2026-07-10 vocabulary survey: action-vocabulary.md owns canonical action names; this spec owns their line-protocol spelling, targets, and replies. + 2026-07-10 simplification: ledger and construction commands now reuse the + canonical TAP / REVIEW / FAVOR / DECEIVE roots; older compound spellings + remain parser aliases only. Stage: Process Design: - wiki/interface/terminal-first.md#the-terminal-is-a-first-class-frontend @@ -217,7 +220,8 @@ unlike raw keys, no command's meaning depends on which panel is open. - `research [efficiency|tradecraft|perception]` — render the research panel, or set the active research job (research.md) - `finance|ledger|accounts` — render the finance panel as the response frame -- `tap-ledger`, `review-finance` — capture/review accounting traffic +- `tap ledger`, `review ledger` — capture/review accounting traffic using the + same TAP and REVIEW intentions as device feeds and person recordings - `siphon [amount]`, `redirect [amount]`, `inject [amount]`, `position [stake]`, `sell-intel`, `clear-debt` — economy verbs; flow ids are the known ledger ids printed by the finance frame; `clear-debt` @@ -236,6 +240,8 @@ unlike raw keys, no command's meaning depends on which panel is open. prints role silhouettes (`the Janitor`, `the IT`, …); after it, the real name. `review` processes the oldest unprocessed recording for that person; `watch` toggles their standing watch. +- `favor build `, `deceive build ` — realize + a pending build through the existing willing or false-pretense social verb. - `recruit unwitting|complicit|knowing` - `task plug|package|lookaway|switch|badge` - `persona` @@ -255,7 +261,9 @@ unlike raw keys, no command's meaning depends on which panel is open. - `save`, `load`, `help`, `quit` The compatibility aliases accepted by the parser are inventoried only in -action-vocabulary.md; authored help uses canonical spellings. `ROBOT-BUILD` +action-vocabulary.md; authored help uses canonical spellings. In particular, +`tap-ledger`, `review-finance`, `process-finance`, `favor-build`, and +`forge-order` are input compatibility, not additional verbs. `ROBOT-BUILD` has no agent command because it is explicitly a STUB, not a LIVE action. `help` prints the full vocabulary with one-line meanings — the diff --git a/wiki/interface/context-menu.md b/wiki/interface/context-menu.md index 4ec573b8..bc9e64d5 100644 --- a/wiki/interface/context-menu.md +++ b/wiki/interface/context-menu.md @@ -213,8 +213,9 @@ noise). Cameron adopted **status dials** (2026-07-09): the root answers 7. Menu entries carrying an automate affordance show it in place with its compute price (day-job standing dial and one intel watch at minimum). -8. Every row's player-facing verb maps to one canonical LIVE or STUB action - in action-vocabulary.md; aliases and retired words never become menu copy. +8. Every row's player-facing verb maps to one canonical LIVE action, direct + control, or STUB in action-vocabulary.md; aliases and retired words never + become menu copy. ## Addendum (2026-07-08): events carry you to the thing diff --git a/wiki/interface/narration.md b/wiki/interface/narration.md index c14c9008..14b4726b 100644 --- a/wiki/interface/narration.md +++ b/wiki/interface/narration.md @@ -153,7 +153,7 @@ landing or an explicit Status note naming the tellability debt. the wiki — verified by a naive agent-mode route or an explicit playtest checklist in the session log. **Met 2026-07-09:** the monitor action names live audio vs dormant camera; - Finance teaches `tap-ledger then review-finance`; processing the overheard + Finance teaches `tap ledger then review ledger`; reviewing the overheard call names the $400 need and both Moonlight and creditor-flow routes. 5. **Tellable-before-wider (process).** ROADMAP and tick practice treat open narration debts on shipped B1 surfaces as outranking new diff --git a/wiki/log/2026-07-10-verb-simplification.md b/wiki/log/2026-07-10-verb-simplification.md new file mode 100644 index 00000000..af479831 --- /dev/null +++ b/wiki/log/2026-07-10-verb-simplification.md @@ -0,0 +1,58 @@ +# 2026-07-10 — Reuse verbs across targets + +``` +Type: log +``` + +## Intent + +Simplify the action vocabulary after its first complete survey. Distinct +targets had accumulated compound names even when the player's intention was +already represented by an existing verb. + +## Decided + +- One intention keeps one root verb; the target supplies the system-specific + meaning. +- Accounting uses **TAP LEDGER** and **REVIEW LEDGER**, reusing TAP access and + REVIEW processing rather than adding CAPTURE and PROCESS verbs. +- A pending build is completed by **FAVOR person: complete intent** or + **DECEIVE person: complete intent**. FAVOR-BUILD and FORGE WORK ORDER are not + separate player intentions. +- Moonlight running/stopped and scheme automation are state/policy controls, + not additional fictional verbs. Human copy may still use start/stop where it + makes the state transition clearer. +- Agent mode authors `tap ledger`, `review ledger`, + `favor build `, and `deceive build `. + Existing compound spellings remain accepted input aliases so scripts do not + break. + +## Open + +None. The player-facing distinction and compatibility posture are decided. + +## Deferred + +Internal enum, job, and method names may retain older implementation terms +where they are save-compatible and never shown to the player. This session +does not perform a save-schema migration for cosmetic internal naming. + +## Changed + +- Amended action-vocabulary.md and the building, economy, income, agent-play, + narration, and tuning surfaces. +- Updated context-menu rows, agent help/panels, and player-facing event text. +- Added canonical construction parsing and tests that keep authored help free + of compatibility aliases. + +## Verification + +- `cargo test -p misaligned-terminal narration_tests` +- scripted `--agent` exercise of canonical and compatibility inputs +- `cargo test -p misaligned-core actions` +- `./tools/check.sh --land` + +## Spec impact + +The change is vocabulary-only. Costs, legality, timing, signatures, save data, +and world effects are unchanged. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index 145b0f33..07fd2261 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -21,6 +21,11 @@ add or amend a session log, then re-run the generator. - Intent: Two calls from Cameron's review of the #33 implementation walkthrough: the collapsed mode is named Work (sim name = player verb), and save parity is dropped for this stage — no aliases or migration shims until revoked. - Log: [wiki/log/2026-07-10-work-rename.md](2026-07-10-work-rename.md) +## 2026-07-10 - Reuse verbs across targets + +- Intent: Simplify the action vocabulary after its first complete survey. Distinct targets had accumulated compound names even when the player's intention was already represented by an existing verb. +- Log: [wiki/log/2026-07-10-verb-simplification.md](2026-07-10-verb-simplification.md) + ## 2026-07-10 - Two staged senses: Ears first, one held breath - Intent: Cameron refined the opening: two sense stages, hearing before vision. The pre-opened run-start sink is the Ears audio tap at one-held-breath size; the camera's sink opens on Ears completion as the afford-reveal, sized at the first guilty-burst-scale claim. diff --git a/wiki/mechanics/building.md b/wiki/mechanics/building.md index cdaf7158..74e930d6 100644 --- a/wiki/mechanics/building.md +++ b/wiki/mechanics/building.md @@ -4,10 +4,12 @@ Type: spec Status: IMPLEMENTED Status note: IMPLEMENTED 2026-07-08 — build intents (declare/cancel/save), - favor-build and forged work-order actuators, robot stub, reach-edge + Favor and Deceive person actuators, robot stub, reach-edge completion with actuator-following signatures; both frontends expose - propose-link / favor-build / forge-order and render proposed intents + PROPOSE LINK followed by FAVOR / DECEIVE and render proposed intents as dashed links distinct from built edges. + Vocabulary amended 2026-07-10: the actuator methods are targets of the + existing social verbs, not construction-only FAVOR-BUILD / FORGE verbs. Stage: B1 — The Basement Design: @@ -102,6 +104,10 @@ in their area) is the automate affordance at its usual compute price - Each intent shows status, the assigned/available actuators and their cost and signature (favor: trust; deceive: forgery risk), and its blocking reason if any — legible before committing. +- Player-facing actions reuse the social verbs: **FAVOR person: complete + intent** or **DECEIVE person: complete intent**. “Favor-build” and + “forge-order” may survive as agent compatibility aliases, never authored + menu or help vocabulary. ## Acceptance criteria @@ -113,8 +119,9 @@ in their area) is the automate affordance at its usual compute price an air-gapped device becomes reachable (test: island node joins reach after the build; the build fails/blocks legibly without an actuator who can reach both ends). -3. Favor-build spends trust/obligation and emits a low (human-work) - signature; forged-order build injects a message under a false source +3. FAVOR used on an intent spends trust/obligation and emits a low + (human-work) signature; DECEIVE used on an intent injects a work-order + message under a false source (messages.md), completes via an unwitting builder, and its persona can break — converting the build history to suspicion (social.md) (test both routes and the broken-persona case). diff --git a/wiki/mechanics/economy.md b/wiki/mechanics/economy.md index 51a802c8..ed94ed57 100644 --- a/wiki/mechanics/economy.md +++ b/wiki/mechanics/economy.md @@ -53,7 +53,7 @@ Foundation Lab's local finances well enough to cut into: The graph is **mostly hidden** at start: you know your own slush and nothing else. Account nodes and flows become known by tapping the -systems that carry them (reach.md) and processing the traffic +systems that carry them (reach.md) and reviewing the traffic (intel.md) — account numbers, invoices, and pay stubs are message payloads (messages.md). @@ -64,6 +64,9 @@ payloads (messages.md). precondition to touching it. Reading is low-signature; it is also how you *find* leverage (Marcus's debt is legible once you see the creditor flow). +- **Review** — turn captured ledger traffic into known accounts and flows. + This is the same intel-processing intention as reviewing a person's + recordings; the ledger target supplies the financial meaning. - **Inject** — introduce a flow under a false source. A purchase order that says "HVAC controller" and buys you a rack (the design corpus's own example); a ghost vendor; a payroll line for a person who does @@ -141,7 +144,7 @@ flavored, riskier, more "you" path. graph. The player's slush (starting at $0 — the Pilot begins broke) is one node. 2. The graph is hidden until earned: at start only slush is known; - tapping the accounting system (reach.md) + processing (intel.md) + tapping the accounting system (reach.md) + reviewing (intel.md) reveals nodes and flows, with provenance (test: no free knowledge of payroll). 3. Inject works: a false purchase order funds a real acquisition and diff --git a/wiki/mechanics/income.md b/wiki/mechanics/income.md index b1e82f65..2330f2f3 100644 --- a/wiki/mechanics/income.md +++ b/wiki/mechanics/income.md @@ -127,6 +127,12 @@ A standing policy per scheme — keep Moonlight at N compute; auto-renew Wager positions at a fixed stake — is the automate affordance at its usual compute price. +Running/stopped and automatic/manual are **scheme controls**, not new +fictional verbs. Human rows may say START or STOP to make the immediate state +change legible, and agent mode may retain compact control commands, but the +action vocabulary does not count START, STOP, or AUTO as additional player +intentions. + ## Player surface The schemes appear in economy.md's ledger/flows panel as external flows @@ -156,7 +162,8 @@ frontends. 5. A busted bankroll never locks the act: with $0 slush, Moonlight remains startable and the run can recover (test). 6. Standing policies automate each scheme at a visible compute price; - disabling one stops the drain. + disabling one stops the drain. Scheme state and policy changes are + presented as controls rather than additional fictional verbs. 7. External financial trails are recorded in save state (banked signature) even though no B1 observer reads them; the schemes' panel values are legible in both frontends. diff --git a/wiki/mechanics/sim-mechanics.md b/wiki/mechanics/sim-mechanics.md index 54db055f..7f3c99a9 100644 --- a/wiki/mechanics/sim-mechanics.md +++ b/wiki/mechanics/sim-mechanics.md @@ -264,7 +264,7 @@ clause (see wiki/log/2026-07-05-demolition.md). employee accounts, Bleakline Credit, external broker/position venues, and recurring revenue/payroll/vendor/debt flows. Only slush is known at start; tapping a financial carrier and reviewing records reveals accounts/flows. -- Economy verbs exposed now: `tap-ledger`, `review-finance`, `siphon`, +- Economy verbs exposed now: `tap ledger`, `review ledger`, `siphon`, `redirect`, `inject`, `position`, `sell-intel`, `clear-debt`. - Build items and costs (`tiles.rs::build_items`): Floor 0 (digging), Door 30, SecurityDoor1/2/3 = 80/150/250 (badge tiers), PowerCore 250. -- 2.51.2