Chase the audit's leads: verify, implement, or reject

Every lead in AUDIT.md, traced to the running source and then settled.

Ceremonial Dagger DESTROYS the joker to its right at blind select
(card.lua:2945) and skips Eternals. The card says so; what it cannot say
is WHICH of your jokers is about to die. JCA.dagger_victim names it in
the tooltip -- "WILL DESTROY Baron at the next blind" -- while there is
still time to reorder, and stays quiet when the neighbour is Eternal.

Four jokers that scored 0 against all 150 now have partners, all verified
in card.lua rather than recalled:
* Burglar + Ramen: Ramen decays per discarded card and is DESTROYED at x1
  (SMODS.destroy_cards). Burglar zeroes discards, so it never decays and
  never dies. Same for Burglar + Green Joker, which is only punished by
  discarding.
* Trading Card + Erosion: Erosion pays per card MISSING from the deck,
  and Trading Card permanently destroys the card it discards.
* Chaos the Clown + Flash Card: a free reroll every shop, and a joker
  that grows per reroll. Both were inert.

Erosion is the mirror of card_gen, so it now clashes with every joker
that permanently adds a card: DNA, Marble, Certificate.

Rejected, with the reasoning recorded so nobody "fixes" it later:
Card Sharp and Supernova reward replaying a hand and Obelisk punishes it,
but neither destroys the other's precondition -- the player's hand choice
does. That is an opposed incentive, not an opposed effect. The clash list
only earns trust while every entry is mechanical.

The audit's own silent-check was wrong: it flagged Square Joker, which
has been paired with Four Fingers all along, and I duplicated that pair
before the suite caught it. Silence now means no tags AND no famous pair.

711 pass locally, 10 in-game.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-07-14 12:36:01 -07:00
parent 96a00d0d0c
commit 8ce5619273
5 changed files with 158 additions and 64 deletions
+22
View File
@@ -302,6 +302,28 @@ eq(copyable, false, 'and flags that vanilla will not copy it (blueprint_compat)'
local fine = field('j_blueprint', 'j_baron')
eq(select(2, JCA.copy_source(fine[1])), true, 'a copyable target reports as copyable')
--------------------------------------------------------------------------------
section('Engine: Ceremonial Dagger names its victim')
--------------------------------------------------------------------------------
-- It destroys the joker to its RIGHT at the next blind, permanently.
local dagger = field('j_baron', 'j_ceremonial', 'j_mime')
local victim, safe = JCA.dagger_victim(dagger[2])
eq(victim, dagger[3], 'it names the joker on its right as the victim')
eq(safe, false, 'and an ordinary joker is not safe from it')
field('j_baron', 'j_mime', 'j_ceremonial')
eq(JCA.dagger_victim(G.jokers.cards[3]), nil, 'a rightmost Dagger eats nothing')
field('j_ceremonial', 'j_baron')
eq(JCA.dagger_victim(G.jokers.cards[2]), nil, 'a non-Dagger has no victim')
-- Vanilla refuses to slice Eternal jokers, so the advisor must not cry wolf.
local eternal = field('j_ceremonial', 'j_baron')
eternal[2].ability = {eternal = true}
local _, is_safe = JCA.dagger_victim(eternal[1])
eq(is_safe, true, 'an Eternal neighbour is reported as safe')
--------------------------------------------------------------------------------
section('Engine: the sell advisor weighs clashes')
--------------------------------------------------------------------------------