Files
geointel/docs/accuracy-program/08-data-contracts.md
T
Jens f41392a415
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s
docs(accuracy): publish phase 4 benchmark evidence
2026-08-02 05:10:05 +02:00

563 lines
37 KiB
Markdown

# GeoIntel Accuracy Improvement Program — 08 Versieerbare datacontracten
- Status: Fase-2 contractnorm met een geïmplementeerde fail-closed
validatiebibliotheek; bestaande DatasetVersions, artefacten en
modelbestanden worden niet stilzwijgend betrouwbaar verklaard
- Scope: raster-, vector-, label- en modeldata, inclusief afgeleide datasets
en uitvoerbare inference-inputs
- Samenhang: 05-metric-framework, 07-source-authority-matrix,
docs/API_CONTRACTS.md en docs/DATABASE_IMPLEMENTATION_PLAN.md
## 1. Doel en harde regel
Een GeoIntel-resultaat is alleen herleidbaar wanneer alle gebruikte data een
versieerbaar contract heeft, de concrete artefacten checksummed zijn, de
validatie-uitkomst is bewaard en ieder derived artifact zijn parents en
transformaties kent.
Voor een nieuwe ingest geldt daarom, met de actuele P2-statuswoorden:
ontvangen -> registered/configured -> ingested + contractvalidatie -> eligible of quarantined
`ready` is hoogstens een bestaande processingstatus, geen trust- of
consumptiestatus. Alleen een record met complete P2-evidence kan via de
consumption gate operationeel worden gebruikt. Er bestaat geen consumptiepad
van een ontvangen of legacy `ready` record naar training,
productie-inference, primaire QA, coverage authority of normale export dat een
gefaalde, ontbrekende of onbekende contractcontrole stilzwijgend overslaat. Een
incomplete legacyrecord blijft zichtbaar als `lineage_incomplete` en krijgt
geen gefingeerde metadata.
## 2. Huidige startsituatie versus Fase-2-doel
De generieke exact-versioned contracten zijn geïmplementeerd in
`backend/app/services/data_contract_validation.py`:
`geointel.vector.geojson@1.0.0`, `geointel.raster.geotiff@1.0.0`,
`geointel.label.yolo@1.0.0` (historisch, geen lege labels),
`geointel.label.yolo@1.1.0` (actueel, expliciete `pure_background`-modus) en
`geointel.model.pytorch@1.0.0`. De ingest- en derived-paden bewaren de
reportvelden. De validator levert een fail-closed report en
`DataQuarantineService` bepaalt de beslissing; `SourceRegistryService` en de
database-quarantinetrigger leggen de persistente quarantine en propagatie vast,
terwijl `DatasetConsumptionGate` operationele consumptie blokkeert. Deze
generieke contracten vervangen geen
toekomstige, strengere productprofielen voor GRB, PICC, UrbIS of
sensor-/modelversies.
| Onderwerp | Aangetroffen op 2026-08-01 | Fase-2 contractdoel |
|---|---|---|
| Datasetbasis | Dataset en DatasetVersion bevatten storage path, checksum, CRS, bounds, resolution/bands JSON, source/provenance JSON en temporele velden. De Phase-2-migratie voegt contract, registry/snapshot, validation, lineage, quarantine en idempotencyvelden toe. | Iedere nieuwe DatasetVersion krijgt contract-id/-versie, registry/source-snapshotbinding, validation report met contractfingerprint en lineage edges. |
| Uploadvalidatie | Generic upload en server-owned vector/rasteracquisities gaan via dezelfde registry/snapshot/contractflow; een upload blijft `manual` ongeacht caller text. | Generic metadata blijft descriptief; source authority, policy en training/production eligibility komen uitsluitend uit server-owned contracts. |
| Specialistische acquisitie | GRB, DHMV en andere adapterpaden voeren bron-specifieke checks uit en gebruiken de centrale registry/contract engine. | Elke adapter levert machineleesbare pass/fail/quarantine evidence; product-specifieke semantische profiles blijven afzonderlijke uitbreidingen. |
| Vector-CRS | Het beoogde model bewaart EPSG:4326, maar Phase 1 reproduceerde een non-4326 relabeling en vier historische detection geometrieën buiten het 4326-domein. | Bron-CRS is verplicht; transform wordt expliciet gelogd; relabeling zonder transform is verboden; legacy is quarantined of traceerbaar gerepareerd. |
| Versions | DatasetVersion en checksums bestaan, met unieke dataset/version. | Een inhoudelijke mutatie maakt een nieuwe snapshot/datasetversion met parent edge en reportfingerprint; de ingest-API wijzigt geen geaccepteerde evidence in place. |
| Labels/modellen | De Phase-1-training- en auditbestanden ontbeerden governed manifest-/review-/split-/runtimecontract. P2 voegt versioned YOLO-labelcontracten, release-/asset-/label-sidecars en een PyTorch-runtime-sidecar toe; historische bestanden blijven legacy. | Labels en modellen zijn first-class contractartefacten met hashes, split/firewall, review en runtime lineage. |
| Quarantine | `DatasetQuarantine`, een validation report en een consumption gate bestaan nu. | Quarantine heeft eigen status, reden, evidence en toegangsblokkade; gefaalde input kan nergens operationeel worden geconsumeerd. |
De bestaande velden zijn waardevol als legacy evidence, maar hun aanwezigheid
bewijst geen source authority, semantic validity of release eligibility. Dit
document voorkomt dat metadata-aanwezigheid met contractacceptatie wordt
verward.
## 3. Universeel contractenvelope
Elke valideerbare entiteit gebruikt een versieerbaar envelope. De fysieke
opslag kan relationeel, GeoJSON, GeoTIFF, manifest-JSON of modelbestand zijn.
De tabel hieronder is de normatieve envelope; de huidige relationele P2-kolommen
en `validation_report_json` realiseren de kernvelden. Nog niet getypeerde
snapshotvelden worden niet als aanwezig of groen verondersteld (zie 07 §5.3).
| Veldgroep | Verplicht veld of regel |
|---|---|
| identity | contract_id, contract_version, entity_kind, immutable entity_id, contract/schema fingerprint en waar van toepassing manifest_sha256 |
| source authority | source_registry_id, source_snapshot_id, authority_class, trust_status en allowed_use; de server-owned registrymetadata bevat de seeding/definition-revisie |
| artifact identity | storage URI/path, media type, byte count, sha256, original filename/object key en retained_at |
| time | observed_at, published_at, fetched_at/imported_at, valid_from, valid_to en precise status voor missing/not_applicable/unknown_with_reason |
| spatial | source_crs, canonical_crs, transformation identifier, bounds in source and canonical CRS, units, spatial resolution/scale, vertical datum/unit if applicable |
| coverage | legal/coverage zone IDs, geometry/bbox checksum, exact AOI/partition identity and coverage completeness/truncation status |
| semantic schema | expected geometry/band/class/attribute contract, ontology version, source feature-id strategy and known limitations |
| validation | validation_status, validator version/code commit, started/finished timestamps, checks run, issue list, warning list and report hash |
| lineage | ordered parent identities/hashes, transformation name/version/config hash, child artifact hashes and derivation purpose |
| lifecycle | SourceSnapshot: registered/configured/not_configured/available/ingested/failed/quarantined/legacy_unverified; Dataset contract: not_validated/passed/failed plus quarantine reason/evidence |
De envelope zelf is canonical JSON. De canonical bytes en ieder gerefereerd
input-/outputartefact zijn SHA-256-bound in een evidence manifest. Filename,
mutable display name and current configuration are never identity substitutes.
Voor een relationele `Dataset` of `DatasetVersion` die `passed` wordt, dwingt
de P2-migratie bovendien een niet-leeg, bijpassend validation report af: exact
contract en versie, registry/snapshot, report- en contractfingerprint,
`provenance_status=complete`, geldige lineage-status,
`quarantine_status=not_quarantined` en een canonieke SHA-256 die exact met de
gebonden `SourceSnapshot` overeenkomt. Die evidencevelden kunnen niet worden
vervangen terwijl het record `passed` blijft; een inhoudelijke correctie is een
nieuwe versie of eerst een expliciete invalidatie/quarantaine. De
databaseregel bewaakt die structurele binding en immutable evidencevelden, maar
herberekent geen contract- of reporthash en valideert geen bronsemantiek. De
applicatievalidator en `DatasetConsumptionGate` bewaken de inhoudelijke
artefactcontrole en consumptie; een JSON-vorm op zichzelf is nooit een
accuracy- of authority-claim.
### 3.1 Version rules
1. Contract major version changes only when semantics or required validation
change incompatibly.
2. New optional fields may use a minor version only when their absence cannot
relax a required gate.
3. A validation rule may become stricter only with a new contract version; old
accepted artifacts retain their historical report and are not silently
relabelled.
4. A re-export, clip, reprojection, normalization, tile build, label repair,
calibration or model conversion is a derived artifact with a new checksum
and lineage edge.
5. A source snapshot is immutable in its source identity/checksum semantics.
Refresh creates a new snapshot and new DatasetVersion/derived graph; it
never overwrites accepted evidence in place. Registry policy is
server-owned; callers never supply an authority or policy version.
### 3.2 Required use policies
The allowed_use field is a server computed set. Its relevant values are:
| Use | Minimum state |
|---|---|
| map_context | accepted contextual/authoritative/corroborative dataset with attribution and spatial contract |
| qa_reference | accepted authoritative source for the exact task/zone/version, or a documented corroborative comparison role |
| training_input | accepted source/derived dataset plus label, temporal, review, split and leakage gates |
| calibration_input | training requirements plus frozen calibration split role |
| protected_test | sealed contract with protected access policy; inaccessible to train/val/calibration processes |
| production_inference_input | accepted raster/tile contract and model compatibility contract |
| export | accepted governed record with complete or explicitly not-applicable lineage; quarantined of lineage-incomplete historic records are not normally exportable |
No client-provided request field can add qa_reference, training_input or
production_inference_input to this set.
## 4. Common validation policy
### 4.1 Mandatory gates
Every ingest validates the following where applicable:
| Gate | Required behaviour | Failure disposition |
|---|---|---|
| source attestation | Registry source and snapshot are chosen by the server-side adapter or an explicit review action. | quarantine with SOURCE_UNATTESTED or SOURCE_POLICY_MISMATCH |
| checksum | Persisted content hash equals the observed or generated artifact hash and matches the manifest. | quarantine with CHECKSUM_MISMATCH |
| file safety | File type, byte size, decompression/container constraints and parser safety match the contract. | reject or quarantine before product persistence |
| CRS | Source CRS is declared and parseable; transform to canonical CRS is explicit and recorded. | quarantine with CRS_MISSING, CRS_INVALID or CRS_TRANSFORM_FAILED |
| bounding box | Bounds are finite, nonempty, in source CRS and consistent after transform with legal/domain scope. | quarantine with BBOX_INVALID or BBOX_OUT_OF_SCOPE |
| units/resolution | Unit, pixel/ground resolution, scale and vertical datum match source/product contract. | quarantine with UNIT_MISMATCH or RESOLUTION_MISMATCH |
| time/freshness | Required source version, observed/valid period, fetched time and freshness policy are satisfied or explicitly classified. | quarantine with TEMPORAL_METADATA_MISSING or FRESHNESS_REVIEW_REQUIRED |
| semantic schema | Geometry/bands/attributes/classes/ontology/feature IDs meet the contract. | quarantine with SCHEMA_MISMATCH |
| lineage | Every parent artifact/version/transformation is resolvable and checksummed. | quarantine with LINEAGE_MISSING or PARENT_INVALID |
| topology/integrity | Geometry/raster/label/model-specific validity is green. | quarantine with the specific integrity code |
At a consumption boundary a concrete snapshot must be `current` or explicitly
`not_applicable`. `unknown`, `review_required`, `due` and `stale` are not
eligible for production inference, primary reference validation, derived
processing, authoritative coverage or normal export. This guard is separate
from source-family classification: an authoritative registry entry never
overrides an unsuitable snapshot.
Warnings never change a failed required gate to accepted. A warning may retain
accepted only when the exact contract explicitly says that it is non-blocking,
the warning is visible, and the allowed_use policy excludes inappropriate uses.
### 4.2 CRS, units and geometry rules
- Canonical persisted vector/result geometry is EPSG:4326 only after an
explicit source-to-canonical transform. Setting SRID to 4326 on coordinates
in EPSG:31370, EPSG:3812 or any other CRS is prohibited.
- Every metric distance, buffer, area, length and topology tolerance uses an
approved metric CRS or a documented geodesic operation. In the Belgian land
scope, EPSG:31370 is the default candidate when suitable; an operation must
record the chosen CRS and unit.
- The Belgian North Sea keeps horizontal CRS and vertical datum separate.
TAW, LAT, mDNG, NAP and depth/elevation semantics never convert implicitly.
- Bbox checks validate coordinate order, finite values, positive extent,
source CRS domain, transformed canonical domain and declared coverage zone.
- Geometry repair is only allowed under a named repair policy. The original
hash, repair method, before/after validity and changed feature count remain
in provenance. A repair that changes type, dimension or exceeds the
tolerance is quarantined for review.
## 5. Raster data contract
### 5.1 Required raster fields
| Group | Required contract content |
|---|---|
| artifact | GeoTIFF/COG or approved format, sha256, byte size, parser/driver result, compression/nodata and immutable storage path |
| spatial | source CRS, affine transform, width/height, source and canonical bounds, pixel size x/y and unit, pixel interpretation and resampling method |
| bands | band count/order, data type, colour interpretation or physical unit, nodata, scale/offset, valid pixel statistics and allowed ranges |
| source/time | source registry/snapshot, product/collection/scene/tile identity, source version, acquisition/observation period and fetched/imported time |
| coverage | requested AOI/partition hash, clipping/mosaic inputs, complete/truncated status, coverage percentage and edge/padding policy |
| lineage | original response/archive hash, normalization/clipping/mosaic operation and configuration hash, every parent raster hash |
| compatibility | task-specific accepted bands, resolution range, colour/channel arrangement and temporal suitability for label/model task |
The parser must reject a non-georeferenced analytical raster unless the
contract explicitly marks it image-space only. Image-space-only data cannot
produce map geometry or location claims.
### 5.2 Raster-specific checks
1. CRS, affine transform, width, height, bounds and resolution must agree
numerically within a contract tolerance.
2. The raster must have the exact expected band count/data type/nodata policy
for the source product; unknown values are not silently filled.
3. Resolution cannot be represented as finer than the source's native
resolution. Derived resampling records source and analysis resolution
separately.
4. Mosaic/clip outputs declare every parent tile, overlap/nodata merge rule,
exact AOI mask and output checksum.
5. Acquisition time is separate from fetch time. A rolling latest orthophoto
with unknown per-pixel observation time remains unknown_per_pixel.
6. A raster used for labels or metrics records the reference-to-imagery time
delta and its policy decision. This closes the temporal source of
D-TEMPORAL-MISMATCH without inventing a date.
### 5.3 Source-specific requirements
| Product family | Additional contract rule |
|---|---|
| Official orthophoto | Product key, provider, native resolution, colour mode, imagery edition/flight-date precision, coverage zone and licence are mandatory. It is imagery/context, not reference truth. |
| Sentinel-2 | Contract must declare processing level, tile/granule, acquisition time, band/resampling method, cloud/nodata mask and native ground resolution. It remains contextual and cannot satisfy a building label/reference contract. |
| DHMV | Contract requires product key, DTM/DSM semantics, EPSG:31370, native/analysis resolution, one-band numeric units, nodata, TAW vertical reference and 2013-2015 period for the currently configured DHMV II source. It is elevation evidence, not building truth. |
| Bathymetry | Vertical datum/reference plane, depth versus bed-elevation semantics, survey epoch and uncertainty are mandatory. No water volume is inferred. |
## 6. Vector data contract
### 6.1 Required vector fields
| Group | Required contract content |
|---|---|
| artifact | GeoJSON/approved vector artifact hash, feature count, media type, source/canonical CRS, original artifact retained path |
| geometry | allowed geometry types/dimensions, empty/valid counts, repair policy, source and canonical bbox, geometry precision/tolerance |
| identity | source feature-id attribute/namespace, uniqueness policy, stable-identity flag and collision report |
| attributes | contract version, required/optional fields, type/domain/null policy, canonical mapping and retained native properties policy |
| authority/time | registry source/snapshot, product/collection, zone, source version, observation/validity/fetched time, licence/attribution |
| topology | per-product topology rules, overlap/gap/containment/line connectivity policy and known exceptions |
| lineage | input artifact hashes, clip/filter/transform configuration, source feature counts and derived output feature mapping |
### 6.2 Vector-specific checks
1. De parser accepteert een feature collection met een expliciete CRS of de
RFC 7946-standaard EPSG:4326. De ingestservice transformeert een niet-4326
bron expliciet vóór canonical persistence; `build_vector_ingest_input`
valideert daarna de getransformeerde feature collection en haar
transformation evidence. Coördinaten buiten het Belgische/Noordzee-domein,
een ongeldige CRS of een Lambertlaag die als 4326 wordt aangeboden, worden
gequarantined; veldvorm alleen is nooit voldoende om een andere CRS te
raden.
De normale `Dataset.storage_path` en zijn checksum verwijzen daarna naar
exact die canonieke EPSG:4326-bytes. Originele niet-canonieke bronbytes
blijven uitsluitend als checksummed provenance-evidence buiten het
consumptiepad bewaard; vectorbewerkingen weigeren een CRS- of
storage-checksum-mismatch fail-closed.
2. Every feature has a nonempty supported geometry. Invalid features are
quarantined individually or cause the dataset to quarantine according to
an all-or-nothing policy recorded in the contract.
3. Source geometry is transformed before canonical PostGIS persistence.
Post-transform coordinates must pass canonical domain/bbox checks.
4. Source feature IDs are unique whenever object lineage/temporal comparison
needs them. Missing/duplicate/unexpected IDs set identity_stable=false and
prevent object-level change claims.
5. Required attributes are type-checked before any source-to-canonical mapping.
Unknown native fields may be retained in properties JSON but can never
satisfy a required canonical attribute by name coincidence.
6. Topology rules are task-specific. A self-intersection is always invalid;
overlapping building footprints may be a source semantic/review event
rather than an automatic geometric repair. The contract states which.
7. Any clipping, buffering, intersection or dissolve creates a derived
contract with parent hashes, metric CRS, units, tolerance, analysis run and
queryable feature-persistence count. A derived Dataset cannot be accepted
while its artifact and vectorfeatures diverge.
### 6.3 Building reference profiles
| Profile | Required fields / checks | Authority rule |
|---|---|---|
| GRB GBG | approved GRB collection, official feature ID, Polygon/MultiPolygon, governed request/response/artifact hashes, exact coverage, source snapshot/version, temporal limitation and EPSG:4326 output transform | Primary authoritative footprint reference in Flanders only when 07-source-authority-matrix conditions hold |
| Buildings Register | building object/version/status, snapshot date, bounded area, privacy-minimized output, raw-page hashes, register-to-GRB reconciliation and exact source URLs | Authoritative for its register semantics; corroborative for footprint reconciliation, never automatic GRB replacement |
| PICC buildings | allowlisted provider product, stable product identity, authorised Walloon coverage, feature ID, native CRS transform, edition/time and geometry contract | Authoritative only for approved Walloon building task/version |
| UrbIS buildings | allowlisted product, Brussels coverage, provider-native identity, native CRS transform, edition/time and geometry contract | Authoritative only for approved Brussels building task/version |
| OSM buildings | OSM extract/version/timestamp/licence, geometry and tag mapping if intentionally ingested | Contextual/corroborative only; no automatic truth, labels or coverage authority |
## 7. Label data contract
Labels are not just text files. Every label has a physical image/tile,
reference/source geometry and a training-policy decision.
### 7.1 Required label-manifest fields
| Group | Required content |
|---|---|
| identity | corpus_id/version, label artifact sha256, image/tile sha256, sample ID, tile-manifest sha256 and ontology/class-map version |
| spatial/image | image CRS/affine/bounds/resolution, tile size/stride/overlap, pixel coordinate convention and image orientation |
| reference | source registry/snapshot, native source feature IDs, geometry/reference hash, source/reference version and license eligibility |
| time | imagery observed/acquisition time, label/reference observed time, delta calculation, temporal policy/reason code |
| semantics | class, inclusion/exclusion rule, difficult/ambiguous/occluded flag, geometry-to-box conversion policy and minimum resolvable size |
| review | review state, reviewer/adjudicator ID, decision/reason code, contact-sheet/overlay hash and decision timestamp |
| split | train/val/calibration/test/background-test role, split-manifest hash, parent AOI/group ID and protected flag |
| eligibility | accepted, excluded, quarantined or uncertain; allowed training/evaluation use and all reasons |
### 7.2 Label validation
- Every label references an image/tile that exists and has exactly the recorded
checksum. A label cannot migrate across tiles by filename matching.
- Coordinates are finite, in the declared pixel convention and within image
bounds. Boxes/polygons must have positive area, supported class and
deterministic normalization.
- The label's native source feature ID, source snapshot, geometry transform
and image/reference time relation are mandatory for trainable labels.
- Below-resolution, post-imagery, dense/occluded, extreme-aspect and
uncertain labels require an explicit disposition. Unknown is not accepted.
- A reviewed label preserves all earlier review decisions; repair produces a
new label release and links the superseded artifact.
- Test- en background-testlabels zijn logisch beschermd door manifest-,
release- en trainingsgates. Ze mogen niet aan samplers, augmentation,
calibration, thresholdselectie of training worden aangeboden. Fysieke
read-only opslag en afzonderlijke credentials mogen pas worden geclaimd
wanneer daarvoor afzonderlijke P2-05-evidence bestaat.
`geointel.label.yolo@1.0.0` is historisch en laat geen lege labelbestanden
toe. `geointel.label.yolo@1.1.0` onderscheidt exact twee modi: `objects` voor
een niet-leeg YOLO-bestand en `pure_background` voor een leeg bestand. Een
leeg bestand wordt dus nooit automatisch als negatief voorbeeld geïnterpreteerd.
Voor `pure_background` zijn naast de normale labelchecks minstens verplicht:
- de exacte `sample_slug` en een toegestane `train`- of `val`-split;
- raster- en referencedataset-ID, checksums, registry en concrete snapshot
via de upstream lineage;
- `review_decision=accepted`, reviewer-ID, tijdstip met tijdzone en hash van
het menselijke reviewartefact/contact sheet.
Objectlabels met `pure_background` en lege labels zonder deze evidence falen
gesloten. Test- en achtergrond-testrollen worden niet toegelaten als deze
trainbare `pure_background`-modus.
Bij het maken van een trainingsrelease wordt ieder label opnieuw gevalideerd
en gebonden in `<dataset.yaml>.geointel-training-label-contracts.json`. Die
immutable sidecar bevat per label de checksum, sample, mode, exact
contract/fingerprint en de tellingen voor objecten/achtergronden; de release
en release-freeze binden vervolgens de sidecarhash. Voor het aanmaken,
verifiëren en elke initial/retry/resume-trainingsstap wordt de bevroren corpus
opnieuw tegen de live Dataset-status gecontroleerd. Een later gequarantined,
ontbrekende of niet-meer-eligible raster/referencepartner herroept de release
en blokkeert training, ook wanneer de freeze zelf ooit groen was.
The current V56 evidence has automated tile syntax checks but zero accepted
human AOI reviews. It therefore remains a legacy candidate corpus, not an
accepted label release under this contract.
Grayscale-transformaties, SAM-labelverfijningen, rotated holdouts en
proposal-crops controleren hun upstream release vóór verwerking, maar erven die
release niet als nieuwe trainability. Hun output is expliciet
`training_eligible=false` totdat een nieuwe governed corpus-, review-,
contract- en releasecyclus de nieuwe bytes heeft geaccepteerd. Dit voorkomt dat
een cosmetische of modelgestuurde afleiding stilzwijgend in een bestaande
PyTorch-trainingsrelease terechtkomt.
## 8. Model data contract
### 8.1 Required model-manifest fields
| Group | Required content |
|---|---|
| identity | model_id, model_version, weights sha256/size, format, architecture and class ontology version |
| origin | base weights hash/source, training code commit, training image/container digest, dependency lock/SBOM and license |
| data | corpus manifest sha256, label release sha256, split manifest sha256, training/validation/calibration roles and data access policy |
| config | preprocessing/tile/normalization/augmentation config hash, input dimensions/bands/colour order, threshold/NMS/max detections and seed |
| runtime | Python/PyTorch/CUDA/Ultralytics/driver versions, required device, GPU identity, deterministic flags and known nondeterminism |
| evidence | training run manifest/checkpoints/logs/curves, evaluator version, calibration and protected-test policy, model card scope polygon/zone IDs |
| lifecycle | candidate/unpromoted/validated/promoted/retired status, promotion report/rollback link and explicit supported/not_configured task scope |
### 8.2 Model validation
1. Weights hash, architecture and class map must load under the recorded
runtime. Load success is runtime evidence only.
2. Input raster/tile contract must match bands, colour order, resolution,
preprocessing and image geometry expected by the model.
3. Model scope is a server-owned geometry/zone policy bound to the model
manifest, never a mutable Area display name.
4. Training reads only its allowed split roles. A protected credential/path,
protected sample identifier or protected assessment causes a hard failure.
5. A detection/segmentation run persists the exact model manifest hash, model
hash, inference config hash, tile manifest hash, dataset version,
transform, seed, container/runtime/hardware and code commit before
status=success can be emitted.
6. Legacy model runs with missing values remain lineage_incomplete. Current
active configuration must not be copied backwards as an invented version.
### 8.3 Runtime sidecar gate for local PyTorch weights
Configured local YOLO and SAM weights are **not runnable** merely because a
`.pt` file exists or is listed as an active model asset. Before
`load_model()` is called, GeoIntel requires a neighbouring immutable sidecar:
<weights-file>.geointel-model.json
The sidecar must validate exactly as `geointel.model.pytorch@1.0.0` and binds
the following at minimum:
- a fixed sidecar schema version, configured model ID and task type;
- the SHA-256 of the physical weights and the source-snapshot checksum of the
same bytes;
- `model_format`, framework, non-empty class mapping and source/model version;
- source registry/snapshot UUIDs, a training-manifest checksum and non-empty
upstream asset/checksum plus transformation lineage;
- a timezone-aware import timestamp; and
- `metadata.runtime_manifest_sha256`: a SHA-256 of canonical sidecar JSON with
only that self-referential field omitted.
Missing, malformed, wrong-contract, version/task/framework-mismatched or
tampered sidecars make the capability `contract_incomplete`; detection and
segmentation do not load the adapter or weights. Validated sidecar evidence is
copied into the analysis run/job and into each configured detection or
segmentation provenance payload. This is a byte-binding and structural
lineage gate, not a promotion or accuracy claim: a model still needs its
separate training, calibration, protected-test and scope evidence before it
can be called validated or nationally suitable.
For production inference the structural sidecar check is insufficient on its
own. Immediately before adapter loading, GeoIntel resolves both UUIDs against
the database and requires the `model` registry entry, a matching immutable
snapshot, safe configured/current and ingested/current states, exact
model/sidecar/snapshot checksum and source-version equality, and no active
quarantine record. A missing, detached, mismatched, stale or quarantined
database record fails before `load_model()`; catalogue and preflight discovery
remain explicitly non-production structural checks.
The fixture detector/segmenter and placeholders remain explicit test-only
paths. They require `fixture_mode=true` where execution is allowed and cannot
be made production-ready by a sidecar or request parameter.
The Phase-1 active model has an asset hash and a successful GPU smoke, but its
historical detection runs lack the complete RunManifest fields and it is not
nationally validated. It cannot meet this model contract retroactively without
original evidence.
## 9. Derived data and lineage graph
### 9.1 Required lineage edge
Each derived entity records:
parent entity id + parent manifest/hash + transformation id/version
+ configuration hash + code commit + runtime/container identity
+ output entity id + output hash + validation report hash
Examples include source raster to clipped raster, raster to tiles, source
vector to normalized vector, vector to label, labels to corpus, corpus to
checkpoint, checkpoint to inference run, detections to QA and QA to export.
The graph must be acyclic. A derived artifact cannot cite itself or a mutable
“latest” path as its only parent. Parent availability, hash and contract state
are checked recursively to the configured evidence boundary.
### 9.2 Idempotency and resume
An ingest/derivation idempotency key is the canonical combination of:
source snapshot or parent hashes, contract version, transformation/config hash,
requested AOI/partition hash and destination semantic role.
Repeated requests with the same key return the existing accepted artifact only
after rechecking its manifest/checksum/validation state. Interrupted work
resumes from staged checkpoint evidence or creates a new attempt record; it
does not invent success, duplicate a visible DatasetVersion or bypass
validation. A partial result is marked failed or quarantined and never reused
as a complete parent.
An identical replay may bind a second project-scoped ingest key to the same
immutable source snapshot. It preserves the snapshot's first recorded
`fetched_at`; all other immutable snapshot evidence, including checksum and
CRS, must still be equal. A changed fetch time alone therefore cannot rewrite
provenance or cause a duplicate snapshot.
## 10. Safe quarantine flow
### 10.1 Policy
Quarantine is preservation, not deletion. De huidige P2-implementatie bewaart
in een `DatasetQuarantine`-record de target-FK's, stage, één reason code,
details JSON, optioneel artifactpad/checksum, status en resolutietimestamps.
Het validation report blijft bij `Dataset`/`DatasetVersion`; lineage wordt via
de lineage-edges en de snapshotbinding herleid. `SourceRegistryService` en de
database-trigger maken het target, gedeelde snapshotpartners en downstream
lineage non-consumable voor training, productie-inference, normale QA en
automatische export. Een fysieke move/copy naar een afzonderlijke
access-controlled quarantine-storage is nog geen gerealiseerd
opslagmechanisme; die ontbrekende fysieke isolatie mag niet als bewijs worden
geclaimd. Tot die uitbreiding houdt de logische quarantine gate de verplichte
operationele veiligheidsgrens in stand.
| Event | Required action |
|---|---|
| parser/file failure | Retain minimal evidence and report; quarantine when artifact preservation is safe, otherwise reject with captured hash/error metadata |
| CRS/bounds/unit failure | Quarantine dataset/feature/run with source coordinates and validator report; never relabel CRS |
| source/trust failure | Route user/manual data to manual/untrusted or quarantine; do not materialize authoritative coverage |
| missing version/time/license | Quarantine when policy requires the field; source freshness shows review_required, not current |
| label-review/split failure | Quarantine label/corpus release and deny training/calibration/test use |
| model/run lineage failure | Mark lineage_incomplete or quarantine candidate output; deny validation/promotion |
| derived persistence mismatch | Roll back the transactional visible result when possible; retain failed attempt evidence and do not emit ready/success |
### 10.2 Quarantine dispositions
De gerealiseerde P2-statuswaarden zijn `quarantined`, `released` en
`rejected`, met de bewaartechnische velden hierboven. Een `released` quarantine
maakt de oorspronkelijke dataset niet opnieuw operationeel: een governed
re-ingest of nieuwe versie blijft vereist. Een rijkere disposition-taxonomie
met severity, secundaire reason codes, validatorversie, reviewer action,
`pending_review`, `remediated_as_new_version` en
`accepted_for_limited_historical_view_only` is vervolgwerk en mag nog niet als
gerealiseerde recordstructuur worden voorgesteld. Een reviewer kan nooit een
authoritative-, protected-split- of source-identity-gate in-place opheffen.
## 11. Contract test matrix
The implementation must retain tests for valid and deliberately invalid
fixtures. At a minimum:
| Dataset kind | Green fixture | Red fixture / expected outcome |
|---|---|---|
| governed GRB vector | bounded GBG fixture with registry attestation, valid CRS, unique IDs and request/response hashes | user upload claiming source_name=grb; it remains manual/untrusted or quarantined |
| vector CRS | EPSG:31370 or EPSG:3812 source transformed to EPSG:4326 with correct bounds | Lambert coordinates persisted as 4326 or source CRS absent; quarantine |
| vector geometry/topology | valid source polygons and explicit valid repair evidence | self-intersection, empty geometry, invalid dimensionality, duplicate required source ID or unsupported attribute type |
| raster/DHMV | one-band EPSG:31370, expected nodata/resolution/TAW metadata | wrong band count, unit, vertical reference, resolution, affine/bounds or checksum |
| Sentinel-2 | deliberately contextual fixture with full sensor/tile/time metadata | attempt to use it as building reference/ground truth; policy failure |
| label | bounded objectlabels of expliciet reviewed `pure_background` labels linked to image/hash/source/review/split manifest | out-of-bounds box, missing source feature, unmarked empty label, post-imagery unknown, unreviewed required sample or protected-role leakage |
| model/run | checksummed model with complete manifest and matching tile contract | model/run missing model hash, tile-manifest hash, GPU/runtime identity or scope policy; no success/promotion |
| lineage | one parent-to-child transformation graph with reproducible output hash | missing parent, changed parent checksum, cycle, partial operation or output count mismatch |
| quarantine | failed record remains non-consumable and visible with reason | attempt to train, infer, QA-as-truth, cover or export a quarantined artifact; hard denial |
Tests include unit, service, API, migration and live PostGIS coverage where
the contract relies on database constraints. A test that only asserts source
text is insufficient; it must exercise the actual validation and state
transition.
## 12. Fase-2 completion gates for data contracts
The source/provenance part of Fase 2 is green only when:
1. every new accessible DatasetVersion, raster, vector, label release and
model/run type is routed through an explicit contract;
2. every new imported dataset has a server-attested registry/snapshot binding,
checksum, validation report and lineage identity;
3. generic uploads cannot acquire authoritative source identity from caller
text;
4. invalid CRS, geometry, bbox, unit, resolution, checksum, freshness,
attribute, topology and lineage fixtures all fail closed;
5. quarantine is tested and has zero path into training, production inference,
primary QA, coverage authority or normal export;
6. migrations preserve existing records, classify legacy gaps and do not
silently backfill uncertain facts;
7. an evidence manifest retains test, migration and source/contract audit
outputs under artifacts/evidence/accuracy/P2.
Until all gates are green, Fase 2 is in progress, Fase 3 is not ready and
training/promotion remains blocked by the Phase-1 execution contract.
> **Historische handoff:** deze zin legt de P2-gate vast zoals die bij oplevering
> van dit document gold. Fase 3 is nadien binnen de afgebakende lokale scope
> uitgevoerd. De actuele fasebeslissing staat uitsluitend in
> `docs/accuracy-program/status.json`.