Connect native Guild rate cancellation and Cunning receipts
This commit is contained in:
1 parent
c10fe0b48c
commit
0db84c81b7
12 files changed
+375
-39
No files matched your search
+44
-21
@@ -26485,9 +26485,8 @@ const CLASSIC_FACTIONS: Partial<Record<FactionId, true>> = {
|
||||
|
||||
/** The independent Karama rate is a card benefit, not Guild's cancelable rate. */
|
||||
function guildRateModeSupported(g: Game): boolean {
|
||||
return !g.expansions.length && !g.homeworlds && !g.leaderSkills &&
|
||||
!g.nexusCards && !g.discoveryEnabled && !g.techTokens && !g.strongholdCards &&
|
||||
g.players.every(player => CLASSIC_FACTIONS[player.faction] === true);
|
||||
return !g.homeworlds && !g.leaderSkills && !g.discoveryEnabled &&
|
||||
!g.techTokens && !g.strongholdCards;
|
||||
}
|
||||
function ordinaryGuildRateFullCost(g: Game, shipment: PendingShipment): number | null {
|
||||
const guild = byFaction(g, 'guild');
|
||||
@@ -26498,7 +26497,7 @@ function ordinaryGuildRateFullCost(g: Game, shipment: PendingShipment): number |
|
||||
(g.guildRateBlocked?.turn === g.turn && g.guildRateBlocked.player === p.id) ||
|
||||
shipment.source || shipment.noField || shipment.alliedNoField ||
|
||||
shipment.smuggler || shipment.smugglerCompanion || shipment.guildSecretEvent ||
|
||||
shipment.guildNexusEvent || shipment.nexusEvent || shipment.richesePair)
|
||||
shipment.nexusEvent || shipment.richesePair)
|
||||
return null;
|
||||
const fullCost = reserveShipmentCost({ faction: p.faction, halfRate: false },
|
||||
territory(shipment.territory).type, shipment.amount);
|
||||
@@ -26507,10 +26506,17 @@ function ordinaryGuildRateFullCost(g: Game, shipment: PendingShipment): number |
|
||||
function openGuildRate(g: Game, shipment: PendingShipment): boolean {
|
||||
const fullCost = ordinaryGuildRateFullCost(g, shipment);
|
||||
if (fullCost === null) return false;
|
||||
const cunning = shipment.guildNexusEvent
|
||||
? validateGuildCunningShipment(g, shipment.player, shipment.guildNexusEvent, 'reserve', shipment)
|
||||
: null;
|
||||
// A validated older Guild-stop declaration may lack this newer turn stamp.
|
||||
shipment.turn ??= g.turn;
|
||||
const event = crypto.randomUUID();
|
||||
shipment.guildRateEvent = event;
|
||||
if (cunning) {
|
||||
cunning.shipment!.frame = JSON.stringify(shipment);
|
||||
saveGuildCunning(g, cunning);
|
||||
}
|
||||
g.pendingShipment = shipment;
|
||||
g.response = {
|
||||
kind: 'guildRate',
|
||||
@@ -26528,7 +26534,7 @@ function validateGuildRateResponse(g: Game, response: ResponseWindow) {
|
||||
const p = shipment && getPlayer(g, shipment.player);
|
||||
const fullCost = shipment ? ordinaryGuildRateFullCost(g, shipment) : null;
|
||||
requireRule(response.kind === 'guildRate' && guild && p && shipment &&
|
||||
g.status === 'playing' && g.phase === 5 && g.active === p.id && !p.shipped &&
|
||||
g.status === 'playing' && g.phase === 5 && g.active === p.id && shipmentAvailable(g, p) &&
|
||||
response.owner === guild.id && typeof shipment.guildRateEvent === 'string' &&
|
||||
shipment.guildRateEvent.length > 0 &&
|
||||
response.guildRateEvent === shipment.guildRateEvent &&
|
||||
@@ -26556,24 +26562,35 @@ function guildRateIntegrity(g: Game) {
|
||||
function finishGuildRateResponse(g: Game, response: ResponseWindow, canceled: boolean) {
|
||||
const { shipment, fullCost } = validateGuildRateResponse(g, response);
|
||||
const shipper = getPlayer(g, shipment.player);
|
||||
const cunning = shipment.guildNexusEvent
|
||||
? validateGuildCunningShipment(g, shipper.id, shipment.guildNexusEvent, 'reserve', shipment)
|
||||
: null;
|
||||
g.pendingShipment = null;
|
||||
delete shipment.guildRateEvent;
|
||||
if (!canceled) {
|
||||
commitShipment(g, shipment);
|
||||
return;
|
||||
if (canceled) {
|
||||
g.guildRateBlocked = { turn: g.turn, player: shipper.id };
|
||||
const bounds = shipmentPaymentBounds(fullCost, shipper.spice,
|
||||
aidFor(g, shipper)?.amount ?? 0);
|
||||
if (shipment.allyPayment < bounds.minimum || shipment.allyPayment > bounds.maximum) {
|
||||
if (cunning) {
|
||||
delete cunning.shipment;
|
||||
saveGuildCunning(g, cunning);
|
||||
}
|
||||
log(g, `Karama removed Guild's half-price rate from ${shipper.name}'s declaration. Its original approved payment split cannot fund the full price, so no spice or forces were spent and shipment remains available at full price this turn.`);
|
||||
return;
|
||||
}
|
||||
shipment.cost = fullCost;
|
||||
checkShipmentIncomeFunding(g, shipper, fullCost, shipment.allyPayment);
|
||||
}
|
||||
g.guildRateBlocked = { turn: g.turn, player: shipper.id };
|
||||
const bounds = shipmentPaymentBounds(fullCost, shipper.spice,
|
||||
aidFor(g, shipper)?.amount ?? 0);
|
||||
if (shipment.allyPayment < bounds.minimum || shipment.allyPayment > bounds.maximum) {
|
||||
log(g, `Karama removed Guild's half-price rate from ${shipper.name}'s declaration. Its original approved payment split cannot fund the full price, so no spice or forces were spent and shipment remains available at full price this turn.`);
|
||||
return;
|
||||
if (cunning) {
|
||||
cunning.shipment!.frame = JSON.stringify(shipment);
|
||||
saveGuildCunning(g, cunning);
|
||||
}
|
||||
shipment.cost = fullCost;
|
||||
checkShipmentIncomeFunding(g, shipper, fullCost, shipment.allyPayment);
|
||||
commitShipment(g, shipment);
|
||||
delete g.guildRateBlocked;
|
||||
log(g, `Karama removed Guild's half-price rate. ${shipper.name} paid the full ${fullCost} spice for the unchanged shipment.`);
|
||||
if (canceled) {
|
||||
delete g.guildRateBlocked;
|
||||
log(g, `Karama removed Guild's half-price rate. ${shipper.name} paid the full ${fullCost} spice for the unchanged shipment.`);
|
||||
}
|
||||
}
|
||||
function guildTransportSignature(intent: PendingGuildTransport): string {
|
||||
return JSON.stringify([intent.event, intent.turn, intent.player, intent.fromReserves,
|
||||
@@ -26618,7 +26635,7 @@ function validateGuildTransportRateResponse(g: Game, response: ResponseWindow) {
|
||||
? ordinaryGuildTransportFullCost(g, shipper, intent) : null;
|
||||
requireRule(response.kind === 'guildRate' && intent && guild && shipper &&
|
||||
g.status === 'playing' && g.phase === 5 && g.active === shipper.id &&
|
||||
!shipper.shipped && intent.turn === g.turn &&
|
||||
shipmentAvailable(g, shipper) && intent.turn === g.turn &&
|
||||
typeof intent.event === 'string' && intent.event.length > 0 &&
|
||||
response.owner === guild.id && response.guildRateEvent === intent.event &&
|
||||
typeof intent.fromReserves === 'boolean' &&
|
||||
@@ -27165,7 +27182,10 @@ function validateGuildCunningShipment(g: Game, owner: string, event: string, kin
|
||||
const record = currentGuildCunning(g,owner);
|
||||
requireRule(record?.stage === 'secondShipment' && record.receipt.event === event && record.shipment?.stage === 'pending' &&
|
||||
record.shipment.kind === kind && record.shipment.frame === JSON.stringify(frame), 'Guild Cunning has lost its original second shipment.');
|
||||
return record;
|
||||
// The validated kind excludes a declined (nonphysical) second shipment.
|
||||
return record as typeof record & {
|
||||
shipment?: Exclude<NonNullable<typeof record.shipment>, {kind: 'declined'}>;
|
||||
};
|
||||
}
|
||||
function finishGuildCunningShipment(g: Game, owner: string, kind: 'reserve'|'guild'|'homeworld', frame: unknown, outcome:'complete'|'stopped' = 'complete') {
|
||||
const record = currentGuildCunning(g,owner);
|
||||
@@ -27227,8 +27247,11 @@ function nexusGuildCunningIntegrity(g: Game) {
|
||||
requireRule(g.pendingShipment?.guildNexusEvent === active.receipt.event, 'Guild Cunning lost its pending reserve shipment.');
|
||||
validateGuildCunningShipment(g,owner.id,active.receipt.event,'reserve',g.pendingShipment);
|
||||
const decisions = homeworldSavedDecisions(g).filter(d => d.kind === 'guildShipment');
|
||||
requireRule(decisions.length > 0,'Guild Cunning lost its shipment interception decision.');
|
||||
const rates = savedNoFieldResponses(g).filter(response => response.kind === 'guildRate');
|
||||
requireRule(decisions.length > 0 || rates.length === 1,
|
||||
'Guild Cunning lost its shipment interception or rate response.');
|
||||
for (const d of decisions) validateGuildShipmentDecision(g,d);
|
||||
for (const rate of rates) validateGuildRateResponse(g,rate);
|
||||
} else if (active.shipment.kind === 'homeworld') {
|
||||
requireRule(g.pendingHomeworldShipment?.guildNexusEvent === active.receipt.event,'Guild Cunning lost its pending Homeworld shipment.');
|
||||
validateGuildCunningShipment(g,owner.id,active.receipt.event,'homeworld',g.pendingHomeworldShipment);
|
||||
|
||||
+10
-9
@@ -142,10 +142,10 @@ const phaseDetails = [
|
||||
[
|
||||
'At the start of this phase, resolve the Atreides spice foresight response. If allowed, Atreides privately inspects the next card, including when using double spice blow.',
|
||||
'Select a destination and sector. Ship from reserves before making a force move.',
|
||||
'A classic Guild or reciprocal ally’s discounted ordinary reserve shipment or eligible cross-planet transport waits for a Karama response before paying. Guild’s own return to reserves waits too. Canceling the rate uses normal destination pricing for the same physical forces and approved payment split; a return costs one spice per force. If the split or exact group cannot complete, the declaration returns unused and a replacement this turn uses full price. Full-price return and unaffordable withdrawal are documented table interpretations, not separate publisher examples. Guild income, purchased Karama rates, transport permission and optional modules remain distinct.',
|
||||
'Native Guild or its reciprocal ally’s discounted ordinary reserve shipment or eligible cross-planet transport waits for a Karama response before paying, including expansion/Nexus tables without Homeworlds, Skills, Discovery, Tech or Strongholds. Guild’s own return waits too. The same physical group and approved split must cover full price after cancellation; otherwise the declaration returns unused and a replacement this turn uses full price. Cunning retains its separate second allowance and original shipped history. Full-price return and unaffordable withdrawal remain provisional policies; income, independent purchased rates and transport permission are distinct.',
|
||||
'For movement, select the source forces. Enable Combine sectors to include several groups from the same territory.',
|
||||
'A Fremen move using the two-territory advantage has a Karama response. Cancellation leaves the forces in place and limits this move to one territory; city ornithopters and a later extra move keep their normal rules.',
|
||||
'Guild transport can move one exact physical group across the planet or return it to reserves. In classic games its normal half-price rate can be canceled separately from its transport permission. Ordinary movement is checked against range, storm and stronghold occupancy.',
|
||||
'Guild transport moves one exact physical group across the planet or returns it to reserves. Native half-price cancellation is separate from transport permission, including supported expansion/Nexus tables and Cunning’s second shipment. Ordinary movement still checks range, storm and stronghold occupancy.',
|
||||
'You may pass through an ally’s territory on a legal route that ends elsewhere. Ordinary physical reserve shipments in both modes may enter allied territory before movement, then depart during that turn. Storm and stronghold capacity remain binding. Basic visibly labels its provisional no-exit policy: excess new visitors still present go to Tanks. Advanced follows supplied p15: all the ending player’s shared forces go to Tanks, including old forces, subject to advisor/Polar/Ecaz exemptions. Neither grants an extra move. Concealed No-Fields and optional arrivals remain separate.',
|
||||
'Ecaz and its reciprocal ally may share territories and count as one faction toward stronghold capacity, without extra movement or storm/Homeworld exceptions. Their three-joint-stronghold victory and desert allocation are connected. Fremen/Ecaz cooccupation permits the Fremen special win in Sietch Tabr in Basic; supplied Advanced p32 permits both Tabr and Habbanya Sietch. Other victory conditions and exceptional combined interactions remain separate.',
|
||||
'A restored pending physical shipment is checked again before forces or spice are committed. If its saved turn, force allocation, destination, price or authorized contribution no longer matches the table, it is rejected without changing the saved declaration.',
|
||||
@@ -1431,7 +1431,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
area: 'Documentation',
|
||||
status: 'Partial',
|
||||
detail:
|
||||
'Source-bound effects, copies and Duke guides remain. Native own-arrival continuation explicitly records existing child-first/live-token order as provisional, preserving actual controls, original tariffs and unsupported paired/module guards. Guild native rate-Karama expansion/Nexus admission is separate unfinished work, not a printed prohibition.',
|
||||
'Source-bound effects, copies and Duke guides remain. Native own-arrival continuation explicitly records child-first/live-token order as provisional, preserving actual controls and unsupported paired/module guards. Separate native rate cancellation now admits expansion/Nexus reserve/cross/return and Cunning receipts; Homeworld/Skills/Discovery/Tech/Stronghold rate compositions remain unfinished.',
|
||||
evidence: ['docs/ECAZ_AMBASSADORS_RULES.md', 'docs/DEFERRED_SHIPMENT_ARRIVAL.md', 'docs/BOT_ARRIVAL_PREFLIGHT.md'],
|
||||
},
|
||||
{
|
||||
@@ -2556,7 +2556,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'If eligible to bid, use the card to take the current auction card without paying spice. A full hand cannot bypass the bidding limit.',
|
||||
'Holding Karama also permits bids beyond your available spice. A winner can choose to spend it; an outbid player keeps it.',
|
||||
'Use Cancel with Karama during a power response. Supported responses include Voice, prescience, Atreides auction and spice peeks, spiritual advisors, Emperor gifts and revival, faction income, Harkonnen bonus cards and allied traitors, plus Fremen storm and worm powers, elite combat strength and Fremen free spice support.',
|
||||
'In classic-faction games without optional modules, cancel Guild’s half-price rate before an ordinary reserve shipment, eligible cross-planet transport or Guild return moves any spice or forces. Full destination price applies to the same physical group if the original approved payment split can afford it; otherwise the declaration returns unused and its replacement is full price this turn. The full-price return tariff and unaffordable withdrawal are documented table policies, not printed refund examples. Guild income, permission to cross/return and the independent rate purchased by Karama remain separate.',
|
||||
'Native Guild half-price cancellation covers ordinary reserve shipment, eligible cross-planet transport and Guild return before payment or arrival, including expansion/Nexus tables without Homeworlds, Skills, Discovery, Tech or Strongholds. Cunning’s second reserve/cross shipment retains its original allowance and history. Full price applies to the same group and approved split if affordable; otherwise the uncommitted attempt returns and its replacement is full price this turn. The return tariff and unaffordable outcome remain documented table policies. Income, transport permission and independent Karama prices are separate.',
|
||||
'During shipment, use Guild rates for the active player before they ship. They choose and pay for their shipment at the rounded half rate, paid to the bank. You may provide this benefit for another player; it expires if they move or finish without shipping.',
|
||||
'Advanced Bene Gesserit may spend Worthless cards as Karama. Each conversion opens a separate cancellation response; the Worthless card is discarded even if the power is canceled. Normal Karama cards resolve without that conversion response.',
|
||||
'A pending Worthless purchase keeps space for its original auction card. Gifts and hand exchanges must leave enough room for every committed incoming card. Refreshing restores the same auction, unused shipment opportunity or original canceled power.',
|
||||
@@ -4653,6 +4653,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'Native Richese Cunning uses the original signed two-No-Field shipment in supported single/paired E2 or selected mixed Ix+CHOAM native Nexus tables with classics, optional Skills/Homeworlds/Discovery/Tech/Advanced Strongholds. Select two distinct unused physical tokens: one reveals immediately into reserve-capped forces, one remains concealed; pay one marker invoice and spend the Nexus. The previous shipment token cannot be either choice, and the concealed one becomes last-used. Native/Guild response and actual payer/counter sources remain; a nested destination must be revealed. Prevention keeps physical tokens and unpaid spice, after any printed card cost. Sandtrout, arbitrary companions, shared allocation and other pending combinations retain their guards.',
|
||||
'Richese Betrayal has a separate opt-in auction preview. Before payment, an unallied rival may spend its physical Richese Nexus card to discard a public self-cache win without any purchase debit, or redirect another buyer’s cache/Black Market payment to the bank while preserving delivery and earned bonus. Every publicly possible holder acknowledges the same opportunity; private Use eligibility cannot determine public timing. Normal hidden self-purchases and private special-Karama acquisitions are not connected. See the dedicated guide for its existing local runtime/browser evidence and remaining release gates; that evidence does not verify Nexus Kull.',
|
||||
'Guild Cunning is declared when finishing your ordinary Shipment and Movement turn. It spends the Nexus and opens one Karama response. Allowance grants a second native shipment at normal Guild prices, including supported cross-shipment, return and Homeworld routes. Cancellation leaves the completed first turn intact. Only an unused Hajr move can follow the second shipment; no ordinary movement or third move is granted. The physical Ornithopter card combination remains unavailable. The separate guild-betrayal profile admits only original native shipment producers and explicitly blocks this second-shipment offer before Nexus spending; Cunning outside that profile is unchanged.',
|
||||
'In supported native expansion/Nexus tables without other physical modules, Cunning’s second reserve/cross shipment has the normal prepayment rate-Karama window. Its original shipped flag stays true. Allowance preserves rounded half price; cancellation pays full price once or returns the uncommitted second attempt without losing that allowance. A replacement stays full price. The first shipment and ordinary movement never reopen.',
|
||||
'With Guild absent, its Secret Ally is an explicit optional source for one ordinary shipment at Guild prices. It supports physical reserve shipment, cross-shipment and return to the holder’s own reserves, including the native-Homeworld return when Homeworlds are enabled, plus half-price independently legal world-to-world shipment. Fremen may retain free reinforcement or choose the paid card route beyond its normal range, outside the storm. Native faction, typed sources and normal movement stay unchanged. Arbitrary foreign-world transport and concealed No-Fields are not granted.',
|
||||
'Borrowed Guild/Richese tariffs do not change native faction or physical reserve origin. Non-Guild/non-Fremen off-planet arrivals can accrue Heighliners once for collection at the original phase end. A paid borrowed Guild route from Fremen southern reserves is still on-planet and does not trigger it; stopped and native-Guild-only shipments likewise remain excluded. The existing Emperor bank-auction purchase retains the actual buyer wallet and creates no industry activity.',
|
||||
'Guild Betrayal has a separate fresh classic/native-Guild development preview. Before a fully funded positive shipment settles, an unallied holder may spend the physical Guild Nexus to take the full original fee, including their own pre-funded payment, instead of Guild, bank or occupied Junction income. Original donor escrow is consumed once and original physical delivery is unchanged. Neutral public acknowledgements reveal no fee/source; only private eligibility exposes Use. Zero/stopped shipments create no award or Nexus cost. See the dedicated guide; new verification remains Planned and ordinary Homeworld occupation/rounding questions stay local.',
|
||||
@@ -4661,11 +4662,11 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
],
|
||||
related: ['ecaz-modules', 'spice-blow', 'alliance-funding', 'choam-worthless', 'choam-kull', 'nexus-choam-kull', 'nexus-richese-betrayal', 'nexus-guild-betrayal', 'nexus-ixian-replacement', 'nexus-ixian-betrayal'],
|
||||
checklist: [
|
||||
{area:"Implementation",status:'Partial',detail:"Shared Traitor snapshots now account for permanent Moritani markers outside reserve/hands/Face Dancers, retaining existing Loyalty exclusion. Exchange, Face Dancer, Betrayal and Rihani consumers bind their own source zone; absent-zone grammar stays unchanged. Historical replacements may be legally returned and drawn again. Existing Cunning timing, costs, custody, actor/parent and roster gates remain; full combinations stay open.",evidence:['game/nexus-cards.ts', 'game/nexus-card-phase.ts', 'game/nexus-traitor-exchange.ts', 'game/traitor-declarations.ts', 'game/nexus-face-dancers.ts', 'game/nexus-suboids.ts', 'game/nexus-advisors.ts', 'game/nexus-sardaukar-options.ts', 'game/nexus-fremen-revival.ts', 'game/nexus-fremen-cunning.ts', 'game/nexus-ecaz-betrayal.ts', 'game/nexus-ecaz-inquiry.ts', 'game/nexus-ecaz-duke.ts', 'game/duke-vidal.ts', 'game/nexus-emperor-secret-ally.ts', 'game/choam-power-options.ts', 'game/nexus-moritani-options.ts', 'game/nexus-moritani-betrayal.ts', 'game/nexus-richese-options.ts', 'game/nexus-richese-betrayal.ts', 'game/nexus-guild-cunning-options.ts', 'game/nexus-guild-secret-ally-options.ts', 'game/nexus-module-profile.ts', 'game/engine.ts', 'game/nexus-tleilaxu-revival.ts', 'game/nexus-borrowed-voice.ts', 'game/combat-response-quote.ts', 'game/karama-context.ts', 'game/nexus-fremen-protection.ts', 'game/admin-seat-ai-shape.ts', 'game/richese-cancellation.ts', 'game/bot-mobility.ts', 'game/planetologist-movement.ts', 'game/revival.ts', 'game/nexus-fremen-revival-options.ts','game/nexus-emperor-payment.ts', 'game/nexus-emperor-secret-ally.ts', 'game/revival-resume.ts', 'game/revival-cancellation.ts', 'game/homeworld-revival-deployment.ts', 'game/homeworld-revival-return.ts', "game/nexus-emperor-purchase.ts", "game/auction-continuation-quote.ts", "game/nexus-emperor-purchase.ts", "game/ambassador-phase.ts", "game/ambassador-resume.ts", "game/battle-aftermath-quote.ts", "game/ecaz-duke-acquisition.ts", "game/ecaz-duke-revival.ts", "game/nexus-ecaz-duke-options.ts", "game/nexus-play-boundary.ts"]},
|
||||
{area:"Player controls",status:'Partial',detail:"Actual390px Secret Ally draws two, returns historical Hasimir6 plus Caid3, keeps Esmar3 and restores the original Mori placement. Passing it reaches the next Storm. A later genuine Esmar3 retirement draws one physical Hasimir again while older exchange history stays unchanged. Hero replacement inspector is private; no overflow/browser errors. Earlier Cunning/purchase controls remain bounded evidence, not full acceptance.",evidence:['components/nexus-cards.tsx', 'components/nexus-traitors.tsx', 'components/nexus-tleilaxu.tsx', 'components/nexus-suboids.tsx', 'components/nexus-advisors.tsx', 'components/nexus-sardaukar.tsx', 'components/choam-power-cost.tsx', 'components/moritani-terror.tsx', 'components/nexus-moritani-betrayal.tsx', 'components/nexus-ecaz-betrayal.tsx', 'components/nexus-ecaz-inquiry.tsx', 'components/nexus-ecaz-duke.tsx', 'components/nexus-richese-betrayal.tsx', 'components/game-table.tsx', 'components/nexus-tleilaxu-revival.tsx', 'components/battle-preparation.tsx', 'components/nexus-fremen-revival.tsx','components/nexus-emperor-payment.tsx', 'components/nexus-emperor-secret-ally.tsx', "components/nexus-emperor-seller-purchase.tsx", "components/nexus-emperor-ambassador-purchase.tsx", "components/richese-special-karama.tsx"]},
|
||||
{area:"AI",status:'Partial',detail:"All four profiles legally complete the actual augmented-hand return, retaining the original parent; in this position each keeps Hasimir rather than following the scripted old-card return. All four also Ready through original owned Mentat initialization before automatic Hero draw. Existing other module adapters remain; strategic AI and calibration are deferred.",evidence:['game/nexus-card-options.ts', 'game/nexus-traitor-options.ts', 'game/nexus-tleilaxu-options.ts', 'game/nexus-suboid-options.ts', 'game/nexus-advisor-options.ts', 'game/nexus-sardaukar-options.ts', 'game/choam-power-options.ts', 'game/nexus-moritani-options.ts', 'game/nexus-moritani-betrayal-options.ts', 'game/nexus-ecaz-betrayal-options.ts', 'game/nexus-ecaz-inquiry-options.ts', 'game/nexus-ecaz-duke-options.ts', 'game/nexus-richese-options.ts', 'game/bot-nexus-richese-betrayal.ts', 'game/nexus-guild-cunning-options.ts', 'game/bots.ts', 'game/nexus-fremen-revival-options.ts','game/nexus-emperor-payment.ts', 'game/nexus-emperor-secret-ally-options.ts']},
|
||||
{area:"Documentation",status:'Partial',detail:"Permanent victim markers, live Traitor custody and historical replacement references are distinct. Hero is a Traitor replacement, not a leader disc or native faction target. Sources/receipts keep their own optional removed zone; old absent formats and existing Loyalty exclusion remain. No past-save authenticity, new numeric ruling or profile/public gate widening is claimed.",evidence:['docs/NEXUS_CARD_RULES.md', 'docs/NEXUS_ATREIDES_RULES.md', 'docs/NEXUS_HARKONNEN_RULES.md', 'docs/NEXUS_TLEILAXU_RULES.md', 'docs/NEXUS_IXIAN_CUNNING_RULES.md', 'docs/NEXUS_CUNNING_RUNTIME.md', 'docs/NEXUS_BENE_GESSERIT_RULES.md', 'docs/NEXUS_ADVISOR_RUNTIME.md', 'docs/NEXUS_EMPEROR_RULES.md', 'docs/NEXUS_SARDAUKAR_RUNTIME.md', 'docs/NEXUS_FREMEN_RULES.md', 'docs/NEXUS_ECAZ_RULES.md', 'docs/NEXUS_CHOAM_RULES.md', 'docs/NEXUS_CHOAM_RUNTIME.md', 'docs/NEXUS_MORITANI_RULES.md', 'docs/NEXUS_MORITANI_RUNTIME.md', 'docs/NEXUS_RICHESE_RUNTIME.md', 'docs/NEXUS_RICHESE_RULES.md', 'docs/NEXUS_GUILD_CUNNING_RUNTIME.md', 'docs/NEXUS_GUILD_RULES.md', "docs/NEXUS_EMPEROR_SECRET_ALLY_RUNTIME.md", "docs/RULE_DECISIONS.md", "docs/RICHESE_AMBASSADOR_RULES.md", "docs/RICHESE_AMBASSADOR_IMPLEMENTATION.md", "docs/RICHESE_ACQUISITION_RULES.md", "docs/DUKE_VIDAL_RULES.md", "docs/ECAZ_DUKE_ACQUISITION.md", "docs/ECAZ_REVIVAL_RULES.md"]},
|
||||
{area:"Verification",status:'Partial',detail:"Current affected15-file134/134, eleven original API/policy cases and three actual390px journeys pass: physical Hero/next Storm, historical replacement return/resumed placement, then the same physical draw after a later second marker. Adjacent old fixtures now consume original borrowed Voice before native Prescience/plans. Earlier Cunning/native evidence stays historical; no saved/deployed or full-module assurance claim.",evidence:['tests/mixed-nexus-modules-runtime.test.ts', 'tests/paired-e3-nexus-modules-runtime.test.ts', 'tests/sample-custody.test.ts', 'tests/ambassador-terror-overlap-engine.test.ts', 'tests/single-nexus-e1-runtime.test.ts', 'tests/single-nexus-e2-runtime.test.ts', 'tests/e3-nexus-ecaz-runtime.test.ts', 'tests/e3-nexus-moritani-runtime.test.ts', 'tests/homeworld-classic-nexus-skills-runtime.test.ts', 'tests/homeworld-classic-discovery-nexus-runtime.test.ts', 'tests/nexus-cards.test.ts', 'tests/nexus-card-engine.test.ts', 'tests/nexus-fremen-cunning.test.ts', 'tests/nexus-fremen-cunning-recovery.test.ts', 'tests/nexus-fremen-cunning-summon.test.ts', 'tests/nexus-fremen-cunning-summon-recovery.test.ts', 'tests/nexus-ecaz-betrayal-quotes.test.ts', 'tests/nexus-ecaz-betrayal.test.ts', 'tests/nexus-ecaz-betrayal-recovery.test.ts', 'tests/nexus-ecaz-inquiry.test.ts', 'tests/nexus-ecaz-duke-quote.test.ts', 'tests/nexus-ecaz-duke-engine.test.ts', 'tests/nexus-ecaz-duke-recovery.test.ts', 'tests/nexus-traitor-recovery.test.ts', 'tests/nexus-face-dancer-engine.test.ts', 'tests/nexus-suboids-engine.test.ts', 'tests/normal-free-support.test.ts', 'tests/nexus-suboid-controls.test.ts', 'tests/nexus-advisor-controls.test.ts', 'tests/nexus-advisor-bots.test.ts', 'tests/nexus-sardaukar-controls.test.ts', 'tests/nexus-sardaukar-bots.test.ts', 'tests/nexus-choam-controls.test.ts', 'tests/nexus-choam-bots.test.ts', 'tests/nexus-moritani-controls.test.ts', 'tests/nexus-moritani-bots.test.ts', 'tests/nexus-moritani-betrayal.test.ts', 'tests/nexus-richese-controls.test.ts', 'tests/nexus-richese-bots.test.ts', 'tests/nexus-richese-betrayal-engine.test.ts', 'tests/nexus-richese-betrayal-recovery.test.ts', 'tests/nexus-guild-cunning-controls.test.ts', 'tests/nexus-guild-cunning-bots.test.ts', 'tests/nexus-module-payments-runtime.test.ts', 'tests/nexus-module-battles-runtime.test.ts', 'tests/paired-ix-nexus-modules-runtime.test.ts', 'tests/paired-choam-nexus-modules-runtime.test.ts', 'tests/classic-nexus-skills-payments-runtime.test.ts', 'tests/classic-nexus-skills-battles-runtime.test.ts', 'tests/nexus-skills-modules-payments-runtime.test.ts', 'tests/nexus-skills-modules-battles-runtime.test.ts', 'tests/paired-ix-nexus-skills-modules-runtime.test.ts', 'tests/paired-choam-nexus-skills-modules-runtime.test.ts', 'tests/ecaz-nexus-skills-modules-runtime.test.ts', 'tests/moritani-nexus-skills-modules-runtime.test.ts', 'docs/NEXUS_CARD_RULES.md', 'tests/nexus-tleilaxu-revival.test.ts', 'tests/fixture-nexus-tleilaxu-secret-ally.ts', 'tests/nexus-tleilaxu-secret-ally-runtime.test.ts', 'tests/nexus-borrowed-voice.test.ts', 'tests/fixture-nexus-borrowed-voice.ts', 'tests/nexus-borrowed-voice-runtime.test.ts', 'tests/nexus-fremen-protection.test.ts', 'tests/fixture-nexus-fremen-protection.ts', 'tests/nexus-fremen-protection-runtime.test.ts', 'tests/fixture-stronghold-factions.ts', 'tests/fixture-nexus-advisor-fresh.ts', 'tests/nexus-advisor-fresh-runtime.test.ts', 'tests/fixture-nexus-advisor-storm.ts', 'tests/nexus-advisor-storm-runtime.test.ts', 'docs/NEXUS_ADVISOR_RUNTIME.md', 'tests/nexus-fremen-free-quota.test.ts', 'tests/fixture-nexus-fremen-free-quota.ts', 'tests/nexus-fremen-free-quota-runtime.test.ts', 'tests/nexus-fremen-revival.test.ts','tests/nexus-emperor-payment.test.ts','tests/fixture-nexus-emperor-payment.ts','tests/nexus-emperor-payment-runtime.test.ts','docs/NEXUS_EMPEROR_RULES.md', 'tests/nexus-emperor-extra-source.test.ts', 'tests/nexus-emperor-extra-continuation.test.ts', 'tests/fixture-nexus-emperor-extra.ts', 'tests/nexus-emperor-extra-runtime.test.ts', 'tests/fixture-single-nexus-e1.ts', 'docs/NEXUS_EMPEROR_SECRET_ALLY_RUNTIME.md', "tests/fixture-nexus-emperor-seller.ts", "tests/nexus-emperor-seller-purchase.test.ts", "tests/nexus-emperor-seller-runtime.test.ts", "tests/fixture-nexus-emperor-ambassador.ts", "tests/nexus-emperor-ambassador-purchase.test.ts", "tests/nexus-emperor-ambassador-runtime.test.ts", "tests/fixture-nexus-emperor-special.ts", "tests/nexus-emperor-special-purchase.test.ts", "tests/nexus-emperor-special-runtime.test.ts", "tests/karama-intents.test.ts", "tests/fixture-nexus-emperor-bank.ts", "tests/nexus-emperor-bank-profile.test.ts", "tests/nexus-emperor-bank-runtime.test.ts", "tests/duke-captured-custody.test.ts", "tests/nexus-ecaz-duke-captured.test.ts", "tests/fixture-nexus-duke-capture.ts", "tests/nexus-duke-capture-runtime.test.ts", "tests/nexus-duke-timing-runtime.test.ts"]},
|
||||
{area:"Implementation",status:'Partial',detail:"Physical Traitor roles, permanent markers, optional-zone receipts and legal recycling remain integrated. Native expansion/Nexus rate cancellation now covers reserve/cross/return. Cunning reserve receipts bind the temporary rate event and settled price; unaffordable release retains only the second allowance. Both validators reuse source-aware shipment availability instead of clearing original shipped history. Remaining physical-module rate compositions and full acceptance stay open.",evidence:['game/nexus-cards.ts', 'game/nexus-card-phase.ts', 'game/nexus-traitor-exchange.ts', 'game/traitor-declarations.ts', 'game/nexus-face-dancers.ts', 'game/nexus-suboids.ts', 'game/nexus-advisors.ts', 'game/nexus-sardaukar-options.ts', 'game/nexus-fremen-revival.ts', 'game/nexus-fremen-cunning.ts', 'game/nexus-ecaz-betrayal.ts', 'game/nexus-ecaz-inquiry.ts', 'game/nexus-ecaz-duke.ts', 'game/duke-vidal.ts', 'game/nexus-emperor-secret-ally.ts', 'game/choam-power-options.ts', 'game/nexus-moritani-options.ts', 'game/nexus-moritani-betrayal.ts', 'game/nexus-richese-options.ts', 'game/nexus-richese-betrayal.ts', 'game/nexus-guild-cunning-options.ts', 'game/nexus-guild-secret-ally-options.ts', 'game/nexus-module-profile.ts', 'game/engine.ts', 'game/nexus-tleilaxu-revival.ts', 'game/nexus-borrowed-voice.ts', 'game/combat-response-quote.ts', 'game/karama-context.ts', 'game/nexus-fremen-protection.ts', 'game/admin-seat-ai-shape.ts', 'game/richese-cancellation.ts', 'game/bot-mobility.ts', 'game/planetologist-movement.ts', 'game/revival.ts', 'game/nexus-fremen-revival-options.ts','game/nexus-emperor-payment.ts', 'game/nexus-emperor-secret-ally.ts', 'game/revival-resume.ts', 'game/revival-cancellation.ts', 'game/homeworld-revival-deployment.ts', 'game/homeworld-revival-return.ts', "game/nexus-emperor-purchase.ts", "game/auction-continuation-quote.ts", "game/nexus-emperor-purchase.ts", "game/ambassador-phase.ts", "game/ambassador-resume.ts", "game/battle-aftermath-quote.ts", "game/ecaz-duke-acquisition.ts", "game/ecaz-duke-revival.ts", "game/nexus-ecaz-duke-options.ts", "game/nexus-play-boundary.ts"]},
|
||||
{area:"Player controls",status:'Partial',detail:"Earlier physical Hero and historical Traitor-return/recycling controls retain source-bound proof. Three current390px journeys exercise native full-price cancellation, unaffordable withdrawal/full-price replacement and Cunning reserve repricing through Finish Guild turn. Original groups, paid first shipment and no ordinary extra movement remain; no overflow/browser errors. The Cunning scene uses the explicitly controlled existing fixture, not the action-only native producer.",evidence:['components/nexus-cards.tsx', 'components/nexus-traitors.tsx', 'components/nexus-tleilaxu.tsx', 'components/nexus-suboids.tsx', 'components/nexus-advisors.tsx', 'components/nexus-sardaukar.tsx', 'components/choam-power-cost.tsx', 'components/moritani-terror.tsx', 'components/nexus-moritani-betrayal.tsx', 'components/nexus-ecaz-betrayal.tsx', 'components/nexus-ecaz-inquiry.tsx', 'components/nexus-ecaz-duke.tsx', 'components/nexus-richese-betrayal.tsx', 'components/game-table.tsx', 'components/nexus-tleilaxu-revival.tsx', 'components/battle-preparation.tsx', 'components/nexus-fremen-revival.tsx','components/nexus-emperor-payment.tsx', 'components/nexus-emperor-secret-ally.tsx', "components/nexus-emperor-seller-purchase.tsx", "components/nexus-emperor-ambassador-purchase.tsx", "components/richese-special-karama.tsx"]},
|
||||
{area:"AI",status:'Partial',detail:"All four actual owner policies legally pass the new native expansion/Nexus rate response, pay rounded two for three and reach the original Ambassador offer; none cancels in that position. Existing Cunning bots and earlier Hero/Traitor-return participation remain covered. Human cancellation/retained-fighter branches are distinct proof. Strategy and calibration remain deferred.",evidence:['game/nexus-card-options.ts', 'game/nexus-traitor-options.ts', 'game/nexus-tleilaxu-options.ts', 'game/nexus-suboid-options.ts', 'game/nexus-advisor-options.ts', 'game/nexus-sardaukar-options.ts', 'game/choam-power-options.ts', 'game/nexus-moritani-options.ts', 'game/nexus-moritani-betrayal-options.ts', 'game/nexus-ecaz-betrayal-options.ts', 'game/nexus-ecaz-inquiry-options.ts', 'game/nexus-ecaz-duke-options.ts', 'game/nexus-richese-options.ts', 'game/bot-nexus-richese-betrayal.ts', 'game/nexus-guild-cunning-options.ts', 'game/bots.ts', 'game/nexus-fremen-revival-options.ts','game/nexus-emperor-payment.ts', 'game/nexus-emperor-secret-ally-options.ts']},
|
||||
{area:"Documentation",status:'Partial',detail:"Physical Hero, permanent victims and historical references stay distinct. Native rate admission and Cunning receipt transitions are documented separately from income and transport permission. Existing full-price return and unaffordable replacement policies remain provisional; no new publisher priority or numerical ruling. Homeworlds, Skills, Discovery, Tech and Stronghold rate combinations and public gates remain separate.",evidence:['docs/NEXUS_CARD_RULES.md', 'docs/NEXUS_ATREIDES_RULES.md', 'docs/NEXUS_HARKONNEN_RULES.md', 'docs/NEXUS_TLEILAXU_RULES.md', 'docs/NEXUS_IXIAN_CUNNING_RULES.md', 'docs/NEXUS_CUNNING_RUNTIME.md', 'docs/NEXUS_BENE_GESSERIT_RULES.md', 'docs/NEXUS_ADVISOR_RUNTIME.md', 'docs/NEXUS_EMPEROR_RULES.md', 'docs/NEXUS_SARDAUKAR_RUNTIME.md', 'docs/NEXUS_FREMEN_RULES.md', 'docs/NEXUS_ECAZ_RULES.md', 'docs/NEXUS_CHOAM_RULES.md', 'docs/NEXUS_CHOAM_RUNTIME.md', 'docs/NEXUS_MORITANI_RULES.md', 'docs/NEXUS_MORITANI_RUNTIME.md', 'docs/NEXUS_RICHESE_RUNTIME.md', 'docs/NEXUS_RICHESE_RULES.md', 'docs/NEXUS_GUILD_CUNNING_RUNTIME.md', 'docs/NEXUS_GUILD_RULES.md', "docs/NEXUS_EMPEROR_SECRET_ALLY_RUNTIME.md", "docs/RULE_DECISIONS.md", "docs/RICHESE_AMBASSADOR_RULES.md", "docs/RICHESE_AMBASSADOR_IMPLEMENTATION.md", "docs/RICHESE_ACQUISITION_RULES.md", "docs/DUKE_VIDAL_RULES.md", "docs/ECAZ_DUKE_ACQUISITION.md", "docs/ECAZ_REVIVAL_RULES.md"]},
|
||||
{area:"Verification",status:'Partial',detail:"Current affected nine-file101/101 and five action-only original API/policy paths pass. Six controlled Cunning reserve/cross cases cover allow/cancel/unaffordable replacement without reopening the first turn. Three actual390px journeys prove full price, no-debt withdrawal/replacement and Cunning turn completion. Earlier134/134 Hero/Traitor lifecycle evidence remains historical. No saved/deployed or full-module assurance claim.",evidence:['tests/mixed-nexus-modules-runtime.test.ts', 'tests/paired-e3-nexus-modules-runtime.test.ts', 'tests/sample-custody.test.ts', 'tests/ambassador-terror-overlap-engine.test.ts', 'tests/single-nexus-e1-runtime.test.ts', 'tests/single-nexus-e2-runtime.test.ts', 'tests/e3-nexus-ecaz-runtime.test.ts', 'tests/e3-nexus-moritani-runtime.test.ts', 'tests/homeworld-classic-nexus-skills-runtime.test.ts', 'tests/homeworld-classic-discovery-nexus-runtime.test.ts', 'tests/nexus-cards.test.ts', 'tests/nexus-card-engine.test.ts', 'tests/nexus-fremen-cunning.test.ts', 'tests/nexus-fremen-cunning-recovery.test.ts', 'tests/nexus-fremen-cunning-summon.test.ts', 'tests/nexus-fremen-cunning-summon-recovery.test.ts', 'tests/nexus-ecaz-betrayal-quotes.test.ts', 'tests/nexus-ecaz-betrayal.test.ts', 'tests/nexus-ecaz-betrayal-recovery.test.ts', 'tests/nexus-ecaz-inquiry.test.ts', 'tests/nexus-ecaz-duke-quote.test.ts', 'tests/nexus-ecaz-duke-engine.test.ts', 'tests/nexus-ecaz-duke-recovery.test.ts', 'tests/nexus-traitor-recovery.test.ts', 'tests/nexus-face-dancer-engine.test.ts', 'tests/nexus-suboids-engine.test.ts', 'tests/normal-free-support.test.ts', 'tests/nexus-suboid-controls.test.ts', 'tests/nexus-advisor-controls.test.ts', 'tests/nexus-advisor-bots.test.ts', 'tests/nexus-sardaukar-controls.test.ts', 'tests/nexus-sardaukar-bots.test.ts', 'tests/nexus-choam-controls.test.ts', 'tests/nexus-choam-bots.test.ts', 'tests/nexus-moritani-controls.test.ts', 'tests/nexus-moritani-bots.test.ts', 'tests/nexus-moritani-betrayal.test.ts', 'tests/nexus-richese-controls.test.ts', 'tests/nexus-richese-bots.test.ts', 'tests/nexus-richese-betrayal-engine.test.ts', 'tests/nexus-richese-betrayal-recovery.test.ts', 'tests/nexus-guild-cunning-controls.test.ts', 'tests/native-guild-rate-karama.test.ts', 'tests/nexus-guild-cunning-engine.test.ts', 'tests/nexus-guild-cunning-bots.test.ts', 'tests/nexus-module-payments-runtime.test.ts', 'tests/nexus-module-battles-runtime.test.ts', 'tests/paired-ix-nexus-modules-runtime.test.ts', 'tests/paired-choam-nexus-modules-runtime.test.ts', 'tests/classic-nexus-skills-payments-runtime.test.ts', 'tests/classic-nexus-skills-battles-runtime.test.ts', 'tests/nexus-skills-modules-payments-runtime.test.ts', 'tests/nexus-skills-modules-battles-runtime.test.ts', 'tests/paired-ix-nexus-skills-modules-runtime.test.ts', 'tests/paired-choam-nexus-skills-modules-runtime.test.ts', 'tests/ecaz-nexus-skills-modules-runtime.test.ts', 'tests/moritani-nexus-skills-modules-runtime.test.ts', 'docs/NEXUS_CARD_RULES.md', 'tests/nexus-tleilaxu-revival.test.ts', 'tests/fixture-nexus-tleilaxu-secret-ally.ts', 'tests/nexus-tleilaxu-secret-ally-runtime.test.ts', 'tests/nexus-borrowed-voice.test.ts', 'tests/fixture-nexus-borrowed-voice.ts', 'tests/nexus-borrowed-voice-runtime.test.ts', 'tests/nexus-fremen-protection.test.ts', 'tests/fixture-nexus-fremen-protection.ts', 'tests/nexus-fremen-protection-runtime.test.ts', 'tests/fixture-stronghold-factions.ts', 'tests/fixture-nexus-advisor-fresh.ts', 'tests/nexus-advisor-fresh-runtime.test.ts', 'tests/fixture-nexus-advisor-storm.ts', 'tests/nexus-advisor-storm-runtime.test.ts', 'docs/NEXUS_ADVISOR_RUNTIME.md', 'tests/nexus-fremen-free-quota.test.ts', 'tests/fixture-nexus-fremen-free-quota.ts', 'tests/nexus-fremen-free-quota-runtime.test.ts', 'tests/nexus-fremen-revival.test.ts','tests/nexus-emperor-payment.test.ts','tests/fixture-nexus-emperor-payment.ts','tests/nexus-emperor-payment-runtime.test.ts','docs/NEXUS_EMPEROR_RULES.md', 'tests/nexus-emperor-extra-source.test.ts', 'tests/nexus-emperor-extra-continuation.test.ts', 'tests/fixture-nexus-emperor-extra.ts', 'tests/nexus-emperor-extra-runtime.test.ts', 'tests/fixture-single-nexus-e1.ts', 'docs/NEXUS_EMPEROR_SECRET_ALLY_RUNTIME.md', "tests/fixture-nexus-emperor-seller.ts", "tests/nexus-emperor-seller-purchase.test.ts", "tests/nexus-emperor-seller-runtime.test.ts", "tests/fixture-nexus-emperor-ambassador.ts", "tests/nexus-emperor-ambassador-purchase.test.ts", "tests/nexus-emperor-ambassador-runtime.test.ts", "tests/fixture-nexus-emperor-special.ts", "tests/nexus-emperor-special-purchase.test.ts", "tests/nexus-emperor-special-runtime.test.ts", "tests/karama-intents.test.ts", "tests/fixture-nexus-emperor-bank.ts", "tests/nexus-emperor-bank-profile.test.ts", "tests/nexus-emperor-bank-runtime.test.ts", "tests/duke-captured-custody.test.ts", "tests/nexus-ecaz-duke-captured.test.ts", "tests/fixture-nexus-duke-capture.ts", "tests/nexus-duke-capture-runtime.test.ts", "Line truncated
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user