Connect Leader Skill battle effects and private Rihani exchanges

Prototype Mentat/Bureaucrat score effects, automatic Sandmaster board spice, and Rihani inspection plus committed exchange. Preserve private views, physical custody, saved winner cleanup and captive/Suk sequencing. Remaining normal bands, missing skill families and combined modules remain gated.

Validation: 45 focused tests; typecheck, lint, 4465 offline tests, production build and 43 HTTP tests passed. Independent rules/privacy/persistence review completed. New isolated browser setup exercised inspection, draw, pending refresh, exchange and completed refresh. Two genuine four-profile Basic/Advanced samples completed without rejected candidates but did not trigger Rihani.

Preserved all 393 opening rooms and original seat/recovery rows (427 rooms after QA/HTTP). SQLite integrity and foreign keys passed. Server remained healthy after the reported outage; no restart or reset.

Verified source tree: c64ce9537269de94c0d785bc08b17346e826c5797352a636771e1dc6ce5e4859
This commit is contained in:
Quintine committed 2026-09-13 19:45:29 +10:00
1 parent af360c836b
commit 06f46c6f79
26 files changed
+1230 -122

No files matched your search

+17
View File
@@ -187,6 +187,23 @@ function play(
return card;
}
void test('Mentat and Bureaucrat change the winner at the score boundary without changing printed strength', () => {
const mentat = battle();
assert.equal(quoteBattleResolution(mentat).winner, 'a');
mentat.defender.leaderSkills = [{ skill: 'mentat', leader: mentat.defender.leader!.id, faceUp: false, captured: false }];
const boosted = quoteBattleResolution(mentat);
assert.equal(boosted.winner, 'd');
assert.deepEqual(boosted.scores, { attacker: 5, defender: 6 });
assert.deepEqual(boosted.leaderStrengths, { attacker: 3, defender: 2 });
const bureau = battle();
bureau.defender.leaderSkills = [{ skill: 'bureaucrat', leader: bureau.defender.leader!.id, faceUp: false, captured: false }];
bureau.attacker.occupiedStrongholds = 2;
const penalized = quoteBattleResolution(bureau);
assert.equal(penalized.winner, 'd');
assert.deepEqual(penalized.scores, { attacker: 3, defender: 4 });
assert.deepEqual(penalized.leaderStrengths, { attacker: 3, defender: 2 });
});
void test('battle quote adds only surviving skill receipts to scores while preserving printed strength and bounty', () => {
const input = battle();
const worthless = play(