Index: test/follow-gating.test.js
===================================================================
--- test/follow-gating.test.js	(revision d1075a16677d12c60b0d792c821a5baea451185d)
+++ test/follow-gating.test.js	(revision 3a0ca0f34e3f112899e4fdc916ec87010867dc3e)
@@ -22,8 +22,21 @@
 });
 
-test('all-quorum: needs every guardian', () => {
+test('een eenvoudige meerderheid beslist: 1 van 2 is genoeg', () => {
+  // WAS: 'all-quorum: needs every guardian'. Barts besluit (8-8) vervangt de
+  // any/all-tweedeling door een meerderheid, en "1/2 is voldoende" waren zijn
+  // woorden. De 'all'-stand die deze toets bewaakte werd nergens gezet -- elke
+  // schrijver gaf 'any' mee -- dus het was een keuze die niemand kon maken.
   G.follows.recordPending('kid', { id: 'f2', follower: STRANGER, inbox: `${STRANGER}/inbox`, quorum: 'all' });
-  assert.equal(G.follows.decide('f2', MOM, 'approve', [MOM, DAD]).outcome, 'waiting');
-  assert.equal(G.follows.decide('f2', DAD, 'approve', [MOM, DAD]).outcome, 'approved');
+  assert.equal(G.follows.decide('f2', MOM, 'approve', [MOM, DAD]).outcome, 'approved');
+});
+
+test('bij drie guardians is een enkele ja NIET meer genoeg', () => {
+  // De andere kant van hetzelfde besluit: tot vandaag stond dit op 'any', en
+  // dan was een enkele ja genoeg hoeveel guardians er ook waren. Voor iedereen
+  // met drie of meer is dit dus een aanscherping.
+  const GRAN = 'https://gran.example/u/gran';
+  G.follows.recordPending('kid', { id: 'f2b', follower: STRANGER, inbox: `${STRANGER}/inbox` });
+  assert.equal(G.follows.decide('f2b', MOM, 'approve', [MOM, DAD, GRAN]).outcome, 'waiting');
+  assert.equal(G.follows.decide('f2b', DAD, 'approve', [MOM, DAD, GRAN]).outcome, 'approved');
 });
 
Index: test/guardian-follow-queues.test.js
===================================================================
--- test/guardian-follow-queues.test.js	(revision d1075a16677d12c60b0d792c821a5baea451185d)
+++ test/guardian-follow-queues.test.js	(revision 3a0ca0f34e3f112899e4fdc916ec87010867dc3e)
@@ -85,2 +85,34 @@
   assert.ok(inn.includes('f-oud'));
 });
+
+// ── De drempel voor een volgverzoek (Barts besluit, 8-8) ────────────────
+
+test('een eenvoudige meerderheid: 1 van 2 is voldoende', () => {
+  // Barts woorden. Bewust soepeler dan de POORTdrempel: een gate opent een deur
+  // voor alles wat daarna komt, een volgverzoek gaat over een persoon en is met
+  // ontvolgen terug te draaien.
+  assert.equal(G.follows.followThreshold(1), 1);
+  assert.equal(G.follows.followThreshold(2), 1);
+  assert.equal(G.follows.followThreshold(3), 2);
+  assert.equal(G.follows.followThreshold(4), 2);
+});
+
+test('en dat is een AANSCHERPING, geen versoepeling', () => {
+  // Tot vandaag stond dit op 'any': een enkele ja, hoeveel guardians er ook
+  // waren. Bij drie of meer is er nu meer nodig, niet minder.
+  assert.ok(G.follows.followThreshold(3) > 1);
+  assert.ok(G.follows.followThreshold(5) > 1);
+});
+
+test('nul guardians vraagt nog steeds iemand', () => {
+  // Een lege set mag nooit "iedereen is het eens" opleveren. Dat is de stille
+  // fout waarmee een verzoek zichzelf goedkeurt.
+  assert.equal(G.follows.followThreshold(0), 1);
+});
+
+test('de drempel voor een POORT blijft strikter', () => {
+  // Twee verschillende vragen, twee drempels, en dat verschil is opzet: 2 van 2
+  // voor een gate, 1 van 2 voor een volgverzoek.
+  assert.equal(G.gated.thresholdFor(2), 2);
+  assert.equal(G.follows.followThreshold(2), 1);
+});
Index: test/outgoing-follow-gate.test.js
===================================================================
--- test/outgoing-follow-gate.test.js	(revision d1075a16677d12c60b0d792c821a5baea451185d)
+++ test/outgoing-follow-gate.test.js	(revision 3a0ca0f34e3f112899e4fdc916ec87010867dc3e)
@@ -110,2 +110,44 @@
   assert.equal(again.status, 'denied', 'tapping follow again does not put it back in front of mum');
 });
+
+// ── De poort zit in followActor, niet alleen in C2S (Barts melding 8-8) ──
+//
+// Esmee's volgverzoeken kwamen nooit bij haar guardians aan. Niet omdat een
+// guardian elders ze niet kon beantwoorden -- die weg werkt -- maar omdat er
+// nooit een verzoek werd aangemaakt: de poort stond in `case 'Follow'` van de
+// C2S-outbox, en dus alleen als je via Shaer volgt. Vanuit Klonkts eigen
+// webinterface liep je er zo omheen.
+//
+// Dezelfde deur-naast-de-poort als bij de antwoordpoort (shaer-r4c), en de reden
+// dat die mutatie 0 fouten gaf: er stond niets op.
+
+test('een ward die vanaf het WEB volgt wordt ook tegengehouden', async () => {
+  const uit = await AP.followActor(kid, 'https://elders.example/users/webvriend');
+  assert.equal(uit.held, true, 'vastgehouden, niet gevolgd');
+  assert.equal(uit.status, 'pending');
+  // En er ligt echt iets voor de guardians, anders is "held" een leeg gebaar.
+  assert.ok(G.outgoing.findFor('kid', 'https://elders.example/users/webvriend'));
+});
+
+test('ook als het kind met een HANDLE volgt', async () => {
+  // De poort staat NA het oplossen. Zou hij alleen naar de ruwe invoer kijken,
+  // dan is elke @naam@server een sluiproute -- de fout die we hier repareren,
+  // een maat kleiner.
+  const uit = await AP.followActor(kid, 'https://elders.example/users/handlevriend');
+  assert.equal(uit.held, true);
+});
+
+test('een goedgekeurd verzoek komt er WEL doorheen', async () => {
+  // Zonder deze doorlaat stuit een goedgekeurd verzoek opnieuw op de poort en
+  // wacht het voor eeuwig -- de poort zou zichzelf voeden.
+  const uit = await AP.followActor(kid, 'https://elders.example/users/webvriend', false, { approved: true });
+  assert.notEqual(uit.held, true);
+});
+
+test('een site ZONDER guardians merkt er niets van', async () => {
+  // Een volwassen account is geen ward. Zou de poort daar ook dichtklappen, dan
+  // kan niemand op deze instance nog iemand volgen.
+  const vrij = site('vrij');
+  const uit = await AP.followActor(vrij, 'https://elders.example/users/iemand');
+  assert.notEqual(uit && uit.held, true);
+});
