File Details
v0.10.33
- R
- Mar 21, 2026
- 5.79 MB
- 141
- 12.0.1+1
- Retail
File Name
Cerebro-v0.10.33.zip
Supported Versions
- 12.0.1
- 11.2.7
Cerebro
v0.10.33 (2026-03-21)
- chore: Bump version to 0.10.33
Fix RCLC import pipeline (date filter, timestamps, dedup), add dry-run simulation command; hide voided transactions in History tab; targeted sync PUSH to divergent peer only; scope Sync Health display to active online peers - fix(ui): use consistent name format for self-skip in Addon Compliance
Use GetFullPlayerName(UnitName("player")) instead of GetPlayerFullName()
for the myName self-skip guard. This matches the same normalizer used for
guild roster names (GetFullPlayerName(gName)), preventing self from being
double-counted due to name format mismatch. - fix(ui): unify Addon Compliance with GetAddonState, remove dead code
Replaced the entire manual addonStatus lookup + age + version comparison
in the Addon Compliance tooltip section with v2:GetAddonState(full) — the
same function that powers green/yellow/gray name colors in the player list.
Removed ~30 lines of dead code: v2INACTIVE, maxVer, v2modRef, addonStatus
variable — all now handled internally by GetAddonState. Self is counted
unconditionally before the loop; the loop uses full ~= myName guard. - fix(ui): always count self in Addon Compliance synced count
Self was being missed when GetPlayerFullName() and GetFullPlayerName(gName)
produced slightly different name strings, causing full == myName to fail.
Fixed by counting self unconditionally before the guild roster loop, and
skipping self inside the loop via full ~= myName guard. - fix(ui): normalize peerHashes short name to full Name-Realm for GetAddonState
AceComm passes sender as short name for same-realm peers, so peerHashes
is keyed by short name (e.g. "Bearlybleeds") while addonStatus uses full
Name-Realm format ("Bearlybleeds-Stormrage"). GetAddonState was always
returning "unknown" for same-realm peers, causing count to be 1/1.
Fix: normalize with GetFullPlayerName() before GetAddonState() in both
ComputeSyncHealth and ShowSyncHealthTooltip. - fix(ui): tighten active-peer filter to synced/outdated only
Previously included "inactive" peers (seen before, now offline) in the
Sync % and tooltip peer counts. Changed condition from != "unknown" to
== "synced" or == "outdated" so only players with an actively running
addon are counted as live peers. - fix(ui): fix active-peer name key mismatch in sync health display
peerHashes keys didn't match addonStatus keys, causing all peers to be
excluded (showing 1/1 instead of 3/3). Replaced addonStatus[name]
lookup with v2:GetAddonState(name) ~= "unknown" in both ComputeSyncHealth
and ShowSyncHealthTooltip — same proven logic used by Addon Compliance. - fix(ui): scope Sync % and tooltip top rows to active peers only
ComputeSyncHealth and ShowSyncHealthTooltip now filter peerHashes to
peers seen within INACTIVE_THRESHOLD (90s). Offline/unknown peers no
longer deflate the Sync % label or the top 3 tooltip rows (Sync Health,
Roster Hash, Config Hash). Addon Compliance section is unchanged and
still shows all guild members. - fix(sync): targeted WHISPER push on raider mismatch instead of GUILD broadcast
When an officer detects a mismatch from a non-officer (raider/stale alt),
send a targeted WHISPER to only that peer instead of broadcasting to
RAID/GUILD. This prevents disrupting already-synced officers who would
temporarily drop from synced state while re-processing the broadcast.- Reuses existing _lastSnapshotTo per-sender cooldown (same as officer path)
- Removes _lastRaidBroadcastAt scalar (no longer needed for this path)
- Net result: stale raider convergence is now invisible to synced peers
- fix(ui): hide voided transactions in History tab; silence ghost stub debug spam
- MainFrame/UISandbox History tabs now skip voided transactions
(previously showed duplicates after RCLC import void+replace cycle) - GetFilteredPlayersForSync: remove per-heartbeat debug log for ghost
stub skipping (Vrock-Eitrigg spam); expected behavior, not worth logging
- MainFrame/UISandbox History tabs now skip voided transactions
- fix(rclc-import): Fix import pipeline and add dry-run simulation
- Add ParseDateArg (MM-DD-YYYY → YYYY/MM/DD RCLC format)
- Remove duplicate ParseDateArg at EOF that returned Unix timestamp
- Fix date scope filter to compare RCLC date strings (not servertime)
- Add full Unix timestamp to NormalizeEntry from date+time fields
- Fix AddTransaction to honor overrideTimestamp from options
- Fix VoidTransactions to convert sinceDate string to Unix for comparison
- Fix audit log bug (date() called with string instead of number)
- Add SimulateImport dry-run (read-only, per-player GP report)
- Register /cb rclc dryrun MM-DD-YYYY command
- Bump version 0.10.32
- fix(sync): fix persistent roster/selection hash divergence between officers
Two bugs caused officers to never fully converge after PR37:
Bug 1 — MergeSelectionData timestamp self-escalation (CommunicationV2.lua):
When incoming selection was accepted, sf:SetSelection() internally called
SaveSelection() which overwrote customEP.lastUpdate with time(). This ratcheted
the local timestamp forward on every successful merge, making the local client
perpetually "newer" than all peers. All future selection merges from those peers
were REJECTED (theirs < mine forever), producing the continuous REJECTED spam seen
in logs. Fix: restore incoming.lastUpdate after SetSelection() clobbers it.
Bug 2 — RepairDatabase lastUpdate bump on login (Database.lua):
The coreAdmittedAt backfill (data.coreAdmittedAt = 1) also bumped
data.lastUpdate = time(). RepairDatabase runs on every login at different
wall-clock seconds per officer, producing different lastUpdate values for
identical EP/GP/status records. Since lastUpdate is included in ComputeRosterHash(),
officers with identical data got different roster hashes → endless FETCH/PUSH loops.
Fix: remove the lastUpdate bump — this is a schema migration, not a data mutation.
Every officer independently applies this migration on login; LWW propagation
is unnecessary and harmful."

