Files
Dune/docs/RICHESE_NO_FIELD_ENGINE_AUDIT.md
T

25 KiB
Raw Blame History

No-Field engine integration audit

Read-only audit, 2026-09-06, followed by a bounded integration checkpoint. The hook findings below describe the engine at the original audit; line numbers are approximate because implementation is concurrent. Function/action names are the durable anchors. It supplements RICHESE_NO_FIELD_RULES.md and does not certify a playable Richese expansion.

Basic mixed runtime amendment — 8 October 2026

Ordinary Basic physical-plus-marker battle admission now has a connected, visibly provisional additive private pool, native joint reveal and actual casualty/aftermath path. Basic bots may form mixed groups; Advanced/combined Occupy guards remain. One direct before/after smoke and current types pass; actual SSR Battle Wheel/plan controls were observed in Chromium. The current contract states the unresolved formula and refinement boundaries. The earlier mixed-battle absence/avoidance claims in the checkpoint below are historical, not the current Basic implementation.

Basic Guild-recipient and already-active Karama allied offers now also use a visibly provisional one-spice/bank quote, with connected supplier, recipient and AI paths. Two direct before/after cases and current types pass; SSR offer/consent surfaces were observed in Chromium. Advanced counterparts remain guarded. This supersedes the earlier blanket price absence below; the payment contract retains the unresolved publisher precedence.

Current resolution of the audited hooks

  • Implemented in development fixtures: separate physical Player.noField custody; public force-presence counting and location keys; own No-Field shipment with cancellation/payment stages; physical-plus-marker or marker-only movement; event-fenced voluntary reveal; collection and occupancy/control consumers; exact exposed storm sector and unprotected worm materialization/casualties; marker-only prospective battle pools, joint reveal and persistent zero-battle identity; server-enforced ordinary prescience no-dial restriction; allied opportunity/private consent/typed immediate shipment with fixed full or equal-split funding; Gamont reveal at a selected marker location followed by one actual force returned when present, including zero and colocated ordinary-unit cases.
  • Player controls integrated, browser coverage bounded: components/richese-no-field.tsx renders public concealed markers and private owner inventory/selection, price and allied-share feedback, reveal availability and last-use state. The parent table supplies explicit marker movement and private battle bounds. Rival board views contain neither token IDs nor denominations. The separate allied component holds an explicit Richese opportunity, then shows the exact proposal and typed acceptance only to its participants. Own shipment/movement/reveal and the allied owner proposal were browser-checked; recipient acceptance and mobile remain pending.
  • AI integrated, bounded policy: owner-only token choices, one-force funding, explicit marker movement, positive reveal and zero concealment; ordinary groups avoid creating unsupported mixed battles. Marker-only battle planning uses battle.ownForces, while opponent estimates use public presence. All profiles avoid forbidden dial prescience and honor pending interactions. Allied bots select positive owner-funded offers and act only on their own opportunity/consent; scheduler tests cover both seating orders and waiting for a human supplier.
  • Still guarded or unfinished: mixed physical-plus-marker battle arithmetic, entire-plan special Karama, Guild/active-Karama allied pricing, broader Truthtrance, protected-worm interpretation, generic removal/card combinations and optional containers. The original table's warnings remain relevant to these paths; they are not all resolved by shared presence helpers. Gamont's exact R2 reveal/return/zero-use rule is now integrated; cancellation retains concealment and stale restored custody aborts safely. The original Gamont hook row below records the pre-integration defect.
  • Focused evidence: 13 model, 10 engine, 8 independent review and 9 AI named scenarios pass, plus 19 existing Gamont regressions. Root reports 29/29 for the combined Gamont and No-Field engine check, including two new Gamont scenarios spanning all values, colocated units, scarce reserves, cancellation and stale events. Full TypeScript and targeted lint pass. Review includes identical complete nonowner projections across 0/3/5, sealed-plan secrecy, actual Thumper worms, safe storm sectors, later same-token stale events and atomic interrupted entry. AI scenarios include finite Basic/Advanced marker-only battles across all four profiles. Subsequent persisted and browser evidence appears below; these focused results alone do not certify complete Richese games.

Each of implementation, player controls, AI, documentation and verification remains Partial in the in-app checklist. Historical findings follow so reviewers can trace why the adapters and guards exist.

Source boundary and model contract

The publisher CHOAM & Richese rulebook, R2 pp6,10–11, was read in /tmp/dune-rules/choam-lelekan-mirror.txt, the verified publisher-authored mirror recorded in the existing source audit. Page6 establishes concealed shipment for one-force price, movement as forces, voluntary reveal before Battle, forced storm/worm reveal, one deployed marker and no consecutive reuse. Battle reveal occurs with the Battle Plan; ordinary Atreides dial inspection is prohibited in that battle. Allied shipment reveals immediately, after revealing any already deployed marker. Pages10–11 confirm one-force effects even for zero, Gamont reveal/return, zero-token leader/cards, reserve-constrained dial and allied payment/Heighliner details.

The intended Player.noField?: RicheseNoField stores the component separately. p.forces must continue to mean actual units, with reserves transferred only when the marker reveals. Concealed presence contributes one to occupancy and ordinary board-presence effects. It does not contribute a casualty unit, an extra reserve, or one guaranteed battle dial. The owner can privately derive prospective materialization as min(token value, current reserves); a public count must not use this value.

Keep distinct helpers for actual unit count, effective presence, occupied location keys, and private prospective battle units. Replacing every at() or fighterCount() with one universal number would contaminate casualties, economic effects and secret projections. Existing pure reveal returns materialization facts, not force/Tanks mutations; the engine must apply those facts once with an event/version fence. Public marker projection must omit physical token IDs and hidden supply values that disclose denomination through elimination.

Concrete engine hooks

Location Required condition or change
game/advisors.ts: forceCount, fighterCount, settleAdvisors, arrivalAsAdvisor Audit presence separately from actual counts. Marker-only Richese is a neighboring faction for ordinary coexistence/occupancy. A helper type restricted to Pick<Player,'forces'> will silently lose the marker unless its explicit contract changes. Do not manufacture a BG advisor or Richese unit.
engine.ts: local at (~758), allowedEntry (~2370) Existing ally prohibition uses at(ally,t), while stronghold occupancy uses fighterCount. Both must recognize a hidden marker, including zero. Keep polar/sector/storm and two-faction occupancy rules. Do not let zero become an undetectable third faction.
battles (~3332) Presence filtering is insufficient: sector accessibility is built from Object.keys(p.forces) for both participants. Include marker location in each side's location-key set. Preserve same-territory storm-separated geometry, allies, Polar Sink and aggressor order. Marker-only versus ordinary forces must create a battle even when the privately selected value is zero.
validatePlan (~3954), combatForces (~944), findLegalBattlePlan (~4208), findReachableBattlePlan and validPrescienceValue Base dial currently caps at actual at; advanced casualty feasibility uses actual force pools. Before reveal, use a private prospective materialized pool for a supported marker-only battle. Do not dial the public marker-one count. Update legal-plan search and validation together to avoid false deadlocks or an invalid fallback plan.
battlePlan action (~9125), recordFullPlanInspection, nextRevealedDecision, resolveBattle, takeBattleLosses Materialize exactly at public plan reveal, once, before traitor/combat/casualty processing. Sealing one plan is not public reveal. Persist a battle-local marker-origin flag: after zero materializes there are no actual Richese units, but the already declared battle, leader, Cheap Hero, cards and traitor calls still exist. Do not rebuild/filter away that battle. Casualties must subsequently use real units and never kill a phantom marker.
continueStorm (~1258) Its current loop enumerates p.forces keys only. Inspect the marker's exact sector and the same exposure/shelter test separately. Reveal and kill materialized units once when caught. A marker in protected Imperial Basin or an unaffected sector must not be removed because another stack is exposed. Shield Wall destruction changes shelter using existing board rules.
beginWorm, wormSurvival, devour (~1356–1396) Fremen-allied protection eligibility currently uses actual at; marker-only ally presence requires recognition. devour kills ordinary stacks but knows nothing about a marker. Apply the appropriate reveal/destruction after the protection decision, retain its continuation, and include summoned-worm routes. Whether a protected marker still reveals is not explicitly answered by the retrieved specific text; record a policy or guard rather than silently choosing.
prepareChoamWorthless: Trip to Gamont (~6032), resolveResponse Gamont settlement (~5280), viewGame.choamWorthless.gamont (~9560) Current validation requires a positive other.forces[key]; options enumerate actual stacks. Include a marker location without exposing its value. After successful CHOAM response, reveal there and return one resulting Richese force if available. Zero remains a successful used-card effect, with no fabricated reserve increment. Do not reveal on a canceled declaration or blindly run current removeGroup(...1) against zero. Mixed existing/materialized force selection needs the source boundary below.
collect (~3783) Changing fighterCount fixes ornithopter/stronghold presence but not this direct Object.entries(p.forces) spice loop. Add marker-one collection exactly once at its sector; a colocated real group collects for its actual units plus one concealed presence. Apply the ordinary rate and storm exclusion, without deducting reserves or revealing. R2 expressly confirms zero collects normally while concealed.
victory (~3818), Fremen special victory, offerMoritaniDuke, allied coexistence at end movement Count marker presence when checking stronghold control and exclusion. No-Field creates a real battle threat for Duke eligibility. Upon zero reveal, control can disappear, but not retroactively erase the current battle. Shared count changes must not change the already established same-turn alliance coexistence exception.
commitShipment (~5831), movement preparation/completeMove (~2562), openTerritoryEntry, openTerrorEntry Ordinary shipment currently pays, subtracts units, places units and logs the exact amount. A concealed shipment needs its own placement commit that performs no reserve subtraction and logs no denomination. Movement removes/adds actual groups; explicitly move a selected marker without duplicating or splitting it. Preserve shipment/movement allowances and pending Guild/BG/CHOAM/entry continuations. Source-confirmed Terror entry includes zero; revealing an already-present marker is not a second entry.

Battle privacy and unresolved arithmetic

For a marker-only supported battle, maximum materialized ordinary units is bounded by denomination and current reserves, with zero dial available but mandatory leader rules unchanged. Mixed ordinary forces plus marker is not resolved by this statement. R2 says not to dial higher than reserves but does not answer whether this overrides existing forces, how mixed sectors combine, or how reserve commitments alter the limit. Do not silently implement ordinary + min(value,reserves) or min(total,reserves) and call it a verified FAQ formula. A narrow guard on unresolved mixed configurations is honest; the engine/UI must explain it without disclosing hidden value. Reserve changes after one plan seals require a stable commitment or explicit incompatible-action guard, not deferred creation of nonexistent units.

Ordinary prescience currently accepts dial in the server field list and prescienceAnswer validates it from actual forces. Remove that choice for an entitled target with a No-Field in this battle, enforce it on the server, and retain the prohibition in battle state after reveal removes the marker. Weapon/defense/leader information remains eligible under ordinary prescience. Update owner/allied beneficiary controls and bot selection; hiding a button alone is insufficient. Do not publish private prospective maxima or reasons to the opponent.

The special entire-plan power currently stores an ordinary plan and viewGame.battle.fullPlanInsight returns it in full to its owner before public reveal. The retrieved No-Field text does not explicitly reconcile entire-plan special Karama with dial secrecy. Do not send the dial through this property on an assumption, nor silently omit part of an advertised entire plan. Guard the unresolved intersection before spending Karama until the rule is settled. Truthtrance structured battle-plan claims, reachable-plan helpers, compliant-plan projections and historical truth answers are separate disclosure paths needing the same audit. The direct dial restriction does not automatically resolve every question about forces or future plans.

Allied shipment and interruption contract

Allied shipment uses Richese's physical token but the ally's reserves and immediately becomes actual ally units. It must first reveal any existing own marker, and the next token cannot repeat the last own/allied use. A canceled shipment must not mutate last-use history or materialize a token merely to validate it. If the old-marker reveal and new allied shipment are separate irreversible steps, persist their stage so a retry cannot reveal twice or rollback a completed reveal accidentally.

The FAQ fixes the cost at one spice in a stronghold, two elsewhere, payable by either player to Guild or bank. Do not apply the ordinary amount-times-price helper to materialized three/five units. Heighliner triggers except when Guild is the shipped ally; the actor identity must therefore be the force recipient, not always the Richese power owner. The follow-up source audit now supplies a reviewed ordinary contract: recipient shipment allowance, private consent and typed physical-unit selection, either full payer or one each for a two-spice shipment. Fremen’s ordinary on-planet reserves are excluded. Only the Guild-rate/active-Karama precedence and additional unresolved entry combinations remain guarded here; see RICHESE_ALLIED_SHIPMENT_AUDIT.md. In particular, generic allied financial pledges are not a substitute for the printed either-payer choice.

Own hidden shipment has the same important actor/representation split: Guild income and BG accompaniment are shipment effects, but the logged amount and entry projection cannot reveal the token. Existing commitShipment can open both Guild response and BG decision before territory-entry effects; do not overwrite them with a new response. Existing unsupported simultaneous-entry handling should reject atomically rather than silently skip Terror/Ambassador effects. Canceling the No-Field power is not necessarily a canceled ordinary shipment: do not grant an automatic fallback shipment without a ruling.

Map, UI, AI and additional effects

components/game-table.tsx directly enumerates forces for map stacks, movement sources, public rosters and Gamont controls, and its basic battle wheel uses fighterCount. A marker needs an explicit concealed glyph at its sector, private owner inspection, marker-specific selection, and a projected private planning bound. Do not inject fake forces[key]=1 to make existing rendering work. That would spend/kill a nonexistent unit and mislead conservation tests. game/bots.ts likewise enumerates actual source groups and derives battle pools; update movement and planning with entitled projected options, while opponents see one uncertain presence rather than zero/three/five.

Audit generic killTerritory/Family Atomics/lasgun-shield, Guild cross-shipment or return-to-reserves, Hajr, Ornithopter, Smuggler, Moritani/Ecaz arrivals and force-transfer effects individually. The specific storm/worm/Gamont instructions do not prove that every generic “remove force” operation has the same reveal-and-return semantics. Mobile Stronghold and Homeworld containers must not be accepted just because a structural location passes. The existing pure module's ordinary Polar Sink address is valid; it does not authorize unsupported off-planet custody.

Required bounded acceptance evidence

  1. Hidden own placement/movement: zero/three/five identical public projection, no reserve debit, exact one-force price, one marker, alternating last use, canceled/stale retry atomicity, marker-only occupancy and storm-separated battle discovery.
  2. Battle: zero retains leader/cards/traitor process and finite finish; positive materializes once after both plans seal; reserve shortage and casualties conserve units; ordinary Atreides dial denial applies through API, allied privilege and bot; unsupported mixed/full-plan/Truth intersections fail before consuming resources.
  3. Storm/worm/Gamont: exact sector/shelter/protection, once-only materialization/destruction, canceled Gamont leaves marker concealed, successful zero Gamont consumes its card without inventing a returned force; refresh at every pending response.
  4. Collection/control: concealed zero harvests at ordinary rate, colocated ordinary units are neither replaced nor double-counted, ornithopter/stronghold/Fremen-victory implications and post-reveal control are tested.
  5. Allied route: recipient reserves, explicit payer, immediate reveal, prior marker, no consecutive reuse, Guild ally Heighliner exception, all authorized reactions and unsupported variants.
  6. Every viewer's private projection, actual all-four-profile behavior, browser map/action inspection and persisted CAS. Pure component tests alone do not establish these engine properties or release expansion gates.

Integrated acceptance update

At the earlier own-No-Field checkpoint, the registered suite passed 1,176 rules/client scenarios and 87 persisted/API scenarios, with TypeScript, lint and production build passing. Four No-Field persisted-room tests cover private projections/reopening, cancellation after reload, competing shipment CAS, movement stale events and duplicate reveal. Browser room QPNV5XJJ exercised shipment of token 5, marker-only movement, fresh invitation recovery and voluntary reveal to five actual forces. The owner inventory/board layout was visually inspected. Full battle/Gamont/mobile browser checks and complete Richese games remain outstanding. Logs and exact QA state are recorded in IMPLEMENTATION_STATUS.md.

Allied hook resolution before final checks

finishAutomaticDecision opens a persisted richeseAllyOpportunity for the supplier before the eligible active ally ships; direct offer also marks that opportunity handled. Ordinary shipment/movement cannot bypass an unanswered opportunity. offerRicheseNoField stores private exact terms; richeseAllyShipment accepts with legal elite bounds or declines. No ordinary fallback is silently chosen. runBots normalizes an unopened opportunity and waits with no bot work pending when the decision belongs to a human.

The payment contract accepts supplier ID, recipient ID or both; both is only valid at the two-spice price and debits exactly one from each. The proposal does not test hidden recipient affordability for the supplier. Revalidation at consent/commit protects current alliance, event, reserves, funding and destination. Karama/Guild prevention resolves before the old marker is revealed and before the new token immediately materializes; movement allowances remain untouched. Typed Sardaukar/Cyborg quantities count physical units, with the recipient selecting its allowed mix. Fremen off-planet eligibility and Guild/active-Karama pricing retain their separately documented exclusions/guards.

Current allied evidence: ten engine, seven independent review, seven AI and three SQLite/API recovery cases pass. The recovery cases include authenticated reopening, private consent, concurrent acceptance, duplicate cancellation and stale Guild commitment. Whole persisted/API suite: 90/90. The expanded rules rerun and final type/lint are pending after one legacy fixture was updated for the new decision (ten focused cases pass). The allied owner proposal was browser-checked at a real saved version 10; recipient browser acceptance is still pending. This supersedes the earlier counts only for the current allied slice; no full-mode certification follows.

Final allied checkpoint

The integrated suite passes 1,207 rules/client and90 persisted/API tests. TypeScript, lint and production build pass. Eleven allied engine cases now include recoverable arrival preflight and an AI decline fallback, alongside seven independent review, seven AI and three persisted cases. The supplier’s real browser offer survived the controlled09:10UTC restart with all995 saved tables unchanged. Recipient acceptance was then exercised through real controls in a deliberately swapped synthetic-role fixture; three actual forces arrived, only the recipient’s shipment was used, and the supplier paid once. This is browser coverage of both interfaces, not a claim of real seat switching. Exact logs, backup paths and fixture transitions are in IMPLEMENTATION_STATUS.md. Complete Richese games and unresolved optional/pricing combinations remain outstanding.