+
+ Return {pending.count} {label} {pending.count === 1 ? 'card' : 'cards'}
+
+
+ Choose exactly {pending.count} to shuffle into the Traitor Deck. Your
+ other cards stay in your hand.
+
+
+ The previous game action is paused until this return finishes.
+
+ {dancers && (
+
+ Previously revealed Face Dancers are not available for this return.
+
+ )}
+
+ {pending.choices.map((choice) => {
+ const identity = identityFor(game, choice.id);
+ if (!identity)
+ return (
+
+ This card’s identity is unavailable. Refresh before choosing it.
+
+ );
+ const checked = selected.includes(choice.id);
+ return (
+
+
+ = pending.count)
+ }
+ onChange={() =>
+ setSelected((old) =>
+ old.includes(choice.id)
+ ? old.filter((id) => id !== choice.id)
+ : [...old, choice.id],
+ )
+ }
+ />
+
+ {identity.name}
+
+ {identity.factionName} · Strength {identity.strength}
+ {choice.drawn ? ' · Newly drawn' : ''}
+ {choice.revealed ? ' · Previously revealed' : ''}
+
+
+
+
+
+ );
+ })}
+
+
+ {selected.length} of {pending.count} selected.
+
+ {game.truthtrance && (
+
+ Finish Truthtrance before returning these cards.
+
+ )}
+ {
+ if (!blocked && action) act(action);
+ }}
+ >
+ Return selected {pending.count === 1 ? 'card' : 'cards'}
+
+
+ );
+}
diff --git a/docs/COMPONENT_INVENTORY.md b/docs/COMPONENT_INVENTORY.md
index 6d55d1dc..84d64c4f 100644
--- a/docs/COMPONENT_INVENTORY.md
+++ b/docs/COMPONENT_INVENTORY.md
@@ -1,6 +1,6 @@
# Component inventory and verification ledger
-**Nexus update, 10 September 2026:** all twelve physical Nexus identities and all thirty-six effect panels are verified against the original printed components. The separate inventory preserves one card per faction, independent of the selected roster; held cards remain private. The internal rules gallery and owner panel provide complete original-language effect text, existing bundled faction artwork and enlarged inspection. Common draws, replacement, preselected own-faction redraw, alliance forfeiture and saved phase progress are integrated. Atreides Cunning and Secret Ally now have inspected battle controls and private history; Betrayal and the other effect families and complete module games remain unfinished and gated. See [NEXUS_ATREIDES_RUNTIME.md](NEXUS_ATREIDES_RUNTIME.md), [NEXUS_CARD_RULES.md](NEXUS_CARD_RULES.md) and [NEXUS_CARD_RUNTIME.md](NEXUS_CARD_RUNTIME.md) for current verification and limits.
+**Nexus update, 10 September 2026:** all twelve physical Nexus identities and all thirty-six effect panels are verified against the original printed components. The separate inventory preserves one card per faction, independent of the selected roster; held cards remain private. The internal rules gallery and owner panel provide complete original-language effect text, existing bundled faction artwork and enlarged inspection. Common draws, replacement, preselected own-faction redraw, alliance forfeiture and saved phase progress are integrated. Atreides Cunning and Secret Ally have inspected battle controls and private history. Harkonnen Cunning and Secret Ally now draw from the physical Traitor Deck before an exact private return; Tleilaxu receives Face Dancers while previously revealed dancers stay protected. The owner selects actual leader identities with enlarged inspection, and observers receive only pending metadata. This adds no duplicate physical deck or new artwork. Betrayal, remaining effects and complete module games remain unfinished and gated. See [NEXUS_HARKONNEN_RUNTIME.md](NEXUS_HARKONNEN_RUNTIME.md), [NEXUS_ATREIDES_RUNTIME.md](NEXUS_ATREIDES_RUNTIME.md), [NEXUS_CARD_RULES.md](NEXUS_CARD_RULES.md) and [NEXUS_CARD_RUNTIME.md](NEXUS_CARD_RUNTIME.md) for current verification and limits; final Harkonnen checkpoint acceptance is pending.
**Homeworld update, 9 September 2026:** all 13 cards and 26 physical faces are verified, including native population/battle values and occupied income symbols. The internal gallery supplies both faces, complete original gameplay prose, enlarged inspection and thirteen original bundled illustrations. Separate typed custody and population helpers are tested; actual Homeworld gameplay, occupation and effect integration remain unfinished and gated. See [HOMEWORLD_IMPLEMENTATION.md](HOMEWORLD_IMPLEMENTATION.md) and [HOMEWORLD_COMPONENT_AUDIT.md](HOMEWORLD_COMPONENT_AUDIT.md). Earlier missing-Homeworld statements below are historical.
diff --git a/docs/IMPLEMENTATION_STATUS.md b/docs/IMPLEMENTATION_STATUS.md
index c1e6c32a..3d4015a6 100644
--- a/docs/IMPLEMENTATION_STATUS.md
+++ b/docs/IMPLEMENTATION_STATUS.md
@@ -1,5 +1,7 @@
# Dune implementation status
+**Harkonnen Nexus exchange checkpoint, 10 September 2026:** [NEXUS_HARKONNEN_RUNTIME.md](NEXUS_HARKONNEN_RUNTIME.md) records draw-first Cunning and absent-faction Secret Ally, exact private returns, protected revealed Face Dancers, saved suspended actions and durable prior traitor declarations. Shared controls and all four bot profiles use projected identities. Independent review fixed lost preceding decisions and the paid Nullentropy action gate. **Types, lint, all 3,885 offline cases, production build and 40 HTTP/session cases pass.** Forty-six new cases cover rules, consumers, continuations and concurrent SQLite recovery. Two three-seat browser rooms passed draw/return, private restoration and desktop/phone inspection. All **3,295** preexisting room versions/hashes remain unchanged. Betrayal remains blocked pending the existing private response timing decision; complete Nexus and expansion games remain unfinished, and no release gate opens. The server was reused, no restart was due, and automation remains removed.
+
**Atreides Nexus inspection checkpoint, 10 September 2026:** [NEXUS_ATREIDES_RUNTIME.md](NEXUS_ATREIDES_RUNTIME.md) records Cunning's distinct second commitment and absent-faction Secret Ally, physical card disposal, No-Field distinctions, private history, all four editor locks and bot handling. Independent review fixed lost-response bypass, first-answer drift and a sealed plan contradicting its signed observation; legitimate Residual reanswers preserve the first historical disclosure. **Types, lint, all 3,839 offline tests, production build and 40 HTTP/session tests pass.** Forty-four new cases include concurrent SQLite recovery and four independent corruption regressions. Three-seat keyboard play, answer, protected plan submission and desktop/phone refresh passed. All **3,234** preexisting room versions/hashes survived the scheduled backup/restart and final comparison. Betrayal response timing, Residual after two answered Cunning fields, other card families and complete module games remain explicitly unfinished; no release gate opened. Automation stays removed; verified checkpoints are authorized for push without another confirmation.
**Nexus ownership and complete component reference checkpoint, 10 September 2026:** [NEXUS_CARD_RUNTIME.md](NEXUS_CARD_RUNTIME.md) records the twelve-card physical deck, whole-phase Basic/Advanced draw opportunity, private replacement policy, all three alliance-forfeiture paths and complete inspectable 36-panel reference. Review fixed real Storm-entry initialization, edited progress/replay acceptance, one-way alliances and the private redraw prompt's public timing leak. Pre-draw preferences resolve without extra confirmations. **Types, lint, all 3,795 offline tests, production build and 40 HTTP/session tests pass.** Three-seat keyboard draw/redraw/refresh and all twelve normal/enlarged desktop/phone cards passed; independent review inspected 48 renders. All **3,173** preexisting room versions/hashes remain unchanged. All individual Nexus effects, Discoveries and complete expansion games remain unfinished; no release gate opened. Existing server reused, no restart due, no automation recreated.
diff --git a/docs/NEXUS_HARKONNEN_RULES.md b/docs/NEXUS_HARKONNEN_RULES.md
new file mode 100644
index 00000000..777ede2d
--- /dev/null
+++ b/docs/NEXUS_HARKONNEN_RULES.md
@@ -0,0 +1,57 @@
+# Harkonnen Nexus: source and implementation contract
+
+Source audit, 10 September 2026. This is a rules contract, not a runtime completion claim. The [common Nexus lifecycle](NEXUS_CARD_RULES.md) and existing expansion release gates still apply. The pending reaction-privacy question remains unresolved; this audit does not authorize a Betrayal reaction policy.
+
+## Primary authority
+
+- [The original printed Nexus components](https://boardgamegeek.com/image/7767032/dune-ecaz-and-moritani): the Harkonnen face was freshly inspected in the previously acquired 3024×4032 photograph, `/tmp/dune-nexus-cards.jpg`. Its three panels establish the effects below. The photographed publisher text is the authority, not the uploader's commentary.
+- [GF9 Ecaz & Moritani, pp.11 and 16](https://www.gf9games.com/dune/wp-content/uploads/EcazMoritani-Rulebook-LOWRES.pdf#page=11): common modes, card disposal and the explicit Tleilaxu/Harkonnen Secret Ally FAQ. Fresh official indexed text and the previously acquired publisher-authored PDF mirror were inspected; direct official retrieval returned 403. Acquisition details are in the common contract.
+- [GF9 base rules, pp.11 and 17](https://www.gf9games.com/dunegame/wp-content/uploads/Dune-Rulebook.pdf#page=11): traitor revelation and battle consequences, Harkonnen's four starting traitors and allied use. [GF9 quick-start, p.4](https://www.gf9games.com/dune/wp-content/uploads/Quick-start-Guide.pdf#page=4) establishes the participating-faction deck and return of unselected setup cards.
+- [GF9 Ixians & Tleilaxu, pp.4, 6–7 and Karama table](https://www.gf9games.com/dunegame/wp-content/uploads/2020/09/IxianAndTleilaxuRulebook.pdf#page=6): shared Traitor Deck, three Face Dancers, reveal/replacement cycle and ordinary Mentat replacement. [GF9 CHOAM & Richese, p.12](https://www.gf9games.com/dune/wp-content/uploads/2021/11/CHOAM-Rulebook-low-res.pdf#page=12) supplies the related Rihani Decipherer ruling.
+- [GF9 November 2020 FAQ, pp.3, 7–8](https://www.gf9games.com/dune/wp-content/uploads/2020/11/Dune-FAQ-Nov-2020.pdf#page=3): retained traitor identities after revival, Karama boundaries, unused-card privacy and Truthtrance. Fresh publisher-indexed text was retrieved. The earlier April FAQ was encountered but is not used to override November's cancellation rules.
+
+## Printed effects
+
+| Mode | Eligibility and timing | Physical operation |
+| --- | --- | --- |
+| Cunning | Harkonnen holds its own Nexus card; at any time. | Draw one Traitor Card into the hand, then secretly select any one held Traitor Card and shuffle it into the Traitor Deck. |
+| Secret Ally | Harkonnen is absent; during Mentat Pause. | Draw two Traitor Cards into the hand, then select two held Traitor Cards and shuffle them into the Traitor Deck. |
+| Betrayal | Another player controls Harkonnen; a Harkonnen traitor has been revealed. | Cancel that traitor, shuffle its card into the Traitor Deck, and give Harkonnen a replacement draw during Mentat Pause. |
+
+These are mandatory draw/return counts once played. Newly drawn identities are in the hand before selection, so they may be returned. Neither exchange permanently increases hand size. The card does not restrict returns to newly drawn cards or currently living leaders. Betrayal's replacement is delayed, whereas returning its canceled identity is immediate. [Printed Harkonnen face](https://boardgamegeek.com/image/7767032/dune-ecaz-and-moritani)
+
+The common rules make these modes mutually exclusive and consume the Nexus card on play. Secret Ally does not create a formal alliance. The E3 FAQ expressly classifies Tleilaxu's retained card as a Face Dancer. It does not describe return eligibility for already revealed dancers. [E3, pp.11,16](https://www.gf9games.com/dune/wp-content/uploads/EcazMoritani-Rulebook-LOWRES.pdf#page=16)
+
+## Supported composition and implementation requirements
+
+**Exchange transaction.** Keep one immutable draw receipt containing the original owner, mode, turn/phase and physical draw group. Suspend the original continuation while the owner chooses exactly the required number of distinct currently held identities. Bind the return to that event; complete custody transfer, shuffle and resume once. Reconnects and retries must not redraw. There is a real choice after the draw, so this pending choice is necessary; no additional acknowledgement is needed afterward. This is implementation composition of the printed sequence.
+
+**Private custody.** Project drawn cards and return options only to the holder. Other seats may see the publicly played Nexus mode and a pending exchange, but not the drawn, returned or remaining identities, deck order, or whether a drawn card matched a combatant. Do not treat a previously exposed ordinary traitor as discarded: the November FAQ says that identity remains a traitor after its leader dies and revives. It also prohibits retaining unused Traitor Cards as reference material. An old private inspection receipt is a historical observation, not proof of current custody. [November FAQ, pp.3,8](https://www.gf9games.com/dune/wp-content/uploads/2020/11/Dune-FAQ-Nov-2020.pdf#page=3)
+
+**Battle cancellation.** Bind Betrayal to the actual revealed identity and Harkonnen caller before committing the traitor outcome. Base rules give a called traitor victory and specific casualty/spice consequences; a double call has a different outcome. Cancellation must therefore remove the targeted call and resolve the surviving situation once, not refund an already resolved battle. Harkonnen can call on an ally's behalf, so an implementation must retain caller and beneficiary separately. [Base rules, pp.11,17](https://www.gf9games.com/dunegame/wp-content/uploads/Dune-Rulebook.pdf#page=17)
+
+**Deck inventory.** Draw from the existing physical reserve, not from current leader discs: capture, gholas and death do not manufacture Traitor Cards. Setup removes absent factions and returns unselected identities; Tleilaxu draws its three from that shared deck afterward. [Quick-start p.4](https://www.gf9games.com/dune/wp-content/uploads/Quick-start-Guide.pdf#page=4), [E1 pp.4,6](https://www.gf9games.com/dunegame/wp-content/uploads/2020/09/IxianAndTleilaxuRulebook.pdf#page=6)
+
+**Setup order follow-up.** Fresh inspection of base p.6 confirms that unchosen setup cards return face down to the **bottom** of the Traitor Deck. Quick-start p.4 agrees. E1 p.6 adds a shuffle after those returns specifically before Tleilaxu draws its initial three. Neither E3's common Nexus rules nor the Harkonnen face orders an additional setup shuffle or a shuffle before its initial exchange draw. Preserve the existing non-Tleilaxu reserve order in fresh and legacy rooms; append actual unchosen cards at setup, then draw from that saved reserve. There is no source basis for a corrective reshuffle migration. The physical order of simultaneous players' setup returns is not separately specified; serialized return order does not justify adding a shuffle. [Base p.6](https://www.gf9games.com/dunegame/wp-content/uploads/Dune-Rulebook.pdf#page=6), [Quick-start p.4](https://www.gf9games.com/dune/wp-content/uploads/Quick-start-Guide.pdf#page=4), [E1 p.6](https://www.gf9games.com/dunegame/wp-content/uploads/2020/09/IxianAndTleilaxuRulebook.pdf#page=6)
+
+No retrieved rule supplies an empty-Traitor-Deck fallback. For the ordinary supported setup this is not an expected shortage: with `n >= 3` five-leader factions, held cards total `n + 3H + 2T`, where `H` and `T` indicate Harkonnen and Tleilaxu. The smallest resulting reserve is seven. These exchanges have zero net growth; Betrayal temporarily increases reserve size. This arithmetic is a bounded inventory argument, not a rule for other variants. Reject undersized/inconsistent custody before spending the Nexus card; never recycle another player's held cards or silently draw fewer.
+
+## Tleilaxu and shared-deck boundaries
+
+E1 distinguishes two operations: after all three dancers reveal, return all three, shuffle and draw three; during Mentat, optionally return one **unrevealed** dancer, shuffle and draw one. Revealed dancers ordinarily stay until the full cycle completes. Its Karama table permits stopping ordinary Mentat replacement but excludes other Face Dancer effects. Harkonnen traitor revelation itself is not an ordinary Karama target. These specific entries do not establish blanket Nexus immunity. [E1 p.7 and Karama table](https://www.gf9games.com/dunegame/wp-content/uploads/2020/09/IxianAndTleilaxuRulebook.pdf#page=7)
+
+The Rihani Decipherer FAQ classifies its acquired identity as a Face Dancer and explicitly restricts replacement to an unrevealed dancer. This is relevant evidence for preserving revealed custody, but is a ruling for that skill. The Harkonnen Nexus FAQ states only the resulting card type. Compose it with E1's existing restriction: return options include newly drawn cards and existing unrevealed dancers; preserve prior revealed dancers. The two new cards guarantee at least two valid return choices, so this supports the full exchange rather than blocking Tleilaxu from playing it. No inspected passage explicitly classifies revealed dancers as being outside a player's hand; the justification is their protected revealed status. [E2 p.12](https://www.gf9games.com/dune/wp-content/uploads/2021/11/CHOAM-Rulebook-low-res.pdf#page=12), [E3 p.16](https://www.gf9games.com/dune/wp-content/uploads/EcazMoritani-Rulebook-LOWRES.pdf#page=16)
+
+## Timing composition
+
+Cunning's anytime permission supports play off turn and after battle plans reveal. Before a traitor declaration, the resulting held identities determine whether Harkonnen can call. After a declaration, preserve the committed call and its original physical identity independently of subsequent hand changes. An exchange changes custody; it does not contain Betrayal's explicit cancellation instruction. A declared identity returned through Cunning therefore must not retract the call or make its original declaration fail retroactive validation. This is composition of the printed effects with an immutable digital declaration, not a separate publisher FAQ about sealed requests.
+
+During Mentat, Tleilaxu can select the order of its own ordinary cycling and Secret Ally exchange. Complete each operation before another deck action begins; do not interleave another draw between Secret Ally's two-card draw and return. No inspected source imposes a priority between these two optional actions. This player-controlled sequencing avoids silently fixing a priority in the phase serializer. It does not resolve competing mandatory draws belonging to different players.
+
+## Material unresolved timing
+
+- No retrieved primary ruling orders Betrayal's Mentat replacement against Tleilaxu's ordinary cycling or other Traitor Deck consumers. Those shuffles can change the next identity drawn. Do not describe a chosen serializer as publisher-mandated priority. Secret Ally and Betrayal themselves cannot compete: they require opposite faction-presence states and use the same unique Nexus card.
+- Likewise, the sources do not establish arbitrary interruption of another player's owned decision or reversal of a completed battle. A full anytime implementation must specify continuation ownership and interaction with existing Truthtrance promises without releasing those promises merely to make an exchange legal.
+- The existing unanswered reaction-privacy question still blocks choosing a Betrayal window policy. Do not repeat that question or infer an answer from this audit. Ordinary victory/end-turn advancement must not silently erase a pending Mentat exchange or an earned replacement obligation.
+
+Focused verification should cover draw-before-return (including returning new cards), zero net hand growth, actual Tleilaxu custody, every-seat privacy, exact restoration of suspended decisions, immutable rejection, and once-only saved shuffle/replacement receipts. These checks do not certify all Nexus effects or expansion combinations.
diff --git a/docs/NEXUS_HARKONNEN_RUNTIME.md b/docs/NEXUS_HARKONNEN_RUNTIME.md
new file mode 100644
index 00000000..a11dc7bf
--- /dev/null
+++ b/docs/NEXUS_HARKONNEN_RUNTIME.md
@@ -0,0 +1,38 @@
+# Harkonnen Nexus exchange checkpoint
+
+10 September 2026. Harkonnen Cunning and absent-faction Secret Ally now use the physical Traitor Deck, an owned draw-first return choice, saved continuation evidence and private controls. This extends the [common Nexus lifecycle](NEXUS_CARD_RUNTIME.md) and [Atreides inspections](NEXUS_ATREIDES_RUNTIME.md). [NEXUS_HARKONNEN_RULES.md](NEXUS_HARKONNEN_RULES.md) records the printed sources, composed interactions and unresolved timing. Betrayal, other unfinished effects and complete module games remain gated; this checkpoint does not open public Nexus or expansion starts.
+
+## Physical exchange
+
+Cunning draws one card into Harkonnen's hand before the owner chooses one held identity to return. Secret Ally requires Harkonnen absent and Mentat Pause, draws two first, and then returns exactly two distinct held identities. Newly drawn identities can be returned. The Nexus card is spent when the draw commits; the Traitor Deck is shuffled only when the return commits. The completed exchange restores the original hand size.
+
+The exchange uses the saved reserve order. It does not rebuild the deck from living leader discs, captured leaders or current hands. The printed participating-faction inventory includes the Advanced CHOAM Auditor and the expansion's shared Cheap Hero identity when applicable. Setup returns remain at the bottom; Tleilaxu's separately sourced setup shuffle remains in its own setup path. There is no corrective reshuffle migration or invented empty-deck fallback.
+
+For Tleilaxu, Secret Ally draws Face Dancers. Existing revealed dancers retain their identities and revealed flags and cannot be selected for this return. Existing unrevealed and newly drawn dancers are eligible; retained new dancers begin unrevealed. This protection composes the specific Face Dancer rules and related FAQ evidence described in the source audit. It is not a claim that the Harkonnen card itself explicitly discusses previously revealed dancers.
+
+## Interrupted actions and declarations
+
+Cunning can start off turn and across a pending response or owned decision. The engine preserves the preceding response, decision, phase opening, Karama/discard context and battle rather than resolving them to make room. While the exchange is pending, ordinary actions and automatic advancement wait for its exact event-bound return. Live Truthtrance takes priority; it does not release existing promises. Closing common Nexus draws and another exchange also prevent starting a new exchange.
+
+The saved exchange history, pending marker and parent signature must agree on the owner, turn, phase, physical source and suspended control context. A reload projects the existing choice without redrawing or reshuffling. These canonical signatures detect inconsistent saved fields; they are not cryptographic authentication against a deliberately rewritten save.
+
+A traitor declaration binds the original voter, beneficiary, target, revealed leader and physical traitor identity independently of later custody. Returning an already declared identity through Cunning does not cancel its call. Conversely, an earlier declined call remains false even if the exchange draws the matching identity. Allied Harkonnen declarations distinguish caller from beneficiary, and Cheap Hero declarations retain the actual sealed card and shared traitor identity. This exchange is not Betrayal's explicit cancellation effect.
+
+## Private controls and bots
+
+The holder sees actual eligible identities, names, factions, strengths, newly drawn status and enlarged Traitor or Face Dancer inspection. No return is preselected: the owner chooses the exact required count and submits once. Observers receive only pending owner/mode/count metadata and a waiting notice; no draw, return or reserve identities are projected or logged publicly.
+
+All four bot profiles consume the same private offer and return choices. The return policy prefers own-faction, dead or lower-strength identities and preserves a matching publicly revealed opposing leader when possible. Optional Cunning is used before an unanswered public traitor call or during Mentat; Secret Ally follows its Mentat restriction. This is a legal policy, not new strategy calibration. Pending exchange handling overrides old automatic flags. Its defensive Truthtrance policy takes precedence over a preserved decision. The existing paid Nullentropy search restriction on new Treachery effects remains in force; this checkpoint does not open Truthtrance inside that search.
+
+## Verified checkpoint
+
+- The new controls/bot suites passed **8/8** cases. They include actual Cunning and Tleilaxu exchanges for all four profiles with physical inventory checks, exact selection, observer getter traps and the Truthtrance/Nullentropy priority regression.
+- A combined run of those suites, existing Atreides inspection controls/bots and full-plan regressions passed **33/33** cases. Owned-file type-aware lint passed. Existing full-table SSR tests emit the preexisting React SVG title-array warning; the standalone exchange controls do not.
+- **All 3,885 offline cases, types, lint, production build and 40 HTTP/session cases pass.** This checkpoint adds 46 cases: 10 pure exchange, 9 declaration, 12 engine, 8 controls/bots, 4 continuation and 3 production in-memory SQLite recovery cases. Independent review found and fixed an unbound preceding decision and the paid Nullentropy early-action gate.
+- SQLite checks preserve exact private custody after lost draw/return responses, accept only one competing return/shuffle and reject damaged parent evidence before writes. Unrelated rooms remain unchanged.
+- Browser acceptance used two isolated three-seat rooms: Cunning preserved and restored a live Prescience cancellation response; Tleilaxu Secret Ally exposed four eligible choices while protecting one revealed Face Dancer. Explicit one/two-card selection, phone layout, desktop/phone enlarged inspection and six authenticated seat restorations passed with no page errors. The inspection script initially used an incorrect accessible button name; it resumed the existing pending choice after correction without repeating the draw.
+- All **3,295** preexisting room versions and state hashes remained unchanged. The HTTP suite added 30 isolated rooms and browser acceptance added two. The existing server was reused; no hourly restart was due during this checkpoint and no automation was recreated.
+
+Implementation: [exchange module](../game/nexus-traitor-exchange.ts), [declaration module](../game/traitor-declarations.ts), [shared options](../game/nexus-traitor-options.ts), [controls](../components/nexus-traitors.tsx), [engine](../game/engine.ts). Tests: [pure exchange](../tests/nexus-traitor-exchange.test.ts), [declarations](../tests/traitor-declarations.test.ts), [engine](../tests/nexus-traitor-engine.test.ts), [controls](../tests/nexus-traitor-controls.test.ts), [bots](../tests/nexus-traitor-bots.test.ts), [SQLite recovery](../tests/nexus-traitor-recovery.test.ts), [continuations](../tests/nexus-traitor-continuations.test.ts).
+
+Betrayal remains blocked pending the existing private response timing decision. Its cancellation and delayed Mentat replacement are not implemented by this exchange. No arbitrary priority between its future replacement and other deck consumers has been adopted. Complete Nexus games and full expansion combinations remain separate release requirements.
diff --git a/game/bots.ts b/game/bots.ts
index 667696a8..6d4efcbd 100644
--- a/game/bots.ts
+++ b/game/bots.ts
@@ -1,4 +1,5 @@
import { nexusCardBotActions } from './nexus-card-options';
+import { nexusTraitorBotActions } from './nexus-traitor-options';
import { tupileIntelligenceActions } from './tupile-intelligence-options';
import { biddingEndActions, choamMarketPolicy } from './bidding-end-options';
import { homeworldRevivalActionBlock, homeworldRevivalDeploymentActions } from './homeworld-revival-deployment-options';
@@ -3314,8 +3315,14 @@ function standaloneGholaAction(g: GameView, ordinary: Action[]): Action | null {
/** Obligations apply across policy branches, including choosing to move first. */
export function botActions(g: GameView): Action[] {
+ if (g.nexusTraitors?.pending)
+ return g.truthtrance
+ ? policyActions({ ...g, decision: null })
+ : nexusTraitorBotActions(g);
if (g.automaticContinuationPending) return [];
if (g.nexusCards?.waiting.length) return nexusCardBotActions(g);
+ const traitorExchange = nexusTraitorBotActions(g);
+ if (traitorExchange.length) return traitorExchange;
const nexus = g.nexusAtreides;
if (
g.status === 'playing' && g.phase === 6 && nexus && !nexus.blocked &&
diff --git a/game/engine.ts b/game/engine.ts
index 786d3f3c..0d8cdfce 100644
--- a/game/engine.ts
+++ b/game/engine.ts
@@ -1,4 +1,6 @@
import { createNexusInspection, allowNexusInspection, answerNexusInspection, reopenNexusInspection, cancelNexusInspection, reopenNexusNative, answerNexusNative, validateNexusInspection, committedPlanElements, type NexusInspection, type BattleInspectionContext } from './battle-inspections';
+import { beginNexusTraitorExchange, finishNexusTraitorExchange, validateNexusTraitorExchange, validateNexusTraitorHistory, validateNexusTraitorSnapshot, type NexusTraitorExchange, type NexusTraitorSnapshot } from './nexus-traitor-exchange';
+import { createTraitorDeclaration, validateTraitorDeclarations, type TraitorDeclaration, type TraitorDeclarationContext } from './traitor-declarations';
import { createNexusCards, validateNexusCards, drawNexusCard, replaceNexusCard, discardNexusCard, projectNexusCards, nexusCardMode, type NexusState } from './nexus-cards';
import { createNexusCardPhase, markNexusCardOccurred, validateNexusCardPhase, closeNexusCardPhase, nexusCardChoices, finishNexusCardChoice, type NexusCardPhase, type NexusCardChoice } from './nexus-card-phase';
import { createHomeworldOccupationHistory, observeHomeworldOccupation, validateHomeworldOccupationHistory, tupileOccupationStatus, type HomeworldOccupationHistory } from './homeworld-occupation-history';
@@ -536,6 +538,8 @@ export type Battle = {
nexusInspection?: NexusInspection;
/** Independent presence marker: deleting a spent-card record is not a legacy save. */
nexusInspectionUsed?: string;
+ traitorDeclarationVersion?: 1;
+ traitorDeclarations?: Record