lightweight tag d783ffd6240c8aa6b6064e2d27c487bb15aaff89 v2026.07.01.1942
Author:	BAThomp24 <bathomp24@gmail.com>
Date:	Wed Jul 1 15:41:51 2026 -0400

commit d783ffd6240c8aa6b6064e2d27c487bb15aaff89
Author: BAThomp24 <bathomp24@gmail.com>
Date:   Wed Jul 1 15:41:51 2026 -0400

    fix: make SwapsAlreadyApplied read-only (root-cause, not a guard)
    
    The popup's swap check was STAGING real talent changes on every dungeon
    entry — SetSelection/PurchaseRank/RefundRank, then RollbackConfig to
    undo them — purely to answer the read-only question "is this swap already
    applied?". That staging was the entire error surface: it could throw or
    taint, fired TRAIT_CONFIG_UPDATED events, and left dangling uncommitted
    changes when the rollback didn't fully revert (the original code already
    pcall'd rollback, anticipating this). A previous change just wrapped the
    whole thing in pcall — treating the symptom.
    
    Replace it with a pure comparison: a swap is "already applied" iff every
    pick is at its target (selected choice / max rank). No mutation, no
    events, nothing to roll back, nothing to error.
    
    The dry-run existed to proactively hide genuinely-stuck builds (a pick
    that can never reach target). That case is already handled reactively by
    suppressedSwaps — set when Apply Swaps reports no progress. Its one gap
    was resetting on /reload, so make it persistent (ZugZugDB.suppressedSwaps,
    cleared on ACTIVE_TALENT_GROUP_CHANGED). Net: no more per-zone talent
    mutation, and stuck builds stay suppressed across reloads.
    
    Also reverts the speculative pcall guard around the call site added in the
    prior commit — no longer needed now that the function can't error.

