fix: vier publicatieblokkades — starttaal, projectadres, checksum-claim, onzichtbare placeholders #652

Merged
brenno merged 5 commits from fix/publicatie-blokkades into main 2026-07-22 17:00:32 +00:00
Owner

Vier van de vijf zwaarste bevindingen uit de publicatiereview. #571 zat al in
een parallelle tak en is hier niet bij.

#572 — de app startte voor iedereen ter wereld in het Nederlands.
settings_provider.dart viel terug op 'nl' en de systeemtaal werd nergens
geraadpleegd (nul aanroepen van PlatformDispatcher in lib/). Dat trof niet
alleen de interface: het toestemmingsscherm mét privacyverklaring is het eerste
wat je ziet en je moet er een vinkje zetten. De terugval is nu Engels, niet
Nederlands — wie een taal opgeeft die wij niet spreken leest met veel grotere
kans Engels. Alleen de startwaarde; een eigen keuze wint altijd.

#573 — het adres van dit project stond in geen enkel publiek document.
Twee gidsen zeiden letterlijk git clone <repository-url>. Dat is erger dan het
lijkt, want 22 van deze documenten zitten als asset in de app en worden daar
gelezen, volledig losgekoppeld van de host. Toegevoegd: een "Where this lives"-
blok in de README, repository:/issue_tracker: in pubspec, en de vier
trackerverwijzingen zijn links geworden. Ook opgelost: CONTRIBUTING zei "branch
from the default branch" (push-rechten die een buitenstaander niet heeft)
terwijl GUIDELINES "fork the repository" zei.

#574 — de checksum-claim over EU-identiteitsnummers was onwaar.
Vier regels hebben geen checksum, en de code zegt dat zelf in commentaar dat de
auteur er juist bij schreef om eerlijk te zijn (dk.cpr, uk.nino, mt.id,
li.peid). Alle vier staan op PrivacyConfidence.likely met verplichte
contextwoorden — nagetrokken, niet aangenomen. De claim was fout, niet de code.
PRIVACY.md telde er twee.

#583 — een tip zag eruit als ingevulde tekst.
Een scorecard-editor toonde een compleet ingevuld formulier in bijna-zwarte
tekst. Het waren placeholders; de dia was leeg, renderde wit, passeerde de
kwaliteitscontrole en exporteerde als lege pagina. De oorzaak zat niet in de
scorecard maar in het thema, dat helemaal geen hintStyle zette — dus élke
hintText in de app erfde de gewone tekstkleur. Daarom is de fix daar.

Wat de poort onderweg ving

Twee dingen die het waard zijn om te noemen, omdat ze zonder de poort waren
doorgegaan:

  1. De taalwijziging brak 97 widgettests: die zoeken Nederlandse knopteksten
    en de app startte nu in de taal van de machine. Opgelost met
    test/flutter_test_config.dart, dat de starttaal één keer voor de hele suite
    vastzet. Op een Nederlandse machine was dit nooit opgevallen, en dát is het
    punt — de suite hoorde sowieso niet van de landinstelling af te hangen.
  2. Mijn eerste kleurkeuze (scheme.onSurfaceVariant) lag maar 0,04 luminantie
    van de gewone tekstkleur af. De test rekende het na en stond terecht rood; het
    is nu muted, de gedempte tekstkleur die dezelfde functie al berekent.

Wat hier NIET in zit

De tweede helft van #583: de kwaliteitscontrole meldt een lege dia nog steeds
niet. Dat vraagt een nieuw SlideQualityIssueKind — zes bestanden en 31
vertalingen — en dat is geen bijvangst van deze PR. #583 blijft daarvoor open.

Waarborgen

make check groen op de huidige main (exitcode 0, 5650 tests). Twee keer
gerebased tijdens het werk omdat main zes commits opschoof; geen conflicten, en
na elke rebase opnieuw gedraaid — de laatste keer ving dat een echte interactie
met de net uitgebreide corpuspoort.

Elke wijziging heeft een test die eerst rood stond: de taalresolutie in beide
richtingen, en het tipcontrast in licht én donker thema.

Vier van de vijf zwaarste bevindingen uit de publicatiereview. #571 zat al in een parallelle tak en is hier niet bij. **#572 — de app startte voor iedereen ter wereld in het Nederlands.** `settings_provider.dart` viel terug op `'nl'` en de systeemtaal werd nergens geraadpleegd (nul aanroepen van `PlatformDispatcher` in `lib/`). Dat trof niet alleen de interface: het toestemmingsscherm mét privacyverklaring is het eerste wat je ziet en je moet er een vinkje zetten. De terugval is nu Engels, niet Nederlands — wie een taal opgeeft die wij niet spreken leest met veel grotere kans Engels. Alleen de startwaarde; een eigen keuze wint altijd. **#573 — het adres van dit project stond in geen enkel publiek document.** Twee gidsen zeiden letterlijk `git clone <repository-url>`. Dat is erger dan het lijkt, want 22 van deze documenten zitten als asset in de app en worden daar gelezen, volledig losgekoppeld van de host. Toegevoegd: een "Where this lives"- blok in de README, `repository:`/`issue_tracker:` in pubspec, en de vier trackerverwijzingen zijn links geworden. Ook opgelost: CONTRIBUTING zei "branch from the default branch" (push-rechten die een buitenstaander niet heeft) terwijl GUIDELINES "fork the repository" zei. **#574 — de checksum-claim over EU-identiteitsnummers was onwaar.** Vier regels hebben geen checksum, en de code zegt dat zelf in commentaar dat de auteur er juist bij schreef om eerlijk te zijn (dk.cpr, uk.nino, mt.id, li.peid). Alle vier staan op `PrivacyConfidence.likely` met verplichte contextwoorden — nagetrokken, niet aangenomen. De claim was fout, niet de code. PRIVACY.md telde er twee. **#583 — een tip zag eruit als ingevulde tekst.** Een scorecard-editor toonde een compleet ingevuld formulier in bijna-zwarte tekst. Het waren placeholders; de dia was leeg, renderde wit, passeerde de kwaliteitscontrole en exporteerde als lege pagina. De oorzaak zat niet in de scorecard maar in het thema, dat helemaal geen `hintStyle` zette — dus élke `hintText` in de app erfde de gewone tekstkleur. Daarom is de fix daar. ## Wat de poort onderweg ving Twee dingen die het waard zijn om te noemen, omdat ze zonder de poort waren doorgegaan: 1. De taalwijziging brak **97 widgettests**: die zoeken Nederlandse knopteksten en de app startte nu in de taal van de machine. Opgelost met `test/flutter_test_config.dart`, dat de starttaal één keer voor de hele suite vastzet. Op een Nederlandse machine was dit nooit opgevallen, en dát is het punt — de suite hoorde sowieso niet van de landinstelling af te hangen. 2. Mijn eerste kleurkeuze (`scheme.onSurfaceVariant`) lag maar **0,04 luminantie** van de gewone tekstkleur af. De test rekende het na en stond terecht rood; het is nu `muted`, de gedempte tekstkleur die dezelfde functie al berekent. ## Wat hier NIET in zit De tweede helft van #583: de kwaliteitscontrole meldt een lege dia nog steeds niet. Dat vraagt een nieuw `SlideQualityIssueKind` — zes bestanden en 31 vertalingen — en dat is geen bijvangst van deze PR. #583 blijft daarvoor open. ## Waarborgen `make check` groen op de huidige main (exitcode 0, 5650 tests). Twee keer gerebased tijdens het werk omdat main zes commits opschoof; geen conflicten, en na elke rebase opnieuw gedraaid — de laatste keer ving dat een echte interactie met de net uitgebreide corpuspoort. Elke wijziging heeft een test die eerst rood stond: de taalresolutie in beide richtingen, en het tipcontrast in licht én donker thema.
De app viel voor iedereen ter wereld terug op 'nl'. Dat trof niet alleen de
interface: het toestemmingsscherm met de privacyverklaring is het eerste wat
je ziet en je moet er een vinkje zetten voor je verder komt. Instemmen in een
taal die je niet leest is precies wat dit project bij anderen zou aanwijzen.

De systeemtaal werd nergens geraadpleegd — geen enkele aanroep van
PlatformDispatcher in lib/. De 32 talen lagen klaar; alleen de startwaarde
wees naar Nederland.

Terugval is nu Engels en niet Nederlands. Wie een taal opgeeft die wij niet
spreken, leest met veel grotere kans Engels. Dit gaat alleen over de
startwaarde: een eigen keuze staat in de voorkeuren en wint altijd.

De resolutie staat bij AppLocalizations, dat de talenlijst al bezit, en de
aanroep in settings_provider is een losse functie buiten SettingsNotifier —
die klasse staat dicht tegen haar regelplafond.

Zie #572.
Het adres van de repo stond in geen enkel publiek document. Twee gidsen
instrueerden letterlijk `git clone <repository-url>`, en zes passages
verwezen naar "the Forgejo tracker" zonder te zeggen waar die staat.

Dat is erger dan het lijkt, want deze documenten reizen: 22 ervan zitten als
asset in de app en worden daar gelezen, volledig losgekoppeld van de host.
Die lezer kon het project niet vinden, geen bug melden en de bouwinstructie
niet uitvoeren. Het enige adres dat wél overal stond is security@librekat.nl,
dus elk kanaalloos verzoek kwam in de beveiligingsbus terecht.

Toegevoegd: een "Where this lives"-blok in de README met repo, tracker en
meldadres, plus de mededeling dat er geen CI-runner is en `.github/` dus
definities bevat die niemand uitvoert. In pubspec staan nu repository: en
issue_tracker:. De vier trackerverwijzingen zijn links geworden.

Ook opgelost: CONTRIBUTING zei "branch from the default branch" (wat push-
rechten veronderstelt die een buitenstaander niet heeft) terwijl
CONTRIBUTING_GUIDELINES "fork the repository" zei. Nu één route.

Zie #573.
De README beweerde dat elk nationaal identiteitsnummer "validated by its own
checksum" is. Vier regels hebben er geen, en de code zegt dat zelf in het
commentaar dat de auteur er juist bij schreef om eerlijk te zijn:

- dk.cpr — de mod-11-controle is in 2007 losgelaten omdat de nummers opraakten
- uk.nino — strak formaat, geen controlecijfer
- mt.id — "Er is geen checksum, en die verzinnen we niet"
- li.peid — geen checksum, geen datum, geen prefix

Alle vier staan op PrivacyConfidence.likely met verplichte contextwoorden
(nagetrokken in privacy_eu_rules.dart:176 en :261). Dat is precies goed; de
claim was fout, niet de code. Een checksum verzinnen zou echte nummers
afwijzen — de verkeerde fout.

PRIVACY.md telde er twee en noemde alleen Malta en Liechtenstein, terwijl
OCIWACHT.md alle vier al goed had staan.

De weerlegging kostte één `grep -n checksum`. Dat is het soort claim dat bij
publicatie de rest van het privacyverhaal meesleurt.

Zie #574.
Een scorecard-editor toonde een compleet ingevuld formulier — titel, kengetal,
waarden — in bijna-zwarte tekst. Het waren placeholders. De dia was leeg, ze
renderde wit, de kwaliteitscontrole zei "geen problemen", en de export leverde
een lege witte pagina. Dat bleek pas op de beamer.

De oorzaak zat niet in de scorecard. Het thema zette helemaal geen hintStyle,
dus elke hintText in de app erfde de gewone tekstkleur. Twee editors
repareerden dat zelf (alt_text_field, _editor_field); de rest niet. Daarom is
de fix hier en niet in scorecard_editor.

Niet scheme.onSurfaceVariant maar `muted`, de profielgestuurde gedempte
tekstkleur die deze functie al berekent: onSurfaceVariant ligt maar 0,04
luminantie van de gewone tekstkleur af — een verschil dat je met een
kleurenkiezer ziet en met het oog niet. De test rekent dat na in beide thema's
en stond eerst rood om precies die reden.

Ook hier ondergebracht: test/flutter_test_config.dart. Sinds de vorige commit
start een installatie zonder taalkeuze in de systeemtaal, en daardoor hingen
97 widgettests af van de landinstelling van de machine — ze zoeken Nederlandse
knopteksten. De suite zet de starttaal nu één keer vast op de brontaal. Op een
Nederlandse machine was dat nooit opgevallen, en dat is het punt.

Wat dit NIET oplost: de kwaliteitscontrole meldt een lege dia nog steeds niet.
Dat is de tweede helft van #583 en vraagt een nieuw SlideQualityIssueKind — zes
bestanden en 31 vertalingen.

Zie #583.
test(privacy): ons eigen meldadres is de afzender, geen bevinding
Some checks failed
CI / Gate (Linux) · Format · Analyze · Coverage (push) Failing after 4s
CI / Web hardening (push) Failing after 4s
CI / Docs links (push) Failing after 4s
CI / Supply-chain (Trivy · advisory) (push) Failing after 5s
CI / Gate (Linux) · Format · Analyze · Coverage (pull_request) Failing after 4s
CI / Web hardening (pull_request) Failing after 5s
CI / Docs links (pull_request) Failing after 5s
CI / Supply-chain (Trivy · advisory) (pull_request) Failing after 5s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Test (macos-latest) (pull_request) Has been cancelled
CI / Test (windows-latest) (pull_request) Has been cancelled
0ac018da22
De corpuspoort is net uitgebreid naar de Markdown in de wortel (#605), en de
README-sectie met het meldadres liet hem afgaan — niet op het adres zelf
(contact.email staat bewust buiten beschouwing), maar op "health" en
"biometric".

Dat is de co-occurrence-regel die precies doet wat hij moet doen: één
contactwaarde tilt elke artikel 9-term in hetzelfde bestand van waarschijnlijk
naar zeker. Alleen noemt de README die termen omdat hij de scánner beschrijft,
en staat security@librekat.nl er omdat een lezer het nodig heeft.

Opgelost met het begrip dat de app hier zelf voor heeft: OwnIdentity, hetzelfde
veld dat een gebruiker in de instellingen invult. Niet door de melding te
onderdrukken en niet door de README te verminken.

Zie #573.
brenno merged commit b043d5fc01 into main 2026-07-22 17:00:32 +00:00
Sign in to join this conversation.
No description provided.