Index: src/routes/guardian.js
===================================================================
--- src/routes/guardian.js	(revision 780a7c655af23759b03e276bc56d8be0bc5d44ff)
+++ src/routes/guardian.js	(revision 3ffbeddc44bcbd1ab3c2faedd568f639623bd203)
@@ -10,4 +10,7 @@
  */
 import express from 'express';
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
 import db from '../config/database.js';
 import { requireAuth } from '../middleware/auth.js';
@@ -17,4 +20,15 @@
 
 const router = express.Router();
+
+// Cache-bust the PWA assets: /assets is served with a 1-year cache, so without
+// a per-build version the browser keeps running an old guardian.js/css after a
+// deploy (that was exactly the "no feedback / not arriving" bug). The version
+// is the file's mtime at process start; a redeploy restarts us and bumps it.
+const __dir = path.dirname(fileURLToPath(import.meta.url));
+function assetVersion(rel) {
+  try { return Math.floor(fs.statSync(path.join(__dir, '..', 'assets', rel)).mtimeMs).toString(36); }
+  catch { return '0'; }
+}
+const ASSET_V = { js: assetVersion('js/guardian.js'), css: assetVersion('css/guardian.css') };
 
 /** The acting site: ?site=slug when owned, else the user's first site. */
@@ -64,4 +78,5 @@
     sites,
     lang: L,
+    assetV: ASSET_V,
     t: (k, v) => i18nT(L, k, v),
     cspNonce: res.locals.cspNonce,
