From 7ef00e0a65ac05c72b929d495b64259f5cc84ed1 Mon Sep 17 00:00:00 2001 From: Quintine <15965533+Quintine@users.noreply.github.com> Date: Fri, 16 Oct 2026 03:26:49 +1100 Subject: [PATCH] Admit original Advanced Tleilaxu Ixian Nexus replacement --- docs/CURRENT_STATUS.md | 47 ++++++++--------------- docs/IMPLEMENTATION_STATUS.md | 13 +++++++ docs/NEXUS_CARD_RULES.md | 2 +- docs/NEXUS_IXIAN_REPLACEMENT_RULES.md | 42 +++++++++++++++----- docs/RULE_DECISIONS.md | 2 +- game/engine.ts | 6 +-- game/reference.ts | 6 +-- tests/fixture-native-ixian-replacement.ts | 7 ++-- tests/native-ixian-replacement.test.ts | 10 +++-- tools/start-prototype.ts | 2 +- 10 files changed, 80 insertions(+), 57 deletions(-) diff --git a/docs/CURRENT_STATUS.md b/docs/CURRENT_STATUS.md index 8c8cf79c..7de07bbc 100644 --- a/docs/CURRENT_STATUS.md +++ b/docs/CURRENT_STATUS.md @@ -29,39 +29,22 @@ optional skill bands, combinations and public expansion starts remain open. Rules implementation continues; comprehensive assurance and administration remain deferred until all rules are implemented. -**Harkonnen Ixian replacement preserves its native bonus — 16 October.** -Original purchased-card Use/Keep now precedes income and bonus under a -visibly provisional order matching the native Ixian ally pipeline. A -replacement is not a second purchase; the original bonus stays cancelable -and replacing at eight cards creates no extra slot. No publisher priority -or explicit user-selected sequence is claimed. +**Ixian Nexus purchased-card interaction wave — 16 October.** +Normal purchased-card replacement now composes: +- successful native BG Karama conversion, after its original counter; +- Harkonnen's original cancelable bonus and eight-card limit under a visibly + provisional replacement → income → bonus order matching the native ally path; +- original Tleilaxu/Ix47 setup and native purchases in Basic **and Advanced**. -Three new behavior cases; affected seven-file64/64, eight original runtime -paths and eight legal policy actions pass. Two original390px journeys -exercise Basic Use/bonus cancellation and Advanced Keep/bonus allowance, -preserving actual income, wallets, card identities and one next-lot advance. -The eight-card fixture separately controls conserved hand acquisition. -Width/scroll390; no browser/application error. No human server, D1, saved -room, deployment or public gate changed. -[Selected policy and scoped evidence](NEXUS_IXIAN_REPLACEMENT_RULES.md#harkonnen-purchase-and-bonus-composition--16-october-2026). -Final types/lint and production build pass with existing warnings. Current -source anchor and19 topic paths resolve; all five facets remain Partial. - -**Ixian Nexus replacement follows native BG purchases — 16 October.** -Successful original BG Worthless-as-Karama acquisition/payment now earns the -same normal purchased-card replacement, after its native counter. Denied -direct acquisition supplies no purchase; native funded winning-payment -recovery supplies a paid, not free, receipt. No printed-cost-only flag remains. - -Four new behavior cases; affected nine-file74/74, four original-action runtime -paths and eight legal policy actions pass. Two original-source390px journeys -replace Hajr with the actual Ghola or keep the winning Shield, preserving -BG5/Emperor12 and one auction continuation. Width/scroll390; no browser/ -application errors. Counter custody is explicitly controlled in two cases. -No human server, D1, saved room, deployment or public gate changed. -[Source and bounded evidence](NEXUS_IXIAN_REPLACEMENT_RULES.md#native-bg-converted-purchases--16-october-2026). -Final types/lint pass; current source anchor and17 topic evidence paths -resolve. No production build or broad assurance run for this slice. +Latest native cases7/7 and affected six-file47/47 pass; four original Advanced +runtime paths, eight legal policy actions and actual CLI help pass. Earlier +BG/Harkonnen rule and mobile-control evidence remains separately source-bound +in the [canonical contract](NEXUS_IXIAN_REPLACEMENT_RULES.md), including the +selected provisional policy and explicit controlled fixtures. All five +facets remain Partial. Special origins/other modules and final assurance +stay separate. No saved room, human server, D1, deployment or public gate +changed. The latest admission slice adds no UI. +Final types/lint pass; current source anchor and19 topic paths resolve. **Semuta connects both physical Shrine roles — 16 October.** Fresh private `semuta --discoveries` setup retains original Richese/CHOAM, diff --git a/docs/IMPLEMENTATION_STATUS.md b/docs/IMPLEMENTATION_STATUS.md index c998fa26..78696236 100644 --- a/docs/IMPLEMENTATION_STATUS.md +++ b/docs/IMPLEMENTATION_STATUS.md @@ -1,5 +1,18 @@ # Dune implementation status +## 16 October 2026 — Advanced native Tleilaxu Ixian replacement + +Removed the Basic-only producer fence from original native Ix47/Tleilaxu +replacement setup. Existing native behavior cases now exercise both modes: +7/7 native and47/47 affected pass. Four original Advanced Use/Keep runtime +paths and eight legal policy actions preserve actual setup/Nexus acquisition, +Thumper/Amal, payment/income and next/final-lot continuation. Actual CLI help +names both modes and prior provisional Harkonnen ordering. No new UI, saved +room, human server, D1, deployment or public gate changed. +[Source and evidence](NEXUS_IXIAN_REPLACEMENT_RULES.md#advanced-native-tleilaxu-admission--16-october-2026). +Final types/lint and actual CLI help pass; source anchor and19 topic evidence +paths resolve. No new build, browser, broad suite or HTTP assurance run. + ## 16 October 2026 — Harkonnen Ixian replacement and original bonus Removed the Harkonnen buyer fence from the existing normal-purchase offer diff --git a/docs/NEXUS_CARD_RULES.md b/docs/NEXUS_CARD_RULES.md index 56568cfa..3323b266 100644 --- a/docs/NEXUS_CARD_RULES.md +++ b/docs/NEXUS_CARD_RULES.md @@ -1540,7 +1540,7 @@ The private holder offer contains CHOAM's name; it includes the hand count only Later focused source contracts cover [Emperor strength, purchases and revival](NEXUS_EMPEROR_RULES.md), [Ixian purchased-card replacement](NEXUS_IXIAN_REPLACEMENT_RULES.md), [Fremen worm and revival effects](NEXUS_FREMEN_RULES.md), and [Richese's separate shipment and auction panels](NEXUS_RICHESE_RULES.md). These audits distinguish implemented work from remaining source/timing questions; current runtime evidence is tracked in [implementation status](IMPLEMENTATION_STATUS.md). Bounded Richese auction and Guild shipment Betrayal checkpoints have their own direct local verification below; neither inherits certification of its complete faction, Nexus family or live deployment from earlier evidence. -The [bounded Ixian Secret Ally replacement integration](NEXUS_IXIAN_REPLACEMENT_RULES.md#bounded-local-runtime-contract) connects genuine normal paid and Karama purchases in the original fresh classic or Basic Tleilaxu profile. Successful native BG conversion qualifies after its native counter. Harkonnen's explicitly provisional order is replacement, original income, original cancelable bonus; no extra bonus or eight-card slot is gained. Replace only the purchased physical card and preserve settlement/full-hand/same-card semantics. Cache/Black Market/special origins and combined modules remain guarded. Neutral timing and provisional ordering are product composition, not publisher policy. The adopted Advanced core PDF supplies no Nexus face or priority ruling. Full-module, recovery and deployed acceptance remain open; source-qualified rule/control proof is recorded in the linked contract. +The [bounded Ixian Secret Ally replacement integration](NEXUS_IXIAN_REPLACEMENT_RULES.md#bounded-local-runtime-contract) connects genuine normal paid and Karama purchases in the original fresh classic or Tleilaxu profile in Basic/Advanced. Successful native BG conversion qualifies after its native counter. Harkonnen's explicitly provisional order is replacement, original income, original cancelable bonus; no extra bonus or eight-card slot is gained. Replace only the purchased physical card and preserve settlement/full-hand/same-card semantics. Cache/Black Market/special origins and combined modules remain guarded. Neutral timing and provisional ordering are product composition, not publisher policy. The adopted Advanced core PDF supplies no Nexus face or priority ruling. Full-module, recovery and deployed acceptance remain open; source-qualified rule/control proof is recorded in the linked contract. **Atreides is the first complete effect family to implement.** It has independent rulebook and physical-face evidence, and the engine already has private plan-element inspection. The Nexus effect needs its own cause and receipt rather than temporarily changing the inspecting faction. The second element must differ from the already inspected element. Preserve the original disclosed value if an allowed later battle edit occurs; follow the existing plan commitment rules instead of refreshing an old observation. The card specifies an element, not the entire hand or battle plan. A weapon/defense request uses actual played-card classification, including the published Reinforcements/Harass exclusions, rather than leaking a card merely because it occupies that slot. diff --git a/docs/NEXUS_IXIAN_REPLACEMENT_RULES.md b/docs/NEXUS_IXIAN_REPLACEMENT_RULES.md index 484838ae..f96b67b9 100644 --- a/docs/NEXUS_IXIAN_REPLACEMENT_RULES.md +++ b/docs/NEXUS_IXIAN_REPLACEMENT_RULES.md @@ -2,10 +2,35 @@ Source audit: 2026-09-10. Bounded local prototype integration and verification: 2026-10-01. **Partial development verified**, not complete Ixian/Nexus family or expansion acceptance. This document records the source and runtime boundary of the fresh `ixian-replacement` profile. Existing [Nexus release gates](NEXUS_CARD_RUNTIME.md) remain in force. +## Advanced native Tleilaxu admission — 16 October 2026 + +The existing fresh Ix47/Tleilaxu-plus-classics profile now admits Advanced +as well as Basic. This removes a producer fence, not a printed rule: the +Nexus replacement face has no Advanced exclusion. Original staged setup, +three Face Dancers, qualifying alliance/Nexus deal, paid purchase, private +Use/Keep and exact native income/next-lot continuation remain original. +Sandtrout is still omitted only at fresh setup; other optional modules, +native Ixians, E2/E3 and public starts stay excluded. + +The existing native behavior cases now exercise both modes: seven native +cases and affected six-file **47/47** pass. Four original Advanced runtime +Use/Keep paths cover Atreides and Tleilaxu buyers; eight legal policy actions +pass. Original Thumper/Amal, payment and Emperor income are preserved, +including final-lot completion. No played cards, wallets, clocks or Nexus +hands are staged. Proof: `/tmp/dune-advanced-tleilaxu-replacement-runtime.json`. +Actual CLI help now names both modes and the prior provisional Harkonnen +order. No new UI, saved-room, human-server, D1, deployment or public gate +changed; this is not full-family or combined-module acceptance. + + +Final types/lint pass; current source anchor and19 topic evidence paths +resolve without reference parse diagnostics. All five facets remain Partial. +No new build, broad suite, browser or HTTP assurance run for this admission. + ## Harkonnen purchase and bonus composition — 16 October 2026 Harkonnen buyers now receive the same neutral purchased-card choice in -the existing original classic Basic/Advanced or Basic Tleilaxu profile. +the existing original classic or native Tleilaxu Basic/Advanced profile. The printed one-for-one replacement preserves the purchase-earned bonus, its original hand cap and native Karama cancellation; it is not a second purchase and earns no extra bonus. The bonus itself is never a replacement @@ -141,7 +166,7 @@ November's Karama table expressly permits stopping the native Ixian ally from di ## Bounded local runtime contract -The original classic branch of the fresh `ixian-replacement` profile admits two through six unique classic factions in Basic or Advanced with base Treachery and Nexus alone. The native section below adds Basic Tleilaxu/classic Ix47. Native Ixians, other expansion families, Leader Skills, Homeworlds, Semuta, Discoveries, Ecaz variants and other overlays remain excluded. Neither branch retrofits an in-play game, enables a public start, resets a saved room or changes existing native Ixian allied replacement. +The fresh `ixian-replacement` profile admits two through six unique classic factions in Basic/Advanced with base Treachery, or native Tleilaxu plus classics in either mode with original Ix47, always with Nexus alone. Native Ixians, other expansion families, Leader Skills, Homeworlds, Semuta, Discoveries, Ecaz variants and other overlays remain excluded. Neither branch retrofits an in-play game, enables a public start, resets a saved room or changes existing native Ixian allied replacement. There is no starting Nexus deal. Native draws require a qualifying closing Nexus with a settled alliance, so a two-seat profile can continue its base @@ -171,13 +196,12 @@ and never add seats to an admitted game or fabricate Nexus hands. ## Native Basic Tleilaxu integration — 2 October 2026 -The additional fresh admission is **Basic Tleilaxu plus unique classic -opponents, exactly the original Ix47 Treachery Deck, and Nexus alone**. -Ixians are absent. This adds to the classic base33 Basic/Advanced profile -above; it does not admit Advanced Tleilaxu, native CHOAM/Richese, mixed -expansions or other overlays. Its fresh setup omits the optional physical -Sandtrout Spice Card, following the existing bounded Ixian Betrayal setup -convention; existing games and their cards are not changed. +The 2 October native integration originally admitted **Basic Tleilaxu plus +unique classic opponents, Ix47 and Nexus alone**, with Ixians absent. +The 16 October addition above extends that same native profile to Advanced; +native CHOAM/Richese, mixed expansions and other overlays remain excluded. +Fresh setup still omits optional Sandtrout under the existing bounded +native setup convention; existing games and their cards are not changed. `game/nexus-ixian-replacement.ts` uses the original `treacheryDeck(['ix'])` catalogue for exact descriptors. Original base33 diff --git a/docs/RULE_DECISIONS.md b/docs/RULE_DECISIONS.md index bfb2a8d2..7522fa9c 100644 --- a/docs/RULE_DECISIONS.md +++ b/docs/RULE_DECISIONS.md @@ -694,7 +694,7 @@ dedicated retrieved worked FAQs. [Contract and remaining limits](HOMEWORLD_OCCUP | Advanced Richese ally contribution | The authorized supplied Advanced Richese Bidding clause routes Richese's contribution to its ally's cache/Black Market purchase to Emperor or bank, even when Emperor buys. Preserve the original donor leg separately from buyer-to-Richese credit; cancellation redirects only the Emperor leg without paying twice. Basic retains R2's earlier receipt. Native Banker counts only final bank legs; exhausted-cache counts, positive Black Market self-bidding and Technology custody remain unresolved. | [Source distinction and recipient contract](RICHESE_AUCTION_RULES.md#authorized-advanced-contribution-recipients--4-october-2026) | | Richese Nexus Betrayal auctions | Pause at a valid original prepayment quote. Public self-cache veto discards the exact card without debit/acquisition; another buyer's positive cache/Black Market invoice keeps price/contributions/delivery and earned Harkonnen bonus while overriding the recipient to bank. All publicly possible unallied other-faction held-Nexus seats acknowledge uniformly; private identity controls only own Use. This neutral protocol is an application choice, not publisher timing. Normal hidden-family self-purchases, special-Karama veto and unsupported overlays remain excluded; no native Karama exception certifies them. Bounded engine/SQL/bot/phone scenarios are verified locally; broader verification remains Partial and public starts/full Nexus gates stay closed. | [Printed face, profile, API and saved continuation](NEXUS_RICHESE_RULES.md#bounded-betrayal-auction-contract--30-september-2026), [common privacy protocol](NEXUS_CARD_RULES.md#richese-betrayal-prepayment-protocol), [auction source boundaries](RICHESE_AUCTION_RULES.md) | | Guild Nexus Betrayal shipment payment | Replace one original funded positive fee in full, including own pre-funded payment and the printed full occupied-Junction override; preserve original payer/contributions, consume already-debited donor escrow once and deliver the original physical shipment once. Native applicable stop/rate responses precede the bounded gate; zero/stopped shipments supply no award or Nexus cost. Public possible held-Nexus seats acknowledge uniformly; private Use changes no public price/source disclosure. Fresh classic/native-Guild/Nexus with optional genuinely seeded Homeworlds only; unsupported native Cunning/Richese shipment overlays block before card/parent commitment, and restored transport independently requires the native Guild grant. Bounded engine/SQL/bot/CLI/phone custody and refresh are locally verified; no new priority/immunity, ordinary occupation/rounding ruling or extra shipment. Broad/public/live gates remain closed. | [Printed source and bounded contract](NEXUS_GUILD_RULES.md#nexus-guild-betrayal), [common protocol](NEXUS_CARD_RULES.md#guild-betrayal-funded-payment-protocol), [internal checklist](../game/reference.ts) | -| Ixian Nexus Secret Ally replacement | Fresh classic/base33 Basic/Advanced or Basic Tleilaxu/classic Ix47, Ixians absent and Nexus alone. Replace only the normal purchased card with the actual deck top; paid, printed Karama and successful native BG conversion retain original settlement. Native BG counter resolves first; funded winning-payment recovery supplies a paid receipt. Harkonnen now uses visibly provisional native order: replacement, original income, original cancelable bonus. No second bonus or eight-card capacity gain. This sequencing and neutral buyer timing are product policy, not publisher priority. Special origins/other overlays remain guarded; no public start or retrofit. | [Base contract](NEXUS_IXIAN_REPLACEMENT_RULES.md#bounded-local-runtime-contract), [BG composition](NEXUS_IXIAN_REPLACEMENT_RULES.md#native-bg-converted-purchases--16-october-2026), [provisional Harkonnen order and evidence](NEXUS_IXIAN_REPLACEMENT_RULES.md#harkonnen-purchase-and-bonus-composition--16-october-2026) | +| Ixian Nexus Secret Ally replacement | Fresh classic/base33 or Tleilaxu/classic Ix47 in Basic/Advanced, Ixians absent and Nexus alone. Replace only the normal purchased card with the actual deck top; paid, printed Karama and successful native BG conversion retain original settlement. Native BG counter resolves first; funded winning-payment recovery supplies a paid receipt. Harkonnen uses visibly provisional native order: replacement, original income, original cancelable bonus. No second bonus or eight-card capacity gain. Sequencing and neutral timing are product policy, not publisher priority. Special origins/other overlays stay guarded; no public start or retrofit. | [Base contract](NEXUS_IXIAN_REPLACEMENT_RULES.md#bounded-local-runtime-contract), [Advanced native admission](NEXUS_IXIAN_REPLACEMENT_RULES.md#advanced-native-tleilaxu-admission--16-october-2026), [BG composition](NEXUS_IXIAN_REPLACEMENT_RULES.md#native-bg-converted-purchases--16-october-2026), [provisional Harkonnen order](NEXUS_IXIAN_REPLACEMENT_RULES.md#harkonnen-purchase-and-bonus-composition--16-october-2026) | | Ixian Nexus Betrayal: Bidding or Technology | Fresh native-Ixian/classic-or-Tleilaxu Basic/Advanced local `ixian-betrayal` uses Ix47 Treachery and Nexus alone, with no initial Nexus deal or old-save retrofit. Resolve actual native Karama/BG counters first; a native denial opens no Nexus gate or cost. After all native passes, uniform publicly possible unallied non-Ixian held-Nexus seats acknowledge before the native effect; concealed face governs only private Use. These are bounded privacy/ordering inferences, not publisher universal priority. One physical Ixian Nexus denies one current Bidding attempt (normal count, no Ixian inspection/return) or one Advanced Technology declaration (both card locations preserved, attempt remains used); all-pass allows the original effect and suffix once. No whole-phase ban, completed undo, invented direct-Nexus Karama counter or blanket immunity. Richese special-lot exchange, wider priority/modules, complete games, strategy and public/live release remain open; verification is Planned pending frozen direct evidence. | [Photographed face and native source protocol](NEXUS_CARD_RULES.md#bounded-ixian-betrayal-source-protocol--1-october-2026), [fresh local runtime and acceptance](NEXUS_CARD_RUNTIME.md#bounded-ixian-betrayal-local-runtime--1-october-2026), [five-facet internal topic](../game/reference.ts) | | Harkonnen Nexus Betrayal local preview | Fresh classic/base33/Nexus-only `harkonnen-betrayal` admits genuine personal/allied native matching calls. Native allied Karama/BG allowance comes first; a provisional uniform acknowledgement precedes the original outcome. Use returns the exact physical traitor immediately and preserves one automatic private actual Mentat replacement. The local ordering/privacy convention is not publisher/user priority and does not answer the previously asked universal reaction policy; public starts, old-game retrofit, arbitrary stacks and combined modules remain gated. Bounded native/private/recovery/CLI/phone verification is Partial development verified, not complete modes or deployment. | [Bounded source contract](NEXUS_HARKONNEN_RULES.md#bounded-betrayal-preview-contract--1-october-2026), [runtime limits](NEXUS_CARD_RUNTIME.md) | | CHOAM Secret Ally | Absent-faction Collection trade spends one actual Worthless card and the Nexus for two bank spice. It is separate from native Cunning and Auditor; the battle inspection alternative remains missing. | [Prototype contract](NEXUS_CHOAM_SECRET_ALLY.md) | diff --git a/game/engine.ts b/game/engine.ts index e7f86d9d..2888caed 100644 --- a/game/engine.ts +++ b/game/engine.ts @@ -9910,12 +9910,12 @@ function decideIxianNexusBetrayal(g: Game,id: string,action: Action): void { if (use) log(g,`${getPlayer(g,id).name} spent Ixian Nexus Betrayal to prevent the original native ${frame.source.kind} attempt.`); finishIxianNativeAttempt(g,frame.continuation,use); } -/** Fresh classic or Basic native Tleilaxu profile; no public start or retrofit. */ +/** Fresh classic or native Tleilaxu profile; no public start or retrofit. */ export function initializeIxianNexusReplacementGameForAudit(state: Game): Game { requireRule(!state.nexusIxianReplacementPreview && !state.pendingNexusIxianReplacement && state.nexusIxianReplacementHistory === undefined && state.nexusIxianReplacementCursor === undefined && ixianNexusReplacementModeSupported(state), - 'Ixian Nexus replacement needs a fresh classic/base or Basic Tleilaxu/Ix lobby with Nexus alone.'); + 'Ixian Nexus replacement needs a fresh classic/base or Tleilaxu/Ix lobby with Nexus alone.'); const g = initializeNexusGameForAudit(state); // Ix supplies Treachery here, not the optional Sandtrout Spice card. if (g.expansions.length) g.spiceDeck = shuffle(spiceDeck()); @@ -9929,7 +9929,7 @@ function ixianNexusReplacementModeSupported(g: Game): boolean { return !!g.nexusCards && g.players.length >= 2 && g.players.length <= 6 && new Set(g.players.map(p => p.faction)).size === g.players.length && ((!g.expansions.length && g.players.every(p => CLASSIC_FACTIONS[p.faction] === true)) || - (!g.advanced && g.expansions.length === 1 && g.expansions[0] === 'ix' && + (g.expansions.length === 1 && g.expansions[0] === 'ix' && g.players.some(p => p.faction === 'tleilaxu') && g.players.every(p => p.faction === 'tleilaxu' || CLASSIC_FACTIONS[p.faction] === true))) && !g.homeworlds && !g.leaderSkills && !g.discoveryEnabled && !g.discoveries && diff --git a/game/reference.ts b/game/reference.ts index 05e0b272..4e55e3f2 100644 --- a/game/reference.ts +++ b/game/reference.ts @@ -4513,7 +4513,7 @@ export const RULE_TOPICS: RuleTopic[] = [ summary: 'In the fresh local ixian-replacement preview, an unallied holder with Ixians absent may spend the physical Ixian Nexus to discard exactly the card just bought in a normal auction and draw the next Treachery deck card privately.', searchText: 'Ixian Nexus Secret Ally purchased card replacement normal auction Karama full hand empty deck same card', steps: [ - 'This fresh local profile admits two-to-six unique classic-faction seats in Basic or Advanced with base Treachery, or additionally Basic Tleilaxu plus classic opponents with the original Ix47 deck and Ixians absent. Nexus alone; optional Sandtrout is omitted only in the fresh native variant. Advanced Tleilaxu, other native expansions, Leader Skills, Homeworlds, Semuta, Discoveries, Ecaz variants and other overlays remain guarded. No public start or saved-game upgrade.', + 'This fresh local profile admits two-to-six unique classic factions with base Treachery or native Tleilaxu plus classics with original Ix47, in Basic or Advanced, with Ixians absent and Nexus alone. Optional Sandtrout is omitted only at fresh native setup. Original native setup, Face Dancers, actual qualifying Nexus draw and normal purchased-card controls remain. Other native expansions, Leader Skills, Homeworlds, Semuta, Discoveries, Ecaz variants and other overlays remain guarded. No public start or played-save upgrade.', 'Nexus has no starting deal. A draw requires a qualifying closing Nexus with an alliance. A two-seat profile can continue its base game but cannot naturally create an unallied Secret Ally holder; actual replacement needs at least three seats, or four for two simultaneous unallied recipients.', 'The photographed publisher face grants an independent Secret Ally operation when Ixians are absent. Remain unallied and hold the actual singleton Ixian Nexus. Native Ixian allied replacement is a different cancelable advantage and is not removed or used as a fallback. The adopted unofficial Advanced rulebook supplies relevant core rules, not this absent Nexus face or a new Nexus ruling.', 'Wait for a genuine normal-auction purchase, paid with spice or through Karama, including direct acquisition before a positive bid. A successful native Advanced BG Worthless-as-Karama conversion gets the same independent replacement choice after its native counter resolves. Canceling direct acquisition supplies no purchase; a canceled winning-payment conversion follows native funded spice recovery and, if bought, supplies a paid receipt instead. Cache, Black Market and special-purchase origins retain their separate guarded Nexus scope. Gifts, bonus draws, Technology swaps and old hand cards are not purchases.', @@ -4531,9 +4531,9 @@ export const RULE_TOPICS: RuleTopic[] = [ checklist: [ { area: 'Implementation', status: 'Partial', detail: 'The bounded profile binds the exact normal purchase, physical replacement and closed history to native settlement. BG conversion and paid recovery remain source-specific. Harkonnen composes replacement before original income/bonus, preserving native bonus cancellation and capacity. Special origins and combined modules remain guarded.', evidence: ['game/nexus-ixian-replacement.ts', 'game/engine.ts', 'tools/prototype-room.ts'] }, { area: 'Player controls', status: 'Partial', detail: 'Neutral Purchased card choice separates buyer-only inspection and Use/Keep from public waiting. Harkonnen sees the provisional replacement-before-income/bonus explanation. Two original390px journeys exercise Use then bonus cancellation, or Keep then one allowed bonus; no overflow/browser error. Broader acceptance remains open.', evidence: ['components/nexus-ixian-replacement.tsx', 'components/game-table.tsx'] }, - { area: 'AI', status: 'Partial', detail: 'Four minimal legal policies consume only their own projected event while the underlying auction waits. Eight original-state actions cover BG conversion, and eight more cover Basic/Advanced Harkonnen replacement/bonus continuation. Full strategy and calibration remain unfinished.', evidence: ['game/bots.ts'] }, + { area: 'AI', status: 'Partial', detail: 'Four minimal legal policies consume only their own projected event while the underlying auction waits. Eight original actions cover BG conversion, eight cover Harkonnen bonus continuation, and eight cover Advanced native Tleilaxu-profile buyers. Full strategy and calibration remain unfinished.', evidence: ['game/bots.ts'] }, { area: 'Documentation', status: 'Partial', detail: 'Printed physical operation, settlement, full-hand/empty-deck rules and explicit provisional Harkonnen replacement-before-bonus policy are recorded. Cache scope, competing effects and complete-family acceptance remain separate; no publisher priority is invented.', evidence: ['docs/NEXUS_IXIAN_REPLACEMENT_RULES.md', 'docs/NEXUS_CARD_RULES.md', 'docs/RULE_DECISIONS.md'] }, - { area: 'Verification', status: 'Partial', detail: 'Earlier base/native evidence remains historical. BG composition passes affected74/74, four original runtime paths, eight policies and two390px journeys. Harkonnen adds three meaningful cases, affected64/64, eight original runtime paths, eight policies and two390px journeys covering separate native bonus cancellation/allowance; the eight-card boundary explicitly controls conserved hand acquisition. No new saved/deployed assurance; full families/modules remain open.', evidence: ['tests/nexus-ixian-replacement.test.ts', 'tests/nexus-ixian-replacement-engine.test.ts', 'tests/fixtures/nexus-ixian-native-depleted.json', 'tests/fixture-nexus-ixian-replacement.ts', 'tests/fixture-native-ixian-replacement.ts', 'tests/native-ixian-replacement.test.ts', 'tests/bg-ixian-replacement.test.ts', 'tests/fixture-bg-ixian-replacement.ts', 'tests/harkonnen-ixian-replacement.test.ts', 'tests/fixture-harkonnen-ixian-replacement.ts'] }, + { area: 'Verification', status: 'Partial', detail: 'Earlier evidence remains historical. BG composition passes affected74/74 and Harkonnen64/64, with their original runtime/control proof. Native Tleilaxu now exercises both modes:7 native cases and affected47/47; four original Advanced Use/Keep paths and eight legal policy actions preserve actual Thumper/Amal purchase, income and next/final-lot continuation. CLI help names both modes. No new UI or saved/deployed assurance; full families/modules remain open.', evidence: ['tests/nexus-ixian-replacement.test.ts', 'tests/nexus-ixian-replacement-engine.test.ts', 'tests/fixtures/nexus-ixian-native-depleted.json', 'tests/fixture-nexus-ixian-replacement.ts', 'tests/fixture-native-ixian-replacement.ts', 'tests/native-ixian-replacement.test.ts', 'tests/bg-ixian-replacement.test.ts', 'tests/fixture-bg-ixian-replacement.ts', 'tests/harkonnen-ixian-replacement.test.ts', 'tests/fixture-harkonnen-ixian-replacement.ts'] }, ], }, { diff --git a/tests/fixture-native-ixian-replacement.ts b/tests/fixture-native-ixian-replacement.ts index 878b4a58..f4c87108 100644 --- a/tests/fixture-native-ixian-replacement.ts +++ b/tests/fixture-native-ixian-replacement.ts @@ -13,6 +13,7 @@ import { export type NativeIxianReplacementOptions = { initial?: Game; + advanced?: boolean; buyerFaction?: 'atreides' | 'tleilaxu'; purchasedId?: string; replacementId?: string; @@ -78,7 +79,7 @@ function orderStartingCards(game: Game, buyer: string, reserved: readonly string ...pool.filter(card => reserved.includes(card.id))]; } -/** Basic native Tleilaxu + classic setup, a full first turn, an actual alliance- +/** Native Tleilaxu + classic setup, a full first turn, an actual alliance- * qualified closing Nexus draw, and an original paid normal-auction purchase. * The unplayed deck is ordered before native auction allocation, not the row. */ export function createNativeIxianReplacementFixture( @@ -91,11 +92,11 @@ export function createNativeIxianReplacementFixture( game.nexusIxianReplacementPreview === true && game.turn === 1 && game.phase === 0 && game.players.every(player => player.hand.length === 0))); } else { - game = createGame('NATIXREP', newPlayer('a', 'Atreides', 'atreides'), false, ['ix']); + game = createGame('NATIXREP', newPlayer('a', 'Atreides', 'atreides'), options.advanced ?? false, ['ix']); joinGame(game, newPlayer('e', 'Emperor', 'emperor')); joinGame(game, newPlayer('t', 'Tleilaxu', 'tleilaxu')); } - assert.equal(game.advanced, false); + if (options.advanced !== undefined) assert.equal(game.advanced, options.advanced); assert.deepEqual(game.expansions, ['ix']); assert.ok(game.players.some(player => player.faction === 'tleilaxu')); const buyer = game.players.find(player => player.faction === (options.buyerFaction ?? 'atreides'))!.id; diff --git a/tests/native-ixian-replacement.test.ts b/tests/native-ixian-replacement.test.ts index b323dc30..fc12da88 100644 --- a/tests/native-ixian-replacement.test.ts +++ b/tests/native-ixian-replacement.test.ts @@ -20,10 +20,11 @@ function reject(game: Game, id: string, action: Action): void { assert.deepEqual(game, before); } +for (const advanced of [false, true]) for (const buyerFaction of ['atreides', 'tleilaxu'] as const) - void test(`Basic native ${buyerFaction} paid Ix special replacement preserves its purchase and settles the real suffix once`, () => { + void test(`${advanced ? 'Advanced' : 'Basic'} native ${buyerFaction} paid Ix special replacement preserves its purchase and settles the real suffix once`, () => { const endingAuction = buyerFaction === 'tleilaxu'; - const f = createNativeIxianReplacementFixture({ buyerFaction, endingAuction }); + const f = createNativeIxianReplacementFixture({ advanced, buyerFaction, endingAuction }); assert.equal(f.beforeNexusDraw.nexusCards!.cards!.hands[f.buyer], null); assert.equal(owner(f.beforeNexusDraw, f.buyer).ally, null); const partners = f.beforeNexusDraw.players.filter(player => player.id !== f.buyer); @@ -62,8 +63,9 @@ for (const buyerFaction of ['atreides', 'tleilaxu'] as const) reject(use, f.buyer, { type: 'nexusIxianReplacementPass', event: f.event }); }); -void test('native Pass keeps the purchased Ix special and genuinely acquired Nexus without a draw or repayment', () => { - const f = createNativeIxianReplacementFixture(); +for (const advanced of [false, true]) +void test(`${advanced ? 'Advanced' : 'Basic'} native Pass keeps the purchased Ix special and acquired Nexus without another draw or payment`, () => { + const f = createNativeIxianReplacementFixture({ advanced }); const offer = viewGame(f.game, f.buyer).nexusIxianReplacement!; const pass = settleIxianReplacementFixture(applyAction(reload(f.game), f.buyer, { type: 'nexusIxianReplacementPass', event: offer.event })); diff --git a/tools/start-prototype.ts b/tools/start-prototype.ts index cdda6226..62eb4a51 100644 --- a/tools/start-prototype.ts +++ b/tools/start-prototype.ts @@ -25,7 +25,7 @@ async function main() { }); if (values.help) { console.log( - 'Usage: node --import tsx tools/start-prototype.ts --profile ix|discovery|homeworld-occupation|leader-skills|banker-income|factions|stronghold-factions|nexus|moritani-assassinate|ecaz-treachery|ecaz-occupy|semuta|kull|richese-betrayal|nexus-kull|guild-betrayal|ixian-replacement|ixian-betrayal|harkonnen-betrayal --db PATH --room CODE --version NUMBER --out /private/new-directory\nStarts only a fresh ready lobby for the selected development prototype. Stronghold-factions opts a fresh ready 2–6-seat Advanced roster with at least one selected native Ixians, Tleilaxu, CHOAM or Richese faction and otherwise classic opponents into Stronghold Cards, optionally preserving unused Tech Tokens at 3–6 seats. Select one or both distinct Ix/CHOAM decks; each native faction requires its family deck. The selected decks supply 47 Ix or combined, or 35 CHOAM canonical physical Treachery Cards, with a separate ten-card Richese cache when Richese plays. Native setup choices, HMS placement, Face Dancers, Richese cache and CHOAM Auditor remain genuine; custody starts unowned and is claimed by actual END Mentat. It does not redeal, reset or retrofit a saved game. Banker-income opts a fresh 2–6-seat classic Basic/Advanced base-deck roster, supported Basic Ixian/Tleilaxu/CHOAM/Moritani skill roster with its single required deck, or Advanced native Ixians, Tleilaxu and/or CHOAM plus classic roster with distinct required family decks, into automatic deferred normal income and native Mentat collection with all fourteen Leader Skills. Original bank payer costs exclude the separate Tleilaxu free-revival award; already-earned spice stays with its original faction under the existing provisional policy. Nexus enables the existing private Nexus setup. Moritani-assassinate explicitly opts into the bounded Advanced assassination preview. Semuta opts a fresh Richese roster into bounded clean-discard reactions; an included Ix deck supplies physical Thumper without opening public starts. Kull opts a fresh eligible CHOAM roster into the user-selected Karama interception preview. Richese-betrayal opts a fresh paired CHOAM/Richese Nexus roster into cache-purchase veto and sale-bank diversion. Nexus-kull opts a fresh CHOAM-plus-classic roster with CHOAM/Ix decks and Nexus into source-aware printed or any-Treachery-fueled Cunning Kull. Guild-betrayal opts a fresh classic roster with native Guild into full funded shipment-payment replacement; it preserves an explicitly enabled Homeworld module for Junction routes. Ixian-replacement opts a fresh classic Basic/Advanced base-deck roster, or Basic Tleilaxu plus classic opponents with the original Ix47 deck and no optional Sandtrout, into the exact normal-auction purchased-card replacement with Nexus alone. Native Ixians, Harkonnen buyers and special purchase sources remain unsupported. Ixian-betrayal opts a fresh 2–6-seat Basic/Advanced native Ixian plus classic/Tleilaxu roster with Ix 47-card Treachery and Nexus only into prevention of one actual native Bidding draw or Advanced Technology exchange, after native Karama counters. Harkonnen-betrayal opts a fresh 2–6-seat classic Basic/Advanced roster with native Harkonnen, base 33-card Treachery and Nexus alone into cancellation of an actual declared personal or allied Harkonnen Traitor Card after native counters, physical retirement and shuffle, and one private actual Mentat replacement. Modules, overlays, public starts and old-game retrofits remain excluded except for each profile’s documented composition. Nexus is not dealt initially: a qualifying alliance requires at least three seats; two unallied receivers require four. Backs up all rooms first, preserves sessions and existing games, and rejects stale versions. Normal game-start and publication gates remain closed.', + "Usage: node --import tsx tools/start-prototype.ts --profile ix|discovery|homeworld-occupation|leader-skills|banker-income|factions|stronghold-factions|nexus|moritani-assassinate|ecaz-treachery|ecaz-occupy|semuta|kull|richese-betrayal|nexus-kull|guild-betrayal|ixian-replacement|ixian-betrayal|harkonnen-betrayal --db PATH --room CODE --version NUMBER --out /private/new-directory\nStarts only a fresh ready lobby for the selected development prototype. Stronghold-factions opts a fresh ready 2–6-seat Advanced roster with at least one selected native Ixians, Tleilaxu, CHOAM or Richese faction and otherwise classic opponents into Stronghold Cards, optionally preserving unused Tech Tokens at 3–6 seats. Select one or both distinct Ix/CHOAM decks; each native faction requires its family deck. The selected decks supply 47 Ix or combined, or 35 CHOAM canonical physical Treachery Cards, with a separate ten-card Richese cache when Richese plays. Native setup choices, HMS placement, Face Dancers, Richese cache and CHOAM Auditor remain genuine; custody starts unowned and is claimed by actual END Mentat. It does not redeal, reset or retrofit a saved game. Banker-income opts a fresh 2–6-seat classic Basic/Advanced base-deck roster, supported Basic Ixian/Tleilaxu/CHOAM/Moritani skill roster with its single required deck, or Advanced native Ixians, Tleilaxu and/or CHOAM plus classic roster with distinct required family decks, into automatic deferred normal income and native Mentat collection with all fourteen Leader Skills. Original bank payer costs exclude the separate Tleilaxu free-revival award; already-earned spice stays with its original faction under the existing provisional policy. Nexus enables the existing private Nexus setup. Moritani-assassinate explicitly opts into the bounded Advanced assassination preview. Semuta opts a fresh Richese roster into bounded clean-discard reactions; an included Ix deck supplies physical Thumper without opening public starts. Kull opts a fresh eligible CHOAM roster into the user-selected Karama interception preview. Richese-betrayal opts a fresh paired CHOAM/Richese Nexus roster into cache-purchase veto and sale-bank diversion. Nexus-kull opts a fresh CHOAM-plus-classic roster with CHOAM/Ix decks and Nexus into source-aware printed or any-Treachery-fueled Cunning Kull. Guild-betrayal opts a fresh classic roster with native Guild into full funded shipment-payment replacement; it preserves an explicitly enabled Homeworld module for Junction routes. Ixian-replacement opts a fresh classic Basic/Advanced base-deck roster, or Basic/Advanced Tleilaxu plus classic opponents with the original Ix47 deck and no optional Sandtrout, into the exact normal-auction purchased-card replacement with Nexus alone. Native Ixians and special purchase sources remain unsupported. Harkonnen uses the visible provisional replacement-before-income/bonus order. Ixian-betrayal opts a fresh 2–6-seat Basic/Advanced native Ixian plus classic/Tleilaxu roster with Ix 47-card Treachery and Nexus only into prevention of one actual native Bidding draw or Advanced Technology exchange, after native Karama counters. Harkonnen-betrayal opts a fresh 2–6-seat classic Basic/Advanced roster with native Harkonnen, base 33-card Treachery and Nexus alone into cancellation of an actual declared personal or allied Harkonnen Traitor Card after native counters, physical retirement and shuffle, and one private actual Mentat replacement. Modules, overlays, public starts and old-game retrofits remain excluded except for each profile’s documented composition. Nexus is not dealt initially: a qualifying alliance requires at least three seats; two unallied receivers require four. Backs up all rooms first, preserves sessions and existing games, and rejects stale versions. Normal game-start and publication gates remain closed.", '\nSemuta additionally admits a fresh Basic roster with native Richese and Moritani, classic opponents, exactly CHOAM and Ecaz decks, and no optional modules. Native setup remains genuine. Private Sabotage and Robbery overflow discards may offer Semuta before a clean ordinary shipment/movement arrival resumes. The victim/draw and original payment/forces are already committed; candidate faces stay hidden until commitment. Advanced Moritani, native Ecaz, Ix/E3 mixtures, worm/Ambassador/overlap arrivals and public starts remain outside this entry.', '\nSemuta with CHOAM and optional Ix preserves original unused Tech Tokens in fresh 3–6-seat Basic/Advanced Richese lobbies under existing native prerequisites. Advanced additionally retains original unused Stronghold Cards at2–6; both modules require3–6. Native setup, first-Storm Tech and final-Mentat Stronghold assignment remain original. Mandatory/winner discards react before the original winner takes one loser-owned token, before Face Dance. Closing Gamont reacts before the original CHOAM finish and changed-board claim. Optional original skills require --leader-skills as described below; other modules, the separate CHOAM/Ecaz Moritani entry, retrofit and public starts remain excluded.', '\n--profile semuta --discoveries uses original fresh Richese/CHOAM and optional Ix Discovery7/8 setup, Basic/Advanced2–6, with original unused Tech3+/Advanced Strongholds. Shrine physical roles stay distinct: Truthtrance may be played as Karama while its printed identity remains; Semuta recovers the used physical cost without replaying its effect. No Skills, Homeworlds, Nexus, E3, played-save conversion or public-mode gate is opened.',