Skip to content

Zet CI op met een statische controle op de projectregels - #2

Merged
chapter42 merged 1 commit into
docs/semver-en-pr-workflowfrom
chore/ci
Jul 27, 2026
Merged

chapter42 merged 1 commit into
docs/semver-en-pr-workflowfrom
chore/ci

Conversation

@chapter42

@chapter42 chapter42 commented Jul 27, 2026 •

Copy link
Copy Markdown
Owner

Gestapeld op #1. De base is docs/semver-en-pr-workflow omdat deze PR de Unreleased-kop uit #1 nodig heeft. Zodra #1 gemerged is, richt GitHub deze automatisch op main. Merge dus #1 eerst.

Wat

CI die bij elke PR draait, plus tools/check.js: een statische controle op de projectregels uit CLAUDE.md.

Waarom

De testsuite bewaakt gedrag. De harde regels in CLAUDE.md — geen dependencies, geen extra uitgaande aanroepen, geen storage.sync — drijven nu op discipline, terwijl SECURITY.md ze wel als belofte aan gebruikers presenteert. Die belofte hoort machinaal afgedwongen te zijn, niet met de hand bewaakt.

Wat tools/check.js controleert

Harde regels

  • geen npm-dependencies (de extensie moet zonder build-stap laadbaar blijven)
  • nergens chrome.storage.sync
  • geen andere uitgaande aanroepen dan de twee same-origin fetches achter Historie ophalen — met een expliciete allowlist, zodat uitbreiden een zichtbare wijziging in de diff vereist in plaats van ongemerkt te gebeuren
  • geen extra host_permissions, permissies of content-script matches
  • geen hardgecodeerde kleuren buiten het :root-blok van ui.css, zodat een wijziging niet stilzwijgend maar één thema ondersteunt

Structuur

  • laadvolgorde in het manifest (util.js eerst, interceptor.js laatst)
  • elke provider op schijf staat in het manifest én implementeert de kern van de interface
  • alle bestands-, HTML- en documentverwijzingen bestaan
  • versie gelijk in manifest.json en package.json, en aanwezig in de CHANGELOG
  • de iconen komen pixel-voor-pixel overeen met hun generator

Wat CI draait

check + testsuite op Node 20, 22 en 24, daarna fixture en previews bouwen.

Geen npm ci — dit project heeft geen dependencies en geen lockfile, dus dat zou falen. Workflow-permissies staan op contents: read.

De eerste CI-run faalde, en dat was terecht

De oorspronkelijke icoon-controle vergeleek bytes: regenereren en git diff --exit-code. Dat faalde meteen op alle drie de Node-versies — de op Linux gegenereerde PNG's waren 283/519/700/1851 bytes tegen 282/510/693/1837 op macOS. Identiek over alle Node-versies heen, dus geen Node-verschil maar zlib die per platform anders comprimeert. De pixels waren gelijk; alleen de DEFLATE-encoding week af.

De controle toetste dus het verkeerde. Byte-gelijkheid is geen garantie die zlib geeft, en ook niet wat we willen bewaken — wat telt is dat de vastgelegde iconen overeenkomen met wat de generator tekent.

check.js decodeert nu beide PNG's (inclusief alle vijf de scanline-filters) en vergelijkt de RGBA-buffers. make-icons.js exporteert daarvoor draw(); bij require() schrijft het niets meer naar schijf, dus de controle muteert de werkmap niet en de aparte CI-stap kon vervallen.

Hoe getest

  • npm test groen (23 controles + 108 checks)
  • CI groen op Node 20, 22 en 24
  • De icoon-controle bewezen op beide fronten: her-comprimeren op niveau 1 (873 bytes) en 6 (709 bytes) laat hem slagen, één omgeklapte pixelbyte laat hem falen met 1 bytes afwijkend
  • check.js faalt aantoonbaar op een echte overtreding: vóór de rebase ontbrak de Unreleased-kop en sloeg de controle terecht aan

Versie

  • geen bump — dit raakt de extensie zelf niet, alleen tooling

Checklist

  • Eén onderwerp in deze PR
  • Regel toegevoegd onder ## [Unreleased] in CHANGELOG.md
  • Geen nieuwe dependencies, host-permissies of uitgaande aanroepen

Na de merge

De status checks hebben nu gedraaid, dus GitHub laat ze als verplicht instellen. Zeg het als je wilt dat ik Node 20 / Node 22 / Node 24 toevoeg onder required_status_checks, zodat een PR pas te mergen is als de tests groen zijn.

🤖 Generated with Claude Code

De testsuite bewaakt gedrag; dit bewaakt de afspraken die je daar niet mee vangt.
Daarmee worden de harde regels uit CLAUDE.md — en dus de beloftes in SECURITY.md
— machinaal afgedwongen in plaats van op discipline te drijven:

- geen npm-dependencies (de extensie moet zonder build-stap laadbaar blijven)
- nergens chrome.storage.sync
- geen andere uitgaande aanroepen dan de twee same-origin fetches achter
  "Historie ophalen", met een expliciete allowlist zodat uitbreiden een
  zichtbare diff-wijziging vereist
- geen extra host_permissions, permissies of content-script matches
- geen hardgecodeerde kleuren buiten het :root-blok van ui.css
- versie gelijk in manifest.json en package.json, en aanwezig in de changelog
- iconen die pixel-voor-pixel overeenkomen met hun generator

Iconen worden bewust op pixels vergeleken en niet op bytes: zlib comprimeert per
platform anders, waardoor dezelfde tekening op Linux een andere PNG oplevert dan
op macOS. Een bytevergelijking faalde daardoor meteen in CI terwijl er niets mis
was. make-icons.js exporteert nu draw() en schrijft bij require() niets naar
schijf, zodat de controle de werkmap niet muteert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chapter42
chapter42 merged commit c2aa496 into docs/semver-en-pr-workflow Jul 27, 2026
3 checks passed
@chapter42
chapter42 deleted the chore/ci branch July 27, 2026 19:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant