Index: src/routes/activitypub.js
===================================================================
--- src/routes/activitypub.js	(revision 8b07c12ebf1ce49b35e4b1ca78fddc8702616a5b)
+++ src/routes/activitypub.js	(revision 1a2d8ac96c0af0189037f8acd658b19b875be8b0)
@@ -19,4 +19,5 @@
 import { apEnabled } from '../services/SettingsService.js';
 import OAuth from '../services/OAuthService.js';
+import * as Guardianship from '../services/guardianship/index.js';
 import multer from 'multer';
 import path from 'path';
@@ -108,4 +109,21 @@
   });
 });
+
+// ── Guardian queues (owner only, FEP-633c, shaer:queues) ──────────
+// The dashboard collections the Shaer clients read: pending adoption offers,
+// gated follows (empty in Klonkt for now) and the guardian's wards. Same
+// contract as the Shaer test daemon.
+function queueRoute(name, build) {
+  router.get(`/ap/users/:slug/queues/${name}`, (req, res) => {
+    const auth = OAuth.verifyBearer(req.headers.authorization);
+    if (!auth || auth.site.slug !== req.params.slug) return res.status(403).end();
+    const base = baseUrl(req);
+    const me = `${base}/ap/users/${auth.site.slug}`;
+    AP.sendAP(res, { '@context': AP.AP_CONTEXT, ...build(`${me}/queues/${name}`, auth.site.slug, me) });
+  });
+}
+queueRoute('offers', (id, slug, me) => Guardianship.offersCollection(id, slug, me));
+queueRoute('follows', (id) => Guardianship.followsCollection(id));
+queueRoute('wards', (id, slug) => Guardianship.wardsCollection(id, slug));
 
 // ── Inbox read (owner only, AP C2S) ───────────────────────────────
