Index: src/routes/activitypub.js
===================================================================
--- src/routes/activitypub.js	(revision aed0092c4492bca99e1c9a5c82332c1d08fe1bee)
+++ src/routes/activitypub.js	(revision 960f0159a39a973d50321222d1610f881d16e6ae)
@@ -444,7 +444,16 @@
 }
 
-/** De naam waaronder deze lezer zichzelf herkent in een Mention. */
+/**
+ * De naam waaronder deze lezer zichzelf herkent in een Mention.
+ *
+ * Via deriveHandle op de actor-URI, niet uit de slug hier opgebouwd. Dit stond
+ * er als `@${slug}@${host}` met `@${slug}` als terugval, en die terugval is een
+ * HALVE naam: zonder host zegt @dev niets op een oppervlak waar iedereen @dev
+ * kan heten. Hij ging alleen af bij een onparseerbare PUBLIC_BASE_URL -- maar
+ * dan klopt elke URI die we bouwen al niet, en is de kale actor-URI (wat
+ * deriveHandle dan teruggeeft) eerlijker dan een naam die compleet lijkt.
+ */
 function ownHandle(base, slug) {
-  try { return `@${slug}@${new URL(base).host}`; } catch { return `@${slug}`; }
+  return AP.deriveHandle(AP.actorId(base, slug));
 }
 
@@ -754,5 +763,5 @@
   // hebben ze nodig, dus een keer, hierboven.
   const me = AP.actorId(base, auth.site.slug);
-  const myHandle = (() => { try { return `@${auth.site.slug}@${new URL(base).host}`; } catch { return `@${auth.site.slug}`; } })();
+  const myHandle = AP.deriveHandle(me);   // een naam, of de kale URI -- nooit een halve
   const guardianUris = (() => { try { return new Set(Guardianship.listGuardians(auth.site.slug).map((g) => g.other_uri)); } catch { return new Set(); } })();
   // ── Alleen het VERSCHIL, als de client daarom vraagt (shaer-pq4) ──
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision aed0092c4492bca99e1c9a5c82332c1d08fe1bee)
+++ src/services/ActivityPubService.js	(revision 960f0159a39a973d50321222d1610f881d16e6ae)
@@ -6521,4 +6521,5 @@
 export default {
   AP_CONTEXT, getOrCreateKeys, apWants, sendAP, actorId, noteId, stripLeadingMentions, pagedCollection,
+  deriveHandle, localSlugOf,
   buildActor, buildNote, buildCreate, buildOutbox, buildFollowers, buildFollowing, buildFeatured,
   channelUrls, channelCategory, timelineFields, guessMediaType,
