Index: test/archive-audio.test.js
===================================================================
--- test/archive-audio.test.js	(revision 9f9b45f0192cafb95f5a26092edd4a5e62d1cb6b)
+++ test/archive-audio.test.js	(revision 861c228ab92d14eec6f839d5157dfaba09749127)
@@ -234,3 +234,27 @@
 });
 
+test('ook een zip-import buigt links naar de bronpost om', () => {
+  // Robin: "het moet wel gebeuren bij migratie direct ook". Een zip-import is
+  // net zo goed een verhuizing, dus dezelfde regel.
+  leeg();
+  try { db.prepare('DELETE FROM posts').run(); } catch { /* leeg */ }
+  db.prepare(`INSERT INTO posts (id, site_id, author_id, slug, title, content, status, published_at)
+              VALUES ('pl1','s1','u1','tiktik','TikTik','<p><a href="https://oud.test/tiktik?fc=2">luister</a></p>','published','2026-01-01T10:00:00Z')`).run();
+  const uit = AX.buildArchive('me');
+
+  db.prepare('DELETE FROM posts').run();
+  // De import doet alsof het archief van oud.test komt; deze site is oud.test
+  // niet, dus de links moeten om.
+  const files = new Map(uit.files);
+  const man = JSON.parse(files.get('manifest.json').toString('utf8'));
+  man.origin = 'https://oud.test';
+  files.set('manifest.json', Buffer.from(JSON.stringify(man)));
+
+  const r = AI.importArchive(files, { slug: 'me', origin: 'https://nieuw.test' });
+  const c = db.prepare("SELECT content FROM posts WHERE slug = 'tiktik'").get().content;
+  assert.ok(c.includes('href="/tiktik?fc=2"'), `omgebogen naar hier, kreeg: ${c}`);
+  assert.ok(!c.includes('oud.test'), 'niets wijst meer naar de bron');
+  assert.equal(r.linksBijgetrokken, 1, 'en het verslag zegt het');
+});
+
 test.after(() => { try { fs.rmSync(TMP, { recursive: true, force: true }); } catch { /* niets */ } });
Index: test/fep1580-migration.test.js
===================================================================
--- test/fep1580-migration.test.js	(revision 9f9b45f0192cafb95f5a26092edd4a5e62d1cb6b)
+++ test/fep1580-migration.test.js	(revision 861c228ab92d14eec6f839d5157dfaba09749127)
@@ -577,4 +577,39 @@
 });
 
+test('links naar de bronpost buigen om naar hier, in dezelfde ronde', async () => {
+  // De gebakken "luister op"-links: buildNote zet
+  // https://oud/<slug>#track-<id> en ?fc=2 in de content. Die bleven naar de
+  // oude site wijzen, en dat is een tijdbom: zodra dat domein weg is staan er
+  // dode links in je eigen berichten. Slugs en track-ids blijven behouden, dus
+  // de fragmenten kloppen vanzelf zodra de host eraf is.
+  const s = site({ aliases: [BRON] });
+  const OUD = 'https://oud.example';
+  const kaart = new Map([
+    [BRON, { id: BRON, type: 'Person', movedTo: IK, outbox: `${BRON}/outbox` }],
+    [`${BRON}/outbox`, { type: 'OrderedCollection', totalItems: 2, first: `${BRON}/outbox?page=1` }],
+    [`${BRON}/outbox?page=1`, { type: 'OrderedCollectionPage', orderedItems: [
+      note(`${BRON}/notes/tiktik`, { url: `${OUD}/tiktik`, content:
+        `<p>🎵 <a href="${OUD}/tiktik#track-t1">TikTik</a> — <a href="${OUD}/tiktik?fc=2">luister</a></p>` }),
+      // een link naar iets dat we NIET hebben blijft met rust
+      note(`${BRON}/notes/ander`, { url: `${OUD}/ander`, content:
+        `<p>zie <a href="${OUD}/bestaat-hier-niet">daar</a></p>` }),
+    ] }],
+  ]);
+  const r = await stil(() => Mig.ingestFromSource(s, { deps: {
+    getJson: async (_s, url) => kaart.get(url) || null,
+    noteId: (b, id) => `${b}/ap/notes/${id}`,
+    noteVisibility: AP.noteVisibility,
+  } }));
+  assert.equal(r.posts, 2);
+  const tik = db.prepare("SELECT content FROM posts WHERE slug = 'tiktik'").get().content;
+  assert.ok(tik.includes('href="/tiktik#track-t1"'), `fragment blijft heel, kreeg: ${tik}`);
+  assert.ok(tik.includes('href="/tiktik?fc=2"'), 'en de querystring ook');
+  assert.ok(!tik.includes('oud.example'), 'er wijst niets meer naar de oude site');
+  const ander = db.prepare("SELECT content FROM posts WHERE slug = 'ander'").get().content;
+  assert.ok(ander.includes(`${OUD}/bestaat-hier-niet`),
+    'een link naar iets dat hier niet bestaat blijft staan: beter de oude site dan een 404 op de nieuwe');
+  assert.equal(r.linksBijgetrokken, 1);
+});
+
 test('een bericht dat je zelf hebt verwijderd komt bij een tweede ronde terug', async () => {
   // Robin: "ik kan handmatig deze keer de posts verwijderen en opnieuw ophalen."
