Index: src/routes/posts.js
===================================================================
--- src/routes/posts.js	(revision dcff893dc8dca9f4ca7461cb1ad2445167d326aa)
+++ src/routes/posts.js	(revision 74d61e6159ea68f2b2b02a0b15a6f8c9746246fb)
@@ -537,5 +537,7 @@
         const id = note.object_uri || uri;
         return Promise.resolve(ActivityPubService.sendInteraction(site, on ? 'boost' : 'unboost', id, note.actor_uri))
-          .then(() => on ? ActivityPubService.markBoosted(site.slug, id) : ActivityPubService.unmarkBoosted(site.slug, id));
+          // Boost → store the post in the timeline (even if you don't follow the author) so it
+          // surfaces in the Cirkel; unboost → just clear the flag.
+          .then(() => on ? ActivityPubService.upsertBoostedNote(site.slug, note) : ActivityPubService.unmarkBoosted(site.slug, id));
       })
       .catch((e) => console.warn('[AP] remote boost failed:', e.message));
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision dcff893dc8dca9f4ca7461cb1ad2445167d326aa)
+++ src/services/ActivityPubService.js	(revision 74d61e6159ea68f2b2b02a0b15a6f8c9746246fb)
@@ -1128,4 +1128,18 @@
   try { const r = db.prepare('SELECT liked, boosted FROM ap_timeline WHERE slug = ? AND id = ?').get(slug, noteId); return { liked: !!(r && r.liked), boosted: !!(r && r.boosted) }; } catch { return { liked: false, boosted: false }; }
 }
+// Boost a REMOTE post that may not be in your timeline (you don't follow the author):
+// store it in ap_timeline (INSERT OR IGNORE → no dup for followed posts) so it shows in
+// the Cirkel with a Boost badge, then flag it boosted.
+export function upsertBoostedNote(slug, note) {
+  if (!slug || !note || !note.object_uri) return;
+  const id = note.object_uri;
+  const media = JSON.stringify((note.images || []).map((u) => ({ url: u, type: 'image/jpeg' })));
+  try {
+    tlStmts().ins.run(id, slug, note.actor_uri || '', note.actor_name || '', note.actor_handle || '',
+      note.actor_icon || '', note.actor_url || '', note.content || '', note.url || null,
+      new Date().toISOString(), media);
+  } catch { /* ignore */ }
+  markBoosted(slug, id);
+}
 export function boostedCount(slug) {
   try { if (!_boostedCount) _boostedCount = db.prepare('SELECT COUNT(*) AS n FROM ap_timeline WHERE slug = ? AND boosted = 1'); return _boostedCount.get(slug).n; } catch { return 0; }
@@ -1378,5 +1392,5 @@
   listOutbox, deliverOutboxDelete,
   webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, getTimeline, sendInteraction,
-  autoBoostCount, boostedCount, markBoosted, unmarkBoosted, markLiked, unmarkLiked, getTimelineReaction, getCirkelPosts, getCirkelMembers, selfHealTimeline,
+  autoBoostCount, boostedCount, markBoosted, unmarkBoosted, markLiked, unmarkLiked, getTimelineReaction, upsertBoostedNote, getCirkelPosts, getCirkelMembers, selfHealTimeline,
   getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
   deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker,
