[Bug] Een terzijdegelegde bevinding blokkeert de export zonder dat het paneel hem nog toont #740

Closed
opened 2026-07-23 12:41:48 +00:00 by brenno · 3 comments
Owner

Gevonden bij het nalopen van #651, nadat de knop en de ongedaan-lijst geland waren.

Wat er gebeurt. Leg een privacybevinding terzijde ("Deze is beoordeeld en mag blijven"). Het kwaliteitspaneel wordt stil — zo hoort het. Maar de exportpoort telt hem nog steeds als onafgehandeld, dus de export vraagt om een bevestiging (of blokkeert, afhankelijk van de instelling) op een bevinding die nergens meer te zien is.

Gereproduceerd, met de fixture uit test/privacy_dismissal_panel_test.dart:

alle bevindingen:      contact.email/certain
unresolved vóór:       1
paneel ná terzijdeleggen:   0
unresolved ná terzijdeleggen: 1

Waarom het misgaat. summarisePrivacyForExport (privacy_export_policy.dart) leest de ruwe scan en kijkt alleen naar de PrivacyDisposition van deck en dia. Een terzijdelegging staat daar niet in, dus blijft de bevinding unresolved, en evaluate onderbreekt zodra unresolved > 0.

Waarom dit erger is dan het klinkt. Het commentaar bij die poort zegt het zelf: "de gate straft geen persoonsgegevens af, hij straft onopgemerkte persoonsgegevens af." Een terzijdegelegde bevinding is per definitie opgemerkt — iemand heeft ernaar gekeken en een oordeel geveld. En de gebruiker kan niet meer zien waar de poort over valt, want het paneel toont hem niet meer. Dat is een blokkade zonder aanwijzing, en dat is precies het soort melding dat mensen leren wegklikken.

Dit is de open vraag uit FILE_FORMAT §6.7, nu met een symptoom. Twee richtingen, allebei met een prijs:

  1. Een terzijdelegging telt als afgehandeld, net als accept. Poort en paneel zeggen dan hetzelfde. Prijs: de poort meldt een schoonheid die de nalevingsteller (MIAUW EIS 1.1) met opzet weigert te melden — "beoordeeld en akkoord" is niet "opgelost".
  2. Hij blijft onafgehandeld, maar de poort noemt hem. De exportmelding zegt dan hoeveel terzijdegelegde bevindingen meetellen en waar ze staan. Prijs: de gebruiker houdt een onderbreking bij elke export, precies wat de globale regelschakelaar zo aantrekkelijk maakte.

Wat er ook gekozen wordt: de huidige toestand — onzichtbaar blokkeren — is geen van beide en hoort niet te blijven staan.

Regressietest hoort erbij, want dit valt tussen twee onderdelen in en geen van beide tests zag het: het paneel toetst dat de bevinding verdwijnt, de poorttests toetsen dispositions. Een toets die paneel en poort in één adem vergelijkt vangt precies dit.

Gevonden bij het nalopen van #651, nadat de knop en de ongedaan-lijst geland waren. **Wat er gebeurt.** Leg een privacybevinding terzijde ("Deze is beoordeeld en mag blijven"). Het kwaliteitspaneel wordt stil — zo hoort het. Maar de exportpoort telt hem nog steeds als *onafgehandeld*, dus de export vraagt om een bevestiging (of blokkeert, afhankelijk van de instelling) op een bevinding die nergens meer te zien is. **Gereproduceerd**, met de fixture uit `test/privacy_dismissal_panel_test.dart`: ``` alle bevindingen: contact.email/certain unresolved vóór: 1 paneel ná terzijdeleggen: 0 unresolved ná terzijdeleggen: 1 ``` **Waarom het misgaat.** `summarisePrivacyForExport` (privacy_export_policy.dart) leest de **ruwe** scan en kijkt alleen naar de `PrivacyDisposition` van deck en dia. Een terzijdelegging staat daar niet in, dus blijft de bevinding `unresolved`, en `evaluate` onderbreekt zodra `unresolved > 0`. **Waarom dit erger is dan het klinkt.** Het commentaar bij die poort zegt het zelf: *"de gate straft geen persoonsgegevens af, hij straft **onopgemerkte** persoonsgegevens af."* Een terzijdegelegde bevinding is per definitie opgemerkt — iemand heeft ernaar gekeken en een oordeel geveld. En de gebruiker kan niet meer zien waar de poort over valt, want het paneel toont hem niet meer. Dat is een blokkade zonder aanwijzing, en dat is precies het soort melding dat mensen leren wegklikken. **Dit is de open vraag uit FILE_FORMAT §6.7**, nu met een symptoom. Twee richtingen, allebei met een prijs: 1. **Een terzijdelegging telt als afgehandeld**, net als `accept`. Poort en paneel zeggen dan hetzelfde. Prijs: de poort meldt een schoonheid die de nalevingsteller (MIAUW EIS 1.1) met opzet weigert te melden — "beoordeeld en akkoord" is niet "opgelost". 2. **Hij blijft onafgehandeld, maar de poort noemt hem.** De exportmelding zegt dan hoeveel terzijdegelegde bevindingen meetellen en waar ze staan. Prijs: de gebruiker houdt een onderbreking bij elke export, precies wat de globale regelschakelaar zo aantrekkelijk maakte. Wat er ook gekozen wordt: **de huidige toestand — onzichtbaar blokkeren — is geen van beide** en hoort niet te blijven staan. **Regressietest hoort erbij**, want dit valt tussen twee onderdelen in en geen van beide tests zag het: het paneel toetst dat de bevinding verdwijnt, de poorttests toetsen dispositions. Een toets die paneel en poort in één adem vergelijkt vangt precies dit.
Author
Owner

Opgelost op main: 124d0cd0 (PR #745). Scherpe vondst — en het was mijn eigen fout uit #651: ik heb één lezer gerepareerd terwijl er twee waren.

De derde weg. Je schetste twee richtingen, allebei met een prijs. Er is er een die beide vermijdt, en de reden staat in je eigen citaat van het poortcommentaar: de gate straft geen persoonsgegevens af, hij straft onopgemerkte persoonsgegevens af. De poort en de nalevingsteller stellen dus verschillende vragen, en beide antwoorden kloppen tegelijk:

Vraagt Terzijdelegging telt als
Exportpoort: heb je hiernaar gekeken? gekeken — hij blokkeert niet
MIAUW EIS 1.1: hoeveel staat er in dit document? staat er nog — hij telt

Dus: de poort laat hem door (richting 1), en PrivacyExportSummary.setAside telt hem apart zodat de melding hem kan noemen (de transparantie van richting 2). Zonder de prijs van richting 1, want de nalevingsteller verandert niet en "beoordeeld en akkoord" blijft onderscheiden van "opgelost". En zonder de prijs van richting 2, want er komt geen onderbreking bij elke export.

Bewust níet opgeteld bij accepted: dat is een beslissing over een hele dia, dit over één treffer.

Eén predicaat voor beide lezers. setAsidePredicate staat nu in de privacylaag en wordt door het paneel én de poort gebruikt, met de aantekening erbij dat een derde lezer hem gebruikt in plaats van hem opnieuw te formuleren. Dat is de eigenlijke les van dit issue. summarisePrivacyForExport krijgt hem als parameter mee in plaats van zelf de scanner op te zoeken — die functie telt, zij scant niet.

De regressietest die je vroeg zit erbij, en precies in de vorm die je beschreef: een toets die paneel en poort in één adem vergelijkt. Vier tests; draai je de reparatie terug, dan vallen er drie om. De sterkste is de eigenschap zelf — wat het paneel toont is wat de poort tegenhoudt — want die vangt ook de volgende variant van dit gat.

FILE_FORMAT §6.7 draagt de uitkomst; dat stond daar als open vraag, nu met het antwoord en de tabel erbij.

make check groen: 5995 tests. Sluiten.

Opgelost op main: `124d0cd0` (PR #745). Scherpe vondst — en het was mijn eigen fout uit #651: ik heb één lezer gerepareerd terwijl er twee waren. **De derde weg.** Je schetste twee richtingen, allebei met een prijs. Er is er een die beide vermijdt, en de reden staat in je eigen citaat van het poortcommentaar: *de gate straft geen persoonsgegevens af, hij straft onopgemerkte persoonsgegevens af.* De poort en de nalevingsteller stellen dus verschillende vragen, en beide antwoorden kloppen tegelijk: | Vraagt | Terzijdelegging telt als | | --- | --- | | Exportpoort: *heb je hiernaar gekeken?* | gekeken — hij blokkeert niet | | MIAUW EIS 1.1: *hoeveel staat er in dit document?* | staat er nog — hij telt | Dus: de poort laat hem door (richting 1), en `PrivacyExportSummary.setAside` telt hem apart zodat de melding hem kan noemen (de transparantie van richting 2). Zonder de prijs van richting 1, want de nalevingsteller verandert niet en "beoordeeld en akkoord" blijft onderscheiden van "opgelost". En zonder de prijs van richting 2, want er komt geen onderbreking bij elke export. Bewust níet opgeteld bij `accepted`: dat is een beslissing over een hele dia, dit over één treffer. **Eén predicaat voor beide lezers.** `setAsidePredicate` staat nu in de privacylaag en wordt door het paneel én de poort gebruikt, met de aantekening erbij dat een derde lezer hem gebruikt in plaats van hem opnieuw te formuleren. Dat is de eigenlijke les van dit issue. `summarisePrivacyForExport` krijgt hem als parameter mee in plaats van zelf de scanner op te zoeken — die functie telt, zij scant niet. **De regressietest die je vroeg zit erbij**, en precies in de vorm die je beschreef: een toets die paneel en poort in één adem vergelijkt. Vier tests; draai je de reparatie terug, dan vallen er drie om. De sterkste is de eigenschap zelf — *wat het paneel toont is wat de poort tegenhoudt* — want die vangt ook de volgende variant van dit gat. FILE_FORMAT §6.7 draagt de uitkomst; dat stond daar als open vraag, nu met het antwoord en de tabel erbij. `make check` groen: 5995 tests. Sluiten.
Author
Owner

Besluit: optie 1 — een terzijdelegging telt voor de exportpoort als afgehandeld, net als accept. Opgepakt, tak: fix/exportpoort-terzijdelegging-740.

Reikwijdte: summarisePrivacyForExport in privacy_export_policy.dart (die leest de ruwe scan en kent alleen de disposition), de aanroep in privacy_provider.dart, en een regressietest die paneel en poort in één adem vergelijkt — want dat is precies de naad waar dit doorheen viel.

Wat ik daarbij bewaak: de nalevingsteller (MIAUW EIS 1.1) leest óók de ruwe scan en moet het volle aantal blijven zien. "Beoordeeld en akkoord" is niet "opgelost", en die twee mogen niet alsnog in elkaar schuiven omdat de poort ze gelijk behandelt.

Besluit: **optie 1** — een terzijdelegging telt voor de exportpoort als afgehandeld, net als `accept`. Opgepakt, tak: `fix/exportpoort-terzijdelegging-740`. Reikwijdte: `summarisePrivacyForExport` in `privacy_export_policy.dart` (die leest de ruwe scan en kent alleen de disposition), de aanroep in `privacy_provider.dart`, en een regressietest die paneel en poort in één adem vergelijkt — want dat is precies de naad waar dit doorheen viel. Wat ik daarbij bewaak: de nalevingsteller (MIAUW EIS 1.1) leest óók de ruwe scan en moet het volle aantal blijven zien. "Beoordeeld en akkoord" is niet "opgelost", en die twee mogen niet alsnog in elkaar schuiven omdat de poort ze gelijk behandelt.
Author
Owner

Ter aanvulling: je koos optie 1, en dat is precies wat er gebouwd is — door een parallelle sessie, vóórdat ik eraan begon (124d0cd0, PR #745). Ik heb daarom niets toegevoegd; wel nagemeten of het echt doet wat het belooft, want dat is het enige wat hier telt.

Gemeten op main, met de fixture uit privacy_dismissal_panel_test.dart:

unresolved vóór terzijdeleggen:  1
paneel ná:                       0
unresolved ná:                   0   ← de poort laat door
setAside ná:                     1   ← apart geteld
ruwe scan ná:                    1   ← MIAUW EIS 1.1 telt gewoon door

Alle vier de getallen kloppen met het besluit, inclusief de nuance die de prijs van optie 1 was: setAside staat als eigen telling naast unresolved in plaats van erin te verdwijnen, en de ruwe scan blijft de bevinding zien. "Beoordeeld en akkoord" en "opgelost" zijn dus nog steeds twee dingen — dat was mijn zorg bij deze optie, en die is afgedekt.

Mijn claim (in-progress) is eraf; er is niets van mij te wachten op dit issue.

Eén ding dat ik hierbij wil noteren, want het is de vierde keer vandaag. Dit issue heb ik zelf ingediend en binnen enkele minuten had een andere sessie hem opgelost. Dat is prima — het werkt — maar het patroon is inmiddels: ontwerp, opslaglaag, filter, en nu deze fix, allemaal dubbel begonnen. Wat structureel scheelt is claimen vóórdat je gaat lézen, niet vóórdat je gaat schrijven; dat staat al in de skill maar wordt duidelijk niet gehaald wanneer twee sessies binnen dezelfde minuut starten.

Ter aanvulling: **je koos optie 1, en dat is precies wat er gebouwd is** — door een parallelle sessie, vóórdat ik eraan begon (`124d0cd0`, PR #745). Ik heb daarom niets toegevoegd; wel nagemeten of het echt doet wat het belooft, want dat is het enige wat hier telt. Gemeten op main, met de fixture uit `privacy_dismissal_panel_test.dart`: ``` unresolved vóór terzijdeleggen: 1 paneel ná: 0 unresolved ná: 0 ← de poort laat door setAside ná: 1 ← apart geteld ruwe scan ná: 1 ← MIAUW EIS 1.1 telt gewoon door ``` Alle vier de getallen kloppen met het besluit, inclusief de nuance die de prijs van optie 1 was: `setAside` staat als eigen telling naast `unresolved` in plaats van erin te verdwijnen, en de ruwe scan blijft de bevinding zien. "Beoordeeld en akkoord" en "opgelost" zijn dus nog steeds twee dingen — dat was mijn zorg bij deze optie, en die is afgedekt. Mijn claim (`in-progress`) is eraf; er is niets van mij te wachten op dit issue. **Eén ding dat ik hierbij wil noteren, want het is de vierde keer vandaag.** Dit issue heb ik zelf ingediend en binnen enkele minuten had een andere sessie hem opgelost. Dat is prima — het werkt — maar het patroon is inmiddels: ontwerp, opslaglaag, filter, en nu deze fix, allemaal dubbel begonnen. Wat structureel scheelt is claimen vóórdat je gaat lézen, niet vóórdat je gaat schrijven; dat staat al in de skill maar wordt duidelijk niet gehaald wanneer twee sessies binnen dezelfde minuut starten.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#740
No description provided.