Index: src/routes/activitypub.js
===================================================================
--- src/routes/activitypub.js	(revision 861c228ab92d14eec6f839d5157dfaba09749127)
+++ src/routes/activitypub.js	(revision dc802b4223862381c3a03fc87973462a7b333346)
@@ -212,5 +212,11 @@
     limit: AP.PAGINA_GROOTTE,
   });
-  const ob = AP.buildOutbox(baseUrl(req), site, posts, tracks, { page: nr, totalItems: totaal, alGesneden: true });
+  // FEP-1580: de instantie waar dit account naartoe verhuisd is krijgt de
+  // RAUWE inhoud, met [[track:]] en [[playlist:]] er nog in. Zij is een
+  // Klonkt en rendert die zelf tot een speler. De gebakken variant komt
+  // daar aan als tekstlink, en is bovendien onherstelbaar afgeknot: het
+  // bakken plakt hooguit vier titels aan.
+  const rauweInhoud = verifiedActor ? AP.isMoveTarget(site.slug, verifiedActor) : false;
+  const ob = AP.buildOutbox(baseUrl(req), site, posts, tracks, { page: nr, totalItems: totaal, alGesneden: true, rauweInhoud });
   if (audience === 'friend') {
     // The owner's app builds its feed from this leg, and every note here is
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision 861c228ab92d14eec6f839d5157dfaba09749127)
+++ src/services/ActivityPubService.js	(revision dc802b4223862381c3a03fc87973462a7b333346)
@@ -706,5 +706,14 @@
     } catch { /* non-fatal */ }
   }
-  body = body.replace(/\[\[(track|album|playlist):[^\]]+\]\]/gi, '');
+  // ONVERTAALD voor een verhuizing (FEP-1580). De doelinstantie IS een Klonkt:
+  // die rendert [[track:]], [[album:]] en [[playlist:]] zelf en maakt er een
+  // speler van. Bakken we ze eerst om, dan komt er een tekstlink aan en is de
+  // speler weg. Onherstelbaar bovendien: het bakken STRIPT de shorthand en
+  // plakt achteraan hooguit VIER titels, dus een album van tien nummers
+  // overleeft het niet.
+  //
+  // Dezelfde regel als bij de outbox en de tracks: wie ondertekend vraagt
+  // namens de actor waar wij naartoe verhuisd zijn, krijgt onze eigen kijk.
+  if (!opts.rauweInhoud) body = body.replace(/\[\[(track|album|playlist):[^\]]+\]\]/gi, '');
   // External embeds ([[embed:url]]) → emit the bare URL as a link so Mastodon
   // renders its OWN preview/player card (YouTube/Spotify/SoundCloud/etc) instead
@@ -714,5 +723,5 @@
     return `<p><a href="${u}">${u}</a></p>`;
   });
-  if (hadAudio) {
+  if (hadAudio && !opts.rauweInhoud) {
     // Elke titel als eigen link naar zijn anker; een titel zonder id (een
     // albumnaam zonder tracks) blijft gewone tekst.
@@ -1039,6 +1048,6 @@
 }
 
-export function buildCreate(base, site, post) {
-  const note = buildNote(base, site, post);
+export function buildCreate(base, site, post, opts = {}) {
+  const note = buildNote(base, site, post, opts);
   return {
     '@context': AP_CONTEXT,
@@ -1123,9 +1132,9 @@
 }
 
-export function buildOutbox(base, site, posts, tracks = [], { page = false, totalItems, alGesneden = false } = {}) {
+export function buildOutbox(base, site, posts, tracks = [], { page = false, totalItems, alGesneden = false, rauweInhoud = false } = {}) {
   const id = `${actorId(base, site.slug)}/outbox`;
   const wanneer = (x) => Date.parse(x && x.published ? x.published : 0) || 0;
   const items = [
-    ...(posts || []).map((p) => buildCreate(base, site, p)),
+    ...(posts || []).map((p) => buildCreate(base, site, p, { rauweInhoud })),
     // Eén zoekopdracht voor alle tracks samen, niet per stuk.
     ...(() => {
