lightweight tag ec8ea80a4f7820b7796cac91c94fb3645431349b v0.3.0
Author:	Brandon Jernigan <brandon@whatisboom.com>
Date:	Wed Jun 24 23:56:26 2026 -0500

commit ec8ea80a4f7820b7796cac91c94fb3645431349b
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Wed Jun 24 23:56:26 2026 -0500

    docs: changelog for 0.3.0

commit e74df00994aeb8c9b383f927d08a28f01de32897
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Wed Jun 24 21:10:09 2026 -0500

    docs: match repo changelog convention; document release process
    
    Revert the [Unreleased] changelog section (af674e0) — this repo writes a dated
    ## [X.Y.Z] section in a single "docs: changelog for X.Y.Z" commit at tag time, not
    a rolling [Unreleased] section. Document the actual release flow in CLAUDE.md: no
    in-repo workflow (CurseForge's GitHub integration packages on tag), version from the
    tag via @project-version@, and the changelog convention to follow.

commit 12e02a275795364f2ec379df201ea4b440fceab5
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Wed Jun 24 20:48:09 2026 -0500

    docs: changelog for the unreleased nudge/eligibility/banked work

commit 6e2897b5f695350c5d593ea360a33dc51d7bcd88
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Wed Jun 24 18:44:21 2026 -0500

    feat: row-wide right-click, tooltip hints, and hide/hidden language
    
    - Right-click now opens the per-character menu anywhere on a roster row, not just
      the name: the menu lives on the row and the child cells (name/banked/slots)
      propagate clicks to it via SetPropagateMouseClicks.
    - "Right-click for per-character settings" hint added to every row tooltip (name,
      each slot, and the Banked cell), so the action is discoverable wherever you hover.
    - Replace "ignore/ignored" language with "hide/hidden", and split the two states
      that were both called "Ignored": a character you turned off now reads "Hidden"
      (right-click option is "Hide"); one that simply hasn't qualified reads
      "No qualifying reward yet". The reveal setting is now "Show all characters".
    - Add a "Show all characters" checkbox to the bottom of the roster window, synced
      both ways with the options-panel setting.
    
    Internal `showIgnored` settings key kept (not user-facing) to avoid a migration.

commit 45ebbba04e02c0dabaf3228e7fc7ea22175c6e8c
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Wed Jun 24 11:30:15 2026 -0500

    fix: address PR review (off-mutes-banked-column, nil reset-timer guards)
    
    - bankedCell returns nil for trackTier == "off", so an explicitly-muted character
      no longer shows banked info in the roster Banked column even when Show ignored
      reveals its dimmed row ("off is off" everywhere).
    - Guard realWeekId against a nil reset timer in Attention.build and Roster:Refresh:
      periodKey(now, nil) is not reset-aligned and could mis-drive the "likely banked"
      inference. A nil timer now cleanly disables just the inference; confirmed banked
      is unaffected. The codebase already treats GetSecondsUntilWeeklyReset() as nullable.
    
    Adds a test for the nil-timer case. 176 -> 177 tests.

commit 0258d7bb9d40df845af8059c35b92b4fc13441ef
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Wed Jun 24 08:18:02 2026 -0500

    feat: sticky eligibility, banked-regardless-of-eligibility, safe period retention
    
    Eligibility is now a stored sticky opt-in flag (presence in the DB = source of
    truth), restoring the original intent that the "seriousness v2" migration drifted
    from. A character becomes tracked the first time it earns a reward at/above its
    line and stays tracked; reset only on M+ season change. effectiveTracked reads the
    flag (Derived.observeEligible in Scanner) instead of recomputing live, so a tracked
    character no longer drops out the week it does nothing. Changing the account
    threshold prompts Reset/Keep (Config:RecomputeAllEligible); a per-character override
    re-evaluates that character immediately; migratedSeriousnessV3 grandfathers existing
    characters.
    
    Confirmed banked loot now surfaces regardless of eligibility (real loot you can
    lose) in chat/tooltip/roster, except a character explicitly set to "off". The
    inferred/soft reasons (likely-banked, untouched, close-to-unlock) still require
    eligibility. Roster keeps such characters visible and un-dimmed (isActive).
    
    Period retention fix: keep the current period + the single most-recent prior
    snapshot (Derived.prunePeriods), no longer gated on hasPendingLoot. The old rule
    deleted prior periods whenever a scan saw no pending loot, including the transient
    false right after a reset before reward data loads -- which destroyed last week's
    banked detail and left bare "banked loot" with no ilvl range. The banked display is
    gated on hasPendingLoot, so a retained-but-claimed period never shows.
    
    Docs: CLAUDE.md eligibility/banked sections and VaultTracker-spec.md retention rule
    updated to match. 154 -> 176 pure-logic tests.

commit 96f59ce4c773c4812fdfef6782de8548c83c1431
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Mon Jun 22 22:48:54 2026 -0500

    feat: gate nudges by earned tier; settle roster sort/glow
    
    Nudge gate: only nudge a track once it has EARNED a slot whose rewardTier is at or
    above the character's effective line (Derived.trackEarnedTier + a line arg on
    partialSlot/partials; Attention passes effectiveLine). An unearned slot's reward is
    unknowable until earned, so a track with nothing earned (its first slot) never nudges
    - mirroring how eligibility won't track a character until bestTier reveals their tier.
    Fixes the "1 more raid boss" nudge for LFR content beneath the character.
    
    Roster: only confirmed banked (red) floats to the top; amber soft states (untouched /
    close-to-unlock / likely-banked) glow in place instead of reordering the list. Current
    character now glows cool blue instead of gold, so "you are here" reads distinct from
    the warm warning colours.
    
    154 -> 167 pure-logic tests. On feat/nudge-ilvl-gate; not merged to main.

commit 05a92f09b7043694bb807185eaaf3202e28d96b3
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Mon Jun 22 17:43:21 2026 -0500

    feat: make login summary actionable with partial-slot nudges
    
    Replace the passive 'X/9, best N' status dump with what to actually go do:
    nudge a character when a vault slot is partway filled and within a configurable
    distance of unlocking, e.g. 'Sinlengua-Thrall: 1 more raid boss, 2 more world
    activities'. Maxed, untouched, clean-boundary, and not-close characters drop off.
    
    Distance is the lowest unmet slot's own progress vs its threshold (the way the
    vault UI reads), so a world slot showing 2/4 is 2 away. New 'Nudge within'
    setting (1-3, default 1) controls how close counts; at 1 only true 'one more'
    states fire, which keeps the closely-spaced raid/world rows from being noisy.
    
    Unified across the login summary, broker tooltip, roster hover, and badge count
    via the shared reason text. Drops the now-unused bestIlvl / REASON_SLOTS_BEST.
    
    126 -> 154 pure-logic tests.

commit cdca6eadbc6c3248bd7d200470d92aa27920d0b0
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Mon Jun 22 17:42:51 2026 -0500

    feat: infer 'likely banked' loot for stale alts
    
    The vault API only reports the logged-in character, so an alt's banked-loot flag
    stays stale until you log into it after the reset. Infer it instead: a character
    whose cached week is exactly one reset old and that had unlocked slots when last
    seen almost certainly has loot waiting. Surface it as a distinct, tentative state
    (amber, '?' marker, 'likely banked loot') so it's never confused with confirmed
    banked loot (red '!'); a real scan overwrites the guess on next login.
    
    Folded into the existing banked trigger and counted in the minimap badge (amber).
    Shows in the broker tooltip, login summary, and a '?'-prefixed roster Banked cell
    whose hover says 'log in to confirm'. Limited to one missed reset, since the game
    only holds the most recent week's unclaimed loot.
    
    Attention.build gains an optional `now` arg (callers pass time()); a shared
    Format.marker centralizes the !/?/- glyphs. 108 -> 126 pure-logic tests.

commit cfed9daf414ebd90814e42023ffe6ef960d28a21
Author: Brandon Jernigan <brandon@whatisboom.com>
Date:   Mon Jun 22 17:39:37 2026 -0500

    feat: show banked-loot ilvl range and count
    
    Replace the single 'banked loot, best N' with the count of items waiting and
    their ilvl span, e.g. 'banked loot, 3 items 626-639', in the broker tooltip,
    login chat summary, and roster hover. Add a Banked column to the roster window
    showing 'N: lo-hi' (collapsing to one ilvl when uniform, em-dash when none),
    with a hover listing each claimable slot's ilvl. The column appears only when
    some shown character has banked loot, widening the frame and shifting the
    track groups.
    
    Computed at read time from the latest cached prior-period snapshot
    (Derived.bankedPeriod / periodRange / bankedRange); no new data is recorded.
    
    91 -> 108 pure-logic tests.

