Index: scripts/migrate-circles.mjs
===================================================================
--- scripts/migrate-circles.mjs	(revision d71ed0317f432dcfec0a7c029d67f8d6f429ff9f)
+++ scripts/migrate-circles.mjs	(revision 355364cee687f9ad4102b295d3349f08fbe10c5a)
@@ -24,5 +24,5 @@
     SELECT cl.remote_url AS url, s.id AS sid, s.slug AS slug
     FROM circle_links cl JOIN sites s ON s.id = cl.local_site_id
-    WHERE cl.status = 'active'
+    WHERE cl.status != 'removed'
   `).all();
 } catch (e) { console.log('no circle_links table — nothing to migrate'); process.exit(0); }
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision d71ed0317f432dcfec0a7c029d67f8d6f429ff9f)
+++ src/services/ActivityPubService.js	(revision 355364cee687f9ad4102b295d3349f08fbe10c5a)
@@ -1070,8 +1070,12 @@
   if (_circlesMigrating) return; _circlesMigrating = true;
   try {
-    let done; try { done = db.prepare('SELECT value FROM app_settings WHERE key = ?').get('circles_migrated_v1'); } catch { return; }
+    let done; try { done = db.prepare('SELECT value FROM app_settings WHERE key = ?').get('circles_migrated_v2'); } catch { return; }
     if (done && done.value === '1') return;
+    // Migrate EVERY link the user added (not only status='active'): the old
+    // 'error'/'outdated' statuses came from the pull-protocol's health checks
+    // (now irrelevant) — e.g. a peer that removed /.klonkt/* shows up as error
+    // but still has a working AP actor.
     let links = [];
-    try { links = db.prepare("SELECT cl.remote_url AS url, s.id AS sid, s.slug AS slug FROM circle_links cl JOIN sites s ON s.id = cl.local_site_id WHERE cl.status = 'active'").all(); } catch { /* no legacy table */ }
+    try { links = db.prepare("SELECT cl.remote_url AS url, s.id AS sid, s.slug AS slug FROM circle_links cl JOIN sites s ON s.id = cl.local_site_id WHERE cl.status != 'removed'").all(); } catch { /* no legacy table */ }
     let ok = 0;
     for (const l of links) {
@@ -1081,5 +1085,5 @@
       } catch { /* best-effort per link */ }
     }
-    try { db.prepare('INSERT OR REPLACE INTO app_settings (key, value) VALUES (?, ?)').run('circles_migrated_v1', '1'); } catch { /* ignore */ }
+    try { db.prepare('INSERT OR REPLACE INTO app_settings (key, value) VALUES (?, ?)').run('circles_migrated_v2', '1'); } catch { /* ignore */ }
     if (links.length) console.log(`[AP] circle migration: ${ok}/${links.length} legacy link(s) -> auto-boost`);
   } catch { /* never block boot */ } finally { _circlesMigrating = false; }
