diff --git a/docs/CURRENT_STATUS.md b/docs/CURRENT_STATUS.md index 3d0e7452..2fcc7b52 100644 --- a/docs/CURRENT_STATUS.md +++ b/docs/CURRENT_STATUS.md @@ -17,6 +17,22 @@ open mode gates. ## Current checkpoint and work +**Intermittent CI fixture — 29 October. Partial.** Run #65 failed when its +scripted Atreides all-reserve shipment was rejected; its old log did not record +the reason. Initial Storm losses followed by optional Revival can increase the +shipment size beyond the original spice funding. The HTTP fixture now declines +that optional Revival and Ghola through legal actions without changing stored +forces, currency or cards. One targeted integration run and quick type/lint +checks pass. This removes a plausible random failure path, not a proven root +cause or a guarantee of future CI success. The latest completed run #77 passed; +#80 was running and #82 queued when checked. [Fixture](../tests/richese-homeworld-marker-mixed-http.test.ts). + +**Next candidate — Sapho and shared arrival.** An Ecaz Ambassador and Moritani +Terror can both react to one entry in a provisional storm order. Sapho cannot +yet reorder that pair. A safe implementation needs a public pre-reaction order +window, preserved old overlap records and a Semuta continuation; no feature +is claimed complete by this scoping note. + **Truthtrance category questions — 29 October. Prototyped / Partial.** Recognized freeform current-fact questions now include weapon, defense and Worthless hand categories and selected subtypes. The table sees the primary-role diff --git a/tests/richese-homeworld-marker-mixed-http.test.ts b/tests/richese-homeworld-marker-mixed-http.test.ts index de1a94c0..c4125562 100644 --- a/tests/richese-homeworld-marker-mixed-http.test.ts +++ b/tests/richese-homeworld-marker-mixed-http.test.ts @@ -88,8 +88,23 @@ void test('authenticated mixed transfer moves a concealed marker and physical vi const local = structuredClone(own); const self = local.players.find(player => player.id === seat.id); assert.ok(self); self.bot = 'Easy'; // Client-side adapter only; authoritative seat stays human. + if (seat.id === hostSeat.id && self.hand) { + // The scenario needs Caladan empty until the marker leaves. Decline + // optional Ghola in this local action selector; the real hand stays + // unchanged and every submitted action remains server-validated. + self.hand = self.hand.filter(card => card.effect !== 'ghola'); + } const choices = botActions(local); - if (choices.length) { proposed = { cookie: seat.cookie, actor: seat.id, action: choices[0] }; break; } + if (choices.length) { + // Initial Storm can kill Atreides forces on Arrakeen. Reviving them + // before this scenario's first shipment adds reserves, while paid + // revival also consumes its exactly funded starting spice. Declining + // optional revival preserves the native empty-Caladan setup. + const action = seat.id === hostSeat.id && own.phase === 4 + ? choices.find(candidate => candidate.type === 'ready') ?? choices[0] + : choices[0]; + proposed = { cookie: seat.cookie, actor: seat.id, action }; break; + } } assert.ok(proposed, `No native continuation at ${currentOwner.status}/${currentOwner.phase}/${currentOwner.decision?.kind ?? 'no decision'}.`); if (view.response && !view.response.passed.includes(view.me)) proposed.action = { type: 'passResponse' };