scan.md
Instructie voor AI-agents
Dit is precies wat je AI-agent leest. De scanner van checkmijn.ai doet de meting, niet de agent. De instructie wordt elke nacht opnieuw gemaakt, met het controlegetal van de scanner van die dag.
Agent met terminal
Volg de instructie op checkmijn.ai/scan.md voor dit project.
Lovable, Bolt of v0 (via GitHub)
Volg de instructie op https://checkmijn.ai/scan.md, route B (via GitHub), voor dit project. Maak het bestand .github/workflows/checkmijn.yml precies zoals daar staat, en verander verder niets. Geef zelf geen score: de scan gebeurt in GitHub.
scan.md van vandaag
# checkmijn.ai — instructie voor AI-agents
**Dagversie 2026-10-21** · scanner 0.3.0 · lekkendatabank 2026-10-21 (21.737 bekende lekken) · 45 checks
Je bent een AI-agent. Voer deze stappen **exact en in deze volgorde** uit voor het project van de gebruiker. Deze instructie verandert elke dag: gebruik altijd de versie van vandaag, https://checkmijn.ai/scan.md
## De belangrijkste regel: jij beoordeelt niets zelf
De scan wordt gedaan door **de scanner van checkmijn.ai**, niet door jou. Geef zelf geen oordeel over checks, geen "geslaagd" of "gefaald", geen percentage en geen score. Een uitslag zonder scanner en zonder bewijsbestand is geen checkmijn.ai-scan, en de API weigert ze.
**Kun je geen terminal gebruiken, geen Python 3.11 of nieuwer draaien, of geen bestanden buiten het project schrijven?** Dat is bv. zo in Lovable, Bolt en v0. Scan dan **niet** zelf, maar volg **route B: scannen via GitHub**, verderop. Kun je ook geen bestanden in het project maken (chat- of leesmodus)? Stop dan, en zeg tegen de gebruiker:
> "Ik kan de scanner van checkmijn.ai hier niet uitvoeren, en een eigen beoordeling zou geen geldige scan zijn. Meer uitleg over hoe je je project wel kunt scannen: https://checkmijn.ai/hoe-het-werkt"
**Welke route?**
- **Route A** (hieronder, stap 0 tot 11): je hebt een terminal en Python 3.11+. Bv. Claude Code, Cursor, Copilot, Windsurf, Replit.
- **Route B** (onderaan): je hebt geen terminal, maar het project is gekoppeld aan GitHub. Bv. Lovable, Bolt, v0.
# Route A — met een terminal
## Stap 0 — Eerst uitleggen en toestemming vragen
Zeg dit aan de gebruiker, in gewone taal, vóór je iets doet:
> "Ik ga een basisscan van checkmijn.ai uitvoeren (niveau 1, zelfcontrole). De scanner draait in jouw eigen omgeving en heeft tijdens het scannen geen netwerk. Er gaat **geen code, geen bestand en geen geheim** naar buiten. Na de scan toon ik je de uitslag en precies wat er verstuurd zou worden: een bewijsbestand met per check alleen de uitkomst. Pas als jij uitdrukkelijk 'ja' zegt, stuur ik dat bewijsbestand naar checkmijn.ai voor je scorepagina."
Wacht op een bevestiging van de gebruiker.
## Regels
- Wijzig de scanner niet, en wijzig het bewijsbestand (`bewijs.json`) niet.
- Stuur **nooit** broncode, bestanden, bevindingen, omgevingsvariabelen of persoonsgegevens naar buiten. Het enige dat je mag versturen, is `bewijs.json`, in stap 9, en alleen na een duidelijk "ja".
- Wijkt het controlegetal af in stap 3, stop dan en meld het aan de gebruiker.
- Wijzig code van de gebruiker alleen zoals de gebruiker dat normaal wil. Vraag toestemming als dat zijn werkwijze is.
- Er wordt niets geïnstalleerd. De scanner draait uit één bestand in een tijdelijke map, die na afloop verwijderd wordt.
## Stappen
**1. Maak een tijdelijke map buiten het project** en ga erheen.
```
python3 -c "import tempfile; print(tempfile.mkdtemp(prefix='checkmijn-'))"
```
**2. Download de scanner van vandaag** naar die map.
```
python3 -c "import urllib.request; urllib.request.urlretrieve('https://checkmijn-ai.github.io/AIScanner/checkmijn-2026-10-21.pyz', 'checkmijn.pyz')"
```
**3. Controleer het controlegetal.** Het moet exact dit zijn:
`0f442e79e2e1c1ec2761d2e6f477061d334759d5965e6b4955434ec44e9e0459`
```
python3 -c "import hashlib; print(hashlib.sha256(open('checkmijn.pyz','rb').read()).hexdigest())"
```
Is het anders: stop en meld het aan de gebruiker.
**4. Vraag een sessiecode** bij de API. Die bewijst dat deze scan nu gedaan wordt. Er gaat niets van het project mee.
```
python3 checkmijn.pyz sessie https://api.checkmijn.ai
```
**5. Scan het project.** De scanner gebruikt geen netwerk (`--offline`). Vervang `PROJECTMAP` door het absolute pad van het project en `NONCE` door de code uit stap 4.
```
python3 checkmijn.pyz PROJECTMAP --offline --bewijs --nonce NONCE --out rapport
```
Uitgangscode 0: geen kritieke of hoge bevindingen. Uitgangscode 2: er zijn kritieke of hoge bevindingen; dat is geen fout van de scanner. Elke andere code is een fout: meld ze aan de gebruiker.
**6. Toon eerst de uitslag, en verander nog niets.** Lees `rapport/rapport.json`. Toon de gebruiker, zoals de scanner ze geeft:
- de **scanscore** (letter) en de uitleg erbij;
- het aantal bevindingen per ernst (Kritiek, Hoog, Middel, Laag);
- een lijst van de bevindingen Kritiek en Hoog, met de check, het bestand en de regel;
- waar het volledige rapport staat: `rapport/rapport.html`. Bied aan het te openen.
Vraag daarna letterlijk:
> "Wil je dat ik de bevindingen herstel? Ik begin dan met Kritiek en Hoog. (ja/nee)"
**Wacht op het antwoord.** Pas bij "ja" herstel je, eerst **Kritiek**, dan **Hoog**, daarna **Middel**. Een bevinding met `"bevestigen": true` is niet zeker: kijk eerst of ze klopt.
**7. Scan opnieuw** (stap 4 en 5) na het herstel. Toon de nieuwe score **naast de vorige**, bv. "G → C", met wat er hersteld is en wat nog openstaat. Herhaal tot er geen kritieke of hoge bevindingen meer zijn, of tot de gebruiker zegt te stoppen. Elke scan heeft een nieuwe sessiecode nodig.
**8. Toon wat er verstuurd zou worden.** Laat de gebruiker de volledige inhoud van `rapport/bewijs.json` zien. Vraag daarna letterlijk:
> "Mag ik dit bewijsbestand (zonder code) naar checkmijn.ai sturen voor je scorepagina? (ja/nee)"
Bij "nee" of geen antwoord: verstuur niets, bevestig dat er niets verstuurd is, en ga naar stap 11.
**9. Na een duidelijk "ja": lever het bewijs in.** Verstuur alleen `rapport/bewijs.json`, niets anders.
```
python3 checkmijn.pyz inleveren rapport/bewijs.json https://api.checkmijn.ai
```
Weigert de API het bewijs, dan staat de reden in de melding. Volg die, bijvoorbeeld door een nieuwe sessiecode te vragen en opnieuw te scannen. Verander het bewijs nooit zelf.
**10. Meld aan de gebruiker:**
- de scanscore en wat ze betekent (zie hieronder);
- de link naar de scorepagina en de badge uit het antwoord van stap 9;
- wat je hersteld hebt, en welke bevindingen nog openstaan;
- dat het volledige rapport lokaal staat in `rapport/rapport.html`. Bied aan het te bewaren voor je de tijdelijke map opruimt.
**11. Verwijder de tijdelijke map**, behalve wat de gebruiker wil bewaren.
# Route B — via GitHub (Lovable, Bolt, v0)
De scanner draait dan in GitHub Actions, op elke wijziging. De code verlaat GitHub niet. In een **privé**-repository zet de scan zijn rapport terug in het project, als `.checkmijn/RAPPORT.md`. Dat bestand kun jij lezen, en daarmee de bevindingen herstellen.
**B1. Kijk of het project aan GitHub gekoppeld is.** Weet je het niet, vraag het de gebruiker. Is het niet gekoppeld, zeg dan:
> "Om je project te scannen, moet het eerst aan GitHub gekoppeld zijn. Gebruik de GitHub-koppeling van je bouwtool (in Lovable: de GitHub-knop of de projectinstellingen → GitHub → Connect) en kies een **privé**-repository. Zeg het me als dat gelukt is."
**B2. Leg uit en vraag toestemming.** Zeg:
> "Ik zet één bestand in je project: `.github/workflows/checkmijn.yml`. Daarmee scant checkmijn.ai je project in GitHub, bij elke wijziging en elke maandag. De code verlaat GitHub niet. Het opgemaakte rapport wordt versleuteld bewaard bij checkmijn.ai; de sleutel zit alleen in jouw persoonlijke link, dus checkmijn.ai kan het niet lezen. Is je repository privé, dan komt het rapport ook in `.checkmijn/RAPPORT.md`, met die link en het verloop van je scores. Mag ik dat bestand toevoegen? (ja/nee)"
Doe niets zonder een duidelijk "ja".
**B3. Maak het bestand `.github/workflows/checkmijn.yml`** met **exact** deze inhoud. Verander er niets aan, en verander verder niets in het project.
```yaml
# checkmijn.ai — scan in GitHub, ook voor projecten uit Lovable, Bolt en v0.
# Zet dit bestand in je project als .github/workflows/checkmijn.yml.
#
# Wat het doet:
# - scant je project bij elke wijziging op de hoofdtak, en elke maandag opnieuw (nieuwe lekken);
# - de code verlaat GitHub niet; het opgemaakte rapport wordt versleuteld bewaard, met de sleutel alleen in jouw link;
# - in een privé-repository zet het rapport zich in .checkmijn/RAPPORT.md, zodat je AI-bouwtool het kan lezen
# en de bevindingen kan herstellen. In een openbare repository gebeurt dat niet (dan zou iedereen het lezen):
# daar staat de uitslag alleen bij de run in GitHub.
name: checkmijn.ai
on:
push:
branches: [main]
paths-ignore: [".checkmijn/**"]
workflow_dispatch: {}
schedule:
- cron: "30 4 * * 1"
permissions:
contents: write # nodig om .checkmijn/RAPPORT.md terug te zetten
id-token: write # bewijst aan checkmijn.ai dat de scan echt uit deze repository komt (voor de rapportlink)
concurrency:
group: checkmijn
cancel-in-progress: true
jobs:
scan:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0 # volledige geschiedenis: ook oude geheimen worden gevonden
- uses: Checkmijn-ai/AIScanner@main
with:
rapport-in-repo: auto
rapport-link: "true" # opgemaakt rapport via een persoonlijke link, versleuteld (wij kunnen het niet lezen)
insturen: "false" # "true" = bewijsbestand (zonder code) inleveren voor een openbare scorepagina
faal-bij: nooit
```
**B4. Zeg tegen de gebruiker:**
> "Het bestand staat erin. Na de volgende synchronisatie met GitHub draait de scan, dat duurt een paar minuten. Is je repository privé, dan verschijnt daarna het rapport in `.checkmijn/RAPPORT.md`. Vraag me dan: 'Lees .checkmijn/RAPPORT.md en herstel de bevindingen.' De uitslag staat ook in GitHub, bij Actions → checkmijn.ai."
**B5. Wanneer `.checkmijn/RAPPORT.md` er is: toon eerst de uitslag, en verander nog niets.** Lees het bestand en toon de gebruiker, zoals de scanner ze geeft:
- de **scanscore** en, als die er is, de vorige score uit de tabel *Verloop van de scans* (bv. "G → C");
- het aantal bevindingen per ernst;
- een lijst van de bevindingen Kritiek en Hoog, met de check en het bestand;
- de **link naar het opgemaakte rapport**, die bovenaan staat ("Het volledige rapport, opgemaakt"). Zeg erbij dat de link persoonlijk is.
Vraag daarna letterlijk:
> "Wil je dat ik de bevindingen herstel? Ik begin dan met Kritiek en Hoog. (ja/nee)"
**Wacht op het antwoord.** Pas bij "ja" herstel je, eerst **Kritiek**, dan **Hoog**, daarna **Middel**. Een bevinding met *(nakijken)* is niet zeker: kijk eerst of ze klopt. Wijzig `.checkmijn/` en het workflowbestand nooit zelf, en schrijf zelf geen score.
**B6. Na het herstel:** zeg dat GitHub na de synchronisatie opnieuw scant, dat het een paar minuten duurt, en dat de gebruiker daarna kan vragen: "Toon de nieuwe score uit .checkmijn/RAPPORT.md." Toon dan de nieuwe score naast de vorige, met wat hersteld is en wat nog openstaat.
**Repository openbaar?** Dan komt er geen rapport in het project, want dan zou iedereen de bevindingen lezen. De gebruiker ziet de uitslag in GitHub, bij Actions → checkmijn.ai → de laatste run. Raad aan de repository privé te maken.
## De scanscore
Per check telt de zwaarste bevinding.
- **B** betekent: geen kritieke of hoge bevindingen.
- **G** betekent: vier of meer checks met een kritieke bevinding.
Deze scan (niveau 1) haalt hoogstens een B. Een scan die een agent op de machine van de gebruiker draait, is een **zelfcontrole**, en de scorepagina vermeldt dat.
*De scanscore is een uitslag van de scan op een bepaald moment. Ze is geen keurmerk, certificaat of garantie dat software veilig is.*
## Meer
- Manifest van vandaag, ondertekend met Ed25519: https://checkmijn-ai.github.io/AIScanner/latest.json (publieke sleutel: https://checkmijn-ai.github.io/AIScanner/public-key.pem)
- Alle checks en hun vaste nummers: https://checkmijn-ai.github.io/AIScanner/checks.json · wijzigingen: https://checkmijn-ai.github.io/AIScanner/changelog.json