# Automatic actions and player decisions Read-only engine/UI/API audit, 2026-09-06, against the updated goal's requirement: automatic effects should not require confirmation; optional 1–2-second house-colored action notifications must not block play. Only this audit document was written. No rule or timing interpretation was changed. ## Safest concrete removals | Current behavior | Why it is redundant | Safe implementation boundary | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `resolveBattle` creates `battleLosses` even when `casualtyOptions` contains exactly one result (`game/engine.ts`, approximately 3753 and 3873). | There is no choice of unit mix. Even a zero-loss result can require a click. This differs from storm casualties, which already resolve a forced mix automatically. | Extract the existing settlement of the selected option from the `battleLosses` handler. Invoke it directly for one option. Preserve the following Ixian substitution decision, winner card-retention choice, and postbattle continuation. Do not bypass them by merely calling `finishBattle`. | | Every power owner must submit `passResponse` for its own power; completion currently counts every player (`game/engine.ts`, approximately 5695–5715; `components/game-table.tsx`, approximately 1495). | The same dispatcher explicitly forbids the owner from canceling its own power. This pass is not an ordinary Karama cancellation choice. | Count the owner as satisfied using public `response.owner`, while requiring all other participants' passes. Use one shared responder predicate for engine, bots and UI; normalize persisted windows and nested Worthless-Karama windows. Keep permitted Truthtrance/CHOAM overlays available while the actual responders decide. Do not globally auto-pass other players based on their hands. | | `fullPlanRead` only accepts `{continue:true}` (`game/engine.ts`, approximately 6291); UI requires “Finish inspection.” | Opponent's plan is already committed, and the Atreides player's next meaningful action is preparing their own plan. The acknowledgement does not choose an effect. | Remove the extra blocking decision only with persistent private inspection in the ordinary plan editor. Preserve `fullPlan` target-first submission and authorized `insight`, including Truthtrance promises. A 1–2-second animation must not be the sole way to inspect a tactical plan. Legacy saved `fullPlanRead` can normalize to the plan editor without submitting a plan. | These findings are based on actual code branches, not a count of buttons labelled “Confirm.” No runtime reproductions were needed to establish the singleton branch or all-player response predicate; new integration tests remain necessary before modifying them. The owner-pass reduction does not establish a new automatic deadline for other players. A player who has already passed can currently still use permitted overlays/cancel before the last responder passes; preserve those existing rights unless a separate authoritative timing change is made. ## Additional candidate requiring a narrower integration check `beginPhase(7)` calls `collect(g)` immediately. The UI then presents “Ready for next phase” to every player even though collection has already happened. Current `collect` contains automatic stronghold/desert awards; no collection allocation choice is exposed in this baseline. A collection-result notification followed by the existing phase-end continuation would remove a likely acknowledgement-only pause. Do **not** implement this by removing all phase readiness or skipping `nextPhase`: CHOAM phase-end market, technology settlement, future Ecaz co-collection choices, and any applicable phase-specific reactions must remain. Complete the current phase's real decisions first. Special CHOAM and Truthtrance currently have broad timing, so verify their existing before/after boundary semantics when advancing automatically. This candidate is less isolated than singleton casualties and is not certified as a universal all-expansions rule. ## Prompts that protect real choices | Prompt/window | Actual choice or reaction protected | | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Storm movement confirmation | Weather Control and Family Atomics before movement. Do not move storm on a display timeout. | | Accept spice blow | Harvester timing; other current Spice Blow continuations also include Thumper, Nexus, Fremen special Karama and worm choices. A publicly Harvester-closed blow can be examined separately, not used to remove all spice windows. | | Phase opening | Amal, including an opportunity after a prior Amal. The engine deliberately offers the same window regardless of hidden ownership. | | Opponents allowing powers | Ordinary Karama; Advanced BG Worthless conversion and nested cancellation. Income that looks automatic still has a cancellation window before settlement. | | Guild shipment, full-plan offer, revival stop | Spending an optional special Karama versus preserving it; hand-independent offers prevent information leaks. | | Charity/Revival ready | Remaining claims, revival resources, leader/force choices and other phase powers. Zero current payable revivals is not proof of no actions when special cards or resources can change. | | Winner card cleanup, Moritani retention, Poison Tooth | Keep/discard/activate choices remain even if one card is involved. One eligible card still offers keep versus discard. | | Advisor arrival/intrusion, Face Dancer, captured leader, Moritani/Ecaz placement | Optional effects, destinations, ownership or spending choices. Their availability is not equivalent to mandatory use. | | Mentat readiness | Negotiation, later turn-end effects, Face Dancer replacement, Gamont and other faction choices; do not globally skip because victory has already been checked once. | | Lobby readiness, battle-plan lock, storm dial | Consent or sealed strategic decisions, never automatic acknowledgements. | `choamTradeConfirm` is a genuine final assent after the ally specifies the returned card. `auctionPayment` can choose Karama versus spice. Do not remove either simply because it contains a confirmation label. ## Existing automatic behavior to preserve - `stormCasualties` calls `kill` directly when the allowable elite-loss interval is a singleton; only a real mix choice creates `stormLosses`. - `finishBattle` transfers a single available technology token directly; multiple tokens produce `techToken`. - Empty winner-card cleanup proceeds immediately; combat with no remaining battles advances through its existing phase-end continuation. - Force transfers, payments, resource awards, setup completion, predetermined casualties and battle results already commit on the server; they need presentation, not new acknowledgements. Do not replace these with client confirmation steps merely to make animations visible. ## Privacy and multiplayer requirements **Do not auto-pass based on a player's hidden hand.** A faster or absent Karama/Amal/Guild-special window would disclose that a player lacks a relevant card. A private local checkbox which emits an immediate pass only when a card is absent can leak through visible timing too. Removing a responder because they publicly own the power is different: that condition is already public and the rules branch prohibits self-cancellation. Automatic rules resolution belongs in the authoritative engine on the disposable action clone, before the database compare-and-swap commits. `db/rooms.ts act` currently applies one action, runs AI, increments version and writes under room-version plus current-token authority. A deterministic normalization chain can share that transaction. It must stop at the first meaningful choice/reaction and use a bound that reports a real loop rather than silently dropping work. Do not imitate human confirmations from the browser or add client timer POSTs. `continueRoomBots` already persists bounded AI batches with version fencing. It is not permission to advance human choices, and an animation completing must not call `advanceBots`, `ready`, or `passResponse`. Read-only GET/reconnect should project state; any migration that resolves a legacy redundant decision must happen at an explicit authoritative write, or a separately designed fenced continuation, never a mutating view. ## Nonblocking notification contract The UI currently has ordinary game logs and reduced-motion CSS, but no audited structured automatic-action notification stream. `Game.log` contains `{seq,text}` and retains 250 entries; one persisted bot batch can produce many events and skip intermediate phase snapshots. A phase-name comparison alone cannot reliably report every action. Prefer small server-authored public event metadata such as `{seq,kind,actorFaction,label}` alongside the settled result. Private effects need viewer-authorized metadata; do not infer secrets from full game state or put inspected cards into public events. Keep action names separate from player-generated names and arbitrary log parsing. Display each notification for approximately 1–2 seconds, with faction colors and a readable action name. It must use no modal backdrop, focus trap, pointer interception or disabled gameplay state. Provide a local toggle, honor reduced motion, and keep a durable readable history. Turning it off must change only presentation. Keep a per-room processed sequence so refresh or stale poll cannot replay old notifications; initialize a newly joined/restored view at its current sequence. Coalesce excessive AI-batch notices rather than queueing minutes of stale animation. Avoid announcing the entire historical log through a live region on every update. ## Meaningful validation before changes land 1. Single-option Advanced casualties settle exactly once, including JSON legacy state; multiple options still ask. Ixian cyborg losses still offer legal substitution. Winner cleanup, Moritani retention, technology/capture/Face Dancer continuations remain intact. 2. Power owner is never a required pass; every other player remains eligible, including an ally. Windows remain identical for hidden-card variants. Nested BG conversion/counter and Truthtrance overlays restore the correct responders. 3. Special prescience proceeds to Atreides planning with persistent private opponent-plan visibility; the opponent cannot change it and other seats cannot inspect it. Refresh preserves the insight; no automatic battle plan is submitted. 4. Automatic settlement survives duplicate requests/concurrent CAS without duplicate payment, RNG, casualties or events. A disconnected owner's redundant acknowledgement cannot stall an otherwise settled window. 5. Notices remain nonblocking on desktop/mobile and keyboard; toggle/reduced-motion behavior does not affect room state. Reconnect and multi-event bot batches do not replay history or expose hidden identities. Full scope remains gated. This is an implementation audit of the present runtime, not a claim that every future expansion effect is automatic or already covered. ## Implemented checkpoint (2026-09-06) The candidate audit above describes the earlier baseline. Singleton auction payment and full-plan acknowledgement removal are now implemented. Exact funded split plus no usable Karama permits automatic payment; a real Karama choice remains explicit. Atreides retains private plan inspection until reveal, including when helping an ally. Legacy saved decisions recover via authenticated CAS continuation. Tests: automatic-decisions, full-plan, automatic-response-recovery, and the full 1,029 rules / 74 persistence checkpoint. Other candidate pauses still require their own timing audit.