110b9c9dfe
The contract books income atLevel = the level the payer upgraded OUT of (upgrade N->N+1 records atLevel=N), so an Ascensus upgrade pass-up was displaying as "Scintilla". Income rows are now classified against the contract's getAllCosts() tables — upgrade pass-ups arrive at full upgrade cost, entry referral rewards at slot cost minus the 5% admin fee — and display "Upgrade to Ascensus" / "Entry — Scintilla" in the admin income table, public feed, and toasts. Stale snapshot rows re-classify via a forced re-snapshot on boot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>