diff --git a/amethyst/plans/2026-07-20-v1.13.0-release-qa.md b/amethyst/plans/2026-07-20-v1.13.0-release-qa.md index 9d243c369e..30e4dde0f4 100644 --- a/amethyst/plans/2026-07-20-v1.13.0-release-qa.md +++ b/amethyst/plans/2026-07-20-v1.13.0-release-qa.md @@ -27,6 +27,8 @@ Everything below is that one configuration unless stated. | NIP-29 relay groups | directory browse (crash found), naddr deep-link join, membership resolution | | Breadth sweep | Messages, NIP-29, Git, Podcasts, Blossom list, Location, Theming | | Location | map picker + teleport, before/after on 4 symptoms, composer path | +| Notifications | tab showed ~3 items; root-caused to a `since` deadlock and fixed — feed now scrolls back 16 months | +| Concord role grants | picker built and device-verified (rank gating, preselection, survives the fold) | ### Fixed but **only unit-verified** — never run on a device @@ -42,7 +44,7 @@ podcast duplicate description · Concord leave affordance · the three revocatio Nests / audio rooms (`quic` + MoQ) · Marmot / MLS · **the entire Desktop app** (where Privacy Lock actually ships) · Blossom "Sync all" (skipped deliberately — uploads to real servers) · podcast chapters / transcripts / credits · Git branch switching · Messages live-typing and per-type toggles · -real payments (zaps, V4V streaming, Cashu redeem) · notifications / push · search · Calendar, Chess, +real payments (zaps, V4V streaming, Cashu redeem) · push notifications · search · Calendar, Chess, Polls, Marketplace, Workouts, Badges, Follow Packs, Emojis, HLS Upload, App Store, Live Streams. NIP-29 admin: the menu is reachable and renders, but Edit metadata, invite creation, subgroups and @@ -87,8 +89,14 @@ pinned messages were never exercised. - **CORD-05: `community_id` does not commit to `community_root`**, so a crafted invite can carry a real community's identity with an attacker's root. **Armada has the identical gap** — this needs a spec conversation, not a unilateral fix. -- `grantConcordRole` is implemented and unreachable; the changelog claims role grants ship. A - proportionate UI exists (a picker beside "Make admin"); it was blocked by concurrent work. +- Concord Members roster: `canBan`/`canRemove` check only `viewerCanBan && !isOwnerTarget && + !isSelf` — never rank — while the ban fold enforces `canActOn`. So Ban and Remove are offered on + members who outrank the viewer and are then silently dropped on fold: exactly the no-op-control + trap the new "Roles…" item avoids. Fix is to route both through `canActOn`. Also affects the + message-level ban path, which is why it wasn't folded into the role-grant change. +- Notification cards whose target note isn't in `LocalCache` render "Event is loading or can't be + found in your relay list" (seen on old zaps). `tagsAnEventByUser` needs the reacted-to note + loaded, so deep history stays partially unresolved. Cosmetic, pre-existing. --- @@ -135,6 +143,13 @@ while being unreachable to users, and the first one actually invoked turned out written**. A lint for "public capability with no caller outside its declaring file" would catch the whole class cheaply. +**A narrow query window can deadlock against its own paging.** The Notifications tab asked relays +for 7 days, and its backward-paging fallback only armed once the feed held a *full page* — so a +quiet inbox could never fill a page, and therefore never widened the window. The EOSE `since` map +is in-memory, so every cold start re-pinned it. Look for this shape wherever a "load more" boundary +is gated on a full page: the empty state is self-sustaining. Note also that the relay-side `limit` +already bounds these queries, which is what makes dropping the time floor safe. + **Hypotheses need measurement, not plausibility.** Four confident diagnoses were wrong: the "npub in title" bug was a `User` lazy-init data race, not a display bug; chat date separators were a `reverseLayout` misconception, not bubble grouping; the map picker had no tile problem at all; and