Repair stale Semuta battle-frame recovery expectation
This commit is contained in:
1 parent
7ae0a9f7ae
commit
63e5f22607
2 files changed
+31
-4
No files matched your search
@@ -29,6 +29,19 @@ optional skill bands, combinations and public expansion starts remain open.
|
||||
Rules implementation continues; comprehensive assurance and administration
|
||||
remain deferred until all rules are implemented.
|
||||
|
||||
**Stale battle-frame recovery expectation repaired — 11 October.** The
|
||||
`authenticated clean Semuta producers claim once through restart and room CAS`
|
||||
case asserted the winner's cheap-hero frame as the first post-battle
|
||||
continuation. Actual native order is the mandatory battle batch
|
||||
(`battleResolved`/`battle:mandatory`, loser's used defense) followed by the
|
||||
winner's compulsory discard (`winnerMandatoryDiscard`/`battle:winnerMandatory`,
|
||||
the hero). The case now walks that real order, keeps its restart/room-CAS and
|
||||
single-claim assertions on the winner frame, and asserts the loser frame
|
||||
separately. Verified pre-existing: the same assertion failed at `5b3729e` in a
|
||||
clean worktree, so it was not a regression from this session's slices.
|
||||
`tests/semuta-recovery.test.ts` passes15/15; the affected offline rule union
|
||||
passes650/650 across60 files; types/lint pass.
|
||||
|
||||
**Semuta / printed native CHOAM cancellation cost — 11 October.**
|
||||
`karamaChoamWorthlessDiscard` reuses the original response-cost path and
|
||||
Worthless cancellation quote for five ordinary printed/Cunning powers.
|
||||
|
||||
@@ -448,14 +448,28 @@ void test('authenticated clean Semuta producers claim once through restart and r
|
||||
defense: nextDefense.id });
|
||||
mandatoryBattle = await act(1, { type: 'traitorCall', call: false });
|
||||
const heroOffer = await act(2, { type: 'traitorCall', call: false });
|
||||
assert.equal(heroOffer.pendingTreacheryDiscard?.continuation.kind, 'winnerMandatoryDiscard');
|
||||
// The winner's cheap hero and the loser's used defense form separate frames:
|
||||
// the mandatory battle batch settles first, then the winner's own compulsory
|
||||
// discard. The Semuta claim under test targets that second frame.
|
||||
assert.equal(heroOffer.pendingTreacheryDiscard?.continuation.kind, 'battleResolved');
|
||||
assert.equal(heroOffer.pendingTreacheryDiscard?.batch.cause, 'battle:mandatory');
|
||||
assert.equal(heroOffer.pendingTreacheryDiscard?.reaction?.stage, 'offer');
|
||||
assert.equal(heroOffer.discard.filter(card => card.id === hero.id).length, 1);
|
||||
assert.equal(heroOffer.discard.filter(card => card.id === nextDefense.id).length, 1);
|
||||
let heroFrame = heroOffer;
|
||||
{
|
||||
const mandatoryEvent = heroOffer.pendingTreacheryDiscard!.batch.event;
|
||||
for (const index of [2, 1, 0])
|
||||
heroFrame = await act(index, { type: 'semutaPass', event: mandatoryEvent });
|
||||
}
|
||||
assert.equal(heroFrame.pendingTreacheryDiscard?.continuation.kind, 'winnerMandatoryDiscard');
|
||||
assert.equal(heroFrame.pendingTreacheryDiscard?.batch.cause, 'battle:winnerMandatory');
|
||||
assert.equal(heroFrame.pendingTreacheryDiscard?.reaction?.stage, 'offer');
|
||||
assert.equal(heroFrame.discard.filter(card => card.id === hero.id).length, 1);
|
||||
await f.restart().continueRoomAutomatic(code, clock);
|
||||
assert.equal((await f.restart().readRoom(code)).version, heroOffer.version);
|
||||
assert.equal((await f.restart().readRoom(code)).version, heroFrame.version);
|
||||
assert.equal((await f.restart().readSeatView(code, auths[0])).semutaReaction?.canCommit, true);
|
||||
const heroClaim = await act(0, { type: 'semutaCommit',
|
||||
event: heroOffer.pendingTreacheryDiscard!.batch.event });
|
||||
event: heroFrame.pendingTreacheryDiscard!.batch.event });
|
||||
assert.equal(heroClaim.pendingTreacheryDiscard, null);
|
||||
assert.equal(heroClaim.decision?.kind, 'battleCards');
|
||||
assert.equal(seat(heroClaim, ids[1]).hand.some(card => card.id === nextWeapon.id), true);
|
||||
|
||||
Reference in new issue
Block a user