Files
geointel/docs/accuracy-program/03-baseline-and-gaps.md
T

21 KiB
Raw Blame History

GeoIntel Accuracy Improvement Program — 03 Baseline en gaps

1. Phase-1-oordeel

De technische foundation draait: frontend, API, PostGIS, jobs, datasetopslag, een echte Ultralytics/PyTorch-adapter en NVIDIA CUDA-inference zijn aantoonbaar operationeel. De accuracy-/releasebaseline is echter rood. Er is geen bewijs voor nationale gebouwdetectiekwaliteit, geen complete menselijke corpusreview, geen onafhankelijke protected-testcyclus en geen sluitende modelhash-per-run-lineage. Zeven kritieke/hoge correctheidsproblemen zijn deterministisch gereproduceerd en de canonieke backend-releasegate is niet groen.

Daarom gelden op 1 augustus 2026 de volgende harde uitspraken:

  • “GeoIntel kan één bestaande tile met het actieve model op de RTX 4080 SUPER verwerken” is bewezen.
  • “GeoIntel is 100% getraind”, “nationaal gevalideerd”, “productie-accurate” of “release ready” is niet bewezen en mag niet worden geclaimd.
  • De bestaande v56/v58/v62/v66-artefacten zijn diagnostische/trainingsevidence; geen daarvan vormt een geldige nationale promotiebundel.
  • Phase 2 mag remediëren en nieuwe evidence opbouwen, maar mag de protected test pas opnieuw bevriezen nadat de leakage-, corpus- en lineageproblemen zijn opgelost.

2. Reproduceerbare softwarebaseline

Alle hieronder genoemde logs zijn retained onder C:\Projects\geointel\artifacts\evidence\accuracy\P1.

Check Exact commando Uitkomst Evidence
volledige backendtestset vanuit repo-root python -m pytest backend/tests -q -p no:cacheprovider -W error::DeprecationWarning --junitxml=artifacts/evidence/accuracy/P1/backend-full-suite.junit.xml fail: 1.180 passed, 17 failed, 70,63 s backend-full-suite.txt, backend-full-suite.junit.xml
canonieke CI/backend-entrypoint vanuit backend: python -m pytest -W error::DeprecationWarning collection fail: 1.194 items verzameld plus importerror scripts.render_operator_polygon_label_qa backend-ci-entrypoint.txt
Phase-1 collectortests python -m pytest tests/test_accuracy_phase1_baseline.py -q -p no:cacheprovider pass: 4/4 phase1-tooling-tests.txt
frontend unit vanuit frontend: npm run test:unit pass: 16 files, 51 tests frontend-vitest-unit.txt
generiek frontendtestcommando npm test -- --run fail: script test ontbreekt frontend-vitest.txt
frontend typecheck npm run typecheck pass frontend-typecheck.txt
frontend build npm run build pass: 1.896 modules; Vite-build voltooid frontend-build.txt
frontend lint npm run lint fail: script lint ontbreekt frontend-lint.txt
Python lintbaseline python -m ruff check backend scripts tests --output-format json fail: 112 findings repository-ruff-baseline.json, .txt
Alembic head vanuit backend: python -m alembic heads pass: één head 202607260001 alembic-heads.txt
volledige offline migratieketen python -m alembic upgrade head --sql pass: alle 11 migraties renderen tot commit alembic-offline-upgrade.sql
API-contractaudit python scripts/audit_api_contracts.py pass: 147 routes; 10 expliciete non-envelope endpoints openapi-contract-audit.txt

De 112 Ruff-bevindingen zijn: E402 13, E701 2, E702 69, F401 23, F403 1, F811 2 en F841 2. De nieuw toegevoegde Phase-1-audittools waren in de afzonderlijke check Ruff-clean; de telling is repositorybreed.

De 17 backendtestfailures zijn bron-/contractasserties tegen frontend-, README- en deployteksten/implementatiedetails. Dat maakt ze niet automatisch onbelangrijk of “alleen stale”: de verwachte automatische model/theme-selectie is bijvoorbeeld doelbewust gewijzigd naar gebruikersselectie, terwijl tests nog het oude contract eisen. Test en actueel productcontract moeten expliciet worden gereconcilieerd. Tot dat gebeurt is de releasegate rood.

De CI-entrypointfout heeft een afzonderlijke oorzaak: vanuit backend resolveert scripts naar backend/scripts, waardoor de rootmodule scripts/render_operator_polygon_label_qa.py niet importeerbaar is. Een root-run met expliciet importpad kan de tests wel verzamelen, maar repareert de feitelijke CI-opdracht niet.

3. Wat de huidige readinessgate niet uitvoert

scripts/run_readiness_check.sh compileert veel Python en draait backendtests, Alembic head, frontend unit/typecheck/build. De volgende checks zijn daar slechts syntaxcontroles:

  • node --check voor de twee frontend-E2E-scripts;
  • bash -n voor live migration, deploy, upgrade/fresh-install, browserruntime, demo, real-data detection/QA, calibratie, training en cleanupflows.

De gate voert dus geen volledige browserjourney, live PostGIS-migratie, externe provideracquisitie, echte CUDA-modelinference, protected-test-evaluatie of AI-imagebuild uit. De GitHub-/Gitea-build installeert standaard geen AI-dependencies. Een groene toekomstige unit/readinessgate blijft daarom onvoldoende zonder afzonderlijke live-, data- en modelgates.

4. Golden QA/QC-baseline

python scripts/run_golden_qa_benchmark.py --json slaagde twee keer semantisch met vier fixture-scenario's:

Scenario Precision Recall F1 Mean IoU FP FN
partial match 0,5 0,5 0,5 0,833976834 1 1
perfect match 1 1 1 1 0 0
no overlap 0 0 null null 1 1
exact MultiPolygon 1 1 1 1 0 0

De twee retained JSON-runs zijn niet byte-identiek: SHA-256 ec96862b… tegenover 4f900711…. De semantische resultaten zijn gelijk; UUID4-gegenereerde project/dataset/quality-check-id's maken de output nondeterministisch. Voor een reproduceerbare benchmarkbundel moeten ids deterministisch zijn of vóór hashing worden genormaliseerd.

Het no-overlapscenario legt daarnaast een metriccontractgap bloot: precision en recall zijn 0, maar F1 is null. Dit kan wiskundig als undefined worden verdedigd, maar aggregators en releasegates moeten één expliciete semantiek hanteren. De Tower-database bevestigt bredere nullvariatie: 58/697 F1, 58/697 precision, 1/697 recall en 90/697 mean IoU zijn null.

De golden benchmark gebruikt kleine checked-in fixtures. Hij bewijst rekenkundige regressiestabiliteit, niet de nauwkeurigheid van het actieve model op Belgische luchtbeelden.

5. Runtime-, database- en GPU-baseline

5.1 GPU-smoke

De retained smoke gebruikte het actieve model:

  • model /app/models/geointel-building-yolov8s-smallbld-minpx3-img640-ft30.pt;
  • SHA-256 a9088b8491dfae36694b53e9e9406cb4e3511d334a5712fa34f75078a47759c1;
  • één 512×512 RGB-tile in EPSG:31370, tile-SHA 134a9e86850c92c577c73bc6ee57a9df7d4c1c513ae6450263e800b6dd47b6ee;
  • manifest-SHA 6ab8a96bf2a1405e224932afb90255311a09bbeaed4e9a2fdcdf8b1bc2230abd;
  • PyTorch 2.11.0+cu128, Ultralytics 8.4.99, NVIDIA GeForce RTX 4080 SUPER;
  • seed 20260801, deterministische algoritmen, imgsz=640, confidence 0,5, max_det=1000;
  • 17 raw building-detecties; inference 0,8837 s, totale model-load plus inference 1,3689 s.

Deze smoke is read-only en passeert. Hij toetst één tile en schrijft geen AnalysisRun/Detection/QA/Export. Hij levert daarom geen accuracy-, calibratie-, georeference-persistence-, schaal- of generalisatieclaim.

5.2 Databaseintegriteit

Positieve baseline:

  • runtime Alembic-head 202607260001;
  • 3.377 datasets en 1.671 versies hebben checksums en source/provenance-metadata;
  • 5.816 directe dataset/version/export-storagepaden gecontroleerd, 0 ontbrekend;
  • 387 area- en 6.689.447 vectorfeaturegeometrieën: 0 leeg, 0 ongeldig, 0 wrong-SRID, 0 buiten EPSG:4326-domein in de gebonden query;
  • 299.233 detection-confidences: 0 buiten [0,1].

Negatieve baseline:

  • 2.377/3.377 datasets zonder observed_at en 1.761/3.377 zonder source_version; eerst per bronfamilie classificeren, niet blind invullen;
  • vier detectiegeometrieën hebben SRID 4326 maar numerieke Lambertcoördinaten rond X 193k/Y 206k;
  • alle 1.146 modelruns hebben een lege modelversie; 1.143 bewaren een modelassethash, drie niet; alle 1.146 missen tile-manifest-SHA, runtime/hardware en seed;
  • 0 segmentaties en 0 detection reviews;
  • 135/4.460 jobs en 2/1.146 analysis runs hebben status failed;
  • PostGIS 3.6.4 meldt dat core/topology procedures uit 3.4.3 een upgrade nodig hebben.

De storagecheck dekt alleen directe DB-referenties. De volledige recursieve storageaudit eindigde in een time-out en is geen pass; daarmee is niet bewezen dat alle niet-gerefereerde caches, trainingoutputs of orphan artifacts bekend zijn.

6. Deterministisch gereproduceerde productfouten

forensic-reproductions.json bevat zeven read-only, deterministische reproducties; alle zeven zijn opnieuw waargenomen.

ID Ernst Geobserveerd Waarom blokkerend
P1-COV-001 critical een kleine buildings-partitie wordt fully_covered=true doordat een roads-bbox in dezelfde bounded union zit coverage- en beschikbaarheidsclaims kunnen inhoudelijk fout zijn
P1-CRS-001 critical 100 “meter” buffer levert bounds [-95,-49,105,151], 200 graden lengtespan units/CRS worden verwisseld; derived geometrie is onbruikbaar
P1-CRS-002 critical EPSG:31370-coördinaten (150000,210000) worden ongewijzigd met SRID 4326 opgebouwd valide SRID-label maskeert verkeerde werkelijkheid
P1-AUTH-001 critical caller-controlled upload source_name=grb wordt operational/authoritative gebruikersmetadata kan officiële bronautoriteit spoofen
P1-AI-001 critical area Mol validation bypass met geometrie in Noord-Amerika passeert modelscope model draait buiten de gevalideerde geografie
P1-COV-002 high dezelfde Vlaamse geometrie werkt als naam Flanders, maar wordt outside=true na rename naar Vlaanderen wettelijke scope hangt van een muteerbare displaynaam af
P1-API-001 high Area PATCH accepteert payload met geometry maar negeert die stil contract en opgeslagen AOI lopen uiteen

Aanvullende statisch bewezen risico's staan nog buiten deze zeven reproductions:

  • clip/buffer/intersect roepen _persist_derived_dataset standaard aan met persist_vector_features=False; een ready derived artifact hoeft dus niet PostGIS-querybaar te zijn;
  • meerdere services slikken secundaire fouten of vallen stil terug, onder meer projectdetailbootstrap en cached rasterpreview; fallback moet expliciete status/provenance krijgen;
  • het tracked mirror geointel/ bevat 1.153 bestanden, waarvan 68 van de rootversie verschillen; Docker sluit de mirror uit, lokale tools niet noodzakelijk.

7. Corpus-, split- en trainingbaseline

7.1 Inventaris is geen kwaliteit

Tower bevat 26 modelassets, 229 trainingscheckpoints (28.512.052.142 bytes), 424 JSON-trainingsrapporten en 36 operator-manifests. De aantallen tonen veel experimenten, niet dat de beste kandidaat is gevonden of geldig vrijgegeven.

7.2 V56 is de breedste aangetroffen corpusbasis, maar niet vrijgegeven

De retained v56-evidence toont:

  • 180 AOI's over Vlaanderen, Wallonië en Brussel;
  • immutable manifest, 0 exacte cross-split rasterhashduplicates en 0 cross-split raster-dataset-id-duplicates;
  • dHash-screen over 4.833 cross-split paren: minimumafstand 17, geen paren op/onder 4;
  • bbox-afstandscreen: minimum 95,7203 m en 24 cross-split paren onder 2 km;
  • 31.452 inputfeatures; 30.662 geaccepteerd, 326 onder pixel-resolutie, 464 na de imageryperiode;
  • automated corpusstatus needs_human_review; 0/180 gereviewd, alle 180 pending;
  • 48 background candidates, maar slechts drie pure-empty background-test-AOI's: Vlaanderen 2, Wallonië 1, Brussel 0;
  • de drie overige background-test-AOI's bevatten 2, 107 en 141 referentiefeatures en zijn moeilijke negatieven.

De exact-hash- en dHashscreen zijn positief maar begrensd. Ze bewijzen geen gebouw-instance-, gemeente-, vluchtstrook-, seizoen- of bronopname-onafhankelijkheid. De 95,7-meter train/testnabijheid en 24 paren onder 2 km vereisen expliciete imagery-/instance-audits voordat een protected split wordt geaccepteerd.

De automated tile-qualityaudit meldt 2.496 tiles, 60.229 geldige labels, 0 invalid/missing labels, 2.072 positieve en 424 negatieve tiles. Dat valideert syntax en enkele pixelregels, niet of daken correct, volledig, tijdsconform of contextueel representatief zijn. Contact sheets bestaan, maar menselijke acceptatiebeslissingen ontbreken.

7.3 V58/V62 halen geen regionale gate

V58 en v62 hebben alleen 144-tile val/calibratiebewijs met IoU 0,5 en 13 confidence-sweeps. Bij threshold 0,15 rapporteren beide aggregate F1 0,512905, precision 0,545647 en recall 0,483871, terwijl Vlaanderen 0 true positives, recall 0 en F1 0 heeft. Bij threshold 0,02 blijft Vlaanderen zwak: v58 F1 0,080402/recall 0,103380; v62 F1 0,067111/recall 0,275348. Dit is geen protected test en geen nationale releaseprestatie.

V62 best.pt bestaat, maar de hash 889ee5… is niet de actieve productiemodelhash a9088b…. Er is geen geldige promotie aangetoond.

7.4 V66 is geen nationale opvolger

Het v66-manifest heeft slechts drie positieve Vlaamse train-AOI's in twee low-rise-contexten, zonder val/calibration/test/background en zonder Wallonië/Brussel. Het is een gerichte trial.

7.5 Protected-testleakage

De trainingloop opent na een geslaagde calibration zowel test als background. Als de kandidaat vervolgens faalt, geeft de loop de volledige assessment aan de failure-driven sampler. Die kiest assessment.get("test") or assessment.get("calibration"), gebruikt regionale testmetrics en background-failures en verandert daarmee repeats van trainingtiles voor de volgende iteratie. Protected tiles worden niet letterlijk opgenomen, maar hun uitkomsten sturen training. De huidige testset is dus voor die loop niet langer onafhankelijk en moet na de correctie worden vervangen of aantoonbaar nooit eerder ingezien zijn.

8. Claim-matrix

Claim Status Maximaal verdedigbare formulering
platform draait technisch ondersteund gezonde Tower-container, echte PostGIS-data en uitvoerbare frontend/API
NVIDIA/PyTorch wordt gebruikt ondersteund één actieve YOLO-adaptercall draaide op RTX 4080 SUPER/CUDA 12.8
volledige inferenceketen is correct niet ondersteund smoke sloeg persistence/georeference/QA/export over; vier historische geometrieën zijn corrupt
actief model is reproduceerbaar gedeeltelijk actief bestand heeft SHA; historische runs missen volledige manifest/runtime-lineage en drie runs missen ook de modelassethash
labels zijn correct niet ondersteund automated syntax ok, maar v56 menselijke review 0/180
splits zijn onafhankelijk niet ondersteund exact/dHashscreen positief, maar nabijheid onbeslist en testuitkomsten sturen retraining
building accuracy voor Mol/Kempen niet vastgesteld in Phase 1 er is geen retained protected Mol/Kempen-releasebenchmark voor actieve hash
building accuracy voor heel België weerlegd als actuele releaseclaim v58/v62 calibration heeft bij bruikbare aggregate threshold Vlaanderen recall/F1 0
pure-backgroundrobustheid per regio niet ondersteund slechts 3 pure-empty AOI's, geen in Brussel
productie-segmentatie niet ondersteund abstraction/fixture aanwezig, 0 runtime segmentaties
officiële bronnen zijn authentiek niet ondersteund source identity kan via uploadmetadata worden gespooft
databasegeometrieën zijn integraal gedeeltelijk areas/vectorfeatures schoon in gebonden query; 4 detecties buiten domein
release ready nee backend/CI/lint rood plus kritieke data-/GIS-/ML-blockers

9. Geprioriteerde gaps

P0 — vóór nieuwe modeltraining of productclaim

  1. Fix en regressietest de zeven gereproduceerde contract-/CRS-/scope-/authorityfouten; maak coverage unions themaspecifiek, source authority server-attested en modelscope geometrisch/checksumgebonden.
  2. Quarantaineer de vier buiten-domeindetecties, identificeer hun producerende code/image/model, herbereken of verwijder ze via een gecontroleerde migratie en laat detailtellingen de gate falen.
  3. Maak vector- en detectie-CRS-transformaties expliciet; verbied SRID relabeling; voer metric buffers in een geschikte lokale CRS uit; persisteer derived features en runlineage atomisch.
  4. Verwijder test/background uit failure-driven sampling en checkpointpromotie. Bevries daarna een nieuwe, ongeziene protected test met hashes en éénmalige-openingspolicy.
  5. Voer menselijke review uit op alle 180 v56-AOI's met beslissingen, reviewer, timestamp, label-/beeldversie en reden; herbouw contact sheets wanneer bron of label verandert.
  6. Voeg onafhankelijke AOI's en pure-empty backgrounds toe per regio/context, in het bijzonder Brussel; audit de 24 cross-split paren onder 2 km op imagery-, vluchtstrook- en instance-overlap.
  7. Herzie image/label time deltas, vooral de 464 uitgesloten features en dichte PICC/UrbIS-zones; definieer regels voor onzekere/occluded/nieuwe/verdwenen gebouwen.
  8. Koppel iedere training, inference-run, detection, QA en export aan model-SHA, datasetmanifest-SHA, codecommit, containerdigest, seed, parameters en dependency lock.

P1 — vóór releasecandidate

  1. Maak de canonieke backend-CI-entrypoint verzamelbaar en reconcilieer de 17 contracttests met de actuele, handmatige modelselectie-UX.
  2. Voeg Ruff en frontend lint toe aan de readinessgate; werk de 112 bestaande bevindingen gecontroleerd weg.
  3. Bouw en test de echte AI/CUDA-image in CI; pin PyTorch/torchvision/Ultralytics en leg image digest/SBOM vast; hef cu128/cu130-drift op.
  4. Draai echte browser-E2E, live PostGIS upgrade/fresh-install, externe-provider- en full inference/persistence/QA/exportjourneys.
  5. Definieer null-/zero-/undefinedsemantiek voor precision, recall, F1 en IoU; maak golden outputs byte-reproduceerbaar of canonicaliseer ids.
  6. Classificeer de 2.377 missende observatietijden en 1.761 missende bronversies per broncontract en maak onverklaarde gevallen fail-closed.
  7. Verwijder bronambiguïteit door de tracked geointel/-mirror gecontroleerd te migreren; niet in Phase 1 destructief opruimen.

10. Wanneer Phase 2 veilig kan trainen

Nieuwe GPU-training is pas zinvol nadat de P0-datacontracten, human review en splitpolicy zijn opgelost. Anders optimaliseert een nieuwe run opnieuw tegen mogelijk foutieve labels, onvoldoende negatives en een gecontamineerde testlus. De veilige volgorde is:

fix contracten -> nieuwe regressietests -> corpusbeslissingen -> onafhankelijke splits -> frozen manifests/hashes -> train/val/calibration -> kandidaatselectie -> éénmalige protected test -> onafhankelijke menselijke foutreview -> promotiebundel -> shadow deploy.

Een trainingsloop mag itereren op train/validation/calibration. Hij mag de protected test niet opnieuw in de loop voeren. “100%” wordt niet als numerieke gate gebruikt; release vereist vooraf vastgelegde, context- en regiogebonden thresholds met confidence intervals, failure budgets en expliciete abstention/unsupported-statussen.

11. Evidence-integriteit

Retained bestand Bytes SHA-256
backend-full-suite.txt 23.972 8521ed48b17b382752418750b3ea374831958fb063e83ef87048212e0fd5ea69
backend-ci-entrypoint.txt 1.601 0ac774ec19b4ff0a15142aab5f1db68c2592a230401d794ae7d040320e3ac0c0
frontend-vitest-unit.txt 2.774 6341bfa51ca3f4fe5ec7d4af7239c3c5e1a29e6bfe8bdfae85e824a2a6482ad0
frontend-typecheck.txt 163 3891c85c77b5ff50a1eb6d27a2a65d40c2c05423768734efd9d980f3784d68fa
frontend-build.txt 2.356 c3b8e10ef177ac1c2dc045bd710df1caeb46f8922a721291be431b304abbc079
frontend-lint.txt 418 1115b013515c753e2dfb73abdad9024aec7b4c2337d117c7e1181341fef15c7f
repository-ruff-baseline.json 59.359 de6617f030e49550e714c49b6e14bf291bf85016fd58086e9ca38b33a52252e9
alembic-heads.txt 116 da4521233c6718fc7a5865c53904e73685fbdce65a1449b19cd0dc2e40d037ed
alembic-offline-upgrade.sql 20.199 e8905b881890cf95885a7515e3d9dcf2a7a0a24c4edbc57e98a363edcb22dd0e
openapi-contract-audit.txt 212 5af3d8f00be3f57fc309bc198fa3995d1eae7270a5f210b3e94d1aeeb653119d
forensic-reproductions.json 3.533 f6349199a15ae789092d3d65c17a39a9b32ea3ed557571c0c228c4be3cf7235e
golden-qa-reproducibility.json 505 576e5667a989c34086db3a2bc57003115a8a61b14e9f49f5407ee380baf0829d
phase1-tooling-tests.txt 250 a9bf261e1a811ad3e8bfa8edc439a11f00b46bc157f9ab6fc970033a87f45748
tower-gpu-inference-smoke.json 5.675 692a9fa193d589123b042110d7e80755f0c6634854f3134c291fc6083adb7b77
tower-runtime-database-snapshot-detailed.json 14.946 744389b6c384a9fb3a9e16e56f1477f3b752e11a5b98e1fad7df47b4703a9ca1
tower-ml-data-lineage-snapshot.json 71.659 d80275e8198ce63366d2a2d44eb8fba1f27c29d85aaaaedb94991d8c56febfb6

Deze hashes zijn van de retained Phase-1-bestanden op het moment van documentgeneratie. Als evidence opnieuw wordt gegenereerd, moet een nieuwe evidence-manifestversie de nieuwe hash, producerende commandoregel, timestamp en reden bewaren; oude evidence wordt niet overschreven of als identiek voorgesteld.