From 41f8a54236ed224fa640aad1d535600d476ce003 Mon Sep 17 00:00:00 2001 From: Jens Date: Sat, 1 Aug 2026 23:46:37 +0200 Subject: [PATCH] docs(accuracy): retain phase 2 provenance evidence --- .../accuracy/P2/evidence-manifest.json | 107 +++ .../P2/postgres-migration-guards.json | 46 ++ .../P2/source-contract-inventory.json | 757 ++++++++++++++++++ docs/CODEX_EXECUTION_LOG.md | 53 ++ .../07-source-authority-matrix.md | 330 ++++++++ docs/accuracy-program/08-data-contracts.md | 557 +++++++++++++ docs/accuracy-program/status.json | 83 +- 7 files changed, 1908 insertions(+), 25 deletions(-) create mode 100644 artifacts/evidence/accuracy/P2/evidence-manifest.json create mode 100644 artifacts/evidence/accuracy/P2/postgres-migration-guards.json create mode 100644 artifacts/evidence/accuracy/P2/source-contract-inventory.json create mode 100644 docs/accuracy-program/07-source-authority-matrix.md create mode 100644 docs/accuracy-program/08-data-contracts.md diff --git a/artifacts/evidence/accuracy/P2/evidence-manifest.json b/artifacts/evidence/accuracy/P2/evidence-manifest.json new file mode 100644 index 00000000..463d518c --- /dev/null +++ b/artifacts/evidence/accuracy/P2/evidence-manifest.json @@ -0,0 +1,107 @@ +{ + "schema_version": 1, + "program": "GeoIntel Accuracy Improvement Program", + "phase": "P2", + "collected_at": "2026-08-01T23:43:55+02:00", + "claim_boundary": "This manifest verifies the implemented source, provenance, contract, quarantine and training-input foundation in the repository and a disposable PostGIS database. It is not a production migration deployment, a complete P2 roadmap result, a corpus approval, a CUDA training result, a protected-test result or a promotion decision.", + "repository": { + "branch": "codex/geointel-accuracy-program", + "head_at_collection": "cebeb5f3b4f836274c0504c2cc5fc2a019a8ea8b", + "working_tree": "dirty; evidence was collected against the uncommitted Phase-2 implementation" + }, + "artifacts": [ + { + "path": "artifacts/evidence/accuracy/P2/postgres-migration-guards.json", + "sha256": "1bf19dc52935372381a974dadfff3f588aafa69925d379f97b192e84380192e3", + "meaning": "Disposable PostGIS upgrade, real trigger-guard DML checks and full downgrade. The fixture database name begins with geointel_phase2_ and is not a production database." + }, + { + "path": "artifacts/evidence/accuracy/P2/source-contract-inventory.json", + "sha256": "c7445ab984407d3a835532182767cf87e5e26fd79b3ecba123aef54ee3cdc733", + "meaning": "Static registry and contract inventory: 40 server-owned source definitions and the active versioned vector, raster, label and model contracts." + } + ], + "verification": [ + { + "command": "python scripts\\verify_phase2_postgres_guards.py --database-url --output artifacts\\evidence\\accuracy\\P2\\postgres-migration-guards.json", + "result": "passed", + "coverage": [ + "upgrade to 202608010001 and downgrade to base", + "source/snapshot pairing and source/snapshot immutability", + "passed contract reports and exact Dataset/DatasetVersion checksum-to-snapshot binding", + "accepted artifact, provenance and temporal-evidence immutability", + "lineage-cycle rejection and insert-only lineage edges", + "version quarantine, shared-snapshot fan-out and transitive A-to-B-to-C lineage quarantine" + ] + }, + { + "command": "python scripts\\run_accuracy_phase2_foundation_audit.py --output artifacts\\evidence\\accuracy\\P2\\source-contract-inventory.json", + "result": "passed", + "coverage": [ + "40 source definitions", + "source classifications and task policy", + "GRB primary building-validation policy", + "separate Buildings Register, DHMV, Sentinel-2 and OSM roles", + "versioned contract fingerprints" + ] + }, + { + "command": "python -m pytest tests/test_accuracy_phase2_foundation_audit.py tests/test_accuracy_phase2_source_registry.py tests/test_data_contract_validation.py tests/test_dataset_consumption_gate.py tests/test_governed_dataset_ingest.py tests/test_phase2_derived_dataset_governance.py tests/test_runtime_model_provenance_service.py tests/test_training_dataset_eligibility.py tests/test_training_release_manifest.py tests/test_rc4_national_coverage.py tests/test_run_state_consistency.py tests/test_sprint196_map_orthophoto_analysis.py tests/test_sprint205_dhmv_terrain.py tests/test_sprint233_operational_completion.py tests/test_sprint12_golden_qa_benchmark.py tests/test_vector_operations_service.py tests/test_geojson_dataset_service.py tests/test_model_asset_catalog.py tests/test_segmentation_configured_models.py tests/test_sprint8_detection_foundation.py tests/test_sprint8b_yolo_foundation.py tests/test_qa_service.py -q -p no:cacheprovider", + "result": "221 passed", + "coverage": [ + "contract validation", + "source registry, governed ingest and immutable snapshot replay", + "consumption gates and quarantine", + "canonical EPSG:4326 vector storage, checksum tamper rejection and derived governance", + "database-bound runtime model provenance before adapter loading", + "training release and protected-data eligibility" + ] + }, + { + "command": "python -m pytest tests -q -p no:cacheprovider", + "result": "34 passed", + "coverage": [ + "proposal-classifier crop provenance and trainer release binding" + ] + }, + { + "command": "npm run typecheck && npm run test:unit && npm run build", + "result": "passed; 51 frontend unit tests", + "coverage": [ + "TypeScript", + "frontend unit tests", + "Vite production build" + ] + } + ], + "non_green_global_gates": [ + { + "command": "python -m pytest -q -p no:cacheprovider", + "result": "1282 passed, 17 failed", + "reason": "The former backend-CI collection error is fixed. Sixteen remaining failures are historical source-text assertions for user-modified UI/deployment/README behavior; one additional Windows run could not spawn the WSL-backed bash.exe for the shell-wrapper syntax test, although that test passes in isolation. They remain visible and block a claim that the complete repository suite is green." + }, + { + "command": "python -m ruff check backend scripts tests --output-format concise", + "result": "95 existing findings", + "reason": "The P2-changed Python paths were linted clean separately; repository-wide Ruff remediation is an outstanding P2-01 gate." + }, + { + "command": "npm run lint", + "result": "failed: script is absent", + "reason": "Frontend lint configuration remains an outstanding P2-01 gate." + } + ], + "remaining_limits": [ + "No production database migration or deployment was performed in this phase; the live migration evidence is disposable only.", + "Legacy Tower datasets and model runs remain incomplete until a new governed ingest/release supplies original evidence.", + "Physical quarantine storage and protected-test credential isolation are not yet proven.", + "End-to-end UI provenance rendering is a required target contract, not yet retained as full browser/API evidence.", + "Human label review, independent AOIs, pure-background/difficult negatives, temporal/dense-label remediation, corpus rebuild, CUDA candidate training, protected testing and promotion remain blocked." + ], + "phase_decision": { + "phase2_status": "in_progress", + "phase3_status": "not_ready", + "training_allowed_now": false, + "promotion_allowed": false + } +} diff --git a/artifacts/evidence/accuracy/P2/postgres-migration-guards.json b/artifacts/evidence/accuracy/P2/postgres-migration-guards.json new file mode 100644 index 00000000..3ec3ac4c --- /dev/null +++ b/artifacts/evidence/accuracy/P2/postgres-migration-guards.json @@ -0,0 +1,46 @@ +{ + "completed_at": "2026-08-01T21:40:13.288545+00:00", + "database_name": "geointel_phase2_guard_test", + "downgrade_output_tail": [ + "DROP TABLE areas", + "INFO [sqlalchemy.engine.Engine] [no key 0.00014s] {}", + "INFO [sqlalchemy.engine.Engine] ", + "DROP TABLE projects", + "INFO [sqlalchemy.engine.Engine] [no key 0.00014s] {}", + "INFO [sqlalchemy.engine.Engine] DELETE FROM alembic_version WHERE alembic_version.version_num = '202601110001'", + "INFO [sqlalchemy.engine.Engine] [generated in 0.00018s] {}", + "INFO [sqlalchemy.engine.Engine] COMMIT" + ], + "guards": { + "accepted_artifact_and_temporal_evidence_immutable": "passed", + "accepted_contract_evidence_immutable": "passed", + "accepted_dataset_version_contract_evidence_immutable": "passed", + "lineage_cycle": "passed", + "lineage_edge_immutable": "passed", + "passed_contract_report_required": "passed", + "passed_dataset_checksum_required_and_snapshot_bound": "passed", + "passed_dataset_version_checksum_required_and_snapshot_bound": "passed", + "snapshot_evidence_immutable": "passed", + "snapshot_quarantine_fanout": "passed", + "snapshot_registry_immutable": "passed", + "snapshot_registry_pairing": "passed", + "source_registry_immutable": "passed", + "transitive_lineage_quarantine": "passed", + "version_quarantine_propagation": "passed" + }, + "migration_revision": "202608010001", + "phase": "P2", + "result": "passed", + "schema_version": 1, + "started_at": "2026-08-01T21:40:07.178237+00:00", + "upgrade_output_tail": [ + " CREATE TRIGGER trg_dataset_quarantines_state_guard", + " AFTER INSERT OR UPDATE OF status, dataset_id, dataset_version_id, source_snapshot_id ON dataset_quarantines", + " FOR EACH ROW EXECUTE FUNCTION geointel_phase2_quarantine_state_guard();", + " ", + "INFO [sqlalchemy.engine.Engine] [generated in 0.00053s] {}", + "INFO [sqlalchemy.engine.Engine] UPDATE alembic_version SET version_num='202608010001' WHERE alembic_version.version_num = '202607260001'", + "INFO [sqlalchemy.engine.Engine] [generated in 0.00021s] {}", + "INFO [sqlalchemy.engine.Engine] COMMIT" + ] +} diff --git a/artifacts/evidence/accuracy/P2/source-contract-inventory.json b/artifacts/evidence/accuracy/P2/source-contract-inventory.json new file mode 100644 index 00000000..6df650f7 --- /dev/null +++ b/artifacts/evidence/accuracy/P2/source-contract-inventory.json @@ -0,0 +1,757 @@ +{ + "claim_boundary": "Static policy/contract inventory only. It does not attest that a database migration ran, that legacy rows are complete, or that a model/corpus is release-ready.", + "collected_at": "2026-08-01T21:40:49.817334+00:00", + "data_contracts": [ + { + "accepted_source_crs": [], + "canonical_storage_crs": null, + "fingerprint_sha256": "908ce483237cc83b35844c3dd21c6f774d10b4241f78f71f8d86a016dd1e9332", + "key": "geointel.label.yolo", + "kind": "label", + "required_metadata_fields": [ + "image_checksum_sha256", + "class_ontology_version", + "tile_manifest_sha256" + ], + "requires_source_registry": true, + "requires_source_snapshot": true, + "requires_upstream_assets": true, + "version": "1.0.0" + }, + { + "accepted_source_crs": [], + "canonical_storage_crs": null, + "fingerprint_sha256": "8eff1113520cca04fad8a919bfadc85d6f1e30e5fd41fcc1ed70e7eb5bd41c07", + "key": "geointel.label.yolo", + "kind": "label", + "required_metadata_fields": [ + "image_checksum_sha256", + "class_ontology_version", + "source_corpus_manifest_sha256", + "label_mode" + ], + "requires_source_registry": true, + "requires_source_snapshot": true, + "requires_upstream_assets": true, + "version": "1.1.0" + }, + { + "accepted_source_crs": [], + "canonical_storage_crs": null, + "fingerprint_sha256": "fa2531c3b34c9ad7e473cb10071a32743a6349cd9dde9345ac2d44e38159b457", + "key": "geointel.model.pytorch", + "kind": "model", + "required_metadata_fields": [ + "training_manifest_sha256", + "runtime_manifest_sha256" + ], + "requires_source_registry": true, + "requires_source_snapshot": true, + "requires_upstream_assets": true, + "version": "1.0.0" + }, + { + "accepted_source_crs": [ + "EPSG:31370", + "EPSG:3812", + "EPSG:4326" + ], + "canonical_storage_crs": null, + "fingerprint_sha256": "51e19aa7b26c555319f26623dbfc837786ce47260025c7af9b878e40ad65478e", + "key": "geointel.raster.geotiff", + "kind": "raster", + "required_metadata_fields": [ + "license" + ], + "requires_source_registry": true, + "requires_source_snapshot": true, + "requires_upstream_assets": false, + "version": "1.0.0" + }, + { + "accepted_source_crs": [ + "EPSG:31370", + "EPSG:3812", + "EPSG:4326" + ], + "canonical_storage_crs": "EPSG:4326", + "fingerprint_sha256": "d6594faa7bea62ae61a41d7e1e254a9c3b7f7693430e90dcc3995b16ff3704fd", + "key": "geointel.vector.geojson", + "kind": "vector", + "required_metadata_fields": [ + "license" + ], + "requires_source_registry": true, + "requires_source_snapshot": true, + "requires_upstream_assets": false, + "version": "1.0.0" + } + ], + "migration_revision": "202608010001", + "phase": "P2", + "program": "GeoIntel Accuracy Improvement Program", + "repository": { + "branch": "codex/geointel-accuracy-program", + "dirty": true, + "head": "cebeb5f3b4f836274c0504c2cc5fc2a019a8ea8b" + }, + "schema_version": 1, + "scope": "Belgium and the Belgian North Sea", + "source_registry": { + "classification_counts": { + "authoritative": 25, + "contextual": 5, + "corroborative": 2, + "derived": 3, + "experimental": 5 + }, + "definition_count": 40, + "definitions": [ + { + "authority_name": "Agentschap Landbouw en Zeevisserij", + "authority_scope": { + "theme": "agricultural_parcels", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "agentschap_landbouw_zeevisserij_agricultural_parcels", + "training_allowed": false + }, + { + "authority_name": "Departement Omgeving", + "authority_scope": { + "theme": "land_use", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "department_omgeving_land_use", + "training_allowed": false + }, + { + "authority_name": "Departement Omgeving", + "authority_scope": { + "theme": "thematic_raster", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "source_specific", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "department_omgeving_thematic_raster", + "training_allowed": false + }, + { + "authority_name": "GeoIntel derived operation", + "authority_scope": { + "scope": "derived_from_registered_input" + }, + "classification": "derived", + "default_crs": "unknown", + "default_units": "unknown", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "derived", + "training_allowed": false + }, + { + "authority_name": "Digitaal Vlaanderen", + "authority_scope": { + "role": "umbrella_catalogue_and_adapter_authority", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "product_specific", + "default_units": "product_specific", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": "digitaal_vlaanderen", + "source_key": "digitaal_vlaanderen", + "training_allowed": false + }, + { + "authority_name": "Digitaal Vlaanderen", + "authority_scope": { + "theme": "buildings_addresses", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": "buildings_addresses_register", + "source_key": "digitaal_vlaanderen_buildings_addresses_register", + "training_allowed": false + }, + { + "authority_name": "Digitaal Vlaanderen", + "authority_scope": { + "role": "terrain_height_corroboration", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "m TAW", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": "dhmv", + "source_key": "digitaal_vlaanderen_dhmv", + "training_allowed": true + }, + { + "authority_name": "Digitaal Vlaanderen", + "authority_scope": { + "role": "imagery", + "zone": "Flanders" + }, + "classification": "contextual", + "default_crs": "EPSG:31370", + "default_units": "pixel", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": null, + "source_key": "digitaal_vlaanderen_orthophoto", + "training_allowed": true + }, + { + "authority_name": "Databank Ondergrond Vlaanderen", + "authority_scope": { + "theme": "soil", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "dov_soil_map", + "training_allowed": false + }, + { + "authority_name": "Unverified", + "authority_scope": { + "scope": "unverified" + }, + "classification": "experimental", + "default_crs": "unknown", + "default_units": "unknown", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "experimental", + "training_allowed": false + }, + { + "authority_name": "GeoIntel test fixture", + "authority_scope": { + "scope": "test_only" + }, + "classification": "experimental", + "default_crs": "fixture_specific", + "default_units": "fixture_specific", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": null, + "source_key": "fixture", + "training_allowed": false + }, + { + "authority_name": "Digitaal Vlaanderen", + "authority_scope": { + "themes": [ + "buildings", + "roads", + "water", + "parcels" + ], + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": true, + "ingest_status": "configured", + "provider_adapter_key": "grb", + "source_key": "grb", + "training_allowed": true + }, + { + "authority_name": "Historical archive provider", + "authority_scope": { + "scope": "Belgium", + "theme": "historical_land_use" + }, + "classification": "corroborative", + "default_crs": "source_specific", + "default_units": "source_specific", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "historical_landuse", + "training_allowed": false + }, + { + "authority_name": "INBO", + "authority_scope": { + "theme": "nature", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "inbo_bwk_natura2000", + "training_allowed": false + }, + { + "authority_name": "Legacy import \u2014 unverified", + "authority_scope": { + "scope": "legacy", + "trust": "unverified" + }, + "classification": "experimental", + "default_crs": "unknown", + "default_units": "unknown", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "legacy_unverified", + "provider_adapter_key": null, + "source_key": "legacy_unknown", + "training_allowed": false + }, + { + "authority_name": "Operator supplied", + "authority_scope": { + "scope": "operator_supplied", + "trust": "unverified" + }, + "classification": "experimental", + "default_crs": "unknown", + "default_units": "unknown", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": null, + "source_key": "manual", + "training_allowed": false + }, + { + "authority_name": "GeoIntel derived operation", + "authority_scope": { + "scope": "derived_from_registered_input" + }, + "classification": "derived", + "default_crs": "EPSG:4326", + "default_units": "source_dependent", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "map_selection", + "training_allowed": false + }, + { + "authority_name": "Maritieme Dienstverlening en Kust", + "authority_scope": { + "theme": "bathymetry", + "zone": "Belgian North Sea" + }, + "classification": "authoritative", + "default_crs": "EPSG:3812", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "mdk_bathymetry", + "training_allowed": false + }, + { + "authority_name": "Maritieme Dienstverlening en Kust", + "authority_scope": { + "role": "coverage_probe_and_governed_acquisition", + "theme": "bathymetry", + "zone": "Belgian North Sea" + }, + "classification": "authoritative", + "default_crs": "EPSG:3812", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "not_configured", + "provider_adapter_key": "mdk_bcp_bathymetry", + "source_key": "mdk_bcp_bathymetry", + "training_allowed": false + }, + { + "authority_name": "GeoIntel model pipeline", + "authority_scope": { + "scope": "internal_model_artifact" + }, + "classification": "experimental", + "default_crs": "unknown", + "default_units": "unknown", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "model", + "training_allowed": false + }, + { + "authority_name": "Nationaal Geografisch Instituut", + "authority_scope": { + "scope": "Belgium" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "ngi_adminvector", + "training_allowed": false + }, + { + "authority_name": "OpenStreetMap contributors", + "authority_scope": { + "role": "contextual", + "scope": "community-maintained" + }, + "classification": "contextual", + "default_crs": "EPSG:4326", + "default_units": "mixed", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "not_configured", + "provider_adapter_key": "osm", + "source_key": "osm", + "training_allowed": false + }, + { + "authority_name": "RBINS", + "authority_scope": { + "zone": "Belgian North Sea" + }, + "classification": "authoritative", + "default_crs": "EPSG:4326", + "default_units": "degrees", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "rbins_marine_reporting_units", + "training_allowed": false + }, + { + "authority_name": "RBINS", + "authority_scope": { + "edition": "2026-2034", + "zone": "Belgian North Sea" + }, + "classification": "authoritative", + "default_crs": "EPSG:4326", + "default_units": "degrees", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "rbins_msp_2026", + "training_allowed": false + }, + { + "authority_name": "Copernicus Programme", + "authority_scope": { + "role": "multispectral_context", + "scope": "Belgium and Belgian North Sea" + }, + "classification": "contextual", + "default_crs": "product_specific", + "default_units": "reflectance", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "not_configured", + "provider_adapter_key": "sentinel_2", + "source_key": "sentinel_2", + "training_allowed": true + }, + { + "authority_name": "Service public de Wallonie", + "authority_scope": { + "theme": "bathymetry", + "zone": "Wallonia" + }, + "classification": "authoritative", + "default_crs": "EPSG:3812", + "default_units": "mDNG", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "spw_bathymetry", + "training_allowed": false + }, + { + "authority_name": "Service public de Wallonie", + "authority_scope": { + "theme": "flood_hazard", + "zone": "Wallonia" + }, + "classification": "authoritative", + "default_crs": "EPSG:3812", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "spw_flood_hazard", + "training_allowed": false + }, + { + "authority_name": "Service public de Wallonie", + "authority_scope": { + "role": "umbrella_catalogue_and_adapter_authority", + "zone": "Wallonia" + }, + "classification": "authoritative", + "default_crs": "product_specific", + "default_units": "product_specific", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": "spw_geoportail", + "source_key": "spw_geoportail", + "training_allowed": false + }, + { + "authority_name": "Service public de Wallonie", + "authority_scope": { + "role": "imagery", + "zone": "Wallonia" + }, + "classification": "contextual", + "default_crs": "EPSG:31370", + "default_units": "pixel", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": null, + "source_key": "spw_orthophoto", + "training_allowed": true + }, + { + "authority_name": "Service public de Wallonie", + "authority_scope": { + "theme": "topography_buildings", + "zone": "Wallonia" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": true, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "spw_picc", + "training_allowed": true + }, + { + "authority_name": "Service public de Wallonie", + "authority_scope": { + "theme": "terrain", + "zone": "Wallonia" + }, + "classification": "corroborative", + "default_crs": "EPSG:3812", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "spw_terrain", + "training_allowed": false + }, + { + "authority_name": "Service public de Wallonie", + "authority_scope": { + "theme": "land_cover", + "zone": "Wallonia" + }, + "classification": "authoritative", + "default_crs": "EPSG:3812", + "default_units": "class_code", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "spw_walous_land_cover", + "training_allowed": false + }, + { + "authority_name": "Statbel", + "authority_scope": { + "scope": "Belgium", + "theme": "population" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "persons", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "statbel", + "training_allowed": false + }, + { + "authority_name": "GeoIntel reviewed label pipeline", + "authority_scope": { + "scope": "derived_from_reviewed_source_snapshots" + }, + "classification": "derived", + "default_crs": "unknown", + "default_units": "unknown", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "training_label", + "training_allowed": false + }, + { + "authority_name": "Brussels Region", + "authority_scope": { + "theme": "topography_buildings", + "zone": "Brussels-Capital Region" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": true, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "urbis", + "training_allowed": true + }, + { + "authority_name": "UrbIS / Brussels Region", + "authority_scope": { + "role": "imagery", + "zone": "Brussels-Capital Region" + }, + "classification": "contextual", + "default_crs": "EPSG:31370", + "default_units": "pixel", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "configured", + "provider_adapter_key": null, + "source_key": "urbis_orthophoto", + "training_allowed": true + }, + { + "authority_name": "Vlaamse Milieumaatschappij", + "authority_scope": { + "theme": "flood_hazard", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "vmm_flood_hazard", + "training_allowed": false + }, + { + "authority_name": "Vlaamse Milieumaatschappij", + "authority_scope": { + "theme": "bathymetry_profiles", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "m TAW", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "vmm_vha_bathymetry_profiles", + "training_allowed": false + }, + { + "authority_name": "Digitaal Vlaanderen", + "authority_scope": { + "theme": "roads", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "metres", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "vrbg", + "training_allowed": false + }, + { + "authority_name": "Waterinfo Vlaanderen", + "authority_scope": { + "theme": "water", + "zone": "Flanders" + }, + "classification": "authoritative", + "default_crs": "EPSG:31370", + "default_units": "source_specific", + "freshness_status": "unknown", + "ground_truth_allowed": false, + "ingest_status": "registered", + "provider_adapter_key": null, + "source_key": "waterinfo", + "training_allowed": false + } + ], + "required_building_policy": { + "buildings_register_classification": "authoritative", + "dhmv_classification": "authoritative", + "grb_primary_building_validation": "primary", + "osm_ground_truth_allowed": false, + "sentinel_2_classification": "contextual" + } + } +} diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index c2475191..cbe1c9c7 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -12308,3 +12308,56 @@ Open: `docs/accuracy-program/06-implementation-roadmap.md`: fix CRS/authority/ coverage/lineage and protected-test isolation, complete human corpus review, rebuild independent data, freeze metrics, then train on `cuda:0`. + +## 2026-08-01 - Accuracy Improvement Program Phase 2 source and provenance foundation + +### Implemented and verified scope + +- Added a server-owned source registry, immutable snapshots, source policies, + dataset/dataset-version provenance fields, lineage edges and durable + quarantine records through Alembic revision `202608010001`. +- Added versioned vector, raster, YOLO label and PyTorch model contracts with + checksum, CRS, bounds, units, resolution, topology, required attributes, + time/freshness and lineage checks. Governed ingestion is idempotent through + ingest keys, can safely replay an identical immutable snapshot across + projects without rewriting its first fetch time, and fails closed into + quarantine when a contract fails. +- Non-WGS84 vector imports now store the exact transformed EPSG:4326 bytes as + the checksummed consumption artifact; original source bytes are retained + only as provenance evidence. Vector operations verify both storage CRS and + byte checksum before reading a dataset. +- Enforced a consumption boundary for production inference, primary reference + QA, derived work, export, coverage and training inputs. GRB is task-bounded + primary authority for suitable Flemish building validation; the Buildings + Register, DHMV, Sentinel-2 and OSM retain distinct roles, and OSM cannot + become automatic truth. +- Production detection/segmentation now resolves model sidecar UUIDs against + the registry and snapshot database records before adapter loading, including + source/snapshot relationship, freshness, quarantine, checksum and version + checks. A structural sidecar alone remains catalogue/preflight evidence. +- Verified the migration in a disposable PostGIS database: upgrade, real + trigger-guard DML checks and downgrade passed. This was not a production + migration or deployment. + +### Evidence and test result + +- Retained proof is under `artifacts/evidence/accuracy/P2/`: the source/ + contract inventory contains 40 server-owned definitions and the PostGIS + guard report covers immutable source/snapshot evidence, exact checksum + binding, lineage cycles and transitive quarantine propagation. +- A final cohesive source-to-training regression set passed 221 tests, + including immutable snapshot replay, canonical CRS/checksum storage and + database-bound model provenance. The governed golden QA benchmark passed. +- Frontend typecheck, 51 frontend unit tests and production build passed. + The complete backend suite now collects but is not green: 1,282 passed and + 17 failed. Sixteen failures are historical source-text assertions; one is + an intermittent Windows WSL-backed `bash.exe` host failure in a syntax test + that passes in isolation. Repository Ruff still has 95 findings and + `npm run lint` is still absent. + +### Decision + +- The source/provenance foundation is implemented and verified in a + disposable environment, but Phase 2 remains **in progress** and Phase 3 is + **not ready**. No training, protected-test release, promotion, national + validation or production migration is authorized by this result. diff --git a/docs/accuracy-program/07-source-authority-matrix.md b/docs/accuracy-program/07-source-authority-matrix.md new file mode 100644 index 00000000..e6c5bca0 --- /dev/null +++ b/docs/accuracy-program/07-source-authority-matrix.md @@ -0,0 +1,330 @@ +# GeoIntel Accuracy Improvement Program — 07 Bronautoriteitsmatrix + +- Status: Fase-2 implementatie in uitvoering; normatief beleid en gerealiseerde bronfundering +- Scope: België en de Belgische Noordzee +- Samenhang: 00-execution-contract, 02-data-lineage, 04-risk-register, 05-metric-framework en 08-data-contracts +- Beslissing: een bronnaam in een upload, feature, dataset of UI-label verleent nooit zelf autoriteit. + +## 0. Gerealiseerde Phase-2-fundering en grens + +De repository bevat nu een server-owned registry in +`backend/app/services/source_registry_service.py`, de persistente modellen +`SourceRegistry` en `SourceSnapshot`, migratie `202608010001`, en expliciete +Dataset/DatasetVersion-koppelingen. Elke nieuwe governed import schrijft een +checksumgebonden snapshot, exacte contractversie en validatierapport. Een +handmatige upload wordt altijd aan `manual` gebonden; een meegegeven +`source_name=grb` blijft slechts een descriptieve claim. + +Dit maakt geen oude Tower-datasets, bestaande modelgewichten of een +historische bronnaam alsnog betrouwbaar. De migratie behoudt die rijen maar +markeert ontbrekende provenance als `incomplete/not_validated`. Zij blijven +niet inzetbaar voor training, productie-inferentie, primaire QA of +authoritative coverage tot een nieuwe governed ingest een eigen snapshot en +contractrapport heeft vastgelegd. + +## 1. Doel en claimgrens + +Dit document bepaalt welke bron beslissend, aanvullend of uitsluitend +contextueel mag zijn voor elk GeoIntel-resultaat. Het maakt twee vragen +expliciet verschillend: + +1. welke organisatie of productfamilie is gezaghebbend voor een concrete + bewering; +2. is de concrete snapshot ook werkelijk met server-attested provenance, + versie, licentie, CRS, dekking en integriteitscontrole beschikbaar? + +Een officiële publicatie zonder gecontroleerde snapshot is geen geactiveerde +autoriteit in een resultaat. Omgekeerd maakt een bestand met source_name=grb +of een UI-label “officieel” een handmatige upload nooit gezaghebbend. Dit +herstelt de door Phase 1 gereproduceerde ACC-R04-breuk. + +Autoriteit is taak-, zone-, product- en tijdsgebonden. Een bron kan dus +authoritative zijn voor één bewering en slechts corroborative of contextual +voor een andere. De classificatie is geen kwaliteitsoordeel over de bron en +maakt geen algemene België-claim. + +## 2. Verplichte classificaties + +| Klasse | Betekenis | Mag beslissend zijn? | Minimale server-attested voorwaarden | +|---|---|---|---| +| authoritative | Formeel bevoegde bron voor een afgebakende taak, zone en productversie. | Alleen voor de exact geregistreerde taak, dekking en tijd. | Goedgekeurde registry-entry, publisher/collection allowlist, snapshot- of editie-identiteit, checksum, licentie/attributie, CRS/eenheden, ruimtelijke en temporele dekking, succesvolle contractvalidatie. | +| corroborative | Onafhankelijke aanvullende bron die een resultaat kan controleren, duiden of van een status voorzien. | Nee; zij kan een mismatch of onzekerheid creëren, maar overschrijft de primaire referentie niet automatisch. | Zelfde minimale provenance als voor authoritative, plus een expliciete comparison/reconciliation policy. | +| contextual | Bron voor kaartcontext, interpretatie, kandidaatselectie of reviewhulp. | Nee. Niet gebruiken als label-, truth- of promotionbeslissing. | Duidelijke attributie/licentie en expliciete limitation; ontbreken daarvan maakt de context onbeschikbaar. | +| derived | Door GeoIntel of een geregistreerde transformatie afgeleid artefact. | Alleen als afgeleide metriek met volledige upstream-lineage; nooit als nieuwe externe autoriteit. | Immutable inputhashes, transformatie/code/config-hash, outputchecksum, validatie en parent-lineage. | +| experimental | Fixture, handmatige upload, proefbron, niet-gevalideerde adapter of niet-beoordeeld model-/labelartefact. | Nee voor productie, training, QA-waarheid, dekking of promotie. | Herkenbaar als experimental/manual/untrusted; expliciete operatorbeperking en quarantainestatus wanneer ongeschikt. | + +De registry bewaart de klasse als server-owned beleid; de seeding- of +definition-revisie staat in de registrymetadata. Een datasetrecord kopieert +die klasse niet vrij tekstueel: het bindt een concrete registry-entry én een +immutable source snapshot met checksum. De ingestlaag schrijft de effectieve +trust/authority-status zelf. Er is in deze eerste P2-migratie bewust nog geen +los mutable UI-veld dat als historische "registry-versie" kan worden +misbruikt; een snapshot/checksum blijft de concrete evidence-identiteit. + +## 3. Bronautoriteit voor gebouwresultaten + +### 3.1 Beslissingsregel + +Een gebouwgerelateerde validatie kiest eerst de zone, vervolgens de concrete +taak en ten slotte de geregistreerde bronversie. Een referentielaag is pas +bruikbaar als geometry-, tijd-, resolutie-, feature-identity- en +provenancecontracten groen zijn. + +| Zone en taak | Primaire referentie | Rol van andere bronnen | Geen-claim / fallbackregel | +|---|---|---|---| +| Vlaanderen: footprint- of gebouwdetectievalidatie | GRB GBG is authoritative en primaire gezagsbron, voor zover de gekozen GRB-snapshot, dekking, beeld/referentietijd en taak dat rechtvaardigen. | Gebouwenregister kan identiteit/lifecycle en GRB-reconciliation corroboreren; orthofoto is waarnemingsinput; DHMV en OSM zijn niet beslissend. | Geen governed, passend GRB-datasetversie betekent not_evaluable of partial; nooit stil OSM, een upload of een oude/onbekende snapshot als truth inzetten. | +| Wallonië: footprint- of gebouwdetectievalidatie | Alleen een expliciet governed PICC-building-product kan authoritative zijn voor zijn eigen product/versie/zone. | GRB heeft geen Vlaamse autoriteit buiten Vlaanderen. Orthofoto, DHMV en OSM zijn slechts volgens hun eigen rol bruikbaar. | Geen semantische pariteit met GRB aannemen; cross-region aggregate blijft not_evaluable totdat een bevroren harmonisatiecontract bestaat. | +| Brussel: footprint- of gebouwdetectievalidatie | Alleen een expliciet governed UrbIS-building-product kan authoritative zijn voor zijn eigen product/versie/zone. | Gebouwenregister en GRB zijn niet automatisch Brusselse truth. OSM/imagery blijven niet-beslissend. | Geen governed UrbIS-versie betekent not_evaluable/partial; geen regionale substitutie. | +| Zoneoverschrijdend België-resultaat | Een per-zone, per-versie gevalideerde portfolio van de bovenstaande referenties. | Alleen vergelijkbare ontologie, tijd, resolutie, matchingpolicy en metriek mogen later geaggregeerd worden. | Een Belgisch cijfer mag geen ontbrekende of mislukte zone verbergen; zonder alle verplichte strata is de status not_evaluable. | +| Gebouwstatus, units en adressen in Vlaanderen | Gebouwen- en Adressenregister is authoritative voor zijn geregistreerde object-/statussemantiek binnen de gedateerde snapshot. | GRB is corroborative voor geometrische reconciliatie; registerstatus is geen GRB-footprint en omgekeerd. | Units/adressen zijn geen woningen, huishoudens, bewoners, volume of modeltruth. | + +GRB is dus de primaire geometrische validatiereferentie voor een passende +Vlaamse building-taak, niet een automatische waarheid voor elk gebouw, iedere +tijd of andere regio. De registerstatus of een zichtbaar dak in imagery kan +een reviewfinding opleveren, maar vervangt een geldige referentie niet zonder +vooraf bevroren adjudicatiebeleid. + +### 3.2 Verboden automatische substituties + +- OSM mag nooit automatisch als building ground truth, labelbron of + promotie-referentie worden gebruikt. +- Sentinel-2 mag nooit als building ground truth, footprintlabel of + fine-grained objectvalidatie worden gebruikt. +- DHMV DTM/DSM mag nooit een gebouwfootprint, gebouwhoogte, waterdiepte of + gebouwtruth fabriceren. +- Een Gebouwenregister-snapshot mag GRB niet automatisch vervangen als + primaire footprintreferentie; zijn lifecycle-/registersemantiek blijft + afzonderlijk. +- Een derived GeoIntel-laag, YOLO-detectie, segmentatie of kaartselectie mag + nooit zijn eigen referentie zijn. +- Wanneer de primaire bron niet beschikbaar, verlopen, temporeel ongeschikt + of contractueel ongeldig is, retourneert GeoIntel expliciet + not_configured, partial, unavailable of not_evaluable. Geen fallback mag + als geslaagde primaire validatie worden weergegeven. + +Een concrete source snapshot is alleen consumeerbaar wanneer zijn +`freshness_status` `current` of expliciet `not_applicable` is. `unknown`, +`review_required`, `due` en `stale` worden aan elke productiegrens +geblokkeerd, ook wanneer de registry-familie op zichzelf authoritative is. +Een historische bron die bewust bruikbaar blijft, moet dus expliciet door +zijn contract als `not_applicable` zijn gemotiveerd; een ontbrekende of oude +status is geen stilzwijgende uitzondering. + +## 4. Matrix van governable source families + +De volgende matrix onderscheidt de beleidsrol van een bron van de actuele +implementatiestatus. “Implemented” betekent uitsluitend dat een begrensde +code-/operatorroute is aangetroffen; het betekent niet dat iedere opgeslagen +dataset al aan het Fase-2 registry-contract voldoet. + +| Registry source id | Klasse per taak | Autoriteit en toepassingsgebied | Toegelaten gebruik | Verboden/limieten | Stand op 2026-08-01 | +|---|---|---|---|---|---| +| grb | authoritative voor Vlaamse GRB-producten; primary voor passende building-footprintvalidatie | Digitaal Vlaanderen; Vlaanderen; GBG, Wegsegment, WTZ/WLAS/WGR en ADP volgens product allowlist | Referentievector, ruimtelijke QA, footprint-/lengte-/oppervlaktemetingen binnen productsemantiek | Geen juridische perceelgrens, vloeroppervlakte, volume, waterdiepte of tijdloze fysieke verandering claimen | Governed OGC acquisition en registry/snapshot/contractbinding zijn geïmplementeerd; een concrete snapshot blijft alleen primary-eligible wanneer taak-, zone-, tijd- en contractchecks slagen. | +| digitaal_vlaanderen_buildings_addresses_register | authoritative voor geregistreerde gebouw-/unit-/adresstatus; corroborative voor footprintreconciliatie | Digitaal Vlaanderen; gedateerde gemeentelijke snapshot; Gebouw, Gebouweenheid en Adres | Registerstatus, stable objectidentity, aggregate unit/adrescontext, GRB-matchreview | Geen automatische vervanger voor GRB footprinttruth; geen persoonsgegevens/adreslabels als featureoutput; geen demografieclaim | Server-owned registry-entry en task policy bestaan; zonder concrete governed snapshot blijft dit een niet-geactiveerde autoriteit. | +| spw_picc | authoritative voor de goedgekeurde PICC building-taak in Wallonië | SPW; Wallonië; exact product/edition en zone | Regionale building reference/QA binnen vastgelegde semantics | Geen GRB-semantic parity of Vlaamse/nationale extrapolatie | Governed official-vector ingest schrijft registry/snapshot/contractbinding; per-versie semantische acceptance en cross-region harmonisatie blijven afzonderlijke gates. | +| urbis | authoritative voor de goedgekeurde UrbIS building-taak in Brussel | Paradigm/competente Brusselse instantie; Brussels Hoofdstedelijk Gewest | Regionale building reference/QA binnen vastgelegde semantics | Geen automatische parity met GRB/PICC of nationale claim | Governed official-vector ingest schrijft registry/snapshot/contractbinding; per-versie semantische acceptance en cross-region harmonisatie blijven afzonderlijke gates. | +| digitaal_vlaanderen_orthophoto | contextual als imagery; observatie-input voor matching en review | Digitaal Vlaanderen; Vlaanderen; product-/vlucht-/editiegebonden | Inference input, visuele labelreview, temporal alignmentcontrole | Geen truth zonder onafhankelijke reference; latest is geen per-pixel observed_at | Governed acquisition en centrale contractvalidatie zijn geïmplementeerd; source version/time blijft per product/snapshot aantoonbaar. | +| spw_orthophoto | contextual als imagery | SPW; Wallonië; product-/editiegebonden | Inference input en review | Geen building truth of semantische parity claim | Implemented governed acquisition volgens API-contract; registry/contractgate vereist | +| urbis_orthophoto | contextual als imagery | Paradigm; Brussel; product-/editiegebonden | Inference input en review | Geen building truth of semantische parity claim | Implemented governed acquisition volgens API-contract; registry/contractgate vereist | +| sentinel_2 | contextual, pas na eigen registered contract | Copernicus/Sentinel-2; sensor-, tile-, processing-level- en acquisitiongebonden | Coarse land-cover/vegetation/temporal context wanneer contract en resolution passend zijn | Nooit building ground truth, footprintlabel, fine building QA of stille fallback voor orthofoto | Planned/not configured: health en API markeren Sentinel als planned/disabled; geen governed ingestadapter aangetroffen | +| digitaal_vlaanderen_dhmv | authoritative voor exact declared elevation product; corroborative voor terrain/elevation bij building reviews | Digitaal Vlaanderen; Vlaanderen; DHMV II DTM/DSM, EPSG:31370, TAW, 2013-2015 | Terrain/reliëf/slope, elevationcontext en review van plausibiliteit | Geen building footprinttruth, directe gebouwhoogte, waterdiepte of volume | Bounded WCS acquisition plus registry/snapshot/raster-contractgate zijn geïmplementeerd; verticale productsemantiek blijft source-specifiek gecontroleerd. | +| osm | contextual; eventueel corroborative alleen onder vooraf vastgelegd onderzoek/handmatige review | OpenStreetMap contributors; vrijwillig bijgewerkte werelddekking | Kaartcontext, kandidaat-/confuserinventaris, menselijke reviewhulp | Nooit automatische ground truth, primary reference, labelbron of coverage-authority | Provider bestaat maar live Overpass/download is not_configured | +| ngi_adminvector, statbel, rbins en andere competentiebronnen | authoritative uitsluitend voor hun eigen bestuurlijke, statistische of maritieme taak | Bevoegde federale/regionale/maritieme instantie en exacte source family | Scope, context en bron-specifieke metrics | Geen building labels tenzij expliciet geregistreerde productsemantiek dat toelaat | De geregistreerde source families hebben server-owned class/policy records; niet-gegovernde historische rows blijven expliciet onvolledig. | +| manual | experimental/untrusted | Door gebruiker aangeleverd; autoriteit onbekend tenzij later formeel ingestbewijs is gekoppeld | Privé-projectcontext of expliciete operatorreview | Nooit officiële authoriteit, coverage, trainingtruth of promotionbasis op naam alleen | Implemented uploadflow; Phase 1 bewees spoofability van source_name en maakt migratie naar manual/untrusted verplicht | +| fixture | experimental | Lokale test- en demofiles | Unit/integratietests en expliciete demo | Nooit productie, nationale metric, source authority of trainingclaim | Implemented and explicitly marked fixture provider | +| derived, map_selection en training_label | derived | GeoIntel-transformatie van bekende parents | Datasets, tiles, metrics, exports met volledige parent-lineage | Geen externe source authority, geen verbergen van incomplete parent | Vector/raster-mapoperaties registreren `derived`/`map_selection`, outputchecksum, contractrapport en parent-edge; ontbrekende of ongeschikte parent leidt tot quarantine. | +| labels en modelartefacten | derived of experimental tot volledig governed | Corpus/label-/trainingrelease | Alleen volgens 08-data-contracts en split/firewallbeleid | Geen training/promotion bij onbekende bron, review, split of hash | V56/V58/V62/V66 evidence is incomplete for release; nationale claim blocked | + +### 4.1 Licentie- en gebruiksgrenzen per bronprofiel + +Een registry-entry bewaart momenteel de family-level licentie of +gebruiksvoorwaarde. Een generieke tekst als “official” is niet voldoende, en +wordt niet automatisch een snapshot-specifieke licentie-eigenschap. De actuele +startinventaris ondersteunt alleen de volgende begrensde uitspraken: + +| Bronprofiel | Vastgelegde of vereiste licentie-/attributiegrens | +|---|---| +| GRB | De bestaande governed adapter bewaart de Digitaal Vlaanderen-attributie en verwijst naar hergebruik volgens de open-datavoorwaarden en bronvermelding. Elke snapshot bewaart de gebruikte catalogue/product identity; een onbekende licentie is niet primary-QA-eligible. | +| Gebouwen- en Adressenregister | De operator bewaart bron-URL's, catalogue URL en Digitaal Vlaanderen-attributie, maar de nieuwe registry moet de concrete hergebruiksvoorwaarde per snapshot vastleggen. Privacy-minimalisatie is verplicht: adreslabels, straat-, huis- en busnummers komen niet in queryable vectorfeatures. | +| DHMV | De bestaande adapter vermeldt het gebruiksrecht voor geografische webdiensten van Digitaal Vlaanderen en bronvermelding. Zij mag geen verticale datum, hoogtesemantiek of resolutie herinterpreteren. | +| PICC en UrbIS | De API-contracten documenteren bekende SPW- respectievelijk Paradigm/FPS Finance-licentienoten. Snapshot-specifieke licentietekst/versie, attribution en redistribution-restrictie zijn nog geen getypeerde P2-velden; een adapter mag ze voorlopig alleen aanvullend in `snapshot_metadata_json` bewaren. Een productcontract dat deze evidence vereist, moet een ontbrekend veld expliciet laten falen of quarantainen. | +| OSM | OSM is onder ODbL met verplichte attributie volgens de bestaande providercapability. Afgeleide of gecombineerde OSM-output volgt de toepasselijke ODbL-verplichtingen en blijft nooit automatic truth. | +| Sentinel-2 | Vóór een toekomstige adapter activeert, legt de registry de exacte Copernicus/Sentinel productlicentie, verwerking, attribution en redistributionvoorwaarden vast. Zonder die snapshot is Sentinel not_configured. | +| Manual, fixture en derived | De uploader/producer kan een licentie beschrijven maar niet authoriteit verlenen. Ontbrekende of onverenigbare gebruiksrechten blokkeren training, publicatie en herdistributie. | + +### 4.2 Verplichte migratie van alle waargenomen source_name-waarden + +Phase 1 zag 28 verschillende source_name-waarden in de Tower-database. De +volgende tabel is de migratieregistratie: een klasse is pas activeerbaar na +controle van publisher, product, licentie en snapshot. De tabel verheft geen +historische row met die naam automatisch tot trusted data. + +| Bestaande source_name | Initiële registry-klasse | Afbakening | +|---|---|---| +| grb | authoritative | Alleen GRB-product/zone/versie volgens de governed allowlist; primary building footprint reference enkel in Vlaanderen. | +| digitaal_vlaanderen_buildings_addresses_register | authoritative + corroborative | Authoritative registersemantiek; corroborative voor footprintreconciliatie. | +| spw_picc | authoritative | Alleen de allowlisted PICC productfamilie in Wallonië; geen GRB-pariteit. | +| urbis | authoritative | Alleen de allowlisted UrbIS productfamilie in Brussel; geen GRB/PICC-pariteit. | +| digitaal_vlaanderen_dhmv | authoritative + corroborative | Authoritative elevation product; corroborative in building-reviewcontext. | +| digitaal_vlaanderen_orthophoto | contextual | Official imageryinput, nooit automatic reference truth. | +| spw_orthophoto | contextual | Walloon imageryinput, nooit automatic reference truth. | +| urbis_orthophoto | contextual | Brussels imageryinput, nooit automatic reference truth. | +| vmm_flood_hazard | authoritative | Alleen voor geregistreerde scenario-/overstromingssemantiek; geen observed_at fabriceren. | +| vmm_vha_bathymetry_profiles | authoritative | Alleen voor exact profiel, datum en verticale referentie; geen raster/depth extrapolatie. | +| department_omgeving_thematic_raster | authoritative | Alleen voor de specifieke Vlaamse klasse/productdefinitie. | +| department_omgeving_land_use | authoritative | Alleen voor de geregistreerde landgebruikeditie/klasse. | +| agentschap_landbouw_zeevisserij_agricultural_parcels | authoritative | Alleen voor declared agricultural use per jaar; geen eigendom/gebouwtruth. | +| waterinfo | authoritative | Alleen voor exact meetreeks-/station-/tijdcontract. | +| statbel | authoritative | Alleen voor statistische publicaties en hun aggregatieniveau. | +| ngi_adminvector | authoritative | Alleen voor governed administratieve scope. | +| rbins_marine_reporting_units | authoritative | Alleen voor mariene rapportage-eenheden en exact legal scope. | +| rbins_msp_2026 | authoritative | Alleen voor het vastgelegde mariene plan/edition. | +| vrbg | authoritative | Alleen voor het wegregister en zijn eigen semantiek. | +| dov_soil_map | authoritative | Alleen voor bodemkaart/surveyperiode; geen actuele ground truth insinueren. | +| inbo_bwk_natura2000 | authoritative | Alleen voor de vastgelegde natuur-/habitatproductsemantiek. | +| spw_walous_land_cover | authoritative | Alleen voor de vastgelegde Waalse landbedekkingsclassificatie. | +| spw_bathymetry | authoritative | Alleen met CRS, verticale referentie, surveyperiode en archive identity. | +| spw_terrain | corroborative | Alleen voor de vastgelegde terreincontext/reconciliatie; geen zelfstandige authoritative claim zonder een toekomstige productpolicy. | +| historical_landuse | corroborative | Alleen als historische context met bron-, editie-, partition- en identity evidence; objecthistory blijft disabled wanneer identity_stable=false. | +| manual | experimental | Manual/untrusted totdat een aparte governed re-ingest een nieuwe accepted snapshot oplevert. | +| fixture | experimental | Alleen test/demo. | +| map_selection | derived | Alleen een GeoIntel-selectie; nooit externe bron, reference of trainingtruth. | + +## 5. Centrale source registry: gerealiseerd datamodel en normatieve uitbreiding + +### 5.1 Registry-entry versus snapshot + +De centrale registry heeft twee server-owned lagen: + +1. SourceDefinition: het server-owned beleid voor een source family/product; +2. SourceSnapshot: de concrete, checksummed acquisitie of + editie die een DatasetVersion mag voeden. + +Een SourceDefinition wordt niet door een client in een uploadformulier +aangemaakt. Een SourceSnapshot kan alleen door een governed adapter of een +expliciet reviewed operator-import aan een Definition worden gebonden. Een +handmatige upload verwijst uitsluitend naar de server-owned manual Definition +met trust_class=experimental/untrusted. + +### 5.2 Verplichte SourceDefinition-velden + +| Veldgroep | Verplichte inhoud | +|---|---| +| identity | getypeerd: immutable source_registry_id, source_key, display name, publisher/authority en registry definition revision in `registry_metadata_json`; toekomstig normatief: afzonderlijke registry-version en deprecated lifecycle | +| authority | source class, trust class, allowed task claims, reference priority, allowed zones/legal scope IDs, forbidden claims en fallbackbeleid | +| access/licence | governed endpoint/catalogue allowlist, attribution template, licence/use/redistribution restrictions, credentials/secret reference buiten de registry-payload | +| spatial | native CRS, canonical storage CRS, approved metric CRS strategy, units inclusief verticale referentie indien relevant, native resolution/scale, expected geometry families/bands | +| temporal | getypeerd: source-version policy, temporal/geografische coverage JSON en freshness policy; toekomstig normatief: afzonderlijke published/observed/valid requirementvelden per product | +| schema | contract id/version voor raster, vector, label of model, expected collections, feature-id strategy, required/optional attributes, topology/attribute constraints | +| operations | approved acquisition adapter, request limits, cache/idempotency policy, allowed transformations, provenance requirements en quarantine routing | +| limitations | source-native semantic beperkingen, comparison exclusions, privacy restrictions, known gaps en operator note | + +### 5.3 SourceSnapshot-velden: gerealiseerd versus normatief + +De getypeerde P2-tabel bevat `source_registry_id`, `snapshot_key`, +`source_version`, `snapshot_at`, `fetched_at`, `source_url`, +`checksum_sha256`, `crs`, `units`, resolution-, temporal- en coverage-JSON, +observed-schema JSON, `freshness_status`, `ingest_status`, known limitations +en `snapshot_metadata_json`. De registry-entry bewaart de bronlicentie, +licentie-URL en gebruiksbeperkingen. Deze velden worden samen met de +Dataset/DatasetVersion-contractversie en validation report gebruikt voor +consumeerbare provenance. + +`published_at`, afzonderlijke request-/collection identity, +snapshot-specifieke licentie/attributie, validation-report-hash en +immutable-manifest-hash zijn in de huidige P2-opslag geen afzonderlijke +getypeerde kolommen. Wanneer een adapter ze kent, bewaart hij ze alleen als +aanvullende `snapshot_metadata_json`; afwezigheid mag geen primary, training- +of productieclaim opleveren wanneer het relevante contract ze vereist. Zij +blijven een expliciete normatieve uitbreiding, geen reeds gerealiseerde +kolommen. + +Fetchtime is nooit een vervanging voor observed_at. Een bron waarvoor een +observatietijd niet bestaat, gebruikt in het datacontract een expliciete +`not_applicable` of `unknown_with_reason`-reden; die tweede term is een +contractbeslissing en geen waarde van `SourceSnapshot.freshness_status`. + +## 6. Freshness, ingest en authority states + +### 6.1 Freshness + +De P2 registry en snapshot gebruiken exact `unknown`, `current`, `due`, +`stale`, `not_applicable` en `review_required`. Fase 2 bindt die betekenis aan +registry-policy en snapshot in plaats van aan vrije metadata. Toegelaten +uitkomsten zijn: + +| Status | Betekenis voor gebruik | +|---|---| +| current | Snapshot valt binnen de geregistreerde review-/geldigheidsregel. | +| due | Snapshot moet worden vernieuwd/gecontroleerd en mag niet door een productiegrens. | +| stale | Snapshot is verlopen en mag niet door een productiegrens. | +| review_required | Een verplichte versie-, tijd-, checksum-, licentie- of policywaarde ontbreekt; niet gebruiken voor authoritative claim. | +| unknown | Freshness is niet aantoonbaar; niet consumeerbaar. | +| not_applicable | Alleen wanneer het concept inhoudelijk niet op de bron past, bijvoorbeeld observed_at voor een niet-temporele vaste bron. | + +### 6.2 Ingest en trust + +| Ingeststatus | Betekenis | Toegang tot training / productie-inference / QA | +|---|---|---| +| registered | Server-owned brondefinitie bestaat, nog geen consumeerbare snapshot. | Geen | +| configured / not_configured / available | Adapter- of beschikbaarheidsstatus; geen ingestbewijs. | Geen | +| ingested | Snapshot is geschreven; Dataset/DatasetVersion moet daarnaast een groen contractrapport hebben. | Alleen volgens source class en task policy | +| failed | Ingest of validatie is mislukt. | Geen | +| quarantined | Fout, twijfel, ontbrekende provenance of policyconflict is vastgelegd. | Geen | +| legacy_unverified | Gemigreerd historisch record zonder complete P2-provenance. | Geen nieuwe training/promotion; UI/API toont beperking | + +Een status ready op de huidige Dataset-tabel is hoogstens een bestaande +processingstatus. Zij is niet gelijk aan accepted, authoritative of +model-validatable totdat de Fase-2 contractstatus dat bewijst. + +## 7. Huidige implementatie en aantoonbare gaten + +| Onderwerp | Aangetroffen | Niet aangetroffen / Fase-2 verplichting | +|---|---|---| +| Provider capabilities | Server-owned registry definieert 40 source families, classificatie, task policy en immutable snapshot-binding. | Per product nog geen volledige typed published/request/licence-manifestvelden; zie §5.3. | +| Dataset provenance | Dataset en DatasetVersion hebben registry/snapshot FK, versioned contract/reportvelden en lineage/quarantine records. | Historische records blijven incompleet; een daadwerkelijke nieuwe governed ingest is nodig voor gebruik. | +| GRB | Bounded allowlisted OGC acquisition, registry/snapshotbinding, contractgate en primaire Vlaamse building-policy zijn aanwezig. | Concrete snapshot blijft zone-, tijd- en productafhankelijk; geen nationale claim. | +| DHMV | Bounded WCS-flow, registry/snapshot/rastercontract en elevation-policy zijn aanwezig. | Geen gebouwfootprinttruth of impliciete verticale semantiek. | +| Gebouwenregister | Registry task policy onderscheidt registersemantiek van GRB-footprintreconciliatie. | Concrete governed snapshot en productcontract blijven vereist voor activatie. | +| Generic upload | Uploads worden server-side als manual/experimental behandeld, niet op caller source_name. | Alleen expliciete reviewed ingest kan later een andere governed route gebruiken. | +| OSM/Sentinel | OSM blijft contextual/not_configured; Sentinel blijft planned/not_configured. | Geen live acquisition of automatic authority totdat adapter en contract bestaan. | +| Quarantine | `SourceRegistryService.quarantine_dataset` en de database-trigger propageren quarantine naar gekoppelde Dataset/DatasetVersion/snapshot en downstream lineage-descendants; consumption gates sluiten training/inference/QA/export/coverage. | Geen in-place release: een governed re-ingest/nieuwe versie is nodig. | + +## 8. Resultaatweergave en fallbackcontract + +Dit is het verplichte doelcontract voor API en UI. De P2-evidence bewijst nog +niet met een end-to-end browser/API-journey dat elk bestaand zichtbaar resultaat +de volledige set velden al toont. + +Ieder zichtbaar GeoIntel-resultaat met bronafhankelijkheid moet minimaal tonen: +source display name, source_registry_id, snapshot/version, source class, +authority scope, observed/published/fetched time, freshness, checksum, +licence/attribution, CRS/units, resolution, coverage and limitation. + +Een resultaat dat op een contextual, derived of experimental bron steunt, draagt +die status in de API en UI. Een resultaatsamenvatting mag niet alleen de +merknaam “GRB” of “officieel” tonen wanneer de concrete DatasetVersion niet +aan de registry is gebonden. + +Voor building QA omvat een mismatch ten minste: candidate/source tile, +primary-reference snapshot, eventuele Gebouwenregister-reconciliatie, +orthophoto observation time, DHMV-context indien gebruikt, en OSM uitsluitend +als contextual review evidence. Die aanvullende bronnen veranderen de +primary-reference match niet zonder een expliciete menselijke adjudicatie. + +## 9. Exit-evidence voor deze matrix + +Fase 2 kan bronautoriteit alleen als groen markeren wanneer bewijs bestaat van: + +1. een migratie- en registry-inventory met alle bestaande source_name-waarden + geclassificeerd of expliciet in quarantine; +2. server-side tests waarin een forged GRB upload manual/untrusted blijft; +3. bounded GRB, DHMV en register-snapshots met registry/snapshot/contract + identity, immutable checksums en validatierapport; +4. tests voor zone-/theme-/version-isolatie en geen cross-theme coverage union; +5. bewijs dat OSM en Sentinel niet als automatic truth/fallback kunnen lopen; +6. resultaten waarin unavailable, partial, not_configured, quarantined en + not_evaluable zichtbaar en niet als success gepresenteerd worden. + +Tot deze evidence bestaat, blijven de Phase-1 bronautoriteitsclaims en de +nationale building-promotion blocked. diff --git a/docs/accuracy-program/08-data-contracts.md b/docs/accuracy-program/08-data-contracts.md new file mode 100644 index 00000000..8dbfeed6 --- /dev/null +++ b/docs/accuracy-program/08-data-contracts.md @@ -0,0 +1,557 @@ +# 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 `.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: + + .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. diff --git a/docs/accuracy-program/status.json b/docs/accuracy-program/status.json index dfd31f50..92c8a246 100644 --- a/docs/accuracy-program/status.json +++ b/docs/accuracy-program/status.json @@ -1,8 +1,8 @@ { "schema_version": 1, "program": "GeoIntel Accuracy Improvement Program", - "phase": "P1", - "generated_at": "2026-08-01T18:40:00+02:00", + "phase": "P2", + "generated_at": "2026-08-01T23:43:55+02:00", "scope": { "product": "Belgium and the Belgian North Sea", "active_building_model_claim": "Mol/Kempen only, operator review required", @@ -12,6 +12,9 @@ "branch": "codex/geointel-accuracy-program", "repository_commit": "0c019bb22f816db1e4b7a68379bcad08924d9a21", "database_migration_head": "202607260001", + "phase2_migration_revision": "202608010001", + "phase2_migration_live_disposable_verified": true, + "phase2_migration_production_deployed": false, "phase1_mutation_scope": "audit tooling, tests, documentation and retained evidence only" }, "phase1": { @@ -37,7 +40,8 @@ "medium_risk_count": 4 }, "phase2": { - "status": "ready_for_controlled_remediation", + "status": "in_progress", + "meaning": "The source/provenance foundation is implemented and verified in a disposable PostGIS environment; the full P2 roadmap and its training/release gates are not complete.", "roadmap": "docs/accuracy-program/06-implementation-roadmap.md", "first_work_package": "P2-00", "required_order": [ @@ -57,6 +61,28 @@ ], "protected_test_rule": "Open exactly once for a pre-registered immutable candidate after all pre-test gates pass; never feed its results back into that candidate family." }, + "phase2_source_provenance": { + "status": "implemented_and_verified_in_disposable_environment", + "evidence_root": "artifacts/evidence/accuracy/P2", + "implemented": [ + "server-owned source registry and immutable source snapshots", + "versioned vector, raster, label and PyTorch model contracts", + "checksum-bound dataset and dataset-version provenance", + "lineage graph, quarantine propagation and consumption gates", + "live disposable PostGIS upgrade, guard and downgrade verification" + ], + "does_not_mean": [ + "all legacy records are provenance complete", + "physical quarantine or protected-test storage isolation is proven", + "every UI result has end-to-end provenance rendering evidence", + "the full P2 roadmap is complete", + "training, promotion or national validation is allowed" + ] + }, + "phase3": { + "status": "not_ready", + "reason": "P2-00 through P2-12 are not all green; human review, corpus rebuild, protected-split evidence, metric gates, candidate CUDA training, protected testing and promotion remain blocked." + }, "runtime": { "cuda_available": true, "device": "NVIDIA GeForce RTX 4080 SUPER", @@ -163,15 +189,16 @@ "verification": { "backend_full_suite": { "status": "failed", - "passed": 1180, + "passed": 1282, "failed": 17, - "duration_seconds": 70.63, - "classification": "stale source/contract assertions; no new audit-tooling failures" + "duration_seconds": 116.62, + "classification": "The canonical backend test import boundary now collects. Sixteen remaining failures are historical source-text assertions for changed UI/deployment/README behavior; one full Windows run also hit an intermittent WSL-backed bash.exe host failure in a shell-wrapper syntax test. This still prevents a whole-suite-green claim." }, "backend_ci_entrypoint": { - "status": "collection_failed", - "collected": 1194, - "error": "ModuleNotFoundError: scripts.render_operator_polygon_label_qa" + "status": "collected_with_failures", + "collected": 1299, + "result": "1282 passed, 17 failed", + "note": "The former scripts.render_operator_polygon_label_qa collection failure is resolved by the canonical backend-test import boundary." }, "phase1_tooling_tests": { "status": "passed", @@ -182,16 +209,8 @@ }, "repository_ruff": { "status": "failed", - "finding_count": 112, - "by_code": { - "E402": 13, - "E701": 2, - "E702": 69, - "F401": 23, - "F403": 1, - "F811": 2, - "F841": 2 - } + "finding_count": 95, + "note": "P2-changed Python paths pass their scoped Ruff check; repository-wide remediation remains an explicit P2-01 gate." }, "frontend_unit": { "status": "passed", @@ -215,12 +234,22 @@ "explicit_non_envelope_endpoints": 10 }, "alembic": { - "status": "passed_offline", + "status": "passed_offline_and_disposable_postgis", "heads": [ - "202607260001" + "202608010001" ], - "offline_upgrade_sql_lines": 496, - "live_migration_tested_locally": false + "offline_upgrade_rendered": true, + "offline_downgrade_rendered": true, + "live_migration_tested_locally": true, + "production_migration_deployed": false + }, + "phase2_source_provenance": { + "status": "passed_in_disposable_environment", + "source_registry_definitions": 40, + "migration_revision": "202608010001", + "migration_guards": "artifacts/evidence/accuracy/P2/postgres-migration-guards.json", + "static_inventory": "artifacts/evidence/accuracy/P2/source-contract-inventory.json", + "claim_boundary": "This is not a production migration deployment, corpus-release, accuracy or promotion result." }, "golden_qa": { "semantic_results_stable": true, @@ -254,8 +283,12 @@ "docs/accuracy-program/03-baseline-and-gaps.md", "docs/accuracy-program/04-risk-register.md", "docs/accuracy-program/05-metric-framework.md", - "docs/accuracy-program/06-implementation-roadmap.md" + "docs/accuracy-program/06-implementation-roadmap.md", + "docs/accuracy-program/07-source-authority-matrix.md", + "docs/accuracy-program/08-data-contracts.md" ], "evidence_root": "artifacts/evidence/accuracy/P1", - "evidence_manifest": "artifacts/evidence/accuracy/P1/evidence-manifest.json" + "evidence_manifest": "artifacts/evidence/accuracy/P1/evidence-manifest.json", + "phase2_evidence_root": "artifacts/evidence/accuracy/P2", + "phase2_evidence_manifest": "artifacts/evidence/accuracy/P2/evidence-manifest.json" }