Integrate Smuggler companion with owned Richese No-Field

Connect the GF9 FAQ combination: one free physical reserve force accompanies an owned concealed No-Field at its unchanged one-marker price. Preserve zero/three/five token values, actual supply at later reveal, optional human choice and all four legal AI paths. Genuine CHOAM & Richese Leader Skills development setup adds the two sourced battle cards without duplicating their Ix identities. Public mode and publication gates stay closed; allied and remaining combined routes are unfinished.

Bind the private declaration across initial No-Field cancellation and later Advanced Guild interception, including saved interruptions. Validate before projection/actions/normalization, hide the internal proof, reject altered declarations immutably, and withdraw the companion once only on successful commitment. Independent rules/privacy/persistence review found no blocker. Preserve other audit setup gates despite expanded deck assembly. Repair the existing randomized recovery test with a genuine seeded Rihani offer and explicit human choice, replacing an inappropriate AI-policy call on a human seat. Initial Karama and later Guild stop retain their distinct existing opportunity outcomes.

Validation: 72 focused regressions plus 10 deck tests; typecheck, lint, 4520 offline tests, production build and 43 HTTP tests passed. SQLite restart, concurrent allowance/cancellation and exact physical custody passed. Browser genuine assignment, private token selection, opt-in, one-spice shipment, refresh, five-force reveal and final refresh preserved six physical Arrakeen forces, 14 reserves, zero Tanks, four spice, Crysknife and Soo-Soo Sook. Genuine four-profile Basic/Advanced games completed in 77/116 actions with 3/4 JSON restores and no rejected candidates; Advanced exercised one companion shipment and later reveal.

After the outage the existing server was healthy. Preserved all 529 opening rooms and original seat/recovery records (563 after QA/HTTP). SQLite integrity and foreign keys passed. No restart, database reset or automation.

Verified source tree: c2aee4138bcb46a05814a340d62eadace3470247ca620844eb0375e78ea4d6c4
This commit is contained in:
Quintine committed 2026-09-13 21:37:50 +10:00
1 parent bf8036dfc1
commit 788453e07e
20 files changed
+1213 -51

No files matched your search

+12 -1
View File
@@ -109,9 +109,20 @@ void test('the Ix expansion has fourteen distinct cards and combines into a fort
baseDeck().some((c) => c.name === 'Basilia Weapon'),
false,
);
for (const expansion of ['choam', 'ecaz', 'unknown'])
for (const expansion of ['ecaz', 'unknown'])
assert.throws(() => treacheryDeck([expansion]), /not implemented/);
});
void test('CHOAM & Richese adds or replaces the same two battle cards without duplicating physical custody', () => {
for (const expansions of [['choam'], ['ix', 'choam'], ['choam', 'ix']]) {
const cards = treacheryDeck(expansions);
assert.equal(cards.length, expansions.includes('ix') ? 47 : 35);
assert.equal(new Set(cards.map(c => c.id)).size, cards.length);
assert.equal(cards.filter(c => c.kind === 'poisonTooth').length, 1);
assert.equal(cards.filter(c => c.kind === 'artillery').length, 1);
assert.equal(cards.filter(c => c.effect === 'karama').length, 2);
assert.equal(cards.find(c => c.kind === 'poisonTooth')!.id, 'ix-poison-tooth');
}
});
void test('deck factories return independent physical cards and retain the earlier Ix identifiers', () => {
const a = treacheryDeck(['ix']),
b = treacheryDeck(['ix']);