Index: src/services/guardianship/queues.js
===================================================================
--- src/services/guardianship/queues.js	(revision 86e6a45456a85581974a889cf6f6eccef3c18081)
+++ src/services/guardianship/queues.js	(revision a9ede28626327289222785b8a329f0844e64ae17)
@@ -191,16 +191,35 @@
 // hetzelfde kind.
 
-/** De hulpvragen van deze guardian, met wie erop af is en of het dicht is. */
-export function helpItemsFor(slug, limit = 50) {
+/**
+ * De hulpvragen van deze guardian, met wie erop af is en of het dicht is.
+ *
+ * OPEN VRAGEN WORDEN NOOIT AFGEKAPT, en dat is geen ruimhartigheid maar de reden
+ * dat de app iets mag CONCLUDEREN uit afwezigheid (Barts punt, 8-8).
+ *
+ * Dit stond op 50, en ik noemde 'tientallen hulpvragen bij een guardian' een
+ * randgeval. Bart wees op de jeugdzorgmedewerker: die heeft geen handvol wards
+ * maar een caseload, en voor hem is dat een gewone dinsdag. De gebruiker die dit
+ * het hardst nodig heeft was precies degene voor wie het brak.
+ *
+ * Met een afkap op alles zag een app een oudere vraag niet in de queue, vond geen
+ * staat, en toonde hem -- terecht, want bij twijfel OPEN -- als openstaand. Een
+ * allang afgehandelde hulpvraag die weer om aandacht vraagt. Nu geldt: staat hij
+ * niet in de queue, dan is hij NIET open. Die gevolgtrekking klopt alleen zolang
+ * we open vragen volledig leveren.
+ *
+ * De geschiedenis mag wel afgekapt: die vraagt niets, en wat eraf valt is nog
+ * steeds op de server te vinden.
+ */
+export function helpItemsFor(slug, historyLimit = 50) {
   let rijen = [];
   try {
     rijen = db.prepare(
       `SELECT object_uri, actor_uri, actor_name, actor_handle, actor_icon, content, published, created_at
-       FROM ap_mentions WHERE slug = ? AND help_request = 1 ORDER BY created_at DESC LIMIT ?`,
-    ).all(slug, limit);
+       FROM ap_mentions WHERE slug = ? AND help_request = 1 ORDER BY created_at DESC`,
+    ).all(slug);
   } catch { return []; }
   const staat = help.statusFor(rijen.map((r) => r.object_uri));
   const mijn = new Set(relations.listWards(slug).map((w) => w.other_uri));
-  return rijen.map((r) => ({
+  const alles = rijen.map((r) => ({
     ...r,
     // Bij twijfel OPEN. Een hulpvraag die er afgehandeld uitziet terwijl hij dat
@@ -211,4 +230,7 @@
     ),
   }));
+  const open = alles.filter((h) => h.state.open);
+  const rest = alles.filter((h) => !h.state.open).slice(0, historyLimit);
+  return [...open, ...rest];
 }
 
@@ -231,4 +253,9 @@
     'shaer:formerWard': h.state.formerWard || undefined,
   }));
-  return collection(id, items);
-}
+  const coll = collection(id, items);
+  // Het teken dat de app mag concluderen uit afwezigheid: elke OPEN vraag zit
+  // hierin. Ontbreekt deze vlag (een oudere server), dan valt de app terug op
+  // bij-twijfel-open, en dat is de veilige kant.
+  coll['shaer:openComplete'] = true;
+  return coll;
+}
Index: test/activitypub-as2.test.js
===================================================================
--- test/activitypub-as2.test.js	(revision 86e6a45456a85581974a889cf6f6eccef3c18081)
+++ test/activitypub-as2.test.js	(revision a9ede28626327289222785b8a329f0844e64ae17)
@@ -43,4 +43,7 @@
   // de feed en wisten niet of er al iemand op af was.
   'shaer:queues', 'offers', 'follows', 'outgoingFollows', 'wards', 'guardians', 'help',
+  // Elke OPEN hulpvraag zit in de collectie; daarom mag een app uit afwezigheid
+  // concluderen dat iets niet open is (shaer-6wt).
+  'shaer:openComplete',
   // ActivityPub §4.1 `endpoints` vocabulary (same category as sharedInbox), used for C2S.
   'oauthAuthorizationEndpoint', 'oauthTokenEndpoint', 'uploadMedia',
Index: test/help-c2s.test.js
===================================================================
--- test/help-c2s.test.js	(revision 86e6a45456a85581974a889cf6f6eccef3c18081)
+++ test/help-c2s.test.js	(revision a9ede28626327289222785b8a329f0844e64ae17)
@@ -83,2 +83,27 @@
   assert.notEqual(uit.status, 400);
 });
+
+test('OPEN vragen worden nooit afgekapt, hoeveel het er ook zijn', () => {
+  // Barts punt (8-8): ik noemde tientallen hulpvragen bij een guardian een
+  // randgeval, maar voor een jeugdzorgmedewerker is dat een caseload en dus een
+  // gewone dinsdag. De gebruiker die dit het hardst nodig heeft was precies
+  // degene voor wie het brak.
+  //
+  // Zonder deze regel viel een oudere vraag buiten de queue, vond de app geen
+  // staat, en toonde hem -- terecht, want bij twijfel OPEN -- alsof er nog
+  // iemand op moest.
+  for (let i = 0; i < 120; i++) {
+    db.prepare(`INSERT INTO ap_mentions (slug, object_uri, actor_uri, actor_handle, content, help_request)
+                VALUES (?,?,?,?,?,1)`).run('oma', `https://elders.test/ap/notes/veel-${i}`, KIND, '@kind', '<p>help</p>');
+  }
+  const open = queues.helpItemsFor('oma').filter((h) => h.state.open);
+  assert.equal(open.length, 120, 'alle 120 open vragen komen mee');
+});
+
+test('de collectie zegt dat je uit afwezigheid mag concluderen', () => {
+  // Zonder die vlag mag een app niets afleiden uit een ontbrekende staat, en
+  // valt hij terug op bij-twijfel-open. Dat is de veilige kant, maar dan komt
+  // een afgehandelde vraag terug in het zicht.
+  const coll = queues.helpCollection('https://x/queues/help', 'oma');
+  assert.equal(coll['shaer:openComplete'], true);
+});
