ad08688bc6
$groupNeedsYou was written by two independent sources: an @user mention (appendGroupChatEntry) and, until now, syncGroupClarify whenever a member blocked on a clarify or approval. Nothing kept the two in sync, so every path that consumed a clarify -- answering it, the server resolving it, disbanding or renaming the room -- left a stale badge lit with nothing behind it, because none of them cleared the copy syncGroupClarify had written. A naive fix (writing false back into $groupNeedsYou on every clarify cleanup path) would have created the opposite bug: clearing an unrelated, still-unresolved @user mention. $groupClarify is already the source of truth for pending clarify/ approval attention. syncGroupClarify no longer writes $groupNeedsYou; a new groupHasPendingClarify(clarifies, group) derives the same signal from a $groupClarify snapshot. It's intentionally pure -- the caller (roster-pane) subscribes to $groupClarify itself via useValue and passes the live snapshot in, so the subscription actually drives the recalculation instead of existing only to force a re-render. A prompt resolving, being answered, or its room being disbanded all self-correct through the existing $groupClarify cleanup paths, with nothing left to keep in sync. Rename needed its own fix: the old clearGroupClarify(oldName) call on rename dropped a clarify-only room's attention entirely, since clarify no longer lives in $groupNeedsYou to be carried over by the existing old->new key swap there. New renameGroupClarify(oldName, newName) re-keys matching mirrors onto the new name in two passes -- unrelated entries first, migrated entries last -- so a stale mirror already stranded at the destination key (left behind by a known, separate in-flight-poll race) can never clobber the just-migrated current prompt. The roster now reads groupNeedsYou[group] || groupHasPendingClarify(...) and subscribes to both stores so either one repaints the row. Tests: multi-clarify sequencing, mention+clarify independence (resolving one must not clear the other), server-side resolution cleanup, rename migration, rename destination-collision (red-green verified against the prior single-pass implementation), a GroupRow badge render test, and a subscription harness using the real stores/useValue/helper end-to-end. (cherry picked from commit e5038f12ccc1a4d1fb56ecc5f0e1a884f1e8b795)