Index: src/routes/circle.js
===================================================================
--- src/routes/circle.js	(revision 1be21ba2ec5d901a86fc24bad71b4a96d6492b6d)
+++ src/routes/circle.js	(revision 682d50402b538f249bed5b329a1b7f78be26b8bf)
@@ -58,8 +58,13 @@
   });
 
-  // Sites in de cirkel (alleen succesvol gesyncte = proto-compatibel) — voor de
-  // grafische header met avatars.
-  const sites = db.prepare('SELECT name, url, avatar FROM remote_actors ORDER BY name')
-    .all()
+  // Sites in de cirkel — alleen actieve links (outdated/error vallen weg, net als
+  // hun posts). Voor de grafische header met avatars.
+  const sites = db.prepare(`
+    SELECT a.name, a.url, a.avatar
+    FROM remote_actors a
+    JOIN circle_links l ON l.remote_actor_id = a.id
+    WHERE l.status = 'active'
+    ORDER BY a.name
+  `).all()
     .map((s) => ({
       name: s.name || 'Onbekend',
Index: src/services/CircleService.js
===================================================================
--- src/services/CircleService.js	(revision 1be21ba2ec5d901a86fc24bad71b4a96d6492b6d)
+++ src/services/CircleService.js	(revision 682d50402b538f249bed5b329a1b7f78be26b8bf)
@@ -31,4 +31,9 @@
 // melding van kan maken i.p.v. een generieke fout.
 function markOutdated(link, msg) {
+  // Gecachte posts van deze bron weghalen: we kunnen ze niet meer verifiëren of
+  // verversen (proto-mismatch), dus ze horen niet meer in de cirkel-feed.
+  if (link.remote_actor_id) {
+    try { db.prepare('DELETE FROM remote_posts WHERE actor_id = ?').run(link.remote_actor_id); } catch {}
+  }
   db.prepare("UPDATE circle_links SET status='outdated', last_error=?, last_synced=CURRENT_TIMESTAMP WHERE id=?")
     .run(String(msg).slice(0, 300), link.id);
