Support typed Advanced Truthtrance shipment commitments

Extend the existing reserve-shipment promise pipeline to base Advanced
games without Guild or optional modules. Share scope between parser, save
validation and UI. Reuse canonical Ghola normal/elite revival eligibility
and retain live BG conversion responses while proving conditional private
feasibility. Hide future-price guidance until pending responses finish.
Show exact Sardaukar/Fedaykin allocation in private executable steps.

Validation: types, lint and all 4,192 offline tests pass; production build
and all 40 HTTP tests pass. 41 focused shipment tests include 15 new cases
covering genuine Advanced setup, all five non-Guild factions and four bot
profiles, typed Ghola quota, BG allowance/cancellation/alternatives,
private views, saved continuations and production SQLite duplicate races.
Independent review found and resolved optional-module scope and pending
price-guidance issues. Browser rooms EUZZ8D4M and GWNCVCAP verified an AI No
route and human Yes with four-force/one-Sardaukar Ghola then six-force
shipment. Phone settlement controls and refresh passed. Both existing
browser room hashes/versions preserved through HTTP tests; 30 rooms added.

Full source-bound report: 20260913-advanced-shipment-final; fingerprint
6c2f29d9b3e61bf6b9544ee3a95c47538abfb05e1c3b2ae9d0a603ef0cef38dd
Broad checks ran once after focused fixes/review. No full-game AI study
or complete Advanced mode acceptance is claimed; all existing release
gates and pending Guild settlement questions remain intact.
This commit is contained in:
Quintine committed 2026-09-13 11:08:29 +10:00
1 parent 6e26ba5daa
commit 32791ed5e2
14 files changed
+902 -38

No files matched your search

+37 -1
View File
@@ -1,5 +1,37 @@
import test from 'node:test';
import { shipmentPromiseModeSupported } from '../game/shipment-promises';
import assert from 'node:assert/strict';
void test('Advanced shipment scope excludes separately enabled optional modules and preserves existing Basic tech scope', () => {
const base = {
advanced: true,
expansions: [],
players: [{ faction: 'emperor' }, { faction: 'atreides' }],
};
assert.equal(shipmentPromiseModeSupported(base), true);
assert.equal(
shipmentPromiseModeSupported({
...base,
players: [...base.players, { faction: 'guild' }],
}),
false,
);
for (const option of [
'techTokens',
'strongholdCards',
'nexusCards',
'homeworlds',
])
assert.equal(
shipmentPromiseModeSupported({ ...base, [option]: {} }),
false,
option,
);
assert.equal(
shipmentPromiseModeSupported({ ...base, advanced: false, techTokens: {} }),
true,
);
});
import {
applyAction,
createGame,
@@ -441,7 +473,10 @@ void test('malformed questions and unsupported public scopes reject without disc
'territory',
]) {
const bad = structuredClone(g);
if (change === 'advanced') bad.advanced = true;
if (change === 'advanced') {
bad.advanced = true;
bad.players[2].faction = 'guild';
}
if (change === 'expansion') bad.expansions = ['ix'];
if (change === 'phase') bad.phase = 4;
if (change === 'spent') bad.players[1].shipped = true;
@@ -511,6 +546,7 @@ void test('saved malformed promise bindings reject before action or normalizatio
},
(g) => {
g.advanced = true;
g.players[2].faction = 'guild';
},
(g) => {
g.phase = 4;