176 lines
11 KiB
Markdown
176 lines
11 KiB
Markdown
# Fase 4 — Evaluatieprotocol
|
||
|
||
## Doel en huidige claimgrens
|
||
|
||
Het Phase-4-harnas maakt evaluatorgedrag, splits, ruwe voorspellingen en
|
||
releasebeslissingen reproduceerbaar. De lokale referentiecases zijn bewust
|
||
synthetisch en bewijzen uitsluitend dat het harnas correct en fail-closed
|
||
werkt. Zij zijn geen meting van productie-accuracy, België-brede
|
||
generaliseerbaarheid of menselijke aanvaardbaarheid.
|
||
|
||
De volledige workflow is:
|
||
|
||
```powershell
|
||
python scripts/run_accuracy_phase4_benchmark.py
|
||
```
|
||
|
||
De standaarduitvoering retourneert exitcode `2` zolang een productgate niet
|
||
groen is. Voor het uitsluitend regenereren en testen van lokale evidence mag:
|
||
|
||
```powershell
|
||
python scripts/run_accuracy_phase4_benchmark.py --allow-product-blocked
|
||
```
|
||
|
||
worden gebruikt. Die vlag verandert geen gate, score of beslissing. Hij maakt
|
||
alleen een succesvolle lokale harnascontrole bruikbaar in CI terwijl externe
|
||
productinput aantoonbaar ontbreekt.
|
||
|
||
## Geïmplementeerde taken
|
||
|
||
De inventaris scheidt geleerde modellen van deterministische GIS-analyse. Een
|
||
officiële of deterministische GIS-functie wordt niet kunstmatig als
|
||
machine-learningmodel voorgesteld.
|
||
|
||
De machineleesbare inventaris omvat 15 concrete platformcapabilities, gemapt
|
||
op zeven evaluatorfamilies. Een family-dekking geldt niet automatisch als een
|
||
zelfstandige benchmarkclaim voor iedere onderliggende microfunctionaliteit.
|
||
|
||
| Taakfamilie | Werkelijke implementatie | Phase-4-metrics | Huidige productstatus |
|
||
| --- | --- | --- | --- |
|
||
| Objectdetectie | `backend/app/services/detection_service.py` | precision, recall, F1, AP50, AP50–95, matched IoU, ECE, Brier, coverage-risk | evaluatorcontract groen; actieve modelbenchmark lokaal niet uitvoerbaar |
|
||
| Gebouwfootprintsegmentatie | `backend/app/services/segmentation_service.py` | object-P/R/F1, IoU, Dice, boundary F1, centroidafstand, relatieve oppervlaktefout, topologie | evaluatorcontract groen; geen representatieve beschermde productset bereikbaar |
|
||
| Vectorvergelijking en detectie-QA | `backend/app/services/qa_service.py`, `backend/app/services/detection_qa_service.py` | object-P/R/F1, mean IoU, topologische geldigheid | referentie-implementatie via de golden QA-fixtures uitgevoerd |
|
||
| Veranderingsdetectie | `backend/app/services/change_detection_service.py` | event-level P/R/F1, apart voor toegevoegd en verwijderd | evaluatorcontract groen; productbaseline niet vastgesteld |
|
||
| Thematische rasterinterpretatie | `backend/app/services/thematic_raster_analysis_service.py` en rasterservices | confusion matrix, pixelaccuracy, class-P/R/F1, class-IoU, mean IoU | alleen metriekcontract voor categorische rasters; er is geen geleerd generiek rasterclassificatiemodel aangetroffen |
|
||
| Hoogte- en terreininterpretatie | terrein-, hoogte-, bathymetrie- en overstromingsservices | MAE, RMSE, bias, coverage en foutverdeling in gedeclareerde eenheid | deterministische bronanalyse; referentiedata en eenheden blijven taakgebonden |
|
||
| Geospatiale datavalidatie | `backend/app/services/data_contract_validation.py` en Phase-3-scanner | anomaly-P/R/F1, blocker/critical misses | contractfixture groen; echte bronscan blijft de Phase-3-evidence |
|
||
|
||
Vector clip/buffer/intersect, ruimtelijke aggregatie, raster inspect/reproject/
|
||
clip/tile, NDVI/NDWI/NDBI, flood hazard, bathymetrie en AOI-partitionering
|
||
vallen onder de overeenkomstige deterministische validatie-, vector-, raster-
|
||
of terreinfamilie. De geo-assistent is een orkestratie-interface en krijgt geen
|
||
misleidende zelfstandige accuracy-score; de onderliggende toolresultaten
|
||
blijven maatgevend.
|
||
|
||
## Metriccontract
|
||
|
||
Alle objectmatches zijn one-to-one en gebruiken de vooraf vastgelegde
|
||
taakconfiguratie. Er is geen data-afhankelijke threshold-, operating-point- of
|
||
modelselectie op test-, background-test- of challenge-input. Vaste diagnostische
|
||
AP- en coverage-riskcurves veranderen het vooraf geregistreerde operating point
|
||
niet. Ongedefinieerde delingen worden `null` met expliciete support, niet
|
||
kunstmatig `1.0`.
|
||
|
||
| Uitvoertype | Verplichte kernmetingen | Aanvullende controle |
|
||
| --- | --- | --- |
|
||
| Objecten | TP, FP, FN, precision, recall, F1 | IoU, AP, calibration en abstention |
|
||
| Footprints | objectmetingen, mean IoU en Dice | boundary F1, centroid, area en topologie |
|
||
| Categorische rasters | confusion matrix, per-class F1/IoU, mean IoU | pixelaccuracy en class-support |
|
||
| Changes | event-level P/R/F1 per changeklasse | globale score mag een klasse niet maskeren |
|
||
| Continue hoogte | MAE, RMSE, bias | coverage, eenheid en foutverdeling |
|
||
| Validatie | anomaly-P/R/F1 | iedere gemiste blocker/critical anomaly blokkeert |
|
||
|
||
Voor binomiale precision en recall rapporteert het harnas 95%-Wilsonintervallen.
|
||
Bij te weinig support blijft de subgroepgate `not_evaluable`; de supportreden
|
||
blijft afzonderlijk zichtbaar. Een breed interval of ontbrekende metric is geen
|
||
positief bewijs. Voor een toekomstige productbenchmark moet bij ruimtelijk
|
||
geclusterde observaties bovendien een vooraf vastgelegde AOI- of
|
||
clusterbootstrap worden gebruikt in plaats van pixels als onafhankelijke
|
||
steekproeven te behandelen.
|
||
|
||
## Splitcontract en leakage-gates
|
||
|
||
`scripts/generate_accuracy_phase4_splits.py` genereert twee afzonderlijke,
|
||
gehashte manifesten uit één versieerbare bron:
|
||
|
||
- development: `train`, `val` en `calibration`;
|
||
- protected release only: immutable `test`, `background-test` en sealed
|
||
`challenge`.
|
||
|
||
Iedere sample draagt minimaal taak, split, `sample_id`, ruimtelijke `group_id`,
|
||
`source_family`, `temporal_family`, acquisition- en parent-rasteridentiteit,
|
||
native feature- en object-ID's, bounding box, ruwe en verwerkte imagehash,
|
||
labelhash, perceptual imagehash, labelgeometriehash en een canonieke recordhash.
|
||
Bij automatische toewijzing worden gekoppelde records eerst als één component
|
||
gegroepeerd. De generator faalt wanneer:
|
||
|
||
- een identiteit, object, bron-/tijdsfamilie, acquisition of parent-raster
|
||
meerdere splits raakt;
|
||
- exacte image-, label- of recordbytes meerdere splits raken;
|
||
- perceptuele of geometrische bijna-duplicaten meerdere splits raken;
|
||
- bounding boxes uit verschillende splits dichter liggen dan de vooraf
|
||
gedeclareerde onafhankelijkheidsbuffer;
|
||
- een verplichte split ontbreekt of een record niet valideerbaar is.
|
||
|
||
Bronvolgorde heeft geen invloed op de bron- of splitmanifesthash. De huidige
|
||
fixture bevat 21 samples over alle zes normatieve rollen en gebruikt een buffer
|
||
van 2.000 meter. Zij kan alleen door een expliciete codeparameter als synthetische
|
||
fixture worden geopend en draagt altijd `production_accuracy_use_allowed=false`.
|
||
Productiemodus vereist een strikt P3-manifest, exact provenance-record, vier
|
||
toegankelijke assetpaden en herberekende bytes-hashes. Dit is dus geen bewijs dat
|
||
het historische Belgische corpus onafhankelijk is. De Phase-3-bevinding van 24
|
||
cross-splitparen onder 2 km blijft blokkerend.
|
||
|
||
## Bescherming van test en challenge
|
||
|
||
De lokale workflow bindt evaluatie aan de exacte protected-manifesthash en
|
||
accepteert alleen de `test`- en `background-test`-ID's uit dat manifest.
|
||
Challengecases en -labels worden door de evaluator geweigerd. Configuraties zijn
|
||
vooraf vast. Per case bewaart `baseline-raw-predictions.json` de exacte
|
||
referenties, pre-filter- en post-filtervoorspellingen, configuratie en lineage.
|
||
`assert_training_inputs_safe()` en de twee echte trainingsdataset-builders
|
||
weigeren beschermde rollen, paden, inhoudshashes en alle relevante identiteit-
|
||
en lineagevelden. In productiemodus worden toegankelijke bronbytes en hun P3-
|
||
en provenancebinding opnieuw gecontroleerd; een padloos of hernoemd record faalt.
|
||
De regressietests bewijzen blokkering en een geldige development-run.
|
||
|
||
Dit is logische bescherming in de repository. Fysieke isolatie met een
|
||
afzonderlijke vault, beperkte credentials en een immutable accesslog is in de
|
||
huidige projectomgeving niet bewezen. Daarom staat
|
||
`protected_storage_isolation` in de productgates op `not_evaluable`; de lokale
|
||
firewall mag niet als vervanging voor die productcontrole worden beschreven.
|
||
|
||
## Stratificatie en failure-evidence
|
||
|
||
Iedere beschermde case declareert waar relevant regio/gemeente, stedelijk of
|
||
landelijk karakter, objectgrootte, bron/sensor, resolutie, seizoen/datum,
|
||
vegetatie/occlusie, moeilijkheid en context. Het metricrapport groepeert die velden en
|
||
legt support expliciet vast. Kritieke subgroepen moeten vóór een echte baseline
|
||
worden vastgesteld; ontbrekende of te kleine groepen blokkeren een release.
|
||
|
||
`baseline-raw-predictions.json` bewaart de ongesommeerde referenties,
|
||
pre-/postfiltervoorspellingen, matches, configuratie en lineage.
|
||
`failure-gallery.json` bewaart stabiele failure-ID's, taak, fouttype, strata en
|
||
concreet machineleesbaar bewijs. Een visuele gallery van echte productbeelden
|
||
kan pas worden gemaakt wanneer de beschermde imagery rechtmatig en gecontroleerd
|
||
bereikbaar is.
|
||
|
||
## Reproduceerbaarheid
|
||
|
||
Het benchmarkmanifest bindt repositorycommit, evaluator- en workflowversie,
|
||
alle drie Phase-4-scripts, de echte QA-service, bronfixtures, protected cases,
|
||
golden QA-fixture, Phase-3-manifesten, bronmatrix, metriekcontract, runtime en
|
||
beide splitmanifesten met SHA-256. Uit `status.json` wordt uitsluitend de
|
||
gate-relevante `/runtime/active_model`-projectie canoniek gehasht. Administratieve
|
||
velden zoals `generated_at`, Phase-4/5-status, documenten en evidence-run-ID's
|
||
zijn bewust geen benchmarkinput: zo kan het schrijven van de evidenceledger niet
|
||
zijn eigen runfingerprint veranderen. Review-, authority-, leakage-, vault- en
|
||
subgroepgates kunnen daardoor niet uit losse statusvelden slagen; zij vereisen
|
||
checksumgebonden product- en Phase-3-evidence. Een productbaseline wordt alleen
|
||
geaccepteerd wanneer dezelfde evaluator alle zeven taakfamilies in-process
|
||
herberekent en exact overeenkomt met checksumgebonden raw-, review-, authority-,
|
||
leakage-, vault- en CUDA-evidence. Dynamische UUID's uit de QA-service worden uit
|
||
de canonieke referentiescore verwijderd. Iedere run krijgt een content-addressed
|
||
ID; twee gelijke uitvoeringen leveren byte-identieke inhoud op en onverwachte
|
||
bestanden of submappen maken de immutable bundle ongeldig.
|
||
|
||
```powershell
|
||
python scripts/run_accuracy_phase4_benchmark.py --allow-product-blocked
|
||
python -m pytest backend/tests/test_accuracy_phase4_evaluation.py backend/tests/test_accuracy_phase4_evaluator_hardening.py backend/tests/test_accuracy_phase4_split_hardening.py -q -p no:cacheprovider
|
||
python -m ruff check scripts/accuracy_phase4_evaluator.py scripts/generate_accuracy_phase4_splits.py scripts/run_accuracy_phase4_benchmark.py backend/tests/test_accuracy_phase4_evaluation.py backend/tests/test_accuracy_phase4_evaluator_hardening.py backend/tests/test_accuracy_phase4_split_hardening.py
|
||
```
|
||
|
||
De machineleesbare bewijsset staat onder
|
||
`artifacts/evidence/accuracy/P4/runs/p4-2.0.1-9677d0ef37db82bcf39b/`. De
|
||
actuele fasebeslissing staat in `12-release-gates.md` en `status.json`.
|