Index: src/routes/guardian.js
===================================================================
--- src/routes/guardian.js	(revision 329873ef53dfe145c0b016df53555fa8de5db70c)
+++ src/routes/guardian.js	(revision c8e03c6553401711c2e513b26dd53e24cc5a9486)
@@ -516,7 +516,14 @@
     // the proposal exists and a threshold of two can never be met.
     if (r.state === 'open') {
+      const wardActor = AP.actorId(base, localWard.slug);
       for (const g of Guardianship.listGuardians(localWard.slug).map((x) => x.other_uri)) {
         if (g === me) continue;
-        AP.deliverToActor(site, g, { ...offer, to: [g] }).catch(() => { /* queued */ });
+        // Signed by the ward, so the body must say the ward: anything else is
+        // a signer mismatch and the receiver answers 401 (as it should).
+        AP.deliverToActor(
+          db.prepare('SELECT * FROM sites WHERE slug = ?').get(localWard.slug),
+          g,
+          { ...offer, actor: wardActor, to: [g], 'shaer:proposer': me },
+        ).catch(() => { /* queued */ });
       }
     }
