Connect typed Homeworld custody, transport, battle, income, revival and Caladan reinforcement flows with private multiplayer recovery and controls. Preserve the optimized test workflow and keep unfinished rules modes gated. Verified with 3682 offline tests, typecheck, lint, production build and 40 HTTP tests; existing saved games remain unchanged.
15 KiB
Homeworld charity and revival integration audit
Read-only inspection, 9 September 2026. This document describes the source at inspection, not a completed implementation or a full Homeworld rules claim. Parent integration may supersede individual line numbers. No runtime or test files were changed for this audit.
Verified scope and existing foundation
HOMEWORLD_RULES.md, based on the GF9 Ecaz/Moritani rulebook pp.9–10 and FAQ p.16, records a low native Homeworld's +1 free-revival rate and +1 bank-paid spice when collecting CHOAM Charity. Salusa supplies neither bonus. Karama cannot cancel Homeworld advantages or penalties. Tleilax's low face specifically conditions its loss of other factions' free-revival income on starting Revival at low population. These are different timing contracts.
homeworld-population.ts:23–59 already derives public native population and potential bonuses from validated physical custody. It excludes visitors and Salusa's bonus, counts Salusa Sardaukar separately, and performs no payment. homeworld-game.ts validates physical inventory before public action, normalization and projection. Native reserve deposits now route revived Emperor normal forces to Kaitain and Sardaukar to Salusa. This physical foundation does not yet apply the economic benefits inspected below.
Population currently reflects physical counters, not the future occupation rule that can retain a low penalty. Reuse it for the released native population domain; do not claim that this completes occupied Homeworld effects.
Charity: split the actual receipt
| Current producer/consumer | Required integration |
|---|---|
charity.ts:17 charityAmount |
Currently returns one ordinary amount, including BG's advanced allowance and Inflation. Keep ordinary eligibility separate from a module bonus: adding one before the wealth threshold would create charity for ordinarily ineligible wealthy players. |
charity.ts:29 charityPayer |
Determines the ordinary CHOAM payer only. Low-population bonus is from the bank even when CHOAM funds ordinary charity. |
engine.ts:16345 charity action |
Claims once via charityTurn, then either pays directly or opens wealthy BG's bgCharity. Produce explicit ordinary and bank portions; commit each exactly once. Do not open a new Karama response for the Homeworld portion. |
engine.ts:9251 payCharity |
Currently charges its entire argument to CHOAM. Passing a combined total would overcharge CHOAM and incorrectly require it to fund the bank bonus. Check CHOAM solvency against only its ordinary portion, and check recipient total safely before mutation. Preserve one Production-token trigger per actual collection. |
engine.ts:12782 BG response completion |
Currently canceled means no payment. Retain the ordinary response and an explicit pending funding split. E1's BG cancellation says no Charity: the conditional bank bonus then has no qualifying claim. Pay both portions only on the supported completion, with no replay on cancellation, counter-canceled BG conversion, refresh or nested restoration. This is not a separately cancelable Homeworld power. |
terminal-cancellation.ts:172, karama-context.ts:150 |
Existing BG terminal quote validates current Advanced claim, owner and safe amount; the source signature contains ordinary response data but no standalone charity receipt. If a new receipt is retained, validate its owner/turn/source and source-bound amount before both initial card cost and paid conversion allowance. Avoid freezing unrelated balances or response-pass lists. |
engine.ts:18144 view; game-table.tsx:3083–3107; bots.ts:2466 |
Project ordinary/bank/total amounts from the same quote. Current UI says all charity comes from one payer; it must describe the bank portion. Bots already use projected positive amount/claim status, so keep that shared surface authoritative. |
The existing CHOAM phase-opening collection (engine.ts:9162) is 2 × seated factions × Inflation multiplier. Do not increase this allocation merely because a claimant's bank bonus exists.
The independent source reviewer confirmed E1's BG Karama row says no Charity, so its conditional Homeworld addition has no qualifying claim. E2 p.8 changes CHOAM Charity itself: the supported composition applies Inflation to the eligible total, including the bank addition, while retaining separate funding sources. No explicit Homeworld/Inflation cross-example was located; label this composition accordingly. Preserve the once-per-turn claim semantics and encode this ordering explicitly rather than letting a single-amount representation decide it.
Normal free revival: shared rate, frozen request, ordinary limits
revival.ts:42–91 provides the shared free remaining, force price and maximum request functions. Their present contexts do not include Homeworld custody. Introduce a public native-rate input or widen their declared context to include validated Homeworld state and public typed reserves. Preserve source provenance: native base/Fremen-alliance free rate, Homeworld addition, ordinary usage and any named restriction.
A low Homeworld increases the free rate, not a general paid-revival limit, global elite limit or available Tanks. The subsequent source audit confirmed E3's explicit four-free Fremen entitlement; the implementation uses the greater of ordinary capacity and current free rate to make that entitlement usable. forceRevivalRemaining also uses free remaining to enforce Fremen's no-paid-revival rule when no Tleilaxu is seated; it must receive the same new rate. Keep Emperor-funded extra returns, Ghola and leader revival separate.
Named prohibition: revivalRules.freeBlocked is CHOAM's La La La, set at engine.ts:12476, not a Karama cancellation flag. The independent source reviewer confirmed E2 p.7 prevents taking Free Revival; direct composition blocks the whole free rate, including the Homeworld addition. Homeworld Karama immunity provides no exception. Likewise, prevention of the entire normal revival is distinct from cancellation of an ordinary price advantage.
| Consumer | Exact concern |
|---|---|
engine.ts:16704 revive declaration |
Use the revised free quote for affordability, chosen free cyborg allocation and frozen PendingRevival.free/normalCost/cost. Sample one batch before depositing forces: that batch can itself raise the Homeworld to high population. |
revival-resume.ts:17 context and :105–136 frozen-price validation |
Add the public state needed for current allowance checks, while preserving a valid frozen request's free/paid split. Existing arithmetic verifies paid physical counts and Ix free cyborg attribution. A new provenance field, if used, requires runtime validation; arbitrary extra free units must not pass by supplying a self-consistent lower price. |
revival-cancellation.ts:22, :280–307 |
CHOAM benefit denial and discount cancellation reprice through forceRevivalQuote. Pass the Homeworld context to these calls, and preserve the noncancelable module source while removing only the named faction price benefit. Do not add module cancellation to their check queue. |
engine.ts:11942 beginRevival and reactive La La La |
A request with any applicable free component still enters the existing CHOAM decision. Denial of La La La resumes the unchanged request through quoteRevivalResume; successful La La La retains its named prohibition. |
engine.ts:11879 finishRevival |
Retain existing native typed deposit, Tanks reduction, ordinary/free usage, elite-per-turn usage and Axlotl quote. Avoid applying the bonus again at settlement or after a frame drain. |
engine.ts:18205 view; game-table.tsx:3230–3378; bots.ts:2644–2665 |
All consume free remaining and pricing. Use the shared quote, explain the module addition, and keep freeBlocked text accurate. No UI-only discount. |
The current usage calculation subtracts total ordinary p.revived, while freeForcesRevived separately records known actual free usage. Do not change this legacy accounting incidentally. Test repeated partial revivals around a population threshold and record the selected timing contract. Recruits' verified doubling of the current rate must use the same source when that card's broader integration is addressed; this audit does not activate it.
Tleilax: persist the phase-start condition
beginPhase at engine.ts:9176 initializes Revival rules and usage. Add one public, turn-bound phase-start receipt identifying the Tleilaxu seat and whether its native Tleilax was low then. A later ordinary revival or Ghola can increase population; neither refresh nor subsequent income may recompute the original starting condition. Reject malformed/stale new receipts and define a deliberate legacy policy rather than inventing historical population from the current board.
openPhase creates an Ix/Amal opening before beginPhase; the current ordinary opening permits Amal/pass, plus explicitly earlier card-transfer overlays. Those do not directly change reserves. Still bind the latch to the actual phase initialization once, preserve it through nested opening parents, and do not overwrite it during JSON recovery. Add it to any saved continuation signature whose next income depends on it.
There are two income producers, both needing one shared eligibility predicate:
revival-resume.ts:338–365quotes normal settlement's paid transfer plus the first free-revival reward, and emits a per-payerfreeIncomereceipt.engine.ts:11821 collectRevivalIncomehandles card/special routes including Ghola, with separatefreeandgholaflags.
Existing revivalFreeIncome[player] = turn only tracks whether a reward opportunity was consumed. It cannot encode Tleilax's starting population. Suppress only the source-supported other-faction free-revival reward. Preserve paid fees; do not blanket-disable revivalIncome, the Tleilaxu seat, or Ghola rewards because the current population is low. The source reviewer confirmed paid fees and the separate Ghola reward remain distinct from the specifically named other-faction Free Revival penalty; retain those routes rather than infer suppression from a boolean's name.
terminal-cancellation.ts:163 deliberately permits Ghola's revival-income response outside phase4. Keep that domain. viewGame hides income amounts from seats other than owner/recipient (engine.ts:18170); the new public phase-start condition does not authorize exposing private payment totals. The ordinaryCardDiscard signature already includes Homeworld custody; any additional phase-start receipt used by its detached income suffix must also be bound.
Bounded verification before release
Test base/ix genuine setup with conserved low/high custody; Basic and Advanced Emperor with Salusa excluded; ordinary wealthy/poor eligibility; CHOAM-funded versus bank portions; BG printed/converted cancellation with duplicate final allowance; Inflation boundary selected from source; and JSON recovery preserving one claim and one token trigger.
For revival, test a free batch crossing high threshold, later partial request, paid/free mixed Ix typing, Fremen cap, La La La allowed/canceled, discount cancellation, physical deposit, and no duplicate usage/fee/income. Test Tleilax low-at-start then raised versus high-at-start then lowered, paid fees preserved, other-faction reward suppressed exactly as sourced, Ghola distinguished, nested saved parents, and private amount projection.
No broad test suite was run for this read-only document. These are required integration checks, not reported passing coverage.