feat: meet doorlooptijd, ratchetbeweging en of de documentatie klopt #558

Merged
brenno merged 7 commits from feat/meetinstrumenten into main 2026-07-22 13:53:13 +00:00
Owner

Summary

The three measurement issues that came out of the CRA decision (#519). All three ask whether the work is good enough, not whether the code runs.

Closes #537
Closes #538
Closes #539

#537 — how long ordinary issues stay open

tool/check_issue_turnaround.dart (make doorlooptijd). Age per open issue and the oldest, time to first response (median and longest), how many are open with no response at all — the number that matters most — and triage issues that never moved. Security reports and PRs are excluded; they have their own norms.

Advisory is the default here, not a flag — the opposite of check_service_norms, because no deadline has been agreed for ordinary issues. --strict is ready for the day one is.

Against the real tracker: 8 open, 14 closed, exit 0.

#538 — are the ratchets actually moving

tool/check_ratchet_trend.dart (make ratchets). Thirteen baselines against a reference point N days back, read from the source text via git show, plus the longest-standing baseline entries and coverage per directory. Standing still is not an error; zero does not count as standing still.

It pays off immediately: 86.2% on average hides lib/widgets at 81.8%.

#539 — documentation that is true

test/docs_claims_match_code_test.dart, mechanical half only. Every currently **N** in CHECKS.md must name its constant and match it; every percentage next to "floor" must be one of the two real floors; every language count about the interface must equal AppLocalizations.languageNames.length.

Two real errors found by it: ARCHITECTURE.md claimed 31 translation files (there are 32), and the "Latest result" table quoted a budget of 21 that was removed on 22-07.

The rebase caught a genuine interaction

#518 landed a fourteenth baseline (classSizeBaseline) while this branch was in flight, and the new measurement's own test — "every baseline in tool/ is actually followed" — went red. That is the test doing precisely its job on day one.

While fixing it: the test typed the baseline count in as a 9, which made it fail on work that had nothing to do with it. That is the same defect docs_claims_match_code_test exists to prevent, one layer up. Now derived from the ratchet list itself.

Verification

Each report tested in both directions with fixed fixtures — quiet tracker versus planted deviation, everything shrinking versus baselines standing still, and four planted documentation lies (all four caught). 34 + 27 tests. No network in any test; the forge token comes from the keychain and appears in no code or fixture.

make check re-run by me after the rebase: exit 0.

Left deliberately

The monthly wiki overview from the #538 discussion (needs pushing), mutation testing per report (make mutate stays manual), the human half of #539, and no gate over the scale table in CHECKS.md — it is a dated snapshot, and a gate over it would go red on every new test file. All noted where they belong rather than silently dropped.

## Summary The three measurement issues that came out of the CRA decision (#519). All three ask whether the *work* is good enough, not whether the code runs. Closes #537 Closes #538 Closes #539 ## #537 — how long ordinary issues stay open `tool/check_issue_turnaround.dart` (`make doorlooptijd`). Age per open issue and the oldest, time to first response (median and longest), **how many are open with no response at all** — the number that matters most — and `triage` issues that never moved. Security reports and PRs are excluded; they have their own norms. Advisory is the **default** here, not a flag — the opposite of `check_service_norms`, because no deadline has been agreed for ordinary issues. `--strict` is ready for the day one is. Against the real tracker: 8 open, 14 closed, exit 0. ## #538 — are the ratchets actually moving `tool/check_ratchet_trend.dart` (`make ratchets`). Thirteen baselines against a reference point N days back, read from the *source text* via `git show`, plus the longest-standing baseline entries and coverage per directory. Standing still is not an error; zero does not count as standing still. It pays off immediately: **86.2% on average hides `lib/widgets` at 81.8%**. ## #539 — documentation that is true `test/docs_claims_match_code_test.dart`, mechanical half only. Every `currently **N**` in CHECKS.md must name its constant and match it; every percentage next to "floor" must be one of the two real floors; every language count about the interface must equal `AppLocalizations.languageNames.length`. **Two real errors found by it:** `ARCHITECTURE.md` claimed 31 translation files (there are 32), and the "Latest result" table quoted a budget of 21 that was removed on 22-07. ## The rebase caught a genuine interaction #518 landed a fourteenth baseline (`classSizeBaseline`) while this branch was in flight, and the new measurement's own test — *"every baseline in `tool/` is actually followed"* — went red. That is the test doing precisely its job on day one. While fixing it: the test **typed the baseline count in as a `9`**, which made it fail on work that had nothing to do with it. That is the same defect `docs_claims_match_code_test` exists to prevent, one layer up. Now derived from the ratchet list itself. ## Verification Each report tested in both directions with fixed fixtures — quiet tracker versus planted deviation, everything shrinking versus baselines standing still, and four planted documentation lies (all four caught). 34 + 27 tests. No network in any test; the forge token comes from the keychain and appears in no code or fixture. `make check` re-run by me after the rebase: exit 0. ## Left deliberately The monthly wiki overview from the #538 discussion (needs pushing), mutation testing per report (`make mutate` stays manual), the human half of #539, and no gate over the scale table in CHECKS.md — it is a dated snapshot, and a gate over it would go red on every new test file. All noted where they belong rather than silently dropped.
check_service_norms meet alleen beveiligingsmeldingen. Voor de gewone
tracker meet niets iets, terwijl een issue dat maanden stil ligt het
eerste is wat een buitenstaander ziet.

Dit instrument meet vier dingen uit tijdstempels die er toch al zijn:
leeftijd per open issue, tijd tot de eerste reactie, hoeveel er open
staan zonder enige reactie (dat getal telt het zwaarst), en issues die
op `triage` blijven staan.

Adviserend is hier de standaard en niet een vlag, andersom dan bij de
zusterpoort: voor gewone issues bestaat bewust geen afgesproken termijn.
Een deadline die je op een rustige week mist, maakt van een leermoment
een verwijt. Eerst een basislijn, dan pas het gesprek over een norm.
`--strict` staat klaar voor wie er later wel een afspreekt.

De ophaallaag staat apart (ForgeGegevens) zodat het rekenwerk zonder
forge te toetsen is: de test voert vaste gegevens in, doet geen enkele
netwerkvraag en draagt geen sleutel.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`make doorlooptijd` naast `make servicenormen`, en om dezelfde reden in
geen enkel verzameldoel: het heeft een persoonlijke leessleutel nodig,
en exit 2 ("kon niet meten") zou bij een medewerker zonder sleutel als
een defect in zijn wijziging lezen.

Beide doelen ontbraken in .PHONY. Dat is nu geen probleem omdat er geen
bestand zo heet, en precies daarom ziet niemand het tot het misgaat.

De CRA-positie noemde deze meting als eerste van drie richtingen; daar
staat nu bij wat er is uitgevoerd, zodat het besluit en de uitvoering
niet uit elkaar lopen. Bewust in assurance/ en niet in docs/: alles in
docs/ reist als asset met de app mee, en een cijfer over reactietijd
wordt daar een toezegging aan derden.

Closes #537

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
De poorten meten of iets werkt, niet of het beter wordt. Er staan
dertien basislijnen in tool/ met dezelfde afspraak — krimpen mag,
groeien niet — en niets liet zien of er ooit iets gekrompen is. Een
ratchet die een jaar stilstaat is geen bewaakte schuld maar een schuld
die comfortabel is gemaakt.

Dit instrument zet elke basislijn naast haar waarde op een ijkpunt (de
laatste commit voor N dagen terug, standaard 90), noemt de langst
staande basislijnregels, en splitst de dekking uit per map. Dat laatste
omdat een gemiddelde de zwakste map achter de sterkste verbergt.

Gelezen uit de brontekst en niet uit de geimporteerde constanten: de
waarde van toen is anders onbereikbaar, en juist het verschil is wat
hier gemeten wordt. Reikt het venster verder terug dan de geschiedenis,
dan valt het terug op de eerste commit en zegt dat erbij.

Stilstand is bewust geen fout. Nul telt niet als stilstand — daar valt
niets meer te winnen — en groei evenmin, want die vangt de poort zelf
al hard af.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`make ratchets`, en om dezelfde reden als de twee meetdoelen ernaast in
geen verzameldoel: het antwoord is een gesprek, geen poort.

In de CRA-positie staat nu bij de tweede richting wat er is uitgevoerd
en vooral wat níét: of een test werkelijk iets bewijst (mutatietesten)
en het maandelijkse beeld op de wiki blijven open. Een halve uitvoering
die als heel wordt genoteerd is erger dan geen notitie.

Closes #538

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs_registration_test bewaakt dat een document bereikbaar is. Dat is
leidingwerk; het zegt niets over de vraag of er iets waars in staat.
CHECKS.md schreef serviceUiImportBaseline op 8 terwijl de code 4 zei, en
het PR-sjabloon noemde 8 talen tegen een werkelijke 32 — allebei netjes
geregistreerd, allebei onwaar.

Deze poort houdt drie soorten beweringen tegen de code aan:

- elke "currently **N**" in CHECKS.md moet in dezelfde adem de constante
  noemen waar dat getal vandaan komt, en gelijk zijn aan die constante.
  De vindplaatsen komen uit de lijst in check_ratchet_trend.dart, zodat
  een nieuwe ratchet maar op één plek hoeft te worden aangemeld;
- elk percentage naast het woord "floor" is een van de twee echte
  vloeren;
- elke taaltelling die over de interface gaat, is het aantal talen in
  AppLocalizations. Tellingen over iets anders — het geloofslexicon
  heeft er 27 omdat EuroVoc er zoveel heeft — vallen er buiten.

Daarvoor is de proza in CHECKS.md op vijf plekken naar één vorm gebracht
(`constante`, currently **N**). Dat is geen opmaak maar de voorwaarde:
een getal zonder naam ernaast valt niet na te rekenen.

ARCHITECTURE.md sprak van 31 vertaalbestanden terwijl het er 32 zijn.
Gevonden door deze test, niet door een lezer.

De menselijke helft — is het te volgen, klopt het verhaal — zit hier
bewust niet in. Die is niet te automatiseren, en een test die doet alsof
verplaatst het probleem alleen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
De "Latest result"-tabel schreef "19 bestanden onder de vloer, tegen een
budget van 21". Dat budget (`filesBelowFloorBudget`) is op 22-07-2026
geschrapt; de poort faalt nu op élk bestand onder de vloer. Een tabel die
een verdwenen constante als geldende toestand opvoert, is precies de
soort onwaarheid waar #539 over gaat — alleen kan geen test hem vinden,
want het is een uitslag en geen bewering over een constante.

De getallen komen uit een eigen volledige `make check` van vandaag: exit
0, 5587 tests, 86,2% dekking, nul bestanden onder de per-bestandsvloer.
De alinea "wat deze run niet dekte" klopte ook niet meer en zegt nu wat
er wél en niet gedraaid is.

De schaal-tabel is bijgewerkt met dezelfde run, en er staat expliciet bij
dat die tellingen bewust géén poort krijgen: het is een momentopname, en
een test erover zou bij elk nieuw testbestand rood worden. De datum is de
waarborg, niet een assertie.

Closes #539

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(meting): volg ook de klasseratchet, en leid het aantal af
Some checks failed
CI / Gate (Linux) · Format · Analyze · Coverage (pull_request) Failing after 4s
CI / Web hardening (pull_request) Failing after 4s
CI / Docs links (pull_request) Failing after 4s
CI / Supply-chain (Trivy · advisory) (pull_request) Failing after 4s
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 / Test (macos-latest) (pull_request) Has been cancelled
CI / Test (windows-latest) (pull_request) Has been cancelled
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
f4c2a3eba7
De ratchetmeting eiste terecht dat élke basislijn in tool/ gevolgd wordt,
en #518 voegde er net een toe: classSizeBaseline. Nu opgenomen.

De test typte het aantal basislijnen in check_conventions over als een 9.
Dat maakte hem rood op werk dat er niets mee te maken had — precies de
fout die docs_claims_match_code_test elders bestrijdt. Nu afgeleid uit de
ratchetlijst zelf.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brenno merged commit 6689e6c6e8 into main 2026-07-22 13:53:13 +00:00
brenno deleted branch feat/meetinstrumenten 2026-07-22 13:53:13 +00:00
Sign in to join this conversation.
No description provided.