Commit a85599f
committed
1. User sets "logged-out visibility: disabled" which adds the !no-unauthenticated self-label to their profile
2. The AppView returns the profile data WITH the label
3. The patched @atproto/api library was always skipping this label in moderation checks (line 70 in decision.js)
4. So the moderation system never created a "blur" for it
5. The ScreenHider component never triggered
6. Profile was visible!
fallback mechanism only works with logged users. and checks the label
for privacy no-authenticated label.
This resolves the issue folkloringjamaica.blacksky.app was experiencing
@ind3fatigable.online was experiencing mute and follow issues which
surrounded cache invalidation issues that was resolved.
I tested with the follow:
Great! Now for Issue 2 (Unfollows/Mutes Not Persisting), here's what you should test:
Test Plan for Issue 2
Test 1: Unfollow Persistence
1. Follow a user (if not already following)
2. Unfollow them by clicking the "Following" button
3. ✅ Expected: Button immediately changes to "Follow"
4. Wait 1-2 seconds (for the AppView indexing lag compensation to kick in)
5. Refresh the page (hard refresh or navigate away and back)
6. ✅ Expected: Still shows "Follow" button (unfollow persisted)
7. Bonus: Check that their posts no longer appear in your Following feed
Test 2: Follow/Unfollow Multiple Times Rapidly
1. Follow a user
2. Immediately unfollow them
3. Repeat this 2-3 times quickly (stress test the mutation queue)
4. Refresh the page
5. ✅ Expected: Final state matches what you see (if you ended on "Follow", it stays "Follow" after refresh)
Test 3: Mute Persistence
1. Navigate to a user's profile
2. Mute them (via the three-dot menu → Mute)
3. ✅ Expected: Profile should indicate they're muted
4. Refresh the page
5. ✅ Expected: Still shows as muted
6. Go to your home feed
7. ✅ Expected: Their posts should no longer appear in your feed
Test 4: Unmute Persistence
1. Unmute a previously muted user
2. Refresh the page
3. ✅ Expected: No longer shows as muted
4. Check your feed
5. ✅ Expected: Their posts can now appear again
Test 5: Cross-Tab Consistency (Advanced)
1. Open the same profile in two browser tabs
2. In Tab 1: Unfollow the user
3. In Tab 2: Refresh the page after 1-2 seconds
4. ✅ Expected: Tab 2 should now show "Follow" button (cache was invalidated)
What Was Fixed:
- Before: Cache wasn't being invalidated, so refreshing would show stale data from cache
- After:
- Immediate cache invalidation on mutation success
- 500ms delayed refetch to handle AppView indexing lag
- Comprehensive invalidation of profile, feed, and related caches
If Tests Fail:
If you still see the old behavior (unfollows/mutes reverting after refresh), let me know and we can investigate further. The fixes should handle:
- ✅ Cache invalidation
- ✅ AppView indexing lag
- ✅ Optimistic updates staying in sync with server state
The issue identified was:
**Date:** November 2, 2025
**Scope:** Analysis of fallback mechanism impact on social interactions, user safety, and moderation
**Repository:** blacksky.community
---
**User-Reported Issue: "Unfollows don't stick, mutes don't persist"**
After comprehensive investigation, the root cause is **NOT the fallback mechanism** as initially suspected. The actual causes are:
1. **Missing cache invalidation** in the unfollow mutation (`useProfileUnfollowMutation`)
2. **Incomplete cache invalidation** in the mute mutation (`useProfileMuteMutation`)
3. **AppView indexing lag** creating race conditions with optimistic UI updates
4. These bugs affect **BOTH** fallback mode AND normal AppView queries
**Critical Safety Finding:**
The fallback mechanism has a **CRITICAL SAFETY GAP** regarding moderation labeler subscriptions:
- 🔴 **HIGH SEVERITY**: Moderation labels are completely bypassed in fallback mode
- Fallback always returns `labels: []` regardless of user's labeler subscriptions
- Users who subscribe to safety labelers (CSAM, self-harm, harassment filters) will see harmful content WITHOUT warnings when fallback is active
- Vulnerable populations are at increased risk
**Fallback Safety Assessment by Category:**
| Category | Safety Rating | Notes |
|----------|---------------|-------|
| Blocks | ✅ Excellent | Cache-first approach prevents privacy bypasses |
| Mutes | ✅ Good | Cache-first approach maintains privacy |
| Follows/Unfollows | 1 parent 3fcc4ac commit a85599f
File tree
4 files changed
+86
-22
lines changed- patches
- src/state/queries
4 files changed
+86
-22
lines changedLines changed: 5 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
| 2 | + | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
10 | 12 | | |
11 | 13 | | |
12 | 14 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
118 | 118 | | |
119 | 119 | | |
120 | 120 | | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
121 | 125 | | |
122 | 126 | | |
123 | 127 | | |
124 | 128 | | |
125 | 129 | | |
126 | 130 | | |
127 | | - | |
128 | | - | |
129 | | - | |
| 131 | + | |
| 132 | + | |
130 | 133 | | |
131 | 134 | | |
132 | 135 | | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
133 | 140 | | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
| 141 | + | |
| 142 | + | |
139 | 143 | | |
140 | | - | |
| 144 | + | |
| 145 | + | |
141 | 146 | | |
142 | 147 | | |
143 | 148 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | 12 | | |
21 | 13 | | |
22 | 14 | | |
| |||
42 | 34 | | |
43 | 35 | | |
44 | 36 | | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| |||
354 | 354 | | |
355 | 355 | | |
356 | 356 | | |
| 357 | + | |
357 | 358 | | |
358 | 359 | | |
359 | 360 | | |
360 | 361 | | |
361 | 362 | | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
362 | 372 | | |
363 | 373 | | |
364 | 374 | | |
| |||
418 | 428 | | |
419 | 429 | | |
420 | 430 | | |
421 | | - | |
| 431 | + | |
| 432 | + | |
422 | 433 | | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
423 | 446 | | |
424 | 447 | | |
425 | 448 | | |
| |||
431 | 454 | | |
432 | 455 | | |
433 | 456 | | |
434 | | - | |
| 457 | + | |
| 458 | + | |
435 | 459 | | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
436 | 472 | | |
437 | 473 | | |
438 | 474 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
109 | 110 | | |
110 | 111 | | |
111 | 112 | | |
| 113 | + | |
112 | 114 | | |
113 | 115 | | |
114 | 116 | | |
| |||
123 | 125 | | |
124 | 126 | | |
125 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
126 | 137 | | |
127 | 138 | | |
128 | 139 | | |
| |||
210 | 221 | | |
211 | 222 | | |
212 | 223 | | |
| 224 | + | |
213 | 225 | | |
214 | 226 | | |
215 | 227 | | |
| |||
226 | 238 | | |
227 | 239 | | |
228 | 240 | | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
229 | 250 | | |
230 | 251 | | |
231 | 252 | | |
| |||
0 commit comments