Compose independent cards with original phase modules

This commit is contained in:
Quintine committed 2026-10-16 15:07:44 +11:00
1 parent 4313983a5c
commit 4a67e8c7be
17 files changed
+1005 -26

No files matched your search

+3 -3
View File
@@ -118,10 +118,10 @@ export function cardPresentation(card: VisibleCard): CardPresentation {
guidance: ecaz.summary,
gameplay: ecaz.gameplay,
availability: ecaz.card.effect === 'recruits'
? 'Recruits has development controls during Revival, including clean classic Basic/Advanced Homeworlds. Double the current native free rate, including low-population bonuses, within the seven-force total; separate requests recheck thresholds. Native typed deposits and special-force caps stay. Recorded prior paid returns keep payment under the provisional no-refund policy; pending transactions, unknown ledgers, later Fremen grants and same-turn replay remain guarded.'
? 'Recruits has development controls during Revival, including clean classic Basic/Advanced Homeworlds. Separately, clean classic/Ix/CHOAM rosters support original Tech3+ and Advanced Strongholds2+ without Homeworlds. Double the current native free rate within the seven-force total; typed deposits, special-force caps and original once-per-phase Axlotl income stay. Recorded prior paid returns keep payment under the provisional no-refund policy; pending transactions, unknown ledgers, later Fremen grants and replay remain guarded.'
: ecaz.card.effect === 'harassWithdraw'
? 'Harass & Withdraw has controls in either battle-card slot, with physical allocation after reveal. Classic Homeworlds returns actual typed counters into native reserve custody: Advanced Emperor normal to Kaitain/Sardaukar to Salusa; Basic preserves its original primary World. The card is forbidden on any own Homeworld. Original sealed commitment/support remains. An own concealed No-Field separately follows provisional materialization first without resetting history. Stone compares post-withdrawal counters provisionally. Other profile/module limits remain guarded.'
: 'Reinforcements works in either slot in clean selected Ix/CHOAM Basic/Advanced native/base rosters, classic tables including Homeworlds, and the selected Advanced Occupy variant. Spend three original own reserves normal-first for +2 normal score, not support or physical tokens. Native World sources seal explicitly when ambiguous; a fee here cannot also fund your own-World dial. Original face/support stays fixed. No-Field must leave three before this cost; future Harass returns cannot fund it. Original/copied Stone ignores +2 but still charges reserves. Cost/order interpretations are provisional; other profiles/modules remain guarded.',
? 'Harass & Withdraw has controls in either battle-card slot, with physical allocation after reveal. Clean classic/Ix/CHOAM rosters compose original Tech3+ and Advanced Strongholds2+ without Homeworlds. Separately, classic Homeworlds returns typed counters through native custody: Advanced Emperor normal to Kaitain/Sardaukar to Salusa; Basic to its primary World. Never use this card on an own Homeworld. Original commitment/support stays. Own No-Field provisionally materializes first without resetting history. Stone compares post-withdrawal counters provisionally; its own profile/allocation guards remain.'
: 'Reinforcements works in either slot in clean selected Ix/CHOAM Basic/Advanced native/base rosters, classic tables including Homeworlds, and selected Advanced Occupy. Clean classic/Ix/CHOAM separately supports original Tech3+ and Advanced Strongholds2+ without Homeworlds. Spend three original own reserves normal-first for +2 normal score, not support or physical tokens. World sources seal when ambiguous; a fee here cannot also fund its dial. Original face/support stays. No-Field must leave three before payment; future Harass cannot fund it. Stone ignores +2 but charges reserves; its own profile guards stay. Cost/order interpretations remain provisional.',
topics: RULE_TOPICS.filter((topic) => topic.id === (ecaz.card.effect === 'harassWithdraw' ? 'card-harass-withdraw' : ecaz.card.effect === 'reinforcements' ? 'card-reinforcements' : 'card-recruits')),
};
const topicIds =
+28 -9
View File
@@ -10704,6 +10704,24 @@ function classicEcazHomeworldProfile(g: Game): boolean {
!g.nexusCards && !g.leaderSkills && !g.techTokens && !g.strongholdCards &&
!g.discoveryEnabled && !g.discoveries && !g.discoveryStash && !g.greatMaker && !g.sandtrout;
}
/** Independent cards compose original phase modules, not unrelated previews. */
function independentCardModulesProfile(g: Game): boolean {
if (!g.ecazTreachery || (!g.techTokens && !g.strongholdCards) ||
g.players.length < (g.techTokens ? 3 : 2) || g.players.length > 6 ||
(g.strongholdCards && !g.advanced) || g.expansions.length > 2 ||
(g.expansions.length === 2 && g.expansions[0] === g.expansions[1]) ||
g.expansions.some(expansion => expansion !== 'ix' && expansion !== 'choam') ||
g.homeworlds || g.nexusCards || g.leaderSkills ||
g.discoveryEnabled || g.discoveries || g.discoveryStash || g.greatMaker || g.sandtrout ||
g.ecazOccupyPreview || g.semutaPreview || g.kullPreview || g.nexusKullPreview ||
g.richeseBetrayalPreview || g.guildBetrayalPreview || g.moritaniAssassinatePreview ||
g.spiceBankerIncomePreview || g.nexusIxianReplacementPreview ||
g.nexusIxianBetrayalPreview || g.nexusHarkonnenBetrayalPreview) return false;
return g.players.every(player => {
const family = faction(player.faction).expansion;
return family === 'base' || ((family === 'ix' || family === 'choam') && g.expansions.includes(family));
});
}
/** Gated development setup for the independent three-card Ecaz variant. */
export function initializeEcazTreacheryGameForAudit(state: Game): Game {
requireRule(!state.ecazTreachery, 'Ecaz Treachery Cards cannot redeal an existing inventory.');
@@ -10736,10 +10754,11 @@ function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = f
(leaderSkills && (classicNexusLeaderSkillsProfile(g) || pairedNexusLeaderSkillsProfile(g) ||
mixedE3NexusLeaderSkillsProfile(g) || singleE1E2NexusLeaderSkillsProfile(g) || mixedE1E2NexusLeaderSkillsProfile(g) ||
pairedE3NexusLeaderSkillsProfile(g) || standaloneE3NexusLeaderSkillsProfile(g))));
requireRule(!g.techTokens || ((skillTech || nativeTech || nexusModules || discoveryComposition) &&
const independentModules = ecazTreachery && independentCardModulesProfile(g);
requireRule(!g.techTokens || ((skillTech || nativeTech || nexusModules || discoveryComposition || independentModules) &&
JSON.stringify(g.techTokens) === JSON.stringify(createTechTokens())),
'Tech Tokens require a fresh supported three-through-six-seat lobby with unused tokens.');
requireRule(!g.strongholdCards || strongholdFactions || ((skillStronghold || homeworldSkills || nexusModules || discoveryComposition) &&
requireRule(!g.strongholdCards || strongholdFactions || ((skillStronghold || homeworldSkills || nexusModules || discoveryComposition || independentModules) &&
JSON.stringify(g.strongholdCards) === JSON.stringify(createStrongholdCards())),
'Stronghold Cards require a fresh supported Advanced lobby with unused cards.');
requireRule(
@@ -10750,8 +10769,8 @@ function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = f
(discovery || !g.discoveryEnabled) &&
(nexus || !g.nexusCards) &&
(ecazTreachery || !g.ecazTreachery) &&
(!g.techTokens || skillTech || nativeTech || nexusModules || discoveryComposition) &&
(strongholdFactions || skillStronghold || homeworldSkills || nexusModules || discoveryComposition || !g.strongholdCards) &&
(!g.techTokens || skillTech || nativeTech || nexusModules || discoveryComposition || independentModules) &&
(strongholdFactions || skillStronghold || homeworldSkills || nexusModules || discoveryComposition || independentModules || !g.strongholdCards) &&
(homeworlds || !g.homeworlds) &&
g.players.every((p) =>
FACTIONS.some(
@@ -13755,12 +13774,13 @@ function ecazTreacheryIntegrity(g: Game) {
}
}
function recruitsModeSupported(g: Game) {
const modules = independentCardModulesProfile(g);
return (
(!g.homeworlds || classicEcazHomeworldProfile(g)) &&
!g.nexusCards &&
!g.leaderSkills &&
!g.techTokens &&
!g.strongholdCards &&
(!g.techTokens || modules) &&
(!g.strongholdCards || modules) &&
!g.discoveryEnabled
);
}
@@ -13867,7 +13887,7 @@ function recruitsPlayBlock(g: Game, owner: Player, card: Card): string | null {
if (!g.ecazTreachery || !ecazTreacheryDefinition(card) || card.id !== RECRUITS_CARD_ID)
return 'Choose the physical Recruits card from the enabled Ecaz Treachery Cards variant.';
if (!recruitsModeSupported(g))
return 'This Recruits prototype requires a faction-only game or clean classic Homeworlds, without other optional modules.';
return 'Recruits requires a supported independent-card profile: faction-only, clean classic Homeworlds, or clean classic/Ix/CHOAM with original Tech and Advanced Strongholds.';
if (g.status !== 'playing' || g.phase !== 4)
return 'Play Recruits during Revival.';
if (g.recruits?.turn === g.turn)
@@ -20762,8 +20782,7 @@ function inspectedPlanMatches(p: Player, field: PlanField, fixed: unknown, candi
function harassModuleBlock(g: Game): string | null {
if (!g.ecazTreachery)
return 'Enable the independent Ecaz Treachery Cards variant before using Harass & Withdraw.';
if ((g.homeworlds && !classicEcazHomeworldProfile(g)) ||
g.nexusCards || g.leaderSkills || g.techTokens || g.strongholdCards || g.discoveryEnabled)
if (!recruitsModeSupported(g))
return 'Harass & Withdraw with these other optional modules is still being implemented.';
return combinedCardBattleBlock(g);
}
+8 -4
View File
@@ -3414,6 +3414,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Sietch Tabr uses the opposing dial, excluding leaders and other bonuses. A single traitor victory qualifies; mutual destruction does not. Tuek pays after an ordinary loss or a single traitor outcome as well as a win; a double traitor gives neither faction spice. Habbanya also decides a tied Stone Burner comparison.',
'Fresh Advanced local development tables may combine all fourteen Leader Skills with Stronghold Cards in classic or supported Ixian, Tleilaxu, CHOAM and Richese skill rosters, two through six players; optional Tech Tokens needs three through six. Original deck/cache and end-Mentat claims remain. Arrakeen pays bank support, not personal income; only the remaining actual payer debit qualifies separate normal Banker income. Skill rescue preserves the original support charge, then card cleanup and Tech reward finish before Face Dance. Modified/copied Diplomat defenses and active skill/Stone interpretations stay guarded; public activation, E3/other overlays and save conversion remain separate.',
'The original standalone Ecaz or Moritani skill roster additionally supports these Advanced combinations with the exact ecaz deck, original five-disc training and native exclusions. Normal Warmaster one on a temporary Duke composes Carthag Shield without granting trained three; normal winner Suk precedes unused-disc Moritani assassination, printed bounty, retained winner Tech and one private Mentat replacement. E3 pairs, mixtures and allied Occupy skills stay separate.',
'Fresh independent Treachery previews separately compose clean classic or selected Ix/CHOAM native/base rosters with Advanced Strongholds2–6 and optional Tech3–6, without Homeworlds. Actual end-Mentat earns custody. Reinforcements adds no supported counters; Harass vacates control without transferring a retained card early. Original card effects, costs and winner Tech order remain, while Stone/Mirror profile guards and unrelated modules stay.',
'The six effects, public ownership and pre-plan choice are integrated in development games. Enable Stronghold Cards in an Advanced preview lobby. Complete Advanced compliance and every expansion interaction remain under verification.',
],
example:
@@ -3521,6 +3522,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Owning all three tokens counts as one additional stronghold at victory checks. An alliance cannot combine separate token holdings to qualify: one member must own the complete set. Multiple sides reaching the victory target can share the win.',
'Token ownership and pending income are public and persist with the room. Fresh supported classic, E1/E2 native or standalone Ecaz/Moritani Leader Skills tables retain original three-through-six-seat Basic/Advanced setup and effects; Advanced may also retain Stronghold Cards. Skill rescue or board-spice awards finish before the mandatory original winner token reward and later Face Dance. Banker remains a separate source-to-Mentat opt-in. CHOAM’s separate native opening payout is not ordinary poverty Charity. Two-player tokens, mixed E3/other combinations and full combined acceptance remain unfinished.',
'Without Skills, fresh native E1/E2 families or standalone Ecaz OR Moritani with classic opponents may preserve unused original Tech Tokens through the local factions entry, Basic/Advanced three through six players; Advanced stronghold-factions adds the original six Stronghold Cards. Native payments, typed casualties, selected Ecaz lead rewards and Moritani original assassination remain separate. Split allied holdings never qualify as a complete set. Basic odd Occupy, Richese cache/No-Field rulings, unrelated overlays, public starts and saved-game conversion remain guarded.',
'Clean classic or selected Ix/CHOAM native/base independent-card previews retain unused Tech3–6 Basic/Advanced, optionally Advanced Strongholds2–6. Recruits changes free rates without repeating Axlotl or advancing its payout. Harass deposits and reserve fees are not free Revival or off-planet shipment. Original phase income and winner custody stay; Homeworlds and other overlays remain separate.',
],
example:
'You own Heighliners and Axlotl Tanks. When Emperor ships from reserves, place two spice on Heighliners. A later shipment adds nothing. Collect the two spice when Shipping and Movement ends.',
@@ -4977,6 +4979,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Atreides rises from two free forces to four; Fremen from three to six; Guild from one to two. The ordinary force limit becomes seven. Native unlimited CHOAM and Tleilaxu allowances remain unlimited, and their free rates become zero and four. Paid prices and separate elite limits still apply.',
'Free prevention still prevents free returns. Prior paid ordinary returns now have a visibly provisional policy: preserve payment, deduct only recorded free returns from the doubled free allowance and all returns from the total cap. Two free plus one paid Atreides may take two more free without refund; this is not a numerical user ruling. Missing/inconsistent ledgers, later Fremen grants, pending transactions and same-turn replay remain guarded.',
'Clean classic2–6 Basic/Advanced Homeworlds compose through the fresh independent36-card setup. Double current native free rates including low-population bonuses, within the seven-force total. Provisionally recheck population and recorded free use on each separate request: low Fremen may take7 together, but1 crossing high leaves5 further free and cannot buy a seventh without Tleilaxu. Original typed destinations and special-force limits stay. Other overlays/rosters, public activation and whole-mode acceptance remain unfinished.',
'Without Homeworlds, clean classic or selected Ix/CHOAM native/base rosters may retain original unused Tech Tokens at3–6 and/or Stronghold Cards at2–6 Advanced. Setup, first-Storm Tech assignment and actual end-Mentat Stronghold custody remain original. Recruits changes free rates, not the once-per-phase Axlotl trigger or delayed payout; Harass returns are not free Revival.',
],
related: ['revival', 'homeworlds', 'ecaz-modules', 'expansion-faction-games', 'implementation-checklist'],
checklist: [
@@ -4984,7 +4987,7 @@ export const RULE_TOPICS: RuleTopic[] = [
{ area: 'Player controls', status: 'Implemented', detail: 'The owned physical card has full inspection, a Revival action and explicit unavailable reasons. All seats see the effective public rates after play.', evidence: ['components/recruits.tsx', 'components/game-table.tsx', 'game/card-presentation.ts'] },
{ area: 'AI', status: 'Partial', detail: 'All four profiles use the same legal owned offer for useful own or allied revival, then existing authoritative revival choices. Complete card strategy and calibration remain unfinished.', evidence: ['game/bots.ts'] },
{ area: 'Documentation', status: 'Implemented', detail: 'The guide records examples, limits, independent-cap inference and the visibly provisional late-paid policy; source alternatives and late-rate questions remain explicit.', evidence: ['docs/RECRUITS_RULES.md', 'docs/RECRUITS_RUNTIME.md'] },
{ area: 'Verification', status: 'Partial', detail: 'Ten new native regressions cover bulk7 versus split6 at a population crossing, Basic/Advanced typed caps, already-ready paid returns and Emperor destinations. Four actual mobile journeys and16 fresh four-policy programmes/104 accepted card/Revival actions reach usable native continuation. Existing authenticated recovery evidence is separate; full variant/mode/calibration/final assurance stays open.', evidence: ['tests/recruits-homeworld.test.ts', 'tests/fixture-recruits-homeworld.ts', 'tests/recruits.test.ts', 'tests/recruits-engine.test.ts', 'tests/recruits-controls.test.tsx', 'tests/recruits-recovery.test.ts', 'tests/prototype-room.test.ts'] },
{ area: 'Verification', status: 'Partial', detail: 'Earlier World proof: ten native cases, four mobile journeys and16 four-policy programmes/104 actions cover rates, typed caps, prior paid returns and destinations. Separate original phase-module proof adds genuine battle-filled Tanks, two mobile Revival journeys and16 useful four-policy programmes/120 actions: doubled rates, paid remainder and one delayed Axlotl payout after two free revivals. No new special-counter revival or complete-mode/calibration claim.', evidence: ['tests/recruits-modules.test.ts', 'tests/fixture-recruits-modules.ts', 'tests/fixture-independent-card-modules.ts', 'tests/recruits-homeworld.test.ts', 'tests/fixture-recruits-homeworld.ts', 'tests/recruits.test.ts', 'tests/recruits-engine.test.ts', 'tests/recruits-controls.test.tsx', 'tests/recruits-recovery.test.ts', 'tests/prototype-room.test.ts'] },
],
},
{
@@ -5002,7 +5005,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'With your own concealed No-Field, the provisional native order materializes its reserve-limited counters before this cost. At least three own reserves must remain after that reveal, before any future Harass return; otherwise Reinforcements is unavailable before the first plan seals. This checks only the actual card user, never its ally’s marker or reserves.',
'Clean classic2–6 Basic/Advanced Homeworlds use exact native normal-first fee sources, sealed in the plan. Ambiguous omissions reject; unique sources may derive. An own-World fee cannot also fund physical dial/casualties, but original printed face/support remains. Original high-face explosion losses survive a fee crossing low. Native-only Traitors, typed Tanks and cost-before-Harass remain; this is explicit provisional composition, not a new card FAQ.',
'One canonical physical-name registry now includes the independent cards for current facts and named battle conditions. Naming Reinforcements in a weapon slot does not make it a weapon category. Native questions use actual combat-location labels. Source-aware legal completion, private full-plan/read-only review and the fill button retain exact native sources.',
'Clean selected Ix and/or CHOAM families retain original Basic/Advanced setup and independent cards, with no Homeworlds or other optional modules/overlays. Original cyborg substitution and Face Dance apply to their own native casualties, not a second copy of the reserve fee. Richese No-Field reveal precedes the fee; physical original/copied Stone ignores the score bonus. Other family/module combinations and public starts remain guarded.',
'Clean selected Ix and/or CHOAM families retain original Basic/Advanced setup and independent cards. Native cyborg substitution and Face Dance use their original physical pools, not a second copy of the reserve fee. Richese No-Field reveal precedes payment; physical Stone ignores +2. Separately retain original Tech3+ and/or Advanced Strongholds2+ without Homeworlds, using actual phase income/earned custody; other family/module and Stone profile guards stay.',
],
related: ['battle-cards', 'battle', 'homeworlds', 'card-recruits', 'card-harass-withdraw', 'card-truthtrance', 'implementation-checklist'],
checklist: [
@@ -5010,7 +5013,7 @@ export const RULE_TOPICS: RuleTopic[] = [
{ area: 'Player controls', status: 'Partial', detail: 'Owner-only cost/source choices, own-World physical bounds, wrapped exact allocation, source-aware legal-plan fill and earned private reviews connect; category answers remain None. Native named-question preview/answer/history uses canonical combat labels.', evidence: ['components/battle-preparation.tsx', 'components/reinforcements-sources.tsx', 'components/private-battle-plan.tsx', 'components/battle-promises.tsx', 'components/truthtrance.tsx', 'components/game-table.tsx'] },
{ area: 'AI', status: 'Partial', detail: 'Four profiles consider legal physical slot candidates and the normal score bonus; strategy and calibration remain unfinished.', evidence: ['game/bots.ts'] },
{ area: 'Documentation', status: 'Partial', detail: 'The printed effect and unresolved Traitor, explosion, type-selection and accounting interpretations are distinguished from this temporary prototype.', evidence: ['docs/ECAZ_TREACHERY_RULES.md', 'docs/REINFORCEMENTS_RUNTIME.md'] },
{ area: 'Verification', status: 'Partial', detail: 'Native actual setup/shipment/movement covers both slots, typed fees, deficient funding, exact World sources, disjointness, frozen face/explosion, Traitors, Harass and named promises. Earlier World proof: six mobile journeys and32 four-policy programmes/114 continuations/1682 valid R proposals. Clean selected-family proof adds seven mobile journeys and48 programmes/194 continuations/3022 proposals, including genuine cyborg, Face Dance, Auditor and marker/Stone paths. Bounded proof, not complete modes or calibration.', evidence: ['tests/native-family-reinforcements.test.ts', 'tests/fixture-native-family-reinforcements.ts', 'tests/richese-reinforcements.test.ts', 'tests/fixture-richese-reinforcements.ts', 'tests/reinforcements-homeworld.test.ts', 'tests/fixture-reinforcements-homeworld.ts', 'tests/reinforcements-homeworld-arrakis.test.ts', 'tests/fixture-reinforcements-homeworld-arrakis.ts', 'tests/no-field-reinforcements.test.ts', 'tests/fixture-no-field-reinforcements.ts', 'tests/stone-reinforcements.test.ts', 'tests/harass-reinforcements.test.ts', 'tests/reinforcements.test.ts', 'tests/reinforcements-engine.test.ts', 'tests/ecaz-occupy-cards-runtime.test.ts', 'docs/ECAZ_OCCUPY_RULES.md'] },
{ area: 'Verification', status: 'Partial', detail: 'Native setup/shipment covers typed fees, deficient funding, exact World sources, disjointness, frozen face/explosion, Traitors, Harass and named promises. Earlier World proof: six mobile/32 programmes/114 continuations/1682 R proposals. Clean families: seven mobile/48 programmes/194 continuations/3022 proposals. Phase modules: two mobile battles/20 programmes/52 continuations/9564 R-or-H proposals with earned bank support, Tabr and Tech rewards. Bounded legal proof, not complete modes or calibration.', evidence: ['tests/battle-card-modules.test.ts', 'tests/fixture-battle-card-modules.ts', 'tests/fixture-independent-card-modules.ts', 'tests/native-family-reinforcements.test.ts', 'tests/fixture-native-family-reinforcements.ts', 'tests/richese-reinforcements.test.ts', 'tests/fixture-richese-reinforcements.ts', 'tests/reinforcements-homeworld.test.ts', 'tests/fixture-reinforcements-homeworld.ts', 'tests/reinforcements-homeworld-arrakis.test.ts', 'tests/fixture-reinforcements-homeworld-arrakis.ts', 'tests/no-field-reinforcements.test.ts', 'tests/fixture-no-field-reinforcements.ts', 'tests/stone-reinforcements.test.ts', 'tests/harass-reinforcements.test.ts', 'tests/reinforcements.test.ts', 'tests/reinforcements-engine.test.ts', 'tests/ecaz-occupy-cards-runtime.test.ts', 'docs/ECAZ_OCCUPY_RULES.md'] },
],
},
{
@@ -5030,6 +5033,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'In supported same-plan Reinforcements, the provisional order pays three original own reserves before Harass returns undialed counters. Future returns cannot fund or change that reserve quote; neither the +2 score bonus nor that cost adds to the physical commitment. Both cards discard after use. An opposing successful Traitor cancels Harass but not the provisional Reinforcements cost.',
'With an own concealed No-Field, this prototype provisionally uses the original materialization-first order. Before sealing, privately forecast its actual ordinary counters at the original marker sector; do not move them early. Both plans seal before native revelation, then any return allocation uses actual counters. Marker0 remains legal with a leader/cards, reserve shortage caps materialization, and withdrawal does not return/reset the token. Opposing successful Traitor cancels Harass, not that native reveal.',
'Clean classic2–6 Basic/Advanced Homeworlds may be selected before independent36-card setup. Harass works on Arrakis or a foreign Homeworld, never any own World. Return actual undialed board/visitor counters through native custody, not Tanks: Basic primary; Advanced Emperor normal to Kaitain/Sardaukar to Salusa. Original dial/support and committed counters remain fixed across thresholds. Native-only Traitors, late defense/explosion and disposal stay. Recruits has native current rates; Reinforcements seals exact original native fees before these returns. Other overlays/rosters remain guarded.',
'Without Homeworlds, clean classic or selected Ix/CHOAM native/base rosters compose original Tech3+ and/or Advanced Strongholds2+. An earned held Stronghold still affects only its original eligible plan/actual support; +2 Reinforcements adds no supported counters. Harass deposits are not an off-planet shipment or free Revival. Original winner card cleanup/Tech reward precedes native Face Dance.',
],
related: ['battle-cards', 'battle', 'card-recruits', 'homeworlds', 'ecaz-modules', 'implementation-checklist'],
checklist: [
@@ -5037,7 +5041,7 @@ export const RULE_TOPICS: RuleTopic[] = [
{ area: 'Player controls', status: 'Partial', detail: 'Either slot and native typed allocation remain. World names, Basic versus Advanced reserve destinations and fixed-commitment timing are explicit. Invaders no longer receive forbidden Traitor controls. Four actual390px journeys complete Basic foreign loss, Advanced foreign victory, Salusa threshold return and own-Salusa ban/plain alternative into Collection.', evidence: ['components/battle-preparation.tsx', 'components/harass-withdraw.tsx', 'components/revealed-battle.tsx', 'components/game-table.tsx', 'components/harass-withdraw-choice.tsx'] },
{ area: 'AI', status: 'Partial', detail: 'All four profiles use legal shared precommit quotes and exact after-reveal allocations without an invader vote. Sixteen native World programs accept36 continuation actions and validate original precommit proposals through normal/explosion/own-World alternatives. Retreat strategy and combined strength remain deferred.', evidence: ['game/bots.ts', 'tests/ecaz-battle-bots.test.ts'] },
{ area: 'Documentation', status: 'Partial', detail: 'Printed own-World restriction and explicit native destination/fixed-commitment composition are separated from original materialization/Stone policies and remaining faction/module/final gates.', evidence: ['docs/HARASS_WITHDRAW_RUNTIME.md', 'docs/ECAZ_TREACHERY_RULES.md', 'docs/STONE_BURNER_ENGINE_AUDIT.md', 'docs/RICHESE_NO_FIELD_RULES.md'] },
{ area: 'Verification', status: 'Partial', detail: 'Native Homeworld regressions cover real typed invasion/Arrakis shipments, both slots/modes, selected full commitment, Basic primary/Advanced split reserves, native-only Traitors, winner disposal, explosion exception and Salusa threshold follow-on. Four mobile and16 policy programs reach original Collection. Earlier No-Field/Stone/recovery evidence remains historical, not complete-mode/new assurance or deployed acceptance.', evidence: ['tests/harass-homeworld.test.ts', 'tests/fixture-harass-homeworld.ts', 'tests/harass-homeworld-arrakis.test.ts', 'tests/fixture-harass-homeworld-arrakis.ts', 'tests/harass-no-field.test.ts', 'tests/fixture-harass-no-field.ts', 'tests/no-field-reinforcements.test.ts', 'tests/stone-harass-quote.test.ts', 'tests/stone-harass-runtime.test.ts', 'tests/fixture-stone-harass.ts', 'tests/ecaz-occupy-harass-quote.test.ts', 'tests/harass-allocation-engine.test.ts', 'tests/harass-allocation-recovery.test.ts', 'tests/harass-withdraw-choice-controls.test.tsx', 'tests/harass-withdraw.test.ts', 'tests/ecaz-battle-controls.test.tsx', 'tests/ecaz-battle-bots.test.ts', 'tests/ecaz-battle-recovery.test.ts'] },
{ area: 'Verification', status: 'Partial', detail: 'Earlier native World cases cover real typed invasion/Arrakis shipments, both slots/modes, selected commitment, reserve destinations, Traitors, disposal, explosion and thresholds; four mobile/16 policy programmes reach Collection. Separate phase-module proof adds earned Arrakeen/Tabr, typed fee-before-return and actual Tech awards: two mobile battles and20 four-policy programmes/52 continuations/9564 R-or-H proposals. No Face Dance route or complete-mode/deployed/calibration claim.', evidence: ['tests/battle-card-modules.test.ts', 'tests/fixture-battle-card-modules.ts', 'tests/fixture-independent-card-modules.ts', 'tests/harass-homeworld.test.ts', 'tests/fixture-harass-homeworld.ts', 'tests/harass-homeworld-arrakis.test.ts', 'tests/fixture-harass-homeworld-arrakis.ts', 'tests/harass-no-field.test.ts', 'tests/fixture-harass-no-field.ts', 'tests/no-field-reinforcements.test.ts', 'tests/stone-harass-quote.test.ts', 'tests/stone-harass-runtime.test.ts', 'tests/fixture-stone-harass.ts', 'tests/ecaz-occupy-harass-quote.test.ts', 'tests/harass-allocation-engine.test.ts', 'tests/harass-allocation-recovery.test.ts', 'tests/harass-withdraw-choice-controls.test.tsx', 'tests/harass-withdraw.test.ts', 'tests/ecaz-battle-controls.test.tsx', 'tests/ecaz-battle-bots.test.ts', 'tests/ecaz-battle-recovery.test.ts'] },
],
},
{