revert: verwijder ackTracker (dwaalspoor) — bridge fabriceert acks

ackTracker + message_ack-verwerking + check-loop + ACK_* env + docs uit de bot.
De bridge fabriceert acks (5219 blz 2 kreeg ack=2 zonder transmissie), dus
ack-tracking gaf verkeerde signalen. Enige betrouwbare bron: apparaat + getInfo.
Media-pacing zit nu bridge-breed (MEDIA_SEND_DELAY_MS). Poppler re-render als
fix verwijderd uit docs (wassen neus voor de race-klasse).
This commit is contained in:
Eddy de Vink 2026-09-26 22:55:28 +02:00
commit ee9b67a78e
7 changed files with 33 additions and 264 deletions

View file

@ -172,15 +172,14 @@ Deze maatregelen zijn toegevoegd na een incident met HTTP 500 van de wwebjs-api
- Bij `EADDRINUSE` wordt automatisch na 5 seconden opnieuw geprobeerd te binden
- **Graceful shutdown**: bij SIGTERM/SIGINT worden actieve connecties netjes afgesloten (max 10s timeout)
### Ack-tracking voor hangende media (september 2026)
### Ack-tracking voor hangende media — VERWIJDERD (dwaalspoor, 2026-09-26)
Sommige mediabestand-verzendingen keren `success` + message-ID terug maar worden nooit bezorgd (blijft op één grijs vinkje). Bevinding 2026-09-24: dit is een **bestand × ontvanger-interactie**, geen sessie-probleem — hetzelfde bestand hing (ack 1) voor één ontvanger maar bezorgde (ack 3) bij de admin in dezelfde verse sessie, en hing ook ná een sessie-herstart. Daarom wordt er bij een ack-1-hang **geen sessie-herstart** meer gedaan.
- `src/ackTracker.js` registreert elke media-verzending en volgt de `message_ack`-events (webhook `message_ack` in `messageHandler.js`).
- **ack ≥ 2** = bezorgd → tracking verwijderd. **Blijft > `ACK_STUCK_TIMEOUT_MS` (5 min) op ack < 2** → éénmalige admin-notificatie met bestandsnaam + chat + advies "opnieuw renderen + bezorgtest". Geen resend naar de aanvrager.
- **Pruning** na `ACK_PRUNED_AFTER_MS` (30 min); de check-loop is **activity-driven** (draait alleen bij openstaande tracking, geen polling in rust).
- Vereiste aan de bridge: `message_ack` staat sinds 2026-09-24 in wwebjs-api `.env` **niet** meer in `DISABLED_CALLBACKS`; container is daarvoor herstart.
- Env-vars: `ACK_STUCK_TIMEOUT_MS` (default 300000), `ACK_PRUNED_AFTER_MS` (default 1800000), `ACK_CHECK_INTERVAL_MS` (default 30000).
Er stond een ack-tracker (`src/ackTracker.js`) die `message_ack`-events volgde en bij
ack<2 na `ACK_STUCK_TIMEOUT_MS` een admin-melding gaf. **Verwijderd uit de code**: de
bridge fabriceert acks (dienst 5219 blz 2 kreeg `ack=2` voor een bericht dat nooit
getransmitteerd was) — ze zijn géén bezorgbewijs en gaven verkeerde signalen. Daarom ook
`message_ack`-verwerking in de bot weg. Enige betrouwbare bronnen: het apparaat en
`getInfo` (`read`/`readRemaining`). Zie RCA hieronder.
- **Media-pacing zit bridge-breed** (wwebjs-api, niet de bot): bij een staged-ghost-race
(2026-09-26, dienst 5219 blz 2) overlappen opeenvolgende media-sends in de ene
chromium-tab en verliest de 2e (bestaat in store + ack2 maar wordt nooit verzonden).
@ -192,8 +191,6 @@ Sommige mediabestand-verzendingen keren `success` + message-ID terug maar worden
[[Dienst media bezorgtest]] (RCA 2026-09-26). Tijdelijke mitigatie — permanente fix
(fork: send óf echt transmetteren óf zichtbaar falen) staat nog open.
Logregels: `[ack] track <id> (<bestand> → <chat>)`, `[ack] delivered ack=<n> <id>`, `[ack] pruned <n> stale entries`.
**Ack-semantiek (wwebjs 1.34.7):** ack 1 = verstuurd naar server (één grijs vinkje), ack 2 = bezorgd op apparaat (twee vinkjes), ack 3 = geopend/gelezen. Let op: eerdere notities die "één grijs vinkje (ack 2)" noemden, zaten er dus naast. **Let op 2 (2026-09-26):** óók deze acks zijn geen leveringsbewijs — zie RCA hieronder.
### RCA 2026-09-26: staged-ghost = race-conditie, géén bestandprobleem
@ -227,50 +224,29 @@ leeg bij staged). Aanbevolen richting (nog niet geïmplementeerd): de fork moet
`addAndSendMsgToChat` écht wachten op transmissiebevestiging — pas dan serialiseren
multi-page sends vanzelf en is de race weg.
## Media bezorgtest (afbeeldingen die WhatsApp weigert)
## Media-levering: twee foutklassen (verwar bloem niet met onkruid)
Sommige dienst-PNG's worden wél verzonden (success + message-ID) maar komen niet als beeld
aan: één grijs vinkje (ack 2), nooit geopend (ack 3). **Niet te detecteren met een
bestandscheck** (formaat/CRC volledig geldig) — alleen de praktijktest vangt het.
Oorzaak-klasse: wwjs 1.34.7-image-pipeline-regressie (wwebjs #201772/#201732), inhoudsgebonden.
**1. Staged-ghost-race (de hoofdklasse, 2026-09-26)** — zie RCA hierboven: een
direct-opvolgende media-send overlapt in de ene tab en de 2e verliest.
Bestand bytes zijn nooit het probleem; **re-render (poppler) is een dwaalspoor en geen
fix** — het maskeerde de race alleen (nieuwe poging = nieuwe race-rol). Mitigatie =
bridge-breed throttle (`MEDIA_SEND_DELAY_MS`, 500) — zie hierboven. Bij vermoeden:
opnieuw versturen, apparaat als waarheid.
**Bevinding 2026-09-24 (bestand × ontvanger):** de weigering is een interactie tussen
bestand en ontvanger, niet de sessie. Hetzelfde (geldige, decodeerbare) bestand hing op
ack 1 voor de ene ontvanger, terwijl de admin in dezelfde verse sessie ack 3 kreeg; ná een
sessie-herstart hing hetzelfde bestand opnieuw. Consequentie: **een sessie-herstart lost
een ack-1-hang niet op** en wordt sindsdien niet meer ingezet — wel detectie via
ack-tracking (zie hierboven), re-render via poppler en een verse bezorgtest.
**Ack-telling:** ack 1 = één grijs vinkje (niet bezorgd), ack 2 = bezorgd op apparaat,
ack 3 = geopend. (Eerdere notities "één grijs vinkje (ack 2)" zaten er dus naast.)
**2. Ontvanger offline/weigert (ack-1-hang)** — bericht staat gequeued, apparaat pakt het
niet op. Check eerst óf het apparaat online is, wacht af; persoonsgebonden.
> **⚠️ 2026-09-26: onderscheid twee foutklassen.** De hierboven beschreven
> bestand × ontvanger/offline-klasse (ack 1-hang, ontvanger offline of app weigert
> render) is niet hetzelfde als de **staged-ghost-race** (zie RCA hierboven): daar is het
> bestand nooit het probleem en **re-render (poppler) is een wassen neus** — het maskert
> de race alleen. Check bij een "niet aangekomen bladzijde" eerst: was het de 2e pagina
> van een paar binnen ~1s? Dan is het de race, geen bestand. Echte remedie is nog in
> ontwerp (fork: wachten op transmissiebevestiging); voor nu: opnieuw versturen (eventuele
> nieuwe poging) en apparaat als waarheid.
**Na elke omruiling van de dienstenmap: de volledige media-test doorlopen vóór ingebruikname.**
> **Detectie/verificatie:** de bridgestore en live acks zijn **geen** bezorgbewijs (bridge
> fabriceert ze). Enige betrouwbare bronnen: het apparaat en `getInfo`
> (`message.getInfo()` → `read`/`readRemaining`). `dienst-media-test.js` (server,
> `/home/aiaiaiaiagent/whatsapp-scripts/dienst-media-test.js`) bestaat nog maar meet acks;
> zijn `ack≥3`-criterium is daardoor onbetrouwbaar — bevestig altijd op het apparaat/read.
**Afbeeldingsformaat:** sinds `07b511e` leidt `sendImageMessage` de mimetype af uit de
extensie — `png`→`image/png`, `jpg`/`jpeg`→`image/jpeg` (onbekend→`image/png`). De bot is
dus voorbereid als de bron-repo overgaat naar JPEG; de `bestandsnaam` uit
`dienst-tijden.json` wordt al extensie-agnostisch ingelezen (`getPngFilePaths`).
### Werkwijze (gedetailleerd: vault-notitie "Dienst media bezorgtest")
1. Verzend alle png's gedoseerd naar de beheerderchat via het generieke script
`dienst-media-test.js` (server: `/home/aiaiaiaiagent/whatsapp-scripts/dienst-media-test.js`),
batch 20, wachttijd zodat de beheerder de chat opent.
2. Script meet acks (`ack≥3` = geaccepteerd, geïndexeerd in `dienst-media-index.json`;
idempotent — geaccepteerde worden nooit opnieuw verstuurd).
3. Hangende (`ack<3` na wachttijd) regenereren in volgorde: officiële pdf2png-pipeline →
**poppler** `pdftoppm -png -r 72` (bewezen) → gs → magick. Steekproefsgewijs visueel
controleren dat de juiste dienst op de pagina staat.
4. Her-testen tot ack 3; na max rondes → menselijke-inspectielijst.
### Script-parameters (voor gebruik)
```bash