Index: src/routes/guardian.js
===================================================================
--- src/routes/guardian.js	(revision 8064da1348e05187fd8888ea0e2c56d9f520603d)
+++ src/routes/guardian.js	(revision f06ed56e637b1e0d99567688ceb0281687dff6f3)
@@ -74,4 +74,8 @@
   'warn_reversible', 'warn_irreversible', 'warn_unknown', 'warn_tally_elsewhere', 'warn_decides', 'warn_not_last', 'warn_go', 'warn_back',
     'help_archive', 'help_archive_hide', 'panel_history',
+    // Het logboek (§4.2): onbekende soorten vallen terug op hun ruwe naam.
+    'log_show', 'log_hide', 'evr_not_a_teapot',
+    'ev_offer_rejected', 'ev_offer_refused', 'ev_committed', 'ev_guardian_left',
+    'ev_coguardian_left', 'ev_gated_outcome', 'ev_lapse_opened',
     'gate_propose_open', 'gate_propose_close', 'gate_default_off',
     'gate_images', 'gate_messages', 'gate_compose', 'gate_replies', 'gate_music', 'gate_quoteCards', 'gate_asked',
@@ -317,4 +321,14 @@
 });
 
+// Het logboek (§4.2): wat er is gebeurd, met de reden erbij. GEEN wachtrij --
+// hier staat niets dat om een antwoord vraagt, en daarom hoort het ingeklapt.
+// Het bestaat omdat een weigering anders alleen te merken was doordat er iets
+// uit een lijst verdween, en "het is weg" vertelt een ward niet waarom.
+router.get('/api/events', requireAuth, (req, res) => {
+  const site = siteForUser(req);
+  if (!site) return res.status(404).json({ error: 'no_site' });
+  res.json({ items: AP.listGuardianEvents(site.slug, 50) });
+});
+
 router.post('/api/follow/:id', requireAuth, express.json({ limit: '4kb' }), async (req, res) => {
   const site = siteForUser(req);
