Initial GeoIntel V1 foundation
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-06-16 23:36:32 +02:00
commit 6ea3586a3e
605 changed files with 45284 additions and 0 deletions
View File
+122
View File
@@ -0,0 +1,122 @@
# START HERE — GeoIntel Architect Canonical Entry Point
This is the single canonical entry point for Codex, reviewers and future contributors.
Older handoff files are historical. If documents conflict, follow the precedence order in this file.
## Current milestone
**M14 — Build Launch Package**
The repository is no longer only a documentation bundle. It is now a specification-controlled engineering repo for building GeoIntel Kempen as a GeoAI Workbench.
## Product one-liner
GeoIntel Kempen is a GeoAI Workbench for the Belgian Kempen that processes raster data, vector data and AI outputs into geospatially correct detections, segmentations, QA/QC metrics and exports.
## Non-negotiable product identity
GeoIntel is:
- a GeoAI Workbench;
- a geospatial data processing product;
- a platform for raster/vector/AI/QA workflows;
- a portfolio-grade implementation of GIS, remote sensing, computer vision and data engineering.
GeoIntel is not primarily:
- a generic dashboard;
- a reporting-only tool;
- a chatbot;
- a QGIS clone;
- a mock demo app.
## Canonical read order for Codex
Read these files in order before coding:
1. `docs/00-start/START_HERE.md`
2. `docs/governance/GEOINTEL_CONSTITUTION.md`
3. `docs/governance/ARCHITECTURE_INVARIANTS.md`
4. `docs/governance/FORBIDDEN_DECISIONS.md`
5. `docs/governance/DECISION_PRECEDENCE.md`
6. `docs/specs/CANONICAL_DOMAIN_MODELS.md`
7. `docs/specs/GIS_STANDARDS.md`
8. `docs/specs/RASTER_STANDARDS.md`
9. `docs/specs/STATE_MACHINES.md`
10. `docs/workflows/GOLDEN_PATHS.md`
11. `docs/build/BUILD_ORDER_DEPENDENCY_GRAPH.md`
12. `docs/build/CODEX_OPERATING_SYSTEM.md`
13. `docs/40-build-launch/SPRINT_1_SCOPE_FREEZE.md`
14. `docs/40-build-launch/BUILD_SUCCESS_DEFINITION.md`
15. `docs/40-build-launch/CODEX_STOP_RULES.md`
16. `prompts/codex/m14/CODEX_FIRST_DAY_MASTER_PROMPT.md`
## Canonical first implementation target
The first vertical slice is:
**Project + Area + Dataset + Raster/Vector metadata + Reference polygons + Detection result import + QA/QC + GeoJSON export.**
Do not start with full AI inference if the foundation is not stable. The first goal is to prove the data lifecycle and geospatial correctness.
## Canonical V1 golden path
1. Create project.
2. Create/select an Area in the Kempen.
3. Upload or load a raster/vector dataset.
4. Extract and persist metadata.
5. Load reference polygons, initially demo GRB-like buildings.
6. Import or generate predicted building detections.
7. Convert outputs to valid geospatial features.
8. Run QA/QC against the reference layer.
9. Show results on the map and in metrics panels.
10. Export GeoJSON.
## What Codex may improve autonomously
Codex may improve:
- implementation quality;
- test coverage;
- type safety;
- error handling;
- UI clarity;
- documentation clarity;
- internal helper abstractions;
- performance within defined budgets.
Codex may not change:
- product identity;
- core stack;
- CRS policy;
- database choice;
- async job architecture;
- API envelope shape;
- state machine names;
- golden path priority;
- forbidden decisions.
## Conflict resolution
If any older document conflicts with this M14 launch layer, follow this order:
1. Constitution and architecture invariants.
2. Forbidden decisions.
3. State machines and canonical models.
4. API/database contracts.
5. Build order dependency graph.
6. M14 build-launch docs for first-run scope and stop rules.
7. Older milestone handoff documents.
## Required pass ending
Every Codex pass must end with:
- files changed;
- commands run;
- tests passed/failed;
- known limitations;
- whether golden paths still pass;
- whether any architecture invariant was touched;
- next recommended pass.
+81
View File
@@ -0,0 +1,81 @@
# Regression Traps
This document lists common failure modes Codex must actively avoid.
## Geospatial Traps
### CRS Loss
Never store or return geometries without CRS context. GeoJSON is usually WGS84 by convention, but source CRS must still be preserved in dataset metadata.
### Bounding Box Confusion
Never mix `[minx, miny, maxx, maxy]` with `[west, south, east, north]` without explicitly naming fields.
### Area Units
Never compute area in degrees. Reproject to an appropriate projected CRS before area or distance calculations. For Flanders/Kempen, prefer Belgian Lambert 72 / EPSG:31370 for metric calculations unless a stronger reason is documented.
### Raster/Vector Alignment
Never compare raster-derived outputs with vector reference layers without documenting resolution, CRS and alignment assumptions.
### Invalid Geometry
Always validate polygons. Attempt safe fixes only when documented; otherwise return a validation error.
## AI Traps
### Confidence Is Not Accuracy
Do not present model confidence as accuracy. Accuracy requires comparison against reference or labels.
### Fixture Detection Is Not Real AI
When using fixture/stub output, label it clearly as fixture/demo mode.
### Silent Model Fallback
Never silently fall back from real model inference to fixture mode. The response must indicate the mode used.
### Mask Polygonization Noise
Segmentation polygonization must include simplification/cleanup parameters and preserve original mask path.
## Backend Traps
### Long Work in Request Thread
Do not run heavy raster/AI operations synchronously inside request handlers. Use a job boundary.
### Inconsistent Status Values
Use the frozen status enum only: `queued`, `running`, `completed`, `failed`, `cancelled`.
### File Path Leakage
API responses may expose logical storage keys or download URLs, not arbitrary host paths.
## Frontend Traps
### UI-Only State
Do not create project, area, dataset or analysis state only in frontend memory. Persist via API.
### Empty Success Screens
Every page must distinguish loading, empty, error, ready and completed states.
### Map Layer Ambiguity
Every map layer must show source, timestamp, opacity, visibility and legend where applicable.
## Documentation Traps
### TODO Instead of Decision
Do not use TODO comments for architecture gaps. Either implement, document a limitation, or ask for a decision.
### Contract Drift
If code changes API responses, update contract docs and examples in the same pass.
+58
View File
@@ -0,0 +1,58 @@
# Self-Review Checklist for Codex
Codex must run this checklist before ending every implementation pass.
## Product Fit
- [ ] Does the work still support GeoIntel as a GeoAI Workbench?
- [ ] Did the pass avoid adding unrelated dashboard/chat features?
- [ ] Is the Kempen/GRB-first strategy preserved?
## API and Backend
- [ ] Are new endpoints documented?
- [ ] Do endpoints return stable JSON shapes?
- [ ] Are errors structured and useful?
- [ ] Are validation failures explicit?
- [ ] Are long-running tasks behind a job/status boundary?
## Database
- [ ] Are migrations included?
- [ ] Are geometry columns documented?
- [ ] Are timestamps and provenance fields included?
- [ ] Is source metadata preserved?
## Geospatial Correctness
- [ ] Is CRS captured?
- [ ] Are metric calculations done in a projected CRS?
- [ ] Are geometries validated?
- [ ] Are bounds and area units explicit?
## AI Pipeline Correctness
- [ ] Is model mode clear: real, stub or fixture?
- [ ] Is confidence not mislabeled as accuracy?
- [ ] Are generated detections georeferenced or explicitly not georeferenced?
- [ ] Are model parameters stored with the run?
## Frontend
- [ ] Are loading, empty, error and success states implemented?
- [ ] Does the UI use API data instead of hardcoded business data?
- [ ] Are map layers inspectable?
- [ ] Can users understand what happened after running an analysis?
## Testing
- [ ] Were relevant tests added or updated?
- [ ] Do smoke scripts still pass?
- [ ] Are fixtures deterministic?
## Documentation
- [ ] Was `CHANGELOG.md` updated?
- [ ] Was `docs/BUILD_STATUS.md` updated?
- [ ] Were affected specs updated?
- [ ] Are known limitations explicit?
@@ -0,0 +1,147 @@
# Build Sequence Lock
This file freezes the order in which Codex should build GeoIntel V1. Codex can split passes into smaller chunks, but it must not reorder major dependencies.
## Phase 0 — Repository Verification
- Verify folder structure.
- Verify documentation set exists.
- Verify `.env.example` and docker-compose exist.
- Verify scripts are executable or document how to run them.
- Verify fixtures are valid GeoJSON.
Exit criteria:
- all preflight scripts run or have clear remediation notes.
## Phase 1 — Backend Foundation
- FastAPI app shell.
- Health endpoint.
- Settings/config loader.
- Structured error response model.
- CORS configured for local frontend.
- Logging baseline.
Exit criteria:
- backend imports successfully.
- `/health` returns service status.
- config is read from environment.
## Phase 2 — Database Foundation
- SQLAlchemy or SQLModel models.
- Alembic migrations.
- PostGIS extension migration.
- project, area, dataset, analysis_run base tables.
- geometry storage strategy implemented.
Exit criteria:
- migrations run against PostGIS.
- seed script creates one project and one area.
## Phase 3 — Project, Area and Dataset APIs
- CRUD for projects.
- CRUD for areas.
- dataset upload endpoint.
- metadata extraction queue boundary.
- file storage path convention.
Exit criteria:
- OpenAPI docs expose complete endpoints.
- API tests pass for create/list/read flows.
## Phase 4 — Geospatial Metadata
- vector metadata extraction.
- raster metadata extraction.
- CRS validation.
- bounds extraction.
- geometry validation.
Exit criteria:
- sample GeoJSON returns feature count, bounds and CRS status.
- sample raster placeholder or documented stub returns safe metadata response.
## Phase 5 — Frontend Shell
- React app.
- routing.
- layout.
- API client.
- project list.
- project workspace.
- map workspace placeholder.
Exit criteria:
- frontend starts.
- health check visible.
- project list loads from API.
## Phase 6 — Map and Layer Foundation
- MapLibre map.
- draw/select area.
- layer manager.
- vector layer rendering.
- dataset detail panel.
Exit criteria:
- fixture GeoJSON renders on map.
- drawn area can be saved through API.
## Phase 7 — QA/QC Foundation
- load predicted and reference polygons.
- compute IoU-based matching.
- compute precision, recall and F1.
- create QA result payload.
- render QA dashboard.
Exit criteria:
- fixture QA returns deterministic metrics.
- false positives and false negatives are exported as GeoJSON.
## Phase 8 — Detection Interface Boundary
- detection run model.
- detection service interface.
- model registry stub.
- deterministic fixture-based inference fallback.
- later YOLO integration boundary.
Exit criteria:
- detection run can produce geospatial detections using fixture mode.
- output is stored and visible as layer.
## Phase 9 — Export Pipeline
- export GeoJSON.
- export metrics JSON.
- prepare report shell.
- export provenance metadata.
Exit criteria:
- user can download GeoJSON output from UI.
## Phase 10 — Stabilization
- smoke tests.
- contract tests.
- docs update.
- changelog.
- known limitations.
Exit criteria:
- V1 vertical slice is demonstrable end-to-end.
@@ -0,0 +1,51 @@
# Codex Decision Boundaries
This document defines where Codex has freedom and where it must not decide alone.
## Codex Can Decide
- internal helper function names
- folder organization within already approved domains
- UI microcopy that clarifies state
- additional tests
- stricter validation when compatible with contracts
- small refactors that reduce duplication
- dependency minor versions when compatible
- CSS implementation details
## Codex Must Follow Existing Specs
- primary tech stack
- FastAPI backend
- React frontend
- PostGIS database
- GRB-first reference strategy
- status enums
- API envelopes
- CRS calculation rules
- QA/QC formulas
- V1 scope boundaries
- build sequence
## Codex Must Ask or Stop
- replacing FastAPI, PostGIS, React or MapLibre
- changing project direction from GeoAI Workbench
- adding authentication
- adding paid services
- changing reference data strategy
- changing scoring/math definitions
- presenting fixture output as real AI
- introducing non-deterministic tests
- removing docs/tests to make builds pass
## Improvement Rule
If Codex sees a better approach, it may implement it only when:
1. it is backward compatible with specs
2. it improves correctness, reliability or clarity
3. it updates docs and tests
4. it does not expand V1 scope
If not, document it as a proposal in `docs/PROPOSED_IMPROVEMENTS.md`.
@@ -0,0 +1,89 @@
# M7 Implementation Control Layer
This layer exists to keep Codex productive without allowing it to improvise core architecture.
## Purpose
M7 adds strict execution control around the existing GeoIntel specifications. It defines how Codex should sequence work, how each pass should prove completion, which traps to avoid, and when it is allowed to improve the design.
## Operating Principle
Codex may improve implementation quality, developer experience, robustness, performance and UX clarity, but it may not silently change product direction, data model semantics, analysis definitions, geospatial meaning or API contracts.
## Build Priorities
1. Keep the vertical slice working at all times.
2. Build backend contracts before frontend polish.
3. Prefer small complete modules over broad incomplete scaffolding.
4. Every result must be reproducible from fixtures or documented sample data.
5. Every analysis output must retain source, parameters, units and assumptions.
6. Every geospatial geometry must carry CRS awareness.
7. Every long-running process must expose status, errors and recoverability.
## Mandatory Per-Pass Output
At the end of every Codex pass, update or create:
- `CHANGELOG.md`
- `docs/BUILD_STATUS.md`
- relevant TODO checkboxes
- test notes
- known limitations
- next recommended pass
If a pass changes API contracts, update `contracts/api/` and all affected frontend service calls.
If a pass changes database models, update migrations, schema docs and seed data.
If a pass changes analysis logic, update analysis specifications, tests and expected fixtures.
## Allowed Improvements
Codex may add:
- better validation
- better error messages
- safer defaults
- clearer UI states
- test fixtures
- helper utilities
- small performance improvements
- developer scripts
- documentation clarifications
Codex may not add without explicit approval:
- multi-user auth
- paid external services
- unrelated AI chat features
- unrelated dashboards
- LiDAR production implementation before V1 slice
- training studio before detection and QA/QC are stable
- new primary data sources that conflict with GRB-first strategy
## Stop Conditions
Codex must stop and report instead of continuing if:
- a core specification conflicts with another specification
- a required dependency cannot be installed
- tests fail for reasons that require product decision changes
- geospatial output cannot be tied to CRS or source metadata
- generated outputs would be misleading or scientifically invalid
## M7 Completion Target
The repository is ready for autonomous implementation when Codex can execute:
1. preflight checks
2. backend foundation
3. database foundation
4. dataset upload and metadata
5. map workspace
6. raster/vector preview
7. demo detection stub or real YOLO integration boundary
8. QA/QC fixture comparison
9. GeoJSON export
10. smoke tests
without needing manual architecture decisions.
@@ -0,0 +1,16 @@
# Module Completion Matrix
This matrix defines what counts as complete for each V1 module.
| Module | Backend | Frontend | Tests | Docs | V1 Complete When |
|---|---|---|---|---|---|
| Project Manager | CRUD endpoints, models | list/detail/create | API tests | API + UI docs | User can create/open project |
| Area Manager | geometry validation, save area | draw/save/list areas | geometry fixture tests | geospatial rules updated | User can draw and persist polygon |
| Dataset Manager | upload, metadata, storage | upload form, dataset table | upload/metadata tests | storage + data docs | Dataset can be uploaded and inspected |
| Raster Lab | metadata boundary, clip/preview stubs | metadata panel, preview state | metadata tests | raster spec | Raster dataset has readable metadata |
| Vector Lab | GeoJSON import, feature count, bounds | map overlay, details | fixture render/API tests | vector spec | Vector layer renders and can be inspected |
| Detection Lab | analysis run + fixture inference | run form, output layer | deterministic fixture tests | detection spec | Fixture detection output is stored and shown |
| Segmentation Lab | analysis run boundary | planned UI state | contract tests | segmentation spec | V1 may show prepared state unless detection is stable |
| QA/QC Lab | IoU, precision, recall, F1 | metrics panel, error layers | golden QA tests | QA spec | Fixture predictions compare to reference |
| Export Center | GeoJSON/metrics export | download buttons | export tests | export spec | User downloads GeoJSON result |
| Build Status | changelog/status docs | optional UI link | smoke docs test | build status | Status remains truthful |
@@ -0,0 +1,79 @@
# API Response Rules
All API responses must be stable and implementation-friendly.
## Success Envelope
For single resources:
```json
{
"data": {},
"meta": {}
}
```
For lists:
```json
{
"data": [],
"meta": {
"count": 0,
"limit": 50,
"offset": 0
}
}
```
## Error Envelope
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Human readable message",
"details": {},
"trace_id": "optional"
}
}
```
## Required Resource Fields
Most persisted resources should include:
- `id`
- `created_at`
- `updated_at`
Geospatial resources should also include:
- `crs`
- `bounds`
- `geometry_type` where applicable
Analysis resources should include:
- `status`
- `parameters`
- `outputs`
- `metrics`
- `error_message` when failed
## Pagination
Use `limit` and `offset` for V1. Cursor pagination can be added later if needed.
## Sorting
Default sort: newest first for projects, datasets, analyses and exports.
## Contract Drift Rule
If implementation changes any response shape, update:
- `contracts/api/`
- API docs
- frontend API client types
- tests
@@ -0,0 +1,70 @@
# Frontend State Rules
GeoIntel frontend must be predictable, API-driven and resistant to partial build regressions.
## State Layers
Use three state categories:
1. Server state: projects, datasets, areas, analysis runs, metrics, exports.
2. UI state: selected tab, open panel, layer opacity, map camera.
3. Draft state: unsaved polygon, upload form, threshold slider before run.
Server state must be loaded through API client functions. Do not duplicate server truth in Zustand except as cached references managed by query tooling.
## Required Page States
Every data-driven page must render:
- initial loading
- empty state
- error state
- ready state
- processing state when jobs exist
## Map State
Map layer state must include:
- id
- name
- source
- visibility
- opacity
- style
- legend label
- feature count if known
## Analysis Run State
Analysis run UI must display:
- status
- started_at
- completed_at when available
- parameters
- model mode if AI-related
- output layers
- metrics
- errors if failed
## Form Validation
Client validation improves UX but must not replace backend validation.
## Navigation
The navigation should preserve the mental model:
- Projects
- Workspace
- Map
- Datasets
- Raster
- Vector
- Detection
- Segmentation
- QA/QC
- Exports
Do not hide core modules behind unrelated dashboard labels.
@@ -0,0 +1,87 @@
# Geospatial Calculation Rules
These rules define how GeoIntel must handle geospatial calculations.
## Coordinate Reference Systems
Default display CRS: EPSG:4326.
Default metric calculation CRS for Flanders/Kempen: EPSG:31370.
Every dataset must store:
- source CRS
- normalized/display CRS if converted
- metric calculation CRS used for area/distance outputs
## Geometry Validation
Before inserting vector features:
1. check geometry exists
2. check geometry type
3. check validity
4. check empty geometry
5. compute bounds
6. compute source feature count
Invalid geometries should be recorded in dataset metadata. Auto-fix may be attempted using buffer(0) or make_valid only if the metadata records this correction.
## Area Calculation
Area values must include units.
Preferred units:
- `m2` for feature-level area
- `ha` for summary land cover areas
- `km2` for large area summaries
Never calculate area from EPSG:4326 degrees.
## Distance Calculation
Distance values must include units.
Preferred units:
- `m` for local distances
- `km` for totals and densities
## Density Calculation
Densities must define denominator:
- buildings per km2
- road km per km2
- vegetation ha per km2
## IoU Calculation
For polygons A and B:
`IoU = area(intersection(A, B)) / area(union(A, B))`
Both geometries must be projected to metric CRS before area calculation.
## Matching Rule
Default object matching threshold for building QA/QC:
`IoU >= 0.5`
Alternative thresholds may be exposed in UI but must default to 0.5 for first V1 implementation.
## Precision, Recall and F1
- TP: predicted feature matched to one reference feature above threshold
- FP: predicted feature without reference match
- FN: reference feature without predicted match
`precision = TP / (TP + FP)`
`recall = TP / (TP + FN)`
`f1 = 2 * precision * recall / (precision + recall)`
If denominator is zero, return null and include explanatory reason.
@@ -0,0 +1,43 @@
# Codex Handoff Briefing
You are inheriting GeoIntel Kempen, a GeoAI Workbench for the Belgian Kempen.
## Read first
1. `README.md`
2. `AGENTS.md`
3. `docs/V1_SCOPE_FREEZE.md`
4. `docs/SERVICE_ARCHITECTURE.md`
5. `docs/REPOSITORY_CONVENTIONS.md`
6. `docs/15-tomorrow-execution/M8_TOMORROW_EXECUTION_PACK.md`
7. `docs/15-tomorrow-execution/DAY_1_EXECUTION_TIMELINE.md`
8. the current pass prompt under `prompts/codex/day-1/`
## Build philosophy
Build thin but real vertical slices. Do not hide missing functionality behind convincing UI. A small working API with tests is better than a beautiful mock.
## The first usable vertical slice
The first vertical slice is:
```text
Project -> Area -> Dataset registration -> Metadata -> Map/Workbench display -> Export-ready internal structure
```
Object detection, segmentation and QA/QC are important, but they must sit on a stable foundation.
## Common failure modes to avoid
- Creating frontend-only mock data that bypasses API state.
- Mixing geometry parsing into random route handlers.
- Adding AI dependencies before the data model is stable.
- Hardcoding local file paths.
- Ignoring CRS metadata.
- Creating database models that cannot handle future PostGIS geometries.
- Implementing upload without storage policy.
- Writing TODOs instead of completing the requested pass.
## Improvement freedom
You may add helper modules, stricter validation, better tests, and cleaner component structure. You may not change the product scope or stack.
@@ -0,0 +1,124 @@
# Day 1 Execution Timeline
This is a practical day plan for Codex. Times are indicative, not strict.
## Block 0 — Repository audit
Goal: understand the repo, identify existing docs, confirm no missing foundation files.
Deliverables:
- updated `docs/CODEX_EXECUTION_LOG.md`;
- short implementation plan;
- no product scope changes.
Do not implement features in this block.
## Block 1 — Backend foundation
Goal: create the minimal FastAPI application architecture.
Deliverables:
- app factory or main app;
- health endpoint;
- config module;
- logging setup;
- consistent response/error envelope;
- backend test harness.
Acceptance:
- backend imports cleanly;
- health test passes;
- no database dependency required for health endpoint.
## Block 2 — Database and domain
Goal: add SQLAlchemy/Alembic/PostGIS-ready domain foundation.
Deliverables:
- database config;
- migration folder;
- core models for projects, areas, datasets, analysis_runs, exports;
- geometry strategy documented in code comments where needed.
Acceptance:
- migrations run on local Postgres/PostGIS;
- tests can run with a safe test DB or mocked DB session layer;
- no raw geometry hacks in API layer.
## Block 3 — Project, Area and Dataset APIs
Goal: implement first real domain APIs.
Deliverables:
- create/list/read projects;
- create/list/read areas;
- dataset registration/upload scaffold;
- validation schemas;
- contract tests.
Acceptance:
- documented API contract examples match actual responses;
- invalid GeoJSON produces structured validation error;
- areas store geometry metadata.
## Block 4 — Frontend shell
Goal: create a navigable frontend shell matching the workbench model.
Deliverables:
- Vite/React/TypeScript app;
- route layout;
- left navigation;
- workspace pages;
- API client with typed methods;
- empty/loading/error states.
Acceptance:
- frontend runs;
- routes do not crash;
- API base URL is environment-driven;
- no random fake product flow.
## Block 5 — Raster/vector metadata
Goal: add the first geospatial processing services.
Deliverables:
- vector metadata parser for GeoJSON;
- raster metadata service scaffold using Rasterio when available;
- dataset metadata endpoint;
- fixture-driven tests.
Acceptance:
- fixtures return deterministic metadata;
- unsupported file type returns controlled error;
- processing outputs are stored according to storage spec.
## Block 6 — Vertical slice stabilization
Goal: make the foundation coherent.
Deliverables:
- smoke script;
- updated docs;
- TODO checked/updated;
- changelog entry;
- known limitations list.
Acceptance:
- one command or documented sequence verifies backend + frontend basics;
- no broken imports;
- no undocumented architectural shortcuts.
@@ -0,0 +1,84 @@
# M8 Tomorrow Execution Pack
This package exists so Codex can start tomorrow with minimal manual steering.
## Operating mode
Codex must work in controlled autonomous passes. Each pass must:
1. read the relevant docs before editing;
2. implement one coherent layer only;
3. run the documented validation commands;
4. write a concise completion report;
5. update TODO, CHANGELOG and CODEX_EXECUTION_LOG;
6. stop when a blocker requires product/architecture judgement.
## Non-negotiable product direction
GeoIntel Kempen is a **GeoAI Workbench**, not a generic dashboard and not a CRUD demo.
The V1 vertical slice must prove:
- geospatial project/area/dataset management;
- raster/vector metadata extraction;
- map-based spatial workflow;
- PostGIS-ready geometry handling;
- controlled AI detection pipeline scaffolding;
- QA/QC against reference geodata;
- geospatial export.
## Day-1 success condition
A successful first Codex day should end with a running foundation that can be started locally and demonstrates:
- backend health endpoint;
- database connection and migrations;
- project/area/dataset APIs;
- frontend shell with routes;
- map workspace placeholder wired to API state;
- deterministic fixtures and smoke checks;
- no uncontrolled mock-only business logic.
## Recommended execution order
1. `prompts/codex/day-1/00_START_HERE.md`
2. `prompts/codex/day-1/01_REPO_AUDIT_AND_PLAN.md`
3. `prompts/codex/day-1/02_BACKEND_FOUNDATION.md`
4. `prompts/codex/day-1/03_DATABASE_AND_DOMAIN.md`
5. `prompts/codex/day-1/04_PROJECT_AREA_DATASET_API.md`
6. `prompts/codex/day-1/05_FRONTEND_SHELL.md`
7. `prompts/codex/day-1/06_RASTER_VECTOR_METADATA.md`
8. `prompts/codex/day-1/07_VERTICAL_SLICE_STABILIZATION.md`
## What Codex may improve without asking
Codex may improve naming, folder hygiene, small helper abstractions, test coverage, typing, validation, error messages, and developer ergonomics if the changes preserve the documented contracts.
## What Codex may not change without explicit approval
Codex may not change:
- product positioning;
- selected stack;
- V1 scope boundaries;
- database aggregate names;
- API envelope conventions;
- storage layout;
- QA/QC metric definitions;
- GRB as primary reference strategy;
- incremental build discipline.
## Required end-of-pass response format
Every pass must end with:
```text
PASS COMPLETED: <name>
CHANGED FILES:
- ...
VALIDATION RUN:
- command: result
OPEN ISSUES:
- ... or none
NEXT RECOMMENDED PASS:
- ...
```
@@ -0,0 +1,31 @@
# Next Pass After Day 1
If Day 1 succeeds, the next priority is not broad feature expansion. The next priority is the first true GeoAI/GIS capability.
## Preferred Day 2 sequence
1. GRB/reference adapter scaffold.
2. Raster tiling interface.
3. Detection model registry scaffold.
4. Deterministic detection fixture adapter.
5. Detection output as GeoJSON.
6. QA/QC overlap metrics against reference fixture.
7. Map overlay display.
## Why this sequence
It creates the first portfolio-relevant technical loop:
```text
Raster/Dataset -> Detection -> Geospatial output -> Reference comparison -> QA metrics -> Export
```
## Do not jump directly to
- full SAM integration;
- real Sentinel downloads;
- LiDAR processing;
- training studio;
- complex report generation.
Those need the Day 1 foundation and Day 2 detection/QA loop first.
@@ -0,0 +1,45 @@
# Autonomy Boundaries for Codex
Codex should be proactive, but not uncontrolled.
## Green zone — Codex can decide
- function and class names when consistent with docs;
- internal helper extraction;
- validation improvements;
- error message clarity;
- test fixture additions;
- component decomposition;
- minor styling improvements;
- logging improvements;
- dependency pinning within the approved stack.
## Yellow zone — Codex can decide but must document
- replacing a library with an equivalent only if dependency installation fails and the replacement stays within the stack intent;
- changing endpoint internals while preserving contracts;
- adding new tables that support existing aggregates;
- adding background job scaffolding earlier than planned;
- improving storage folder structure while preserving published paths.
Must be documented in:
- `docs/CODEX_EXECUTION_LOG.md`;
- `CHANGELOG.md`;
- relevant ADR/RFC if architectural.
## Red zone — Codex must stop and ask
- changing FastAPI/React/PostGIS stack;
- removing GRB-centered QA/QC direction;
- turning the product into a generic GIS dashboard;
- removing AI pipeline readiness;
- changing V1 scope boundaries;
- adding authentication/multi-user as core V1;
- adding paid/cloud-only dependencies as mandatory;
- implementing real external downloads without source strategy and license notes;
- changing output formats away from GeoJSON/COCO/YOLO/masks without approval.
## Safe fallback principle
When a dependency, data source or model cannot be used yet, implement a controlled adapter interface and deterministic fixture-backed behavior. Mark it as a scaffold, not as production-complete.
@@ -0,0 +1,51 @@
# Failure Recovery Playbook
Codex must not spiral when a build fails. Use this playbook.
## Backend import failure
1. Run the smallest import command available.
2. Fix circular imports first.
3. Verify package `__init__.py` files.
4. Ensure config does not require unavailable services at import time.
5. Add or update a smoke test.
## Database failure
1. Check environment variables.
2. Check whether PostGIS extension is required at migration time.
3. Separate pure unit tests from DB integration tests.
4. Do not remove geometry capability to make tests pass.
5. Document required local Postgres/PostGIS command.
## Frontend build failure
1. Run TypeScript check.
2. Fix missing exports/imports.
3. Do not silence errors with `any` unless documented and temporary.
4. Ensure API types match contract fixtures.
5. Add an empty/error state rather than fake success.
## Rasterio/GDAL dependency failure
1. Keep service interface intact.
2. Add graceful unavailable-state handling.
3. Keep GeoJSON/vector paths working.
4. Document local dependency requirement.
5. Do not fake raster metadata as real metadata.
## YOLO/SAM unavailable
1. Keep model registry and detection service interface.
2. Implement deterministic fixture inference adapter.
3. Mark adapter as demo/scaffold.
4. Preserve output shape expected by QA/QC.
5. Do not block foundation work.
## External data source unavailable
1. Fall back to fixtures.
2. Preserve source adapter contract.
3. Add retry/error state.
4. Do not hardcode one live response.
5. Document the failure in execution log.
@@ -0,0 +1,43 @@
# Improvement Policy
GeoIntel should be strict enough for autonomous execution but flexible enough for good engineering.
## Desired improvements
Codex is encouraged to improve:
- typed API clients;
- service boundaries;
- validation specificity;
- reusable geospatial utilities;
- test determinism;
- frontend state handling;
- developer commands;
- logging and diagnostics;
- small UX clarity improvements.
## Undesired improvements
Do not add:
- unrelated dashboards;
- user accounts before V1;
- payment/billing;
- social features;
- generic file manager replacing dataset manager;
- raw LLM chatbot as a central feature;
- unsupported live data scraping;
- excessive styling frameworks beyond the chosen frontend stack.
## Improvement report format
When making improvements beyond the exact prompt, add:
```text
IMPROVEMENT:
- what changed
- why it helps GeoIntel
- why it does not change scope
```
inside `docs/CODEX_EXECUTION_LOG.md`.
@@ -0,0 +1,24 @@
# Quality Gate Matrix
Every implementation pass must satisfy the relevant gates.
| Gate | Backend | Frontend | Data/GIS | AI | Required before merge |
|---|---|---|---|---|---|
| Import/build | app imports | TS builds | processing modules import | model adapters import | yes |
| Contract | response envelope | API client typed | metadata shape stable | detection output shape stable | yes |
| Validation | request schemas | form errors | CRS/file errors | threshold/model errors | yes |
| Tests | unit/contract | component where feasible | fixture processing | adapter test | yes for touched area |
| Docs | route/service docs | UI states docs | source/operation docs | model notes | yes |
| No fake success | errors visible | empty states real | unsupported explicit | unavailable explicit | yes |
## Minimum gates for Day 1
- Backend health passes.
- Project/area/dataset contracts pass.
- Frontend shell builds.
- Fixture metadata tests pass.
- Smoke script documents exact failures if any remain.
## Gate failure response
If a gate fails, Codex must either fix it or mark the pass incomplete. Do not claim completion when validation was skipped.
@@ -0,0 +1,91 @@
# M9 API Validation Examples
All errors must use the documented API envelope.
## Invalid Project Name
Request:
```json
{ "name": "" }
```
Response:
```json
{
"success": false,
"data": null,
"error": {
"code": "validation_error",
"message": "Project name is required.",
"details": { "field": "name" }
},
"meta": {}
}
```
## Invalid GeoJSON Polygon
```json
{
"success": false,
"data": null,
"error": {
"code": "invalid_geometry",
"message": "Area geometry must be a valid Polygon or MultiPolygon in EPSG:4326.",
"details": {
"reason": "self_intersection"
}
},
"meta": {}
}
```
## Unsupported Dataset Type
```json
{
"success": false,
"data": null,
"error": {
"code": "unsupported_dataset_type",
"message": "This file type is not supported in V1.",
"details": {
"allowed_extensions": [".geojson", ".json", ".tif", ".tiff", ".gpkg"]
}
},
"meta": {}
}
```
## External Source Unavailable
```json
{
"success": false,
"data": null,
"error": {
"code": "external_service_unavailable",
"message": "The GRB service is unavailable. Use cached data or retry later.",
"details": { "source": "GRB" }
},
"meta": {}
}
```
## Job Failed
```json
{
"success": true,
"data": {
"job_id": "uuid",
"status": "failed",
"error_code": "model_not_available",
"error_message": "No compatible detection model is configured."
},
"error": null,
"meta": {}
}
```
@@ -0,0 +1,89 @@
# M9 Autonomous Build Doctrine
## Purpose
This document defines how Codex should behave when building GeoIntel with minimal human intervention.
## Build Philosophy
GeoIntel must grow like a professional engineering system:
1. Contracts first.
2. Backend services second.
3. Frontend integration third.
4. AI pipelines only after stable data flow.
5. QA/QC after outputs exist.
6. Polish only after functionality is testable.
## Strictness Levels
### Frozen
Codex must not change these:
- FastAPI backend.
- React TypeScript frontend.
- PostgreSQL/PostGIS database.
- Docker Compose local stack.
- Project/Area/Dataset/Analysis domain model.
- API response envelope.
- Storage root conventions.
- V1 scope.
### Guided
Codex may choose implementation details within these:
- exact Python package split,
- React component granularity,
- internal helper names,
- validation library patterns,
- test fixture organization,
- queue abstraction internals.
### Open Improvement Area
Codex may improve freely if documented:
- UI microcopy,
- accessibility,
- loading states,
- logging clarity,
- test coverage,
- developer command quality,
- type safety.
## Self-Driving Loop
Every build pass must follow this loop:
1. Read relevant specs.
2. Identify scope for the pass.
3. Implement the smallest complete vertical slice.
4. Run tests/lint/type checks where available.
5. Update execution log.
6. Update build status.
7. List next pass.
## Anti-Patterns
Do not:
- create huge untested code dumps,
- implement UI without API contracts,
- invent fake geospatial values,
- build YOLO UI before dataset IO works,
- create multiple competing state stores,
- store geospatial data as plain strings when PostGIS geometry is required,
- ignore CRS handling,
- call external services without adapter boundaries.
## Autonomy Boundary
Codex can keep working independently as long as:
- tests are passing or failures are honestly documented,
- no frozen decision is changed,
- V1 scope is preserved,
- every new file belongs to an approved module,
- build logs are updated.
@@ -0,0 +1,101 @@
# M9 Build Blockers and Recovery
## Database connection failure
Symptoms:
- backend cannot connect to PostgreSQL,
- migrations fail,
- PostGIS extension missing.
Recovery:
1. Check Docker Compose service names.
2. Check environment variables.
3. Confirm database is reachable from backend container or local process.
4. Run a minimal connection test.
5. Do not replace PostGIS with SQLite except for explicitly isolated unit tests.
## PostGIS geometry error
Symptoms:
- invalid geometry,
- SRID missing,
- geometry column cannot be created.
Recovery:
1. Store all app geometry in EPSG:4326 unless a processing-specific CRS is required.
2. Validate GeoJSON before persistence.
3. Use Shapely for geometry validation.
4. Use PostGIS geometry column for persistent area/reference features.
5. Document any CRS transformation.
## Frontend API mismatch
Symptoms:
- UI expects raw data but API returns envelope,
- errors not shown,
- undefined data states.
Recovery:
1. Update frontend API client, not individual components.
2. Normalize envelope handling centrally.
3. Ensure every component handles loading, empty, error and ready states.
## Dependency installation failure
Symptoms:
- GDAL/Rasterio install errors,
- PyTorch package issue,
- platform binary mismatch.
Recovery:
1. Do not remove the feature from docs.
2. Add dependency note to `docs/DEPENDENCY_LOCK_PLAN.md`.
3. Implement interfaces and tests around pure-Python parts first.
4. Defer heavy binary package execution if needed, but leave adapter boundaries.
## External data unavailable
Symptoms:
- WFS unavailable,
- Sentinel catalog unavailable,
- credentials missing.
Recovery:
1. Use demo fixtures.
2. Keep adapter disabled but present.
3. Return explicit `external_service_unavailable` status.
4. Do not fake that live data was fetched.
## AI model unavailable
Symptoms:
- YOLO weights missing,
- SAM unavailable,
- GPU unavailable.
Recovery:
1. Build model registry and adapter interface.
2. Add CPU-safe mock inference only if marked as demo mode.
3. Keep output schema identical to real inference.
4. Do not present demo inference as production inference.
## Test failures
Recovery:
1. Fix tests if implementation is wrong.
2. Fix implementation if test reflects contract.
3. Update specs only if they are clearly inconsistent.
4. Document unresolved failures in execution log.
@@ -0,0 +1,110 @@
# M9 Detailed Data Contracts
## Project
```json
{
"id": "uuid",
"name": "Geel Building Detection Demo",
"description": "Building detection and QA against reference features.",
"region": "Kempen",
"created_at": "2026-06-11T12:00:00Z",
"updated_at": "2026-06-11T12:00:00Z"
}
```
Validation:
- name is required,
- region defaults to Kempen,
- description optional.
## Area
```json
{
"id": "uuid",
"project_id": "uuid",
"name": "Geel center test area",
"geometry": { "type": "Polygon", "coordinates": [] },
"crs": "EPSG:4326",
"area_m2": 12345.67,
"bounds": [4.98, 51.15, 5.02, 51.18]
}
```
Validation:
- geometry must be Polygon or MultiPolygon,
- geometry must be valid,
- geometry must not be empty,
- area_m2 must be computed server-side,
- CRS is EPSG:4326 for API IO unless explicitly documented.
## Dataset
```json
{
"id": "uuid",
"project_id": "uuid",
"name": "reference_buildings.geojson",
"dataset_type": "vector",
"source_mode": "demo",
"source_name": "fixture",
"storage_path": "storage/projects/.../raw/reference_buildings.geojson",
"status": "uploaded|processing|ready|failed",
"crs": "EPSG:4326",
"bounds": [4.98, 51.15, 5.02, 51.18],
"feature_count": 100,
"metadata": {}
}
```
## Analysis Run
```json
{
"id": "uuid",
"project_id": "uuid",
"area_id": "uuid",
"analysis_type": "object_detection|segmentation|qaqc|raster_metadata|vector_metadata",
"status": "queued|running|completed|failed|cancelled",
"parameters": {},
"started_at": null,
"finished_at": null,
"error": null
}
```
## Detection Feature
```json
{
"id": "uuid",
"analysis_run_id": "uuid",
"class_name": "building",
"confidence": 0.91,
"geometry": { "type": "Polygon", "coordinates": [] },
"bbox": [4.99, 51.16, 4.991, 51.161],
"source_tile": "tile_001.tif",
"metadata": {}
}
```
## QA/QC Result
```json
{
"analysis_run_id": "uuid",
"reference_dataset_id": "uuid",
"predicted_dataset_id": "uuid",
"match_threshold_iou": 0.5,
"precision": 0.94,
"recall": 0.91,
"f1": 0.925,
"true_positives": 94,
"false_positives": 6,
"false_negatives": 9,
"findings": []
}
```
@@ -0,0 +1,46 @@
# M9 Final Pre-Code Checklist
Before starting a long Codex build session, verify:
## Repository
- [ ] Full zip extracted cleanly.
- [ ] Git initialized.
- [ ] Initial commit made before Codex changes.
- [ ] `.env.example` exists.
- [ ] Docker Compose file exists.
- [ ] README explains the project.
## Codex Input
- [ ] Master prompt available.
- [ ] Build order available.
- [ ] Definition of Done available.
- [ ] Scorecards available.
- [ ] Failure recovery available.
## Scope
- [ ] V1 scope freeze read.
- [ ] No LiDAR in first pass.
- [ ] No training studio in first pass.
- [ ] No QGIS plugin in first pass.
- [ ] No advanced Sentinel implementation in first pass.
## Expected First Output
- [ ] Pass 0 audit.
- [ ] Execution log.
- [ ] Build status.
- [ ] Gap report.
## Local Environment
- [ ] Docker available.
- [ ] Node available.
- [ ] Python available.
- [ ] PostgreSQL/PostGIS preferably via Docker.
## Human Intervention Rules
Only intervene if Codex asks to change a frozen decision or cannot proceed due to environment failure.
@@ -0,0 +1,54 @@
# M9 Gap-to-Task Conversion Rules
When Codex finds a gap, it must convert it into an actionable task instead of leaving vague notes.
## Task Format
```md
### TASK-ID: Short title
Type: backend | frontend | docs | test | devops | data | ai
Priority: P0 | P1 | P2 | P3
Status: open | in_progress | done | blocked
Owner: Codex
Context:
...
Required changes:
- ...
Acceptance criteria:
- [ ] ...
Validation commands:
- ...
Blocked by:
- none or exact blocker
```
## Priority Rules
### P0
Blocks app startup, database, API envelope, project/area/dataset foundation.
### P1
Blocks V1 core workflow but not app startup.
### P2
Improves quality, tests, UX, docs.
### P3
Nice-to-have or future extension.
## Gap Handling
- If gap is architecture-related: update docs before code.
- If gap is implementation-related: create ticket and implement if in current pass.
- If gap is dependency-related: document in dependency plan and add fallback interface.
- If gap is scope expansion: move to proposed improvements.
@@ -0,0 +1,90 @@
# M9 Geospatial Edge Cases
Codex must account for these cases early to avoid later rewrites.
## Invalid polygon
Examples:
- self-intersection,
- unclosed ring,
- empty coordinates,
- wrong coordinate nesting.
Required behavior:
- reject with validation error,
- return specific message,
- do not persist.
## MultiPolygon
Required behavior:
- accept for areas and vector features,
- compute total area across all parts,
- display as a single layer.
## CRS mismatch
Scenario:
- reference data is EPSG:31370,
- API uses EPSG:4326,
- raster processing may use native CRS.
Required behavior:
- store original CRS in dataset metadata,
- transform API geometries to EPSG:4326 for frontend,
- use projected CRS for area/length calculations when needed,
- document transformations.
## Very large file
Required behavior:
- reject files above configured limit with clear error,
- do not load huge files into memory at once,
- expose future chunking/tile strategy.
## Raster without georeference
Required behavior:
- accept only as non-georeferenced image if supported,
- mark geospatial operations unavailable,
- do not pretend map alignment exists.
## Feature outside selected area
Required behavior:
- clip if operation requested,
- otherwise keep original and display warning if used for area analysis.
## Geometry collection
Required behavior:
- reject for V1 unless explicitly converted,
- explain supported geometry types.
## Zero-area feature
Required behavior:
- keep for line/point layers,
- reject or ignore for polygon-area metrics,
- record warning in analysis result.
## Duplicate features
Required behavior:
- do not automatically delete without audit trail,
- expose duplicate count in data quality metadata.
## Antimeridian/global edge cases
Not relevant for Kempen V1. Document as out of scope.
@@ -0,0 +1,59 @@
# M9 Implementation Review Script
Use this manual review script after Codex produces a build.
## 1. Repository Hygiene
- [ ] No random root-level files.
- [ ] No duplicate docs with conflicting instructions.
- [ ] No generated caches committed.
- [ ] No secrets committed.
- [ ] `.env.example` updated if env vars changed.
## 2. Backend
- [ ] App starts.
- [ ] Health endpoint returns envelope or documented health format.
- [ ] API routes grouped logically.
- [ ] Validation errors are structured.
- [ ] Database models match schema docs.
- [ ] Geometry fields are not plain unvalidated strings.
- [ ] Tests exist for implemented endpoints.
## 3. Frontend
- [ ] App starts.
- [ ] No blank route screens.
- [ ] API client centralizes envelope parsing.
- [ ] Loading, empty, error states present.
- [ ] Demo workflow visible.
- [ ] Map shell does not depend on unavailable live data.
## 4. Geospatial Logic
- [ ] CRS metadata preserved.
- [ ] Area calculations are server-side.
- [ ] Invalid geometries rejected.
- [ ] Demo fixtures load correctly.
- [ ] No fake geospatial metrics presented as real.
## 5. Documentation
- [ ] Changelog updated.
- [ ] Build status updated.
- [ ] Execution log updated.
- [ ] Known limitations updated if needed.
## 6. Commands
Run what is available:
```bash
python -m pytest
npm test
npm run build
npm run lint
docker compose config
```
If commands are not available yet, Codex must document why.
@@ -0,0 +1,27 @@
# M9 Long-Form Codex Prompt Variants
Use these prompts when Codex needs a more specific instruction after the master prompt.
## Prompt: Backend Foundation Only
Build only the backend foundation for GeoIntel. Do not work on frontend or AI. Implement FastAPI app startup, settings, health endpoint, response envelope, structured error handling, and basic tests. Follow `docs/API_CONTRACTS.md`, `docs/ERROR_HANDLING_AND_STATUSES.md`, and `docs/17-max-prep/M9_PASS_SCORECARDS.md`. Update execution log, build status and changelog.
## Prompt: Database Foundation Only
Implement database foundation only. Configure PostgreSQL/PostGIS using the documented Docker Compose environment. Add ORM models and migrations for projects, areas, datasets and analysis_runs. Geometry must use PostGIS-compatible fields. Do not implement AI or advanced datasets. Add tests where possible and update docs.
## Prompt: Dataset Manager Only
Implement the V1 Dataset Manager skeleton. Support upload metadata, storage path conventions, dataset status lifecycle and list/read endpoints. Use demo fixtures for tests. Do not fetch live GRB or Sentinel yet. Ensure source_mode is present. Update execution log and build status.
## Prompt: Frontend Shell Only
Implement the frontend shell with React TypeScript. Add routing, layout, project list, workspace shell, dataset manager shell and map workbench placeholder with correct states. Use API client envelope parsing. Do not hardcode fake analysis results.
## Prompt: QA/QC Skeleton Only
Implement pure geometry QA utilities and tests: IoU, precision, recall, F1 using fixture polygons. Add a backend service interface and endpoint skeleton if foundation exists. Do not require YOLO outputs yet; use fixture reference/predicted layers.
## Prompt: Stabilization Pass
Do not add features. Run all available tests/builds/lints. Fix failures. Update docs, changelog, known limitations and execution log. Remove dead code and root-folder clutter. Ensure app startup paths are documented.
@@ -0,0 +1,83 @@
# M9 Max Preparation Pack
Status: specification expansion after M8.
Purpose: make GeoIntel as close as possible to a self-driving Codex project while still allowing Codex to make local implementation improvements.
## Goal
GeoIntel must be prepared so that Codex can:
1. read the repository,
2. understand the product and constraints,
3. build the foundation,
4. validate itself,
5. recover from common failures,
6. report honestly what was completed,
7. avoid architectural drift.
## Principle
Strict on architecture. Flexible on implementation details.
Codex may improve:
- component structure inside the approved route/component map,
- service internals if IO contracts remain stable,
- validation messages if API envelope remains stable,
- tests if they increase coverage,
- UI polish if it does not change the workflow.
Codex may not change without explicit approval:
- backend framework,
- frontend framework,
- database choice,
- PostGIS requirement,
- core entity names,
- API response envelope,
- dataset storage layout,
- project positioning as a GeoAI Workbench,
- V1 scope freeze.
## M9 Additions
This pack adds:
- final autonomous build doctrine,
- exact day-one Codex master prompt,
- build pass scorecards,
- gap-to-task conversion rules,
- real-versus-demo data policy,
- geospatial edge case handling,
- failure mode catalog,
- module data contracts,
- UI empty/loading/error states,
- API validation examples,
- seed fixtures policy,
- regression map,
- implementation review scripts,
- handoff checklist.
## Expected Use Tomorrow
1. Extract the full zip.
2. Open the repository in Codex.
3. Paste `prompts/codex/M9_DAY_ONE_MASTER_PROMPT.md`.
4. Let Codex run Pass 0 first.
5. Require Codex to update `docs/CODEX_EXECUTION_LOG.md` after each pass.
6. Do not allow feature expansion until Pass 1-4 are green.
## Success Definition
The preparation is successful if Codex can start from an empty implementation and produce:
- a working FastAPI app,
- a working React app,
- Docker Compose services,
- PostGIS models/migrations,
- project/area/dataset APIs,
- demo fixture loading,
- initial map UI shell,
- validation and health checks,
- tests for the implemented pieces,
- a changelog and execution log.
@@ -0,0 +1,133 @@
# M9 Module Dataflow Checklist
Every module must declare its dataflow.
## Dataset Manager
Input:
- file upload,
- project id,
- optional area id.
Processing:
- validate extension,
- store raw file,
- inspect metadata,
- persist dataset record,
- schedule optional processing job.
Output:
- dataset record,
- status,
- metadata.
## Raster Lab
Input:
- raster dataset id,
- optional area geometry.
Processing:
- read raster metadata,
- compute bounds,
- inspect bands,
- clip if requested,
- generate preview/tiles later.
Output:
- metadata,
- preview descriptor,
- derived dataset if clipped.
## Vector Lab
Input:
- vector dataset id,
- optional area geometry.
Processing:
- load features,
- validate CRS,
- compute feature count,
- compute bounds,
- clip if requested.
Output:
- vector metadata,
- clipped layer,
- operation report.
## Detection Lab
Input:
- raster dataset id,
- model id,
- threshold,
- classes.
Processing:
- tile raster,
- run model adapter,
- merge detections,
- georeference outputs,
- persist detection layer.
Output:
- detection dataset/layer,
- analysis run,
- metrics.
## Segmentation Lab
Input:
- raster dataset id,
- model id,
- classes/prompts.
Processing:
- generate masks,
- polygonize,
- clean geometry,
- compute areas,
- persist layer.
Output:
- mask path,
- polygon layer,
- metrics.
## QA/QC Lab
Input:
- reference vector layer,
- predicted vector layer,
- matching threshold.
Processing:
- spatial match,
- IoU calculation,
- precision/recall/F1,
- false positive/negative features.
Output:
- QA metrics,
- findings,
- QA overlay layers.
+91
View File
@@ -0,0 +1,91 @@
# M9 Build Pass Scorecards
Use these scorecards after every Codex pass. A pass is not considered complete until its scorecard is mostly green.
## Pass 0 — Audit
- [ ] Repository tree inspected.
- [ ] Existing docs summarized.
- [ ] Missing implementation listed.
- [ ] Build blockers listed.
- [ ] Next pass selected.
- [ ] No feature code added.
## Pass 1 — Backend Foundation
- [ ] FastAPI app starts.
- [ ] Health endpoint exists.
- [ ] Settings load from environment.
- [ ] CORS configured for local frontend.
- [ ] API envelope helper exists.
- [ ] Error handler exists.
- [ ] Backend tests run.
## Pass 2 — Database Foundation
- [ ] SQLAlchemy or approved ORM configured.
- [ ] Alembic migrations initialized.
- [ ] PostGIS extension migration exists.
- [ ] Project model exists.
- [ ] Area model exists with geometry.
- [ ] Dataset model exists.
- [ ] Local database connection documented.
## Pass 3 — Project/Area APIs
- [ ] Create/list/read project.
- [ ] Create/list/read area.
- [ ] GeoJSON polygon validation.
- [ ] Area size calculation.
- [ ] Envelope responses.
- [ ] Error responses for invalid geometry.
- [ ] Tests for happy and failure paths.
## Pass 4 — Dataset Manager Skeleton
- [ ] Dataset upload endpoint.
- [ ] File stored under documented storage root.
- [ ] Metadata extraction placeholder with real file inspection when possible.
- [ ] Dataset list/read APIs.
- [ ] Status lifecycle present.
- [ ] Tests with fixtures.
## Pass 5 — Frontend Foundation
- [ ] React app starts.
- [ ] Route shell exists.
- [ ] API client uses envelope.
- [ ] Error/loading/empty states exist.
- [ ] Project list page exists.
- [ ] Workspace shell exists.
## Pass 6 — Map Workbench Shell
- [ ] MapLibre or approved map abstraction installed.
- [ ] Area polygon can be displayed.
- [ ] Demo GeoJSON can be loaded.
- [ ] Layer panel shell exists.
- [ ] No hardcoded fake analysis results.
## Pass 7 — Raster/Vector Core Skeleton
- [ ] Raster metadata endpoint skeleton.
- [ ] Vector metadata endpoint skeleton.
- [ ] CRS field exposed.
- [ ] Bounds field exposed.
- [ ] UI metadata panels exist.
## Pass 8 — QA/QC Skeleton
- [ ] QA service interface exists.
- [ ] IoU function unit-tested with fixtures.
- [ ] Precision/recall formulas implemented.
- [ ] QA endpoint accepts reference and predicted layer IDs or fixture IDs.
- [ ] QA result card exists.
## Pass 9 — Stabilization
- [ ] All smoke commands documented.
- [ ] Changelog updated.
- [ ] Known limitations updated.
- [ ] Next advanced module recommendation written.
@@ -0,0 +1,59 @@
# Real vs Demo Data Policy
GeoIntel may use demo fixtures during early development, but the UI and backend must clearly distinguish demo data from live data.
## Data Categories
### Real Data
Data fetched from or uploaded by a real source:
- GRB WFS/cache,
- user-uploaded GeoTIFF,
- user-uploaded GeoJSON/Shapefile/GPKG,
- Sentinel scene,
- DHMV product.
### Demo Fixture Data
Small repository-contained examples used for development and tests:
- `demo/geel/reference_buildings.geojson`,
- `demo/geel/demo_detections.geojson`,
- `fixtures/geojson/*`.
### Synthetic Test Data
Minimal generated data used only in unit tests.
## Rules
- Demo data may be used to build UI states and verify pipelines.
- Demo data must be labeled as demo in API responses.
- Real-data adapters must not silently fall back to demo data.
- A failed external fetch must return an error/status, not demo data.
- Synthetic data must not appear in production UI unless under a test/demo route.
## Dataset Metadata Field
Every dataset must include:
```json
{
"source_mode": "real|demo|synthetic",
"source_name": "GRB|OSM|user_upload|fixture|generated_test",
"license": "string or unknown",
"retrieved_at": "ISO date or null"
}
```
## UI Requirement
The dataset table must display a source badge:
- Real
- Demo
- Synthetic
- Unknown
Synthetic should never be shown in normal user workflows.
+81
View File
@@ -0,0 +1,81 @@
# M9 Regression Map
These are the most likely regressions during autonomous builds.
## API Envelope Drift
Risk: some endpoints return raw data while others return envelopes.
Prevention:
- central response helper,
- API client tests,
- sample responses.
## Geometry Stored Incorrectly
Risk: GeoJSON stored as text everywhere.
Prevention:
- PostGIS geometry columns,
- schema tests,
- validation utilities.
## Demo Data Masquerades as Real Data
Risk: UI shows fixture metrics without labeling them.
Prevention:
- source_mode field,
- demo badge,
- no fallback-to-fixture for external failures.
## Frontend State Duplication
Risk: every component fetches differently.
Prevention:
- central API client,
- shared hooks,
- state contracts.
## Heavy AI Implemented Too Early
Risk: Codex spends time on YOLO/SAM before storage and datasets work.
Prevention:
- pass scorecards,
- V1 ordering,
- disabled state for model features.
## CRS Ignored
Risk: area/length values wrong.
Prevention:
- CRS field mandatory,
- projected calculations documented,
- geospatial edge cases.
## Docs Not Updated
Risk: implementation diverges from specs.
Prevention:
- Definition of Done includes docs,
- execution log mandatory.
## Root Folder Pollution
Risk: scripts and generated outputs appear at root.
Prevention:
- repository conventions,
- review script.
+108
View File
@@ -0,0 +1,108 @@
# M9 UI State Specification
Every page and major component must implement these states.
## Required States
### Initial
No user action yet.
Example copy:
> Start by creating a project or opening the Geel demo.
### Loading
Data is being fetched or processed.
Requirements:
- spinner or skeleton,
- clear label,
- no layout jump where avoidable.
### Empty
Request succeeded but no records exist.
Example:
> No datasets have been added to this project yet.
### Ready
Data exists and actions are available.
### Error
Request failed or validation failed.
Requirements:
- readable error,
- retry action where safe,
- technical details hidden behind details/expand if useful.
### Disabled/Future
Feature is planned but not implemented in V1.
Requirements:
- show disabled state,
- explain why,
- do not show fake results.
## Page Requirements
### Home
- Initial: explain GeoIntel.
- Empty: no recent projects.
- Ready: project cards and demo card.
### Project Workspace
- Loading project.
- Missing project error.
- Empty datasets/areas states.
- Ready dashboard.
### Dataset Manager
- Empty upload area.
- Upload progress.
- Upload failed.
- Processing.
- Ready metadata.
### Map Workbench
- No area selected.
- Area loaded.
- Layer loading.
- Layer error.
- Unsupported layer type.
### Detection Lab
- No raster selected.
- No model configured.
- Running job.
- Completed detections.
- Failed inference.
### QA/QC Lab
- Missing reference dataset.
- Missing predicted dataset.
- Running comparison.
- Metrics ready.
- No matches found.
## Do Not
- Do not leave blank panels.
- Do not show random demo metrics in ready state.
- Do not hide errors in console only.
@@ -0,0 +1,41 @@
# Autonomous Build Charter
## Mission
Codex must build GeoIntel Kempen as a production-shaped GeoAI Workbench, not as a demo-only UI. Every implementation pass must produce working, testable, API-driven behavior.
## Frozen Product Identity
GeoIntel is a GeoAI Workbench for the Kempen focused on raster/vector processing, AI detection, segmentation, QA/QC against reference data, and geospatial exports.
## Allowed Autonomy
Codex may improve:
- internal code organization when it keeps documented contracts intact;
- UI microcopy and layout when it improves clarity;
- validation and error messages;
- tests, fixtures, logging, and developer tooling;
- performance optimizations that do not alter outputs;
- accessibility and keyboard navigation;
- extra helper utilities that support documented workflows.
## Not Allowed Without Explicit User Approval
Codex must not:
- replace FastAPI, React, TypeScript, PostgreSQL/PostGIS, or Python GIS stack;
- introduce a different product direction such as a generic chatbot or CRUD dashboard;
- remove GRB/QA/QC as a first-class concept;
- make LiDAR, training studio, or MLOps part of V1 core;
- hardcode fake results while presenting them as real processing;
- break existing documented API contracts;
- silently change geometry formats or CRS assumptions;
- ignore tests because a dependency is missing.
## Output Expectations Per Pass
Every Codex pass must end with:
1. changed files list;
2. completed tasks;
3. skipped tasks with reason;
4. commands run;
5. test results;
6. known limitations;
7. next recommended pass.
## Quality Principle
If a feature cannot be fully implemented in the pass, Codex must implement the durable skeleton plus honest status handling, not a fake success path.
+66
View File
@@ -0,0 +1,66 @@
# Build Pass Template
Use this exact structure for every Codex build pass.
## Pass Name
Example: `Pass 03 — Dataset Manager Backend`
## Goal
One sentence describing the feature outcome.
## Inputs
- Required docs:
- Required contracts:
- Required fixtures:
- Previous pass dependencies:
## Scope
### Must implement
- [ ] Item
### May improve
- [ ] Item
### Must not touch
- [ ] Item
## Implementation Steps
1. Inspect existing repo state.
2. Confirm relevant contracts.
3. Implement backend/domain changes.
4. Implement frontend/API client changes if applicable.
5. Add or update tests.
6. Add fixtures if needed.
7. Update docs and TODO status.
8. Run validation commands.
9. Produce pass summary.
## Validation Commands
```bash
# backend
pytest
ruff check backend || true
# frontend
npm run build
npm run typecheck || true
npm run lint || true
```
## Acceptance Criteria
- [ ] Feature works through API or UI.
- [ ] Errors are explicit and typed.
- [ ] No mock success path is presented as real.
- [ ] Tests or fixtures cover the happy path and at least one failure path.
- [ ] Documentation is updated.
## Handoff Format
```md
# Pass Summary
## Completed
## Changed Files
## Commands Run
## Test Results
## Known Issues
## Next Step
```
+24
View File
@@ -0,0 +1,24 @@
# Codex Start Here
Read these files first, in this exact order:
1. `README.md`
2. `AGENTS.md`
3. `docs/18-ultra-prep/AUTONOMOUS_BUILD_CHARTER.md`
4. `docs/V1_SCOPE_FREEZE.md`
5. `docs/SERVICE_ARCHITECTURE.md`
6. `docs/REPOSITORY_CONVENTIONS.md`
7. `docs/API_CONTRACTS.md`
8. `docs/DATABASE_IMPLEMENTATION_PLAN.md`
9. `docs/18-ultra-prep/CRITICAL_PATH_TO_V1.md`
10. `docs/18-ultra-prep/BUILD_PASS_TEMPLATE.md`
Then execute the first incomplete pass from:
- `prompts/codex/M10_PASS_SEQUENCE.md`
Rules:
- Do not skip ahead.
- Do not start UI polish before backend contracts exist.
- Do not fake geospatial processing; return honest pending/unavailable states.
- Update TODO/checklists after every pass.
@@ -0,0 +1,27 @@
# Connector Implementation Guide
## Connector Interface
Every external data connector should expose:
- `name`
- `capabilities`
- `is_configured()`
- `health_check()`
- `fetch_by_area(area_geometry, parameters)`
- `normalize(raw_result)`
- `cache_key(area, parameters)`
## Required Connectors
### GRB Connector
V1 target: fetch or register reference building polygons. If live WFS cannot be implemented immediately, build the interface and support fixture/local import honestly.
### OSM Connector
V1 target: fetch buildings/roads/water/green where possible using Overpass or local fixture fallback.
### Sentinel Connector
V2 target. In V1 it should remain disabled with clear roadmap state.
## Connector Failure Behavior
- timeout -> `CONNECTOR_TIMEOUT`
- missing config -> `CONNECTOR_UNCONFIGURED`
- invalid response -> `CONNECTOR_INVALID_RESPONSE`
- no data -> valid empty result, not error
+35
View File
@@ -0,0 +1,35 @@
# Critical Path to V1
This is the shortest reliable path to a portfolio-ready V1.
## V1 Critical Path
1. Repo foundation and dev environment.
2. Database and PostGIS schema.
3. Project and area CRUD.
4. Dataset upload and metadata extraction.
5. Vector import and display.
6. Raster import and metadata display.
7. Map workbench with layer management.
8. OSM/GRB reference ingest interface or stubbed real-data connector with honest unavailable state.
9. Detection pipeline architecture with YOLO adapter.
10. Detection result storage as geospatial features.
11. QA/QC comparison engine against reference polygons.
12. GeoJSON export.
13. Demo scenario page.
14. Smoke tests and documentation.
## V1 Can Be Portfolio-Ready Without
- full Sentinel automation;
- actual production GRB WFS credentials or final endpoint if unavailable;
- LiDAR processing;
- model training;
- multi-user auth;
- perfect visual polish.
## V1 Cannot Be Portfolio-Ready Without
- a working map-driven workflow;
- actual geospatial data models;
- real CRS/geometry handling;
- honest dataset status handling;
- at least one end-to-end detection/QA workflow, even if it uses a small local demo fixture/model adapter first;
- clear export output.
+24
View File
@@ -0,0 +1,24 @@
# CRS Policy
## API Boundary
GeoJSON in API responses should be EPSG:4326.
## Analytical Operations
For Belgium/Kempen projected calculations, use EPSG:31370 where possible.
## Raster Operations
Raster operations must preserve source CRS unless a reproject operation is explicitly requested.
## Required Metadata
Every dataset must store:
- source CRS;
- normalized CRS string;
- bounds in source CRS;
- bounds in EPSG:4326;
- transform/affine for rasters where available.
## Unsupported Cases
If CRS cannot be determined:
- dataset can be stored as `metadata_failed` or `requires_crs`;
- processing requiring geospatial alignment must be blocked;
- UI must ask for CRS or show limitation.
+36
View File
@@ -0,0 +1,36 @@
# Error Taxonomy
All API errors must use a consistent shape.
```json
{
"error": {
"code": "DATASET_UNSUPPORTED_FORMAT",
"message": "The uploaded file format is not supported for this operation.",
"details": {},
"trace_id": "optional"
}
}
```
## Core Error Codes
- `VALIDATION_ERROR`
- `NOT_FOUND`
- `CONFLICT`
- `FEATURE_DISABLED`
- `DATASET_UPLOAD_FAILED`
- `DATASET_UNSUPPORTED_FORMAT`
- `CRS_MISSING`
- `CRS_UNSUPPORTED`
- `GEOMETRY_INVALID`
- `RASTER_METADATA_FAILED`
- `VECTOR_METADATA_FAILED`
- `PROCESSING_JOB_FAILED`
- `MODEL_UNAVAILABLE`
- `INFERENCE_FAILED`
- `REFERENCE_LAYER_MISSING`
- `QA_MATCHING_FAILED`
- `EXPORT_FAILED`
## Frontend Requirements
Every error code should render a useful message and suggested next action.
@@ -0,0 +1,34 @@
# Feature Flag Strategy
Feature flags prevent future modules from appearing as broken V1 features.
## Required Flags
- `ENABLE_GRB_CONNECTOR`
- `ENABLE_OSM_CONNECTOR`
- `ENABLE_SENTINEL_LAB`
- `ENABLE_SAM_SEGMENTATION`
- `ENABLE_YOLO_DETECTION`
- `ENABLE_LIDAR_LAB`
- `ENABLE_TRAINING_STUDIO`
- `ENABLE_QGIS_EXPORT`
## V1 Defaults
```env
ENABLE_GRB_CONNECTOR=true
ENABLE_OSM_CONNECTOR=true
ENABLE_SENTINEL_LAB=false
ENABLE_SAM_SEGMENTATION=false
ENABLE_YOLO_DETECTION=true
ENABLE_LIDAR_LAB=false
ENABLE_TRAINING_STUDIO=false
ENABLE_QGIS_EXPORT=false
```
## UI Behavior
Disabled features may be visible as roadmap cards, but must not look like broken tools. They should show:
- why disabled;
- what dependency is missing;
- which milestone enables them.
## Backend Behavior
Disabled endpoints return a typed `FEATURE_DISABLED` error, not 404 and not silent success.
@@ -0,0 +1,14 @@
# Final Pre-Codex Checklist
Before starting tomorrow's Codex build:
- [ ] Extract latest full zip.
- [ ] Open repo root in Codex environment.
- [ ] Confirm `.env.example` exists.
- [ ] Confirm Docker/PostGIS plan is present.
- [ ] Give Codex `prompts/codex/M10_MASTER_AUTONOMOUS_PROMPT.md`.
- [ ] Tell Codex to execute only one pass at a time.
- [ ] After each pass, require pass report.
- [ ] Reject pass if it changes frozen scope.
- [ ] Reject pass if it hides missing functionality behind fake success.
- [ ] Save output as new update/full zip after meaningful passes.
@@ -0,0 +1,30 @@
# Frontend State Machine
Every async module must model these states explicitly:
- `idle`
- `loading`
- `empty`
- `ready`
- `error`
- `unavailable`
- `disabled`
## Dataset Card
- idle: not selected
- loading: metadata extraction running
- empty: no datasets uploaded
- ready: dataset metadata available
- error: upload/extraction failed
- unavailable: operation unsupported for this dataset type
- disabled: feature flag off
## Analysis Run
- queued
- running
- succeeded
- failed
- cancelled
## UI Rule
Never leave users with a blank panel. Every panel must explain what is happening or what to do next.
+29
View File
@@ -0,0 +1,29 @@
# Geometry Contracts
## Internal Geometry Standard
- Database geometries are stored in PostGIS.
- Default storage CRS: EPSG:31370 for Belgian projected operations where appropriate, or EPSG:4326 for API interchange.
- API GeoJSON is always EPSG:4326 unless explicitly stated.
- Area calculations must use projected CRS, not raw WGS84 degrees.
## Accepted Area Input
- GeoJSON Polygon
- GeoJSON MultiPolygon
- drawn polygon from frontend
- future: municipality selection
## Validation Rules
- polygon must be closed;
- polygon must be valid;
- polygon must have non-zero area;
- self-intersections must be rejected or repaired explicitly;
- extremely large areas must require confirmation or be rejected by configured max area.
## Output Rules
- include `crs` metadata if transformed;
- include computed area in square meters;
- include bounds;
- include geometry validity status.
## Common Trap
Never compute area or distance in degrees.
@@ -0,0 +1,16 @@
# Known Limitations Template
Use this file format after each major build.
## Current Limitations
| Area | Limitation | Impact | Workaround | Target Milestone |
|---|---|---|---|---|
| Detection | YOLO weights not configured | Demo adapter only | Configure local weights | V1.x |
## Data Limitations
- GRB live connector may require endpoint details or local downloads.
- Sentinel automation is V2.
- LiDAR is outside V1.
## Technical Debt
List only real debt, not unfinished planned scope.
+34
View File
@@ -0,0 +1,34 @@
# Model Adapter Guide
## Purpose
Detection and segmentation must be implemented behind stable adapters so V1 can support demo/local model flows while remaining ready for YOLO/SAM integration.
## Detection Adapter Interface
```python
class DetectionAdapter:
name: str
supported_classes: list[str]
def is_available(self) -> bool: ...
def predict(self, image_tile, parameters) -> list[DetectionResult]: ...
```
## Detection Result
Fields:
- class_name
- confidence
- bbox_pixel
- bbox_geo optional after georeferencing
- source_tile
- metadata
## Segmentation Adapter Interface
```python
class SegmentationAdapter:
name: str
supported_classes: list[str]
def is_available(self) -> bool: ...
def segment(self, image_tile, parameters) -> list[SegmentationResult]: ...
```
## V1 Rule
If real YOLO weights are not configured, use a demo adapter only when clearly labelled as demo and never present it as production AI.
+34
View File
@@ -0,0 +1,34 @@
# Observability Plan
## Required Logs
- request start/end with trace id;
- dataset upload registration;
- metadata extraction status;
- job lifecycle transitions;
- model adapter selection;
- inference start/end;
- QA/QC matching summary;
- export creation.
## Required Health Checks
- API health;
- database connection;
- PostGIS extension availability;
- storage write check;
- optional Redis check;
- optional model registry check.
## Diagnostics Endpoint
`GET /system/diagnostics`
Should return safe non-secret status:
```json
{
"api": "ok",
"database": "ok",
"postgis": "ok",
"storage": "ok",
"redis": "unconfigured",
"models": "unconfigured"
}
```
+25
View File
@@ -0,0 +1,25 @@
# Performance Budgets
## API
- health endpoint: < 200ms local
- project list: < 500ms for 100 projects
- dataset metadata: < 500ms after extraction
- synchronous upload response: should register file quickly and hand off heavy work to job queue
## Raster
- never load large rasters fully into memory for preview;
- prefer windowed reads and overviews;
- large tiling must run as background job.
## Vector
- use spatial indexes for intersection/QA operations;
- simplify only for display, not source-of-truth unless explicitly stored as derived layer.
## Frontend
- initial app load should not require heavy GIS data;
- map layers should be lazy-loaded;
- large GeoJSON should be paged, tiled, or simplified.
## Jobs
Long-running operations must have status transitions:
`queued -> running -> succeeded|failed|cancelled`.
@@ -0,0 +1,41 @@
# QA/QC Matching Algorithm
## Goal
Compare AI detections/segmentations with a reference layer such as GRB buildings.
## Inputs
- predicted polygons
- reference polygons
- class filter
- IoU threshold, default 0.5
## Steps
1. Validate CRS alignment.
2. Reproject to analytical CRS.
3. Build spatial indexes.
4. For every predicted polygon, find candidate reference polygons by bbox intersection.
5. Compute IoU for candidates.
6. Assign best match above threshold greedily, one reference per prediction.
7. Count true positives, false positives, false negatives.
8. Compute precision, recall, F1, mean IoU.
9. Produce unmatched prediction layer and unmatched reference layer.
## Metrics
```text
precision = TP / (TP + FP)
recall = TP / (TP + FN)
f1 = 2 * precision * recall / (precision + recall)
IoU = intersection_area / union_area
```
## Output Layers
- matched predictions
- false positives
- false negatives
- low IoU matches
## Edge Cases
- empty predictions and empty reference: score should be explicit `no_objects` not perfect success;
- empty predictions with reference: recall 0;
- predictions with empty reference: precision 0;
- invalid polygons must be repaired or excluded with warning.
+13
View File
@@ -0,0 +1,13 @@
# M10 Ultra Preparation Pack
This folder contains the additional control layer for making GeoIntel as autonomous-build-ready as possible for Codex.
Purpose:
- remove hidden architecture ambiguity;
- give Codex concrete implementation contracts;
- define allowed freedom versus frozen decisions;
- provide validation and recovery procedures;
- prevent common GIS/AI/web-app regressions;
- make each build pass reviewable without manual guessing.
M10 does not replace the previous documentation. It adds the final execution scaffolding around it.
+27
View File
@@ -0,0 +1,27 @@
# V1 Release Gate
GeoIntel V1 is releasable when all gates pass.
## Product Gate
- [ ] User can create project.
- [ ] User can create/select area.
- [ ] User can upload at least one vector dataset.
- [ ] User can upload/register at least one raster dataset.
- [ ] User can see datasets on map or metadata panel.
- [ ] User can run a detection workflow or labelled demo adapter.
- [ ] User can compare detections to reference polygons.
- [ ] User can export GeoJSON.
## Engineering Gate
- [ ] Backend starts from clean checkout.
- [ ] Frontend builds from clean checkout.
- [ ] Database migrations apply.
- [ ] Tests run.
- [ ] Smoke script passes.
- [ ] Docs explain setup.
## Integrity Gate
- [ ] No fake success states.
- [ ] CRS assumptions documented.
- [ ] Feature-disabled states are clear.
- [ ] Known limitations are listed.
+28
View File
@@ -0,0 +1,28 @@
# Repo Hygiene Rules
## Do Commit
- source code;
- documentation;
- small fixtures;
- config examples;
- migration files;
- test data under size limits.
## Do Not Commit
- `.env` with secrets;
- large rasters;
- model weights;
- generated cache;
- local database volumes;
- node_modules;
- Python virtualenvs;
- personal paths.
## Naming
- backend modules use snake_case;
- frontend components use PascalCase;
- docs use uppercase topic names or numbered folders;
- fixtures describe region and purpose.
## Generated Outputs
Generated exports should go under `exports/` and be gitignored unless they are tiny documented sample fixtures.
@@ -0,0 +1,26 @@
# Security and Secret Handling
## Secrets
Never commit API keys, tokens, model credentials, STAC credentials, database passwords, or private URLs.
## Environment Variables
All secrets must be loaded from `.env` or deployment environment.
## File Upload Safety
- limit accepted extensions;
- validate MIME/type where possible;
- store uploads outside source directories;
- generate server-side filenames;
- never execute uploaded files;
- reject path traversal.
## External Connectors
- log endpoint names but not credentials;
- timeout external requests;
- cache responses where appropriate;
- show connector status in UI.
## AI/Model Safety
- model files must be treated as artifacts;
- do not auto-download arbitrary executable code;
- keep model registry metadata separate from weights.
+37
View File
@@ -0,0 +1,37 @@
# UI Copy Bank
## Product Language
Use:
- GeoAI Workbench
- Dataset
- Analysis Run
- Reference Layer
- Detection Result
- QA/QC
- Export
Avoid:
- magic AI
- automatic truth
- perfect detection
- black box conclusions
## Empty States
### No Projects
"Start a GeoAI project by selecting an area in the Kempen or opening the prepared demo scenario."
### No Datasets
"Upload a GeoTIFF, GeoJSON, Shapefile, or use a connector to add reference data."
### No Analysis Runs
"Run a raster, vector, detection, segmentation, or QA/QC analysis to generate geospatial outputs."
## Error Suggestions
### CRS Missing
"This dataset has no detected CRS. Add CRS metadata before using it in spatial operations."
### Model Unavailable
"No detection model is configured. Configure YOLO weights or use the labelled demo adapter."
### Reference Missing
"QA/QC requires a reference layer such as GRB buildings or a local reference GeoJSON."
@@ -0,0 +1,81 @@
# M11 Architect Audit Report
## Audit summary
The repo has strong breadth: product docs, architecture docs, API plans, build prompts, fixtures, smoke scripts and milestone handoffs exist. The main risk is no longer lack of documentation; it is competing documentation and missing hierarchy.
## Findings
### Finding 1 — Too many competing start points
There are multiple handoff files and prompt files from M0 through M10. This is useful historically but dangerous for Codex.
Resolution:
- added `docs/00-start/START_HERE.md` as canonical entry point;
- added decision precedence;
- older files remain historical.
### Finding 2 — Governance rules were implied, not constitutional
Previous docs often said what to build, but not which principles override conflicts.
Resolution:
- added GeoIntel Constitution;
- added Architecture Invariants;
- added Forbidden Decisions.
### Finding 3 — Domain language needed locking
Terms like Dataset, Layer, Analysis, Detection and Segmentation could be implemented inconsistently.
Resolution:
- added Canonical Domain Models.
### Finding 4 — State machines needed canonical names
Multiple docs referenced statuses, but a single source of truth was missing.
Resolution:
- added `STATE_MACHINES.md`.
### Finding 5 — Build order needed dependency graph, not only phase lists
Codex needs to know not only tasks, but why one task must precede another.
Resolution:
- added Build Order Dependency Graph.
### Finding 6 — Golden paths needed stronger protection
The desired demo was clear, but not protected as regression-critical workflows.
Resolution:
- added `GOLDEN_PATHS.md`.
### Finding 7 — Error handling needed stable codes
The frontend and backend need a common error taxonomy.
Resolution:
- added `ERROR_CATALOG.md`.
## Remaining recommendations for M12+
1. Generate actual starter code skeleton aligned with the docs.
2. Add OpenAPI YAML snapshot once backend exists.
3. Add migration files once database models exist.
4. Convert golden paths into executable tests.
5. Add real small GeoTIFF fixture if licensing/file size allows.
6. Add GRB WFS proof-of-concept adapter after local fixture path is stable.
7. Add QGIS export verification later.
## Architect verdict
The repo is now suitable for a disciplined autonomous Codex build, provided Codex starts from `docs/00-start/START_HERE.md` and treats older handoff docs as historical.
@@ -0,0 +1,86 @@
# Codex Tomorrow Runbook
## Before starting
Use the latest full repo zip, extract it, and open the repository root.
Read:
1. `CODEX_START.md`
2. `docs/00-start/START_HERE.md`
3. `docs/20-run-readiness/RUN_READINESS_FINAL.md`
4. `docs/20-run-readiness/PASS_SEQUENCE_FINAL.md`
5. `prompts/codex/final/DAY_1_MASTER_PROMPT.md`
## Operating rhythm
For each pass:
1. Restate the pass goal.
2. List files expected to change.
3. Implement only the pass scope.
4. Run the relevant commands.
5. Fix failures within scope.
6. Update status docs.
7. Produce pass report.
## Do not allow Codex to drift into
- redesigning the product;
- adding auth/multi-user early;
- building a chatbot first;
- implementing LiDAR first;
- building a full report generator first;
- replacing FastAPI/PostGIS/React;
- using only demo data without real-data-ready interfaces;
- hiding broken states behind TODO comments.
## Recommended first commands
```bash
find . -maxdepth 3 -type f | sort | head -200
bash scripts/check_repo_structure.sh
python scripts/smoke_docs.py
python scripts/validate_fixtures.py
python scripts/preimplementation_audit.py
```
If scripts fail because permissions are missing, run them with `bash scriptname.sh` or `python scriptname.py` rather than changing architecture.
## Pass report template
```text
Pass:
Scope:
Files changed:
Commands run:
Tests/smoke checks:
What works now:
Known limitations:
Architecture invariants touched:
Golden path status:
Next pass:
```
## Stop conditions
Stop and create a proposal note instead of coding when:
- a required architecture decision is missing;
- a chosen dependency conflicts with the dependency policy;
- a requested change violates an invariant;
- API contracts require breaking changes;
- a geospatial assumption is unclear and affects data correctness.
## Success definition for tomorrow
A successful day does not require every advanced module. A successful day means:
- backend foundation exists;
- database/domain foundation exists;
- project/area/dataset flow works;
- fixture vector import works;
- QA/QC can run on fixture buildings;
- GeoJSON export exists;
- minimal UI can display the workflow or at least consume the API;
- docs and tests reflect reality.
@@ -0,0 +1,40 @@
# Implementation Readiness Checklist
## Repo readiness
- [ ] `CODEX_START.md` exists at repo root.
- [ ] `docs/00-start/START_HERE.md` exists.
- [ ] `docs/20-run-readiness/RUN_READINESS_FINAL.md` exists.
- [ ] `prompts/codex/final/DAY_1_MASTER_PROMPT.md` exists.
- [ ] `scripts/preimplementation_audit.py` runs.
- [ ] Demo fixtures validate.
## Architecture readiness
- [ ] Product identity is fixed.
- [ ] Stack is fixed.
- [ ] Database choice is fixed.
- [ ] CRS/GIS standards are fixed.
- [ ] State machines are fixed.
- [ ] Golden paths are fixed.
- [ ] Forbidden decisions are explicit.
## Build readiness
- [ ] Pass order is known.
- [ ] First vertical slice is known.
- [ ] V1 exclusions are known.
- [ ] Definition of Done is known.
- [ ] Smoke tests are known.
- [ ] Pass report format is known.
## Release readiness target
- [ ] Backend imports.
- [ ] Health endpoint works.
- [ ] Database models exist.
- [ ] Project/Area/Dataset APIs exist.
- [ ] Fixtures can be imported.
- [ ] QA/QC metrics can be computed.
- [ ] GeoJSON can be exported.
- [ ] Minimal UI can show results.
@@ -0,0 +1,206 @@
# Final Codex Pass Sequence
Codex must execute these passes in order. Do not skip ahead unless the previous pass is complete and smoke-checked.
## Pass 0 — Repo audit and bootstrap
Goal: confirm the repo can be used as an implementation workspace.
Deliverables:
- confirm folder structure;
- install/dependency plan selected;
- create missing backend/frontend scaffolding only if absent;
- no product feature work yet;
- run docs smoke scripts.
Exit criteria:
- `CODEX_START.md` is acknowledged;
- canonical docs are read;
- no conflicting start path remains unaddressed in notes.
## Pass 1 — Backend application foundation
Goal: create a FastAPI app that imports and serves health/status endpoints.
Deliverables:
- `backend/app/main.py`;
- settings/config module;
- API router structure;
- health endpoint;
- error envelope helper;
- minimal tests.
Exit criteria:
- backend imports successfully;
- health endpoint test passes;
- no database required yet.
## Pass 2 — Database and domain foundation
Goal: establish SQLAlchemy/Alembic/PostGIS-ready domain models.
Deliverables:
- DB config;
- migration skeleton;
- models for Project, Area, Dataset, AnalysisRun, Detection, Metric, Export;
- schemas for request/response;
- geometry storage strategy documented in code comments and docs.
Exit criteria:
- migrations can be generated/applied in local environment;
- models match canonical domain docs;
- no geometry stored as arbitrary string when PostGIS type is available.
## Pass 3 — Project and Area API
Goal: implement the first user-managed domain objects.
Deliverables:
- project CRUD;
- area CRUD;
- geometry validation;
- area calculation;
- API tests;
- response envelope compliance.
Exit criteria:
- create/list/read project works;
- create/list/read area works;
- invalid geometry returns controlled error.
## Pass 4 — Dataset manager foundation
Goal: register datasets and extract basic metadata.
Deliverables:
- dataset upload/registration endpoint;
- metadata schema;
- storage path convention;
- fixture registration path;
- dataset state machine implemented.
Exit criteria:
- fixture vector dataset can be registered;
- dataset moves through valid states;
- failed validation is explicit.
## Pass 5 — Vector processing core
Goal: load reference polygons and predicted detection polygons.
Deliverables:
- GeoJSON import;
- geometry normalization;
- CRS handling;
- feature count and bounds metrics;
- persistence of reference and predicted layers.
Exit criteria:
- reference buildings fixture imports;
- predicted buildings fixture imports;
- invalid GeoJSON is rejected safely.
## Pass 6 — QA/QC engine foundation
Goal: compare predicted detections against reference polygons.
Deliverables:
- IoU/overlap matching;
- precision, recall, F1;
- false positive/false negative outputs;
- quality check records;
- tests with demo fixtures.
Exit criteria:
- expected demo metrics are reproduced or documented;
- algorithm is deterministic;
- matching thresholds are configurable but defaulted.
## Pass 7 — GeoJSON export
Goal: export geospatial outputs from the system.
Deliverables:
- export endpoint;
- export records;
- GeoJSON FeatureCollection output;
- export validation;
- smoke test.
Exit criteria:
- detections export as valid GeoJSON;
- QA/QC outputs can be exported;
- no broken geometry emitted.
## Pass 8 — Frontend workbench shell
Goal: create a minimal but coherent UI.
Deliverables:
- React/TypeScript app shell;
- route structure;
- project list/detail;
- map workbench placeholder with layer panel;
- API client;
- loading/error/empty states.
Exit criteria:
- frontend builds;
- health/status can be displayed;
- no hardcoded permanent fake data except clearly marked demo fixtures.
## Pass 9 — Map and metrics integration
Goal: show the vertical slice visually.
Deliverables:
- render area/reference/prediction layers;
- metrics panel;
- QA/QC result cards;
- export action;
- basic style guide compliance.
Exit criteria:
- demo Geel workflow can be clicked through;
- layer visibility/opacity works at minimum level;
- UI does not obscure the map or results.
## Pass 10 — Stabilization and release candidate
Goal: make the first vertical slice releasable.
Deliverables:
- smoke tests;
- docs update;
- known limitations;
- changelog;
- run instructions;
- regression checklist.
Exit criteria:
- backend tests pass;
- frontend build passes;
- demo workflow documented;
- no architecture invariant violated.
@@ -0,0 +1,37 @@
# Repo Conflict Resolution
The repo contains many milestone documents. This is intentional, but implementation must not follow conflicting instructions.
## Conflict categories
### Product conflict
Example: one document says GeoIntel is a dashboard, another says GeoIntel is a GeoAI Workbench.
Resolution: follow `GEOINTEL_CONSTITUTION.md`.
### Stack conflict
Example: one document suggests another backend framework.
Resolution: follow ADRs and `ARCHITECTURE_INVARIANTS.md`.
### Scope conflict
Example: one older document prioritizes reports before QA/QC.
Resolution: follow `PASS_SEQUENCE_FINAL.md` and `V1_SCOPE_FREEZE.md`.
### API conflict
Example: endpoint naming differs between older docs.
Resolution: follow `API_CONTRACTS.md`, `API_CONTRACT_FREEZE_M2.md`, and response envelope contracts.
### CRS/geospatial conflict
Resolution: follow `GIS_STANDARDS.md`, `CRS_POLICY.md`, and canonical geometry contracts.
## Rule
When implementing, newer canonical control docs are binding. Older milestone docs are explanatory only.
@@ -0,0 +1,75 @@
# M12 Run Readiness Final Audit
## Purpose
This document converts the large GeoIntel preparation set into a practical final execution layer for Codex. The repo contains many useful milestone documents, but the implementation run must follow one canonical path.
## Final readiness status
GeoIntel is ready to start implementation when Codex follows the canonical path below and does not treat older milestone documents as competing instructions.
## Canonical control stack
1. Product identity: `docs/governance/GEOINTEL_CONSTITUTION.md`
2. Architecture invariants: `docs/governance/ARCHITECTURE_INVARIANTS.md`
3. Forbidden decisions: `docs/governance/FORBIDDEN_DECISIONS.md`
4. Decision precedence: `docs/governance/DECISION_PRECEDENCE.md`
5. Domain models: `docs/specs/CANONICAL_DOMAIN_MODELS.md`
6. GIS standards: `docs/specs/GIS_STANDARDS.md`
7. Raster standards: `docs/specs/RASTER_STANDARDS.md`
8. State machines: `docs/specs/STATE_MACHINES.md`
9. Golden paths: `docs/workflows/GOLDEN_PATHS.md`
10. Build dependency graph: `docs/build/BUILD_ORDER_DEPENDENCY_GRAPH.md`
11. Final pass sequence: `docs/20-run-readiness/PASS_SEQUENCE_FINAL.md`
12. Day 1 master prompt: `prompts/codex/final/DAY_1_MASTER_PROMPT.md`
## Older milestone documents
Older M0-M11 documents remain valuable as supporting context. They are not deleted because they contain useful details, but they must not override the canonical control stack.
When in doubt, Codex must follow:
`CODEX_START.md` → `START_HERE.md` → M12 run-readiness docs → governance/specs → implementation prompts.
## Final V1 scope
V1 is the foundation GeoAI Workbench vertical slice.
V1 includes:
- backend skeleton;
- database models and migrations;
- project CRUD;
- area CRUD with geometry validation;
- dataset registration/upload metadata;
- vector import using fixtures first;
- raster metadata extraction where libraries are available;
- reference polygon loading;
- predicted detection import;
- QA/QC matching against reference polygons;
- metric persistence;
- GeoJSON export;
- minimal frontend workbench;
- status/error handling;
- smoke tests.
V1 excludes:
- live production GRB sync as a blocker;
- heavy model training;
- full SAM/YOLO production inference as a blocker;
- LiDAR processing;
- MLOps registry implementation;
- QGIS plugin;
- multi-user permissions;
- advanced PDF report generation.
## Implementation policy
Codex may improve implementation details, UX clarity, tests, types, helper abstractions and documentation. Codex must not alter product identity, stack, state machines, response envelope, database choice, CRS policy or golden path priority without an ADR proposal.
## Final release target
The first release target is not a complete GeoAI platform. It is a stable, demonstrable vertical slice proving that GeoIntel can move geospatial data through the core pipeline:
`data → processing → geospatial output → QA/QC → export`.
@@ -0,0 +1,43 @@
# M13 Codex Optimization Overview
M13 adds an optimization layer on top of the M12 run-ready repository. The goal is to improve Codex output quality by making the implementation process more constrained where correctness matters, while still allowing local improvements inside documented boundaries.
## M13 purpose
Codex should be able to:
1. choose the correct entry document without ambiguity;
2. work pass-by-pass without re-planning the whole product;
3. use reusable skills for repeated implementation patterns;
4. respect token and context budgets;
5. avoid secrets leakage;
6. split work safely across parallel agents or worktrees;
7. self-review every implementation pass against explicit gates;
8. escalate only real blockers.
## New canonical Codex flow
1. Read `CODEX_START.md`.
2. Read `docs/30-codex-optimization/CODEX_RUN_CHECKLIST.md`.
3. Read `docs/30-codex-optimization/PROMPT_DISCIPLINE.md`.
4. Select the active pass from `docs/20-run-readiness/PASS_SEQUENCE_FINAL.md`.
5. Select only the relevant skill from `skills/`.
6. Implement the smallest coherent pass.
7. Run `make readiness` plus module-specific checks.
8. Fill in `docs/CODEX_EXECUTION_LOG.md`.
9. Produce a pass summary using `prompts/codex/m13/PASS_COMPLETION_REPORT_PROMPT.md`.
## M13 rule hierarchy
If instructions conflict, follow this order:
1. `docs/governance/GEOINTEL_CONSTITUTION.md`
2. `docs/governance/ARCHITECTURE_INVARIANTS.md`
3. `docs/governance/FORBIDDEN_DECISIONS.md`
4. `CODEX_START.md`
5. `docs/30-codex-optimization/*`
6. active pass prompt
7. module documentation
8. historical milestone documents
Historical M0-M12 documents remain useful, but they must not override governance, invariants, M12 final readiness, or M13 optimization rules.
@@ -0,0 +1,48 @@
# Codex Run Checklist
Use this checklist at the start and end of every Codex session.
## Before starting
- [ ] Confirm the current branch/worktree.
- [ ] Read `CODEX_START.md`.
- [ ] Read `docs/00-start/START_HERE.md`.
- [ ] Read `docs/30-codex-optimization/CODEX_OPTIMIZATION_OVERVIEW.md`.
- [ ] Read `docs/30-codex-optimization/PROMPT_DISCIPLINE.md`.
- [ ] Read only the active pass prompt.
- [ ] Read the relevant skill from `skills/`.
- [ ] Run `make readiness` if the repository has shell/python available.
- [ ] Identify the exact files expected to change.
## During implementation
- [ ] Keep changes scoped to the active pass.
- [ ] Do not introduce new frameworks without ADR.
- [ ] Do not change API contracts unless the active pass explicitly requires it.
- [ ] Do not create permanent mock-only implementations.
- [ ] Prefer small, verifiable service boundaries.
- [ ] Keep GIS units and CRS assumptions explicit.
- [ ] Record real limitations as limitations, not hidden TODOs.
## Before finishing
- [ ] Run relevant tests/smoke checks.
- [ ] Run `make readiness` when possible.
- [ ] Update `docs/CODEX_EXECUTION_LOG.md`.
- [ ] Update `CHANGELOG.md`.
- [ ] List changed files.
- [ ] List what works.
- [ ] List what remains incomplete.
- [ ] List any deliberate deviations from docs.
- [ ] Produce a self-review scorecard.
## Stop conditions
Stop and report instead of guessing when:
- a governance invariant would be violated;
- a required external credential is missing;
- a data source license or endpoint is unclear;
- a destructive migration would be needed;
- tests indicate a core regression;
- implementation requires a new major dependency not already approved.
@@ -0,0 +1,28 @@
# Codex Skills Index
Skills are reusable implementation workflows. Use one skill per implementation pass unless the task clearly spans two tightly coupled areas.
## Available skills
| Skill | Use when |
|---|---|
| `geoai-backend-build` | creating FastAPI services, routers, schemas, domain logic |
| `postgis-migration` | creating database models, Alembic migrations, geometry fields |
| `raster-pipeline` | implementing Rasterio/GDAL-style raster metadata, clip, tile, indices |
| `vector-processing` | implementing GeoPandas/Shapely vector operations and exports |
| `frontend-maplibre-workbench` | building React/MapLibre pages, layers, UI states |
| `qaqc-review` | implementing IoU, precision/recall, false positives/negatives |
| `codex-pass-review` | final self-review, regression scan and pass completion reports |
## Skill usage protocol
1. Read active pass prompt.
2. Select the closest skill.
3. Read `skills/<skill>/SKILL.md`.
4. Implement using the skill checklist.
5. Run module-specific checks.
6. End with the skill's required report fields.
## Skill conflict rule
If a skill conflicts with governance docs, governance wins. Update the skill later; do not violate governance.
@@ -0,0 +1,29 @@
# M13 Handoff Summary — Codex Optimization Pack
M13 adds the final layer intended to improve tomorrow's Codex execution quality.
## Added
- Codex optimization overview.
- Codex run checklist.
- Prompt discipline rules.
- Token/context budget policy.
- Secrets and environment policy.
- Parallel agent strategy.
- Codex skills index.
- Reusable skills under `skills/`.
- M13 day-one optimized master prompt.
- Pass completion report prompt.
- Updated readiness checks for M13 assets.
## Why this matters
M12 made the repository run-ready. M13 makes the repository easier for Codex to execute correctly without wasting context, drifting from contracts, leaking secrets, or making undocumented architecture choices.
## Recommended next action
Use:
- `prompts/codex/m13/DAY_1_OPTIMIZED_MASTER_PROMPT.md`
for the first serious Codex build run.
@@ -0,0 +1,87 @@
# Parallel Agent Strategy
GeoIntel can use multiple Codex agents only when their work areas do not conflict.
## Safe parallel tracks
### Track A — Backend foundation
Allowed paths:
- `backend/`
- `tests/backend/`
- database docs when needed
Do not touch frontend except API contract comments.
### Track B — Frontend shell
Allowed paths:
- `frontend/`
- `tests/frontend/`
- UI docs when needed
Do not change API contracts without coordination.
### Track C — Documentation/runbooks
Allowed paths:
- `docs/`
- `prompts/`
- `skills/`
- `checklists/`
Do not change implementation code.
### Track D — Fixtures/tests
Allowed paths:
- `tests/fixtures/`
- `fixtures/`
- `scripts/`
- test docs
Do not alter production services except to expose stable test hooks.
## Unsafe parallel work
Do not run parallel agents on:
- database schema plus API schemas unless coordinated;
- API contracts plus frontend client generation unless coordinated;
- storage paths plus dataset manager unless coordinated;
- detection output schemas plus QA/QC engine unless coordinated.
## Worktree naming convention
```text
worktrees/
geointel-backend-foundation
geointel-frontend-shell
geointel-qaqc-engine
geointel-docs-control
```
## Merge order
1. governance/docs updates;
2. database/domain foundation;
3. backend APIs;
4. frontend API client;
5. UI pages;
6. tests/fixtures;
7. polish.
## Parallel agent completion report
Every agent must report:
- branch/worktree name;
- files changed;
- contracts touched;
- tests run;
- merge risks;
- required follow-up from other tracks.
@@ -0,0 +1,94 @@
# Prompt Discipline for Codex Runs
Codex performs best when each run has one active objective, a clear source of truth, explicit stop conditions, and a small set of expected outputs.
## Required prompt shape
Every implementation prompt should contain:
1. Active milestone.
2. Active pass.
3. Required documents to read.
4. Forbidden documents to treat as historical only.
5. Expected files or directories to touch.
6. Expected tests/checks.
7. Definition of Done.
8. Reporting format.
## Good prompt pattern
```text
You are working on GeoIntel Kempen.
Active pass: PASS_02_DATABASE_DOMAIN.
Read first: CODEX_START.md, docs/30-codex-optimization/CODEX_RUN_CHECKLIST.md, skills/postgis-migration/SKILL.md, docs/DATABASE_IMPLEMENTATION_PLAN.md.
Do not modify frontend files in this pass.
Implement only the database/domain foundation described in the active pass.
Run make readiness and relevant backend checks.
End with changed files, commands run, tests, risks, next pass.
```
## Bad prompt pattern
```text
Build the whole platform. Improve whatever you see. Make it production ready.
```
This is forbidden because it causes scope creep, undocumented architecture choices, and conflicting implementations.
## Improvement boundary
Codex may improve:
- naming consistency;
- validation details;
- typing;
- docstrings;
- tests;
- small helper functions;
- error messages;
- UI empty/loading/error states;
- non-breaking internal structure.
Codex may not independently change:
- primary stack;
- database choice;
- job queue choice;
- CRS policy;
- API contract shape;
- V1 scope;
- security model;
- storage architecture;
- model governance rules.
## Context loading rule
Do not read the entire repository for every pass. Load context in this order:
1. root start files;
2. governance docs;
3. active pass prompt;
4. relevant skill;
5. directly relevant module docs;
6. code files affected by the pass;
7. tests/fixtures for the affected area.
## End-of-pass response format
Codex must end each pass with:
```md
## Completed
## Changed files
## Commands run
## Test results
## Known limitations
## Deviations from docs
## Next recommended pass
```
@@ -0,0 +1,50 @@
# Secrets and Environment Policy
GeoIntel must be safe to publish as a portfolio repository.
## Absolute rules
- Never commit real API keys.
- Never commit credentials, tokens, cookies or private endpoints.
- Never place secrets in docs, fixtures, tests or screenshots.
- `.env.example` may contain placeholder values only.
- Runtime secrets are read from environment variables.
- If a real key is accidentally found, remove it and rotate it outside the repo.
## Approved environment variables
- `DATABASE_URL`
- `POSTGRES_HOST`
- `POSTGRES_PORT`
- `POSTGRES_DB`
- `POSTGRES_USER`
- `POSTGRES_PASSWORD`
- `REDIS_URL`
- `STORAGE_ROOT`
- `OPENAI_API_KEY`
- `COPERNICUS_CLIENT_ID`
- `COPERNICUS_CLIENT_SECRET`
- `GRB_WFS_BASE_URL`
- `OSM_OVERPASS_URL`
## Codex behavior
When credentials are missing, Codex must:
1. implement a clear configuration error;
2. document the missing variable;
3. provide an example in `.env.example`;
4. avoid hardcoded fallback secrets;
5. keep external-service calls behind adapters.
## Local development fallback
For V1 foundation work, services should be able to run with:
- local PostGIS;
- local Redis;
- fixture datasets;
- disabled external fetchers;
- deterministic demo outputs.
This fallback is not fake production behavior. It is a development mode and must be labeled as such.
@@ -0,0 +1,45 @@
# Token and Context Budget Policy
This repository is intentionally documentation-heavy. Codex must not load all documents for every task.
## Context tiers
### Tier 0 — Always read
- `CODEX_START.md`
- `docs/00-start/START_HERE.md`
- `docs/30-codex-optimization/CODEX_RUN_CHECKLIST.md`
- active pass prompt
### Tier 1 — Read when architecture-sensitive
- `docs/governance/GEOINTEL_CONSTITUTION.md`
- `docs/governance/ARCHITECTURE_INVARIANTS.md`
- `docs/governance/FORBIDDEN_DECISIONS.md`
- relevant ADRs
### Tier 2 — Read when module-specific
- relevant module spec
- relevant skill
- relevant API/database contract
- relevant tests/fixtures
### Tier 3 — Historical reference only
- old milestone handoff summaries
- previous pass prompts not active for the current run
- release notes from previous preparation milestones
## Budget rules
- Prefer reading indexes before detailed specs.
- Prefer targeted `grep/find` over opening large unrelated docs.
- Do not re-summarize old milestones unless needed.
- Work in small coherent diffs.
- If a task requires touching more than three major subsystems, split it into passes.
- If the active prompt conflicts with governance, stop and report.
## Large file policy
Large generated files, model artifacts, tiles, rasters and exports must not be created during documentation-preparation passes unless they are tiny fixtures. Real heavy assets belong outside git or in storage paths documented by `docs/STORAGE_ARCHITECTURE.md`.
@@ -0,0 +1,41 @@
# BACKLOG PRIORITIES — MoSCoW
## Must have for Sprint 1
- Backend app foundation.
- Database/PostGIS foundation.
- Project Manager.
- Area Manager.
- Dataset Manager for GeoJSON.
- Metadata extraction.
- Frontend shell.
- MapLibre map.
- Demo fixture display.
- Readiness checks.
## Should have for Sprint 1 if musts are complete
- GeoJSON export baseline.
- Area import from fixture.
- Dataset detail metadata panel.
- Simple layer tree.
- Basic smoke tests for frontend build.
## Could have later in same early phase
- Reference/prediction fixture import.
- QA/QC schema validation.
- Simple feature statistics.
- Layer opacity controls.
## Won't have in Sprint 1
- Live YOLO inference.
- Live SAM segmentation.
- GRB live WFS.
- Sentinel automation.
- LiDAR processing.
- Training Studio.
- AI Copilot.
- Full PDF report generator.
- Multi-user auth.
+78
View File
@@ -0,0 +1,78 @@
# BUILD ORDER GRAPH — M14 Launch
Codex must follow this dependency graph for implementation.
## Graph
```text
Repository readiness
-> Environment/config
-> Backend app foundation
-> Database/PostGIS foundation
-> Domain models/schemas
-> Migrations
-> Project API
-> Area API
-> Dataset API
-> Storage service
-> Metadata extraction
-> Frontend shell
-> Frontend API client
-> Map workbench shell
-> Dataset UI
-> Fixture layer display
-> Export baseline
-> Tests and readiness
```
## Blocked until foundation is stable
The following are blocked until the above graph is green:
- Detection Lab.
- Segmentation Lab.
- QA/QC engine beyond fixture/schema validation.
- Remote Sensing Lab.
- GRB live adapter.
- OSM live adapter.
- LiDAR Workbench.
- Training Studio.
## Rule
If a later module requires missing foundation work, Codex must complete the foundation work first instead of building around it.
## Preferred first implementation passes
### Pass 1 — Backend and config
- Create app structure.
- Add config/settings.
- Add health endpoint.
- Add response envelope and error handling.
### Pass 2 — Database and domain
- Add database connection.
- Add migrations.
- Add core models.
- Enable PostGIS.
### Pass 3 — Project/Area/Dataset API
- Implement CRUD.
- Validate geometry.
- Extract metadata.
### Pass 4 — Frontend shell and map
- React app.
- Layout.
- MapLibre.
- API client.
### Pass 5 — Fixture-driven integration
- Load demo area/reference layer.
- Display layers.
- Run smoke tests.
@@ -0,0 +1,106 @@
# BUILD SUCCESS DEFINITION — Sprint 1 / First Codex Run
This document defines the exact point at which Codex must stop expanding scope and consider the first implementation run successful.
## Purpose
The first build is not successful because many features exist. It is successful when the foundation is stable, testable and ready for the next module.
## Sprint 1 success statement
Sprint 1 is successful when GeoIntel can run locally with a backend, frontend, database and a minimal geospatial dataset workflow.
The vertical slice is:
```text
Project
-> Area
-> Dataset upload/registration
-> Metadata extraction
-> PostGIS persistence
-> Minimal map display
-> GeoJSON export
```
## Required backend success criteria
- FastAPI application starts without import errors.
- `/health` returns a successful response.
- `/docs` or OpenAPI schema is available in development.
- Database configuration is loaded from environment variables.
- PostgreSQL connection is verified by a health or readiness check.
- PostGIS extension is created or verified by migration/bootstrap logic.
- Project CRUD works through API endpoints.
- Area CRUD works with valid GeoJSON polygon input.
- Dataset registration or upload works for at least GeoJSON.
- Dataset metadata is extracted and persisted.
- API responses use the canonical response envelope.
- Errors use the canonical error format.
## Required database success criteria
- Alembic or equivalent migration path exists.
- Core tables exist:
- `projects`
- `areas`
- `datasets`
- `dataset_versions` or documented equivalent
- `analysis_runs` placeholder/table if needed for future compatibility
- `exports` placeholder/table if needed for future compatibility
- Geometry columns use PostGIS types.
- CRS/SRID rules follow `docs/specs/GIS_STANDARDS.md`.
- Demo seed data can be loaded or fixtures can be used in tests.
## Required frontend success criteria
- React/Vite application starts.
- Main layout is visible.
- MapLibre map renders.
- Project list/detail state exists.
- Dataset upload/registration UI exists for the Sprint 1 dataset type.
- Area display or drawing/import flow exists in minimal form.
- API client uses configured backend base URL.
- Loading, empty and error states exist for the implemented pages.
## Required storage success criteria
- Uploaded/registered dataset files are stored under a controlled storage path.
- Storage paths are not hardcoded to a developer machine.
- Metadata in the database references stored files where applicable.
- Generated exports go to a controlled exports folder.
## Required testing success criteria
At minimum:
- Backend import smoke test passes.
- Health endpoint test passes.
- Database connection/migration smoke test passes or has a documented fallback if no DB is available in CI.
- GeoJSON fixture validation passes.
- Frontend build or typecheck passes.
- `make readiness` passes.
## Explicitly not required for Sprint 1
Do not block Sprint 1 on:
- YOLO inference.
- SAM inference.
- Sentinel download automation.
- GRB live WFS integration.
- LiDAR processing.
- Training Studio.
- AI Copilot.
- Advanced reporting.
- Multi-user authentication.
- Production deployment.
## Stop condition
When all Sprint 1 success criteria are met, Codex must stop feature expansion and produce:
- changelog entry;
- commands run;
- test results;
- known limitations;
- next pass recommendation.
+45
View File
@@ -0,0 +1,45 @@
# CODEX STOP RULES
Codex must stop or pause expansion when these conditions occur.
## Hard stop conditions
Stop implementation and report if:
- backend cannot import;
- frontend cannot build due to own changes;
- migrations cannot be generated or applied due to unclear schema conflict;
- API contract conflict is found;
- architecture invariant would need to be broken;
- dependency choice conflicts with ADRs;
- secrets or API keys are accidentally introduced;
- external service is required for a Sprint 1 must-have.
## Soft stop conditions
Pause expansion and finish cleanup if:
- tests fail after the intended module is implemented;
- a feature starts requiring a non-Sprint-1 module;
- implementation requires more than one new abstraction not already documented;
- generated code duplicates existing logic;
- TODO comments are being used to hide incomplete logic.
## What Codex must do at stop
Report:
- exact blocker;
- files affected;
- commands run;
- failing output summary;
- recommended fix;
- whether rollback is needed.
## What Codex must not do
- Do not continue building unrelated modules while the build is broken.
- Do not silence errors by weakening tests.
- Do not replace real functionality with permanent mock logic.
- Do not change the architecture to make one test pass.
- Do not introduce a new dependency without ADR-compatible justification.
@@ -0,0 +1,116 @@
# DATA ACQUISITION PLAYBOOK
This playbook tells Codex how to think about data acquisition without spending the first build researching or overengineering live integrations.
## Principle
Sprint 1 uses local demo fixtures first. Live external data integrations are later adapters.
The data hierarchy is:
1. Golden fixtures for tests and UI development.
2. Local user-uploaded files.
3. Cached reference extracts.
4. Live external data services.
## Sprint 1 data sources
### Golden GeoJSON fixtures
Use existing files in `demo/geel/` as the first source of truth:
- `area_geel_center.geojson`
- `reference_buildings.geojson`
- `demo_detections.geojson`
- `expected_qaqc_metrics.json`
These are not meant to be geographically complete. They are contract fixtures.
### User upload/register
Support GeoJSON first. Validate:
- file extension;
- JSON parse;
- FeatureCollection shape;
- geometry existence;
- CRS handling fallback;
- bounds calculation.
## GRB strategy
GRB is the professional reference layer for Vlaanderen. It is the preferred future reference for buildings and related vector features.
### Sprint 1
- Do not implement live GRB WFS yet.
- Use GRB-like local fixture data.
- Design a `ReferenceDataAdapter` interface so GRB can be added without rewriting QA/QC.
### Sprint 2+
- Add GRB adapter.
- Prefer bbox/area-scoped retrieval.
- Cache retrieved features in PostGIS.
- Track source, retrieval timestamp and layer name.
### Fallback
If GRB is unavailable:
- use cached extract;
- show external-source-unavailable status;
- do not fake live data.
## OSM strategy
OSM can be useful as a broad fallback/reference but must not replace GRB for professional building QA where GRB is available.
### Sprint 1
- No live OSM required.
- Keep adapter boundary ready.
### Later
- Use Overpass or local extracts for bounded areas.
- Cache in PostGIS.
## Sentinel strategy
Sentinel belongs to the Remote Sensing Lab, not Sprint 1.
### Sprint 1
- No Sentinel automation.
- Do not add Copernicus dependencies.
### Later
- Prefer STAC-based lookup where possible.
- Support NDVI/NDWI/NDBI through raster pipeline.
- Cache downloaded scenes/derived rasters.
## DHMV / height data strategy
DHMV/DEM/DSM belongs after raster/vector foundations are stable.
### Sprint 1
- No height integration.
### Later
- Add DEM/DSM products as raster datasets.
- Reuse raster metadata, clipping and tiling pipelines.
## Data acquisition acceptance criteria
A new data source is accepted only when it has:
- adapter boundary;
- source metadata;
- cache strategy;
- error handling;
- tests or fixture equivalent;
- documentation update.
+75
View File
@@ -0,0 +1,75 @@
# FOLDER OWNERSHIP AND RESPONSIBILITIES
Codex must keep responsibilities separated.
## `backend/app/api/`
HTTP routes only. No heavy business logic.
## `backend/app/schemas/`
Pydantic request/response models and API DTOs.
## `backend/app/models/`
Database ORM models.
## `backend/app/services/`
Business logic and orchestration.
## `backend/app/repositories/`
Database access patterns if repository layer is used.
## `backend/app/workers/`
RQ/Celery/background job entry points.
## `backend/app/geo/`
GIS-specific helpers: CRS, geometry validation, bounds, area calculations.
## `backend/app/storage/`
File storage logic.
## `backend/tests/`
Backend tests. Tests should not live beside production modules unless project conventions are changed deliberately.
## `frontend/src/pages/`
Route-level pages.
## `frontend/src/components/`
Reusable UI components.
## `frontend/src/features/`
Feature-oriented frontend modules, e.g. projects, datasets, map, exports.
## `frontend/src/services/`
API client/services.
## `frontend/src/stores/`
Client state only if needed.
## `docs/`
Architecture, specs and governance. Update docs when contracts or build rules change.
## `demo/`
Small golden fixtures and demo manifests. Not production storage.
## `datasets/`
Local development data folders. Do not commit large real datasets.
## `storage/`
Runtime storage. Keep `.gitkeep`, do not commit generated artifacts.
@@ -0,0 +1,67 @@
# GOLDEN DATASET PACKAGE
The golden dataset package defines the stable demo/test inputs that Codex must protect.
## Purpose
Golden data allows Codex to build and test without depending on live external services.
## Golden area
`demo/geel/area_geel_center.geojson`
Represents the canonical Sprint 1 area fixture. It must remain valid GeoJSON.
## Golden reference layer
`demo/geel/reference_buildings.geojson`
Represents reference building polygons. In future this will map to GRB-like reference data.
Required properties:
- stable feature IDs where possible;
- polygon or multipolygon geometry;
- deterministic feature count;
- valid geometries.
## Golden prediction layer
`demo/geel/demo_detections.geojson`
Represents predicted building detections or imported detection outputs.
Required properties:
- class label;
- confidence where available;
- polygon or bbox-derived polygon geometry;
- stable enough for QA/QC fixture checks.
## Golden expected metrics
`demo/geel/expected_qaqc_metrics.json`
Represents expected QA/QC output for the demo fixture. Codex may update this only if:
- the fixture geometry intentionally changes;
- the QA/QC algorithm version changes;
- changelog explains the reason.
## Golden data rules
- Do not delete golden fixtures.
- Do not replace golden fixtures with random generated data.
- Do not make tests depend on external services when golden fixtures are sufficient.
- Keep fixtures small enough for fast CI/smoke runs.
- If new fixture files are added, update `docs/DEMO_FIXTURE_MANIFEST.md`.
## Sprint 1 usage
Codex should use golden data for:
- frontend map layer smoke display;
- backend fixture validation;
- dataset metadata extraction tests;
- future QA/QC regression tests;
- export contract tests.
@@ -0,0 +1,83 @@
# MODULE ACCEPTANCE CRITERIA
This document defines when a module is considered done enough to move forward.
## Backend foundation
Done when:
- app imports without error;
- health endpoint works;
- config is environment-driven;
- response envelope is used;
- error shape is canonical;
- backend smoke test exists.
## Database foundation
Done when:
- database connection is configured;
- PostGIS is enabled or checked;
- migrations exist;
- core tables can be created;
- geometry storage works;
- tests or smoke checks exist.
## Project Manager
Done when:
- project create/list/read works;
- invalid payloads return canonical errors;
- frontend can display projects;
- tests cover at least one create/list/read path.
## Area Manager
Done when:
- valid GeoJSON polygon can be stored;
- invalid geometry is rejected;
- bounds or area metadata is returned where practical;
- geometry is stored in PostGIS;
- frontend can display at least one area on the map.
## Dataset Manager
Done when:
- GeoJSON dataset can be registered/uploaded;
- metadata is extracted;
- metadata is persisted;
- original file or reference is stored;
- dataset state follows the state machine;
- frontend can list datasets.
## Map Workbench Foundation
Done when:
- MapLibre renders;
- fixture layer can be displayed;
- layer loading state exists;
- error state exists;
- map controls do not break layout.
## Export baseline
Done when:
- at least one valid GeoJSON export path exists;
- export file is stored or streamed consistently;
- export metadata is recorded or returned;
- invalid export requests fail gracefully.
## QA/QC skeleton
Done when:
- schema for reference and prediction layers is documented/implemented;
- no live AI inference is required;
- future QA engine can plug into analysis run structure;
- fixture metrics can be validated if implemented.
+68
View File
@@ -0,0 +1,68 @@
# RELEASE STRATEGY
GeoIntel releases must be small, testable and aligned with the build order graph.
## Version targets
### v0.1 — Foundation
- Backend starts.
- Frontend starts.
- Database/PostGIS works.
- Health/readiness works.
### v0.2 — Project and Area Manager
- Project CRUD.
- Area CRUD.
- Geometry persistence.
- Map displays area fixtures.
### v0.3 — Dataset Manager
- GeoJSON upload/register.
- Metadata extraction.
- Dataset list/detail UI.
### v0.4 — Raster/Vector Foundation
- Raster metadata skeleton if dependencies are available.
- Vector operations baseline.
- Layer display improvements.
### v0.5 — Detection Import / Detection Lab Skeleton
- Detection result import.
- Detection layer display.
- Model-adapter boundary, no heavy inference required yet.
### v0.6 — QA/QC Foundation
- Reference vs prediction matching.
- Metrics.
- False positive/false negative outputs.
### v0.7 — GeoJSON Export and Review
- Stable export workflow.
- Export validation.
- Basic review UI.
### v1.0 — GeoAI Workbench MVP
- Stable dataset workflow.
- Raster/vector foundations.
- Detection/segmentation architecture.
- QA/QC workflow.
- Export workflow.
- Portfolio-ready demo.
## Release rule
A release cannot be cut if:
- readiness checks fail;
- golden paths regress;
- docs are stale;
- API contracts drift without documentation;
- known limitations are hidden.
+82
View File
@@ -0,0 +1,82 @@
# RISK REGISTER
This register captures known build and product risks before the first implementation run.
## R1 — Scope creep during first Codex run
Impact: high.
Mitigation:
- Follow `SPRINT_1_SCOPE_FREEZE.md`.
- Use `CODEX_STOP_RULES.md`.
- Add out-of-scope items to backlog.
## R2 — External data source instability
Impact: medium/high.
Mitigation:
- Use golden fixtures in Sprint 1.
- Add live adapters later.
- Cache retrieved external data.
## R3 — GIS CRS mistakes
Impact: high.
Mitigation:
- Follow `docs/specs/GIS_STANDARDS.md`.
- Validate geometries.
- Store SRID explicitly.
- Test fixture bounds.
## R4 — Raster files too large
Impact: medium.
Mitigation:
- No heavy raster processing in Sprint 1.
- Use tiling strategy later.
- Enforce file size limits when upload is implemented.
## R5 — AI modules introduced too early
Impact: high.
Mitigation:
- Keep live inference out of Sprint 1.
- Implement adapter boundaries only when needed.
- Use imported demo detections before live models.
## R6 — Frontend becomes dashboard-first
Impact: medium.
Mitigation:
- Follow Constitution: data -> processing -> QA/QC -> export.
- Map supports analysis; it is not the product by itself.
## R7 — Mock data becomes permanent
Impact: high.
Mitigation:
- Golden fixtures are contract data, not fake product behavior.
- Mark demo/fixture paths clearly.
- Production endpoints must use persisted data.
## R8 — Too many competing docs
Impact: medium.
Mitigation:
- Follow `CODEX_START.md` and `docs/00-start/START_HERE.md`.
- M14 launch docs supersede older first-run plans where conflicts exist.
@@ -0,0 +1,97 @@
# SPRINT 1 SCOPE FREEZE
This document freezes the first implementation scope. Codex must not expand Sprint 1 beyond this boundary.
## Sprint 1 goal
Build the GeoIntel foundation vertical slice: a locally runnable app that proves project, area, dataset, PostGIS and map foundations.
## Must build
### Backend foundation
- FastAPI app skeleton.
- Settings/config module.
- Structured logging baseline.
- Health/readiness endpoint.
- API response envelope.
- Error handling middleware or equivalent.
- CORS configuration for local frontend.
### Database foundation
- PostgreSQL/PostGIS connection.
- Migration tooling.
- Core models/schemas for projects, areas and datasets.
- Geometry persistence.
- Minimal seed/fixture support.
### Project and area workflow
- Create/list/read project.
- Create/list/read area.
- Store area geometry.
- Validate geometry.
- Return area metadata such as area size where practical.
### Dataset workflow
- Register/upload GeoJSON dataset.
- Store original file or registered reference.
- Extract metadata:
- dataset type;
- feature count;
- geometry type;
- CRS if available;
- bounds.
- Persist metadata.
### Frontend foundation
- Vite/React/TypeScript app.
- Main shell/layout.
- MapLibre map.
- Project workspace page.
- Dataset manager page/panel.
- Minimal layer display using demo GeoJSON.
- API client.
### Tooling
- Docker Compose for DB and services.
- README quickstart updated if implementation changes commands.
- `make readiness` remains green.
- Basic tests/smoke scripts.
## Should build if Sprint 1 musts are complete
- Area import from fixture.
- GeoJSON export endpoint for area or dataset features.
- Minimal QA placeholder that validates reference vs prediction fixture schema, but does not run full QA engine yet.
- Frontend layer opacity toggle.
## May build only if zero risk
- Demo fixture loader.
- Simple statistics card for feature count and area.
- Simple project status panel.
## Must not build in Sprint 1
- YOLO live inference.
- SAM live segmentation.
- Sentinel/STAC integration.
- GRB live WFS client.
- DHMV integration.
- LiDAR LAS/LAZ processing.
- Training Studio.
- Model registry UI.
- AI Copilot.
- Advanced PDF reports.
- Multi-user authentication.
- Role-based permissions.
- Production Kubernetes/deployment stack.
## Scope conflict rule
If a task seems useful but is not listed under `Must`, `Should` or `May`, Codex must not implement it in Sprint 1. Add it to backlog/open issues instead.
+66
View File
@@ -0,0 +1,66 @@
# Acceptance Criteria
## Milestone M1 — Working foundation
M1 is accepted when:
- backend starts successfully;
- frontend starts successfully;
- project can be created;
- area can be added as polygon;
- dataset can be uploaded or fixture-imported;
- metadata is persisted;
- basic map/workbench UI exists;
- tests cover project/area basics.
## Milestone M2 — Raster/vector foundation
M2 is accepted when:
- vector data can be imported;
- raster metadata can be read;
- CRS/bounds/resolution are visible;
- area/length calculations use metric CRS;
- vector clipping works;
- raster clipping either works or fails with a clear limitation message;
- outputs are persisted as artifacts.
## Milestone M3 — Detection foundation
M3 is accepted when:
- a detection run can be started;
- detections are persisted with class, confidence and geometry;
- detections can be visualized/listed;
- detections can be exported as GeoJSON;
- provider interface supports future YOLO implementation.
## Milestone M4 — QA/QC foundation
M4 is accepted when:
- predictions can be compared with a reference layer;
- IoU matching works;
- precision, recall and F1 are calculated;
- false positives and false negatives are available as separate findings/layers;
- unit tests cover edge cases.
## Milestone M5 — End-to-end demo
M5 is accepted when Demo 1 runs from UI:
1. Open project.
2. Select area.
3. Load raster/reference fixtures.
4. Run detection.
5. Run QA/QC against reference.
6. View map/results.
7. Export GeoJSON and summary.
## Quality gates
Before any handoff:
- no syntax errors;
- no obvious broken imports;
- backend test suite run;
- frontend build/typecheck run if available;
- docs updated;
- limitations documented.
## Rejection criteria
Reject a build if:
- core pages are placeholder-only;
- endpoints return hardcoded success without persisted data;
- geospatial outputs lack CRS metadata;
- code ignores service boundaries;
- major errors are hidden from UI;
- a feature claims GRB/YOLO/SAM support without provider separation or explicit development-provider labeling.
+62
View File
@@ -0,0 +1,62 @@
# Acceptance Matrix
## Foundation
Accepted when:
- Backend starts.
- Frontend starts.
- Database connects.
- Health endpoint works.
- Environment variables are documented.
## Dataset Manager
Accepted when:
- Datasets can be registered and listed.
- Upload status is persisted.
- Metadata extraction is visible.
- Unsupported files are rejected cleanly.
## Map Workbench
Accepted when:
- Areas can be displayed as GeoJSON.
- Layers can be toggled.
- Selected features show metadata.
## Raster Lab
Accepted when:
- Raster metadata is extracted.
- Raster bounds are shown.
- Clip job can be queued.
- Raster artifacts are stored predictably.
## Vector Lab
Accepted when:
- GeoJSON fixture imports.
- Clip/intersection operation works.
- Area/length metrics are correct.
## Detection Lab
Accepted when:
- Detection run can be created.
- Results are stored as geospatial features.
- Confidence threshold is respected.
- GeoJSON export works.
## QA/QC Lab
Accepted when:
- Prediction/reference matching works.
- Precision/recall/F1/IoU are calculated.
- False positives and false negatives are visible.
+66
View File
@@ -0,0 +1,66 @@
# Acceptance Test Catalog
## Foundation
- Health endpoint returns application status.
- API error responses follow the standard envelope.
- CORS is configured for frontend local development.
- Database connection failure is reported but does not crash import-time tests.
## Projects
- Create project with valid payload.
- Reject empty name.
- List projects sorted by newest first.
- Get missing project returns 404 envelope.
## Areas
- Create area from valid Polygon GeoJSON.
- Reject invalid geometry.
- Store geometry with expected SRID.
- Return FeatureCollection for project areas.
## Datasets
- Upload supported vector file.
- Extract geometry type, feature count, bounds and CRS when available.
- Reject unsupported extension with explicit error code.
- Dataset status transitions: uploaded -> metadata_extracted -> ready or failed.
## Raster
- Read raster metadata when valid raster available.
- Return band count, bounds, CRS, width, height and resolution.
- Clip request creates a processing job.
- Tile request creates deterministic tile manifest.
## Vector
- Read vector metadata from GeoJSON fixture.
- Clip vector features to area.
- Buffer vector features by distance in meters.
- Intersect two vector layers.
## Detection
- Create detection analysis run.
- Demo-mode detector creates stable predictions.
- Detections include class, confidence, geometry and source tile.
- Detection outputs are exportable as GeoJSON.
## Segmentation
- Create segmentation analysis run.
- Demo-mode segmenter creates stable polygons.
- Segmentations include class, area_m2, confidence and optional mask path.
## QA/QC
- Match detection to reference by IoU threshold.
- Calculate TP, FP, FN.
- Calculate precision, recall and F1.
- Generate false positive and false negative layers.
## Frontend
- Every route has loading, empty, error and success states.
- Project creation navigates to workspace.
- Map page can render GeoJSON area fixture.
- Dataset detail shows extracted metadata.
- Analysis status updates are visible.
## Export
- GeoJSON export returns downloadable file.
- CSV metrics export includes metric key, value and unit.
- Export records are listed in project exports.
+232
View File
@@ -0,0 +1,232 @@
# AI Pipelines
## 1. Object Detection Pipeline
```text
Raster dataset
↓
Clip to analysis area
↓
Tile raster
↓
Normalize tiles
↓
Run YOLO/PyTorch inference
↓
Filter by confidence
↓
Convert pixel boxes to geospatial polygons
↓
Merge overlapping detections
↓
Store in PostGIS
↓
Expose as GeoJSON layer
↓
Run QA/QC if reference data exists
```
### Sprint 8 foundation status
Sprint 8 implements the detection persistence and execution boundary only:
- `detections` are first-class PostGIS records linked to project, dataset, job and analysis run.
- `analysis_runs` remain separate from jobs and store model metadata, parameters, result summaries and lifecycle status.
- `yolo-placeholder` reports `not_configured`; no YOLO/PyTorch model is downloaded or executed.
- `manual-fixture-detector` is test/demo-only and persists detections only when `fixture_mode=true` and fixture detections are explicitly supplied.
- Normal application behavior must not create fake detections.
### Sprint 8B configured YOLO status
Sprint 8B adds an import-safe real YOLO adapter path:
- `ultralytics` and `torch` are optional backend extras, not default runtime dependencies.
- `yolo-configured` reports `not_configured` until `YOLO_ENABLED=true`, `YOLO_MODEL_PATH` points to an existing local model file and optional AI dependencies are installed.
- GeoIntel never downloads model weights automatically.
- Real YOLO inference uses an existing raster tile manifest generated by the raster tile operation.
- YOLO pixel boxes are converted to EPSG:4326 detection polygons from tile transform or tile bounds metadata.
- Detection runs remain synchronous behind the existing job and analysis-run persistence boundary for Sprint 8B.
### Sprint 13 YOLO operational preflight
Sprint 13 adds a local preflight command for configured YOLO operation:
```bash
python scripts/yolo_preflight.py --model-path /absolute/path/to/model.pt --tile-manifest-path /absolute/path/to/manifest.json
```
For machines without optional AI dependencies, path and manifest checks can be exercised without pretending inference is available:
```bash
python scripts/yolo_preflight.py --model-path /absolute/path/to/model.pt --tile-manifest-path /absolute/path/to/manifest.json --assume-dependencies --json
```
The preflight checks:
- `YOLO_ENABLED` / explicit enabled state;
- optional dependency availability unless `--assume-dependencies` is used;
- local model file existence;
- tile manifest JSON validity;
- tile count against `YOLO_MAX_TILES`;
- referenced tile file existence.
The preflight does not load the model, does not import Ultralytics unless dependency discovery requires package metadata, does not run inference and never downloads model weights.
Environment variables:
- `YOLO_ENABLED`
- `YOLO_MODEL_PATH`
- `YOLO_MODEL_ID`
- `YOLO_MODEL_DISPLAY_NAME`
- `YOLO_MODEL_VERSION`
- `YOLO_DEVICE`
- `YOLO_IMAGE_SIZE`
- `YOLO_MAX_TILES`
- `YOLO_BATCH_SIZE`
### Sprint 8C detection visualization and QA status
Sprint 8C makes persisted detections reviewable:
- Detection runs can be listed and selected.
- Persisted detections can be listed and filtered by run, dataset, class and minimum confidence.
- Persisted detection geometries can be returned as GeoJSON FeatureCollections for MapLibre display.
- Detection QA compares candidate detection geometries against persisted reference `vector_features`.
- QA results reuse `quality_checks` and `metrics`; no parallel QA persistence system is introduced.
- Segmentation remains out of scope for Sprint 8C.
## 2. Tile Metadata
Elke tile moet opslaan:
- tile path
- parent raster id
- pixel window
- geospatial bounds
- transform
- CRS
- tile size
- overlap
Zonder tile metadata kunnen modeloutputs niet correct teruggeprojecteerd worden.
## 3. Detection Output Contract
Elke detectie bevat:
- class_name
- confidence
- bbox pixel coords
- source tile
- geospatial polygon
- model id/version
- analysis run id
## 4. Segmentation Pipeline
```text
Raster dataset
↓
Clip/tile
↓
Run segmentation model
↓
Generate mask
↓
Georeference mask
↓
Polygonize mask
↓
Simplify/clean geometries
↓
Store polygons + mask path
↓
Expose as map layer
```
### Sprint 9 segmentation foundation status
Sprint 9 implements the segmentation persistence and review boundary only:
- `segmentations` are first-class PostGIS records linked to project, dataset, job and analysis run.
- PostGIS MultiPolygon geometry in EPSG:4326 is authoritative for map display, QA and GeoJSON output.
- Mask paths are persisted as artifact/provenance references, not authoritative feature state.
- `segmentation-placeholder`, `yolo-seg-configured` and `sam-configured` report `not_configured`.
- `fixture-segmenter` is test/demo-only and persists segmentations only when `fixture_mode=true` and fixture segmentations are explicitly supplied.
- Segmentation QA compares persisted segmentation geometries against persisted reference `vector_features`.
- QA results reuse `quality_checks` and `metrics`; no parallel QA system is introduced.
- GeoIntel does not install SAM, run YOLO-seg, download model weights or fake production segmentations in Sprint 9.
## 5. Change Detection Pipeline
Fase 1: vector/detection based.
```text
Run A detections
+
Run B detections
↓
Spatial matching
↓
added / removed / changed
↓
Change polygons
↓
Metrics
```
Fase 2: raster index based.
```text
Raster A index
+
Raster B index
↓
Difference raster
↓
Threshold
↓
Polygonize changed zones
```
Fase 3: segmentation based.
```text
Mask A
+
Mask B
↓
Class difference
↓
Change polygons
```
## 6. Model Strategy
V1:
- gebruik een bestaande YOLO-integratie met configureerbaar modelpad
- demo-model mag lokaal worden geplaatst in `models/`
- code moet ook zonder model kunnen starten, maar detection job moet dan duidelijke fout geven
V2:
- SAM/YOLO segmentation
V3:
- annotation export
- finetuning
## 7. Reproduceerbaarheid
Elke analysis run moet bewaren:
- model id
- model version
- parameters
- confidence threshold
- tile size
- overlap
- input dataset id
- code path/version indien mogelijk
+160
View File
@@ -0,0 +1,160 @@
# Analysis Engine
De Analysis Engine bevat alle reproduceerbare berekeningen. AI mag interpretaties schrijven, maar de cijfers komen uit deze engine.
## 1. BuildingAnalyzer
### Input
- gebouwpolygonen uit GRB, OSM of detecties
- analysegebied
### Output metrics
```json
{
"building_count": 123,
"building_area_total_m2": 45678.9,
"building_density_per_km2": 87.2,
"average_building_area_m2": 371.4,
"built_ratio": 0.23
}
```
## 2. RoadAnalyzer
### Input
- wegvectoren
- analysegebied
### Output
- totale weglengte
- wegendichtheid
- verdeling per wegtype
- nabijheid tot hoofdwegen
## 3. RasterAnalyzer
### Input
- rasterdataset
- analysegebied
### Output
- metadata
- bounds
- resolutie
- bandstatistieken
- histogram
- nodata-percentage
## 4. VegetationAnalyzer
### Input
- NDVI-raster of vegetatiesegmentatie
### Output
- vegetatieoppervlakte
- vegetatiepercentage
- gemiddelde NDVI
- lage vegetatiegebieden
- hoge vegetatiegebieden
## 5. WaterAnalyzer
### Input
- waterpolygonen of NDWI-raster
### Output
- wateroppervlakte
- waterpercentage
- afstand tot water
- waterverandering later
## 6. DetectionAnalyzer
### Input
- detecties
- analysegebied
### Output
- aantal per klasse
- gemiddelde confidence
- confidence distributie
- oppervlakte per klasse indien polygonen beschikbaar
- detectiedichtheid
## 7. SegmentationAnalyzer
### Input
- mask/polygon segmentaties
### Output
- oppervlakte per klasse
- segment count
- gemiddelde confidence
- dekking binnen analysegebied
## 8. QAAnalyzer
### Input
- AI-output
- referentielaag
- IoU threshold
### Output
```json
{
"true_positives": 100,
"false_positives": 8,
"false_negatives": 12,
"precision": 0.9259,
"recall": 0.8928,
"f1": 0.9090,
"mean_iou": 0.71
}
```
### Regels
- Een detectie matcht met een referentieobject als IoU >= threshold.
- Meerdere detecties op één referentieobject moeten gededupliceerd worden.
- Niet-gematchte detecties zijn false positives.
- Niet-gematchte referentieobjecten zijn false negatives.
## 9. ChangeAnalyzer
### Input
- analysis run A
- analysis run B
### Output
- added objects
- removed objects
- changed objects
- changed area
- change density
## 10. ScoreEngine later
Scores zijn niet de primaire focus voor de vacaturegerichte versie, maar kunnen later worden toegevoegd:
- Open Space Pressure Score
- Urban Expansion Score
- Nature Connectivity Score
- Water Resilience Score
+250
View File
@@ -0,0 +1,250 @@
# GeoIntel Kempen — Analysis Specifications v1.0
This file defines exact inputs, outputs and formulas for the first implementation of the analysis engine.
## Global rules
- All area-based metrics must be calculated in a projected CRS suitable for Belgium/Flanders, preferably EPSG:31370 internally for metric calculations.
- Store geometries consistently and transform only at API/render boundaries when needed.
- All metrics must include unit, input dataset ids, analysis run id and calculation parameters.
- Never let the AI copilot invent metrics. Metrics must come from the analysis engine.
## AreaAnalyzer
### Input
- Area polygon.
### Output metrics
| Key | Unit | Formula |
|---|---|---|
| `area_m2` | m² | `ST_Area(area.geometry)` |
| `area_km2` | km² | `area_m2 / 1_000_000` |
| `perimeter_m` | m | `ST_Perimeter(area.geometry)` |
| `bbox` | geometry/json | calculated bounds |
## BuildingAnalyzer
### Input
- Area polygon.
- Building polygons from GRB, OSM, user vector layer, or AI segmentation/detection polygons.
### Processing
1. Clip building geometries to area.
2. Remove invalid geometries or repair with `make_valid`.
3. Calculate per-building clipped area.
4. Aggregate.
### Output metrics
| Key | Unit | Formula |
|---|---|---|
| `building_count` | count | number of building features intersecting area |
| `building_area_total_m2` | m² | sum clipped building area |
| `building_area_total_ha` | ha | `building_area_total_m2 / 10000` |
| `building_coverage_ratio` | ratio | `building_area_total_m2 / area_m2` |
| `building_density_per_km2` | count/km² | `building_count / area_km2` |
| `mean_building_area_m2` | m² | `building_area_total_m2 / building_count` |
| `largest_building_area_m2` | m² | max building area |
### Output layers
- `buildings_clipped`
- `building_centroids`
- `large_buildings_top_20`
## RoadAnalyzer
### Input
- Area polygon.
- Road line or polygon features.
### Output metrics
| Key | Unit | Formula |
|---|---|---|
| `road_length_total_m` | m | sum clipped road lengths |
| `road_length_total_km` | km | `/1000` |
| `road_density_km_per_km2` | km/km² | `road_length_total_km / area_km2` |
| `major_road_length_km` | km | filtered by road class if available |
### Output layers
- `roads_clipped`
- `major_roads_clipped`
## GreenAnalyzer
### Input options
- Green polygons from OSM/GRB/landuse.
- NDVI raster threshold result.
- Segmentation polygons classified as vegetation.
### Output metrics
| Key | Unit | Formula |
|---|---|---|
| `green_area_total_m2` | m² | sum green polygons clipped to area |
| `green_ratio` | ratio | `green_area_total_m2 / area_m2` |
| `green_patch_count` | count | number of disjoint green patches |
| `largest_green_patch_m2` | m² | max patch area |
| `green_fragmentation_index` | index | `green_patch_count / max(green_area_total_ha, 0.01)` |
### Interpretation
High fragmentation means green is split into many smaller patches.
## WaterAnalyzer
### Input
- Water polygons/lines from GRB/OSM.
- NDWI threshold polygons later.
### Output metrics
| Key | Unit | Formula |
|---|---|---|
| `water_area_total_m2` | m² | sum clipped water polygon area |
| `water_ratio` | ratio | `water_area_total_m2 / area_m2` |
| `watercourse_length_m` | m | sum water line length |
| `distance_to_nearest_water_m` | m | minimum distance from area centroid to water geometry |
## RasterAnalyzer
### Input
- Raster dataset.
- Optional area polygon.
### Output metrics
Per band:
| Key | Unit |
|---|---|
| `band_min` | band unit |
| `band_max` | band unit |
| `band_mean` | band unit |
| `band_std` | band unit |
| `nodata_ratio` | ratio |
### Required operations
- Read metadata.
- Clip by area.
- Compute statistics.
- Generate preview tile or PNG.
## RemoteSensingIndexAnalyzer
### NDVI
Formula:
```text
NDVI = (NIR - Red) / (NIR + Red)
```
Output:
- `ndvi_mean`
- `ndvi_median`
- `ndvi_low_ratio` using threshold configurable, default `< 0.2`
- `ndvi_high_ratio` using threshold configurable, default `> 0.5`
- vectorized high/low vegetation zones later
### NDWI
```text
NDWI = (Green - NIR) / (Green + NIR)
```
### NDBI
```text
NDBI = (SWIR - NIR) / (SWIR + NIR)
```
## DetectionAnalyzer
### Input
- Detection records with class, confidence and geometry.
- Area polygon.
### Output metrics
| Key | Unit | Formula |
|---|---|---|
| `detection_count` | count | detections within area |
| `detection_count_by_class` | json | group by class |
| `mean_confidence` | ratio | average confidence |
| `low_confidence_count` | count | confidence below threshold |
| `detected_area_m2_by_class` | json | sum polygon area where available |
## ScoreEngine v1
The score engine must be transparent. Every score returns value, inputs, weights and explanation.
### Open Space Pressure Score
Default weights:
```yaml
building_coverage_ratio: 0.35
road_density_normalized: 0.25
green_ratio_inverse: 0.25
urban_growth_normalized: 0.15
```
Score:
```text
100 * weighted_sum(normalized_factors)
```
### Nature Connectivity Score
Default weights:
```yaml
green_ratio: 0.35
largest_green_patch_ratio: 0.25
fragmentation_inverse: 0.25
major_road_barrier_inverse: 0.15
```
### Water Resilience Score
Default weights:
```yaml
green_ratio: 0.30
water_buffer_presence: 0.20
impervious_inverse: 0.30
low_point_risk_inverse: 0.20
```
V1 may calculate a simplified score without height data by marking height-dependent factors as unavailable.
## Metric storage contract
Each metric row must include:
```json
{
"analysis_run_id": "uuid",
"key": "building_density_per_km2",
"value": 123.4,
"unit": "count/km2",
"method": "BuildingAnalyzer.v1",
"inputs": ["dataset_uuid"],
"parameters": {},
"quality_flags": []
}
```
+972
View File
@@ -0,0 +1,972 @@
# API Contracts v1
This document freezes the first API shape. Codex may add implementation details but must not rename these routes without updating this file and the frontend API client.
## API principles
- Base path: `/api/v1`.
- JSON by default.
- GeoJSON accepted for geometries where possible.
- Long processing tasks return a job or analysis run record instead of blocking.
- Error responses use the shared `ApiError` schema.
## Shared schemas
### ApiError
```json
{
"error": "string",
"message": "human readable message",
"details": {},
"request_id": "optional string"
}
```
### GeoJsonGeometry
Any valid GeoJSON geometry object. V1 primarily expects `Polygon` and `MultiPolygon` for areas.
### BoundingBox
```json
{
"min_x": 0.0,
"min_y": 0.0,
"max_x": 0.0,
"max_y": 0.0,
"crs": "EPSG:4326"
}
```
## Health
### GET `/health`
Returns service status.
```json
{
"status": "ok",
"service": "geointel-backend",
"version": "0.1.0"
}
```
### GET `/api/v1/system/capabilities`
Returns enabled feature flags and tool availability.
```json
{
"postgis": true,
"rasterio": true,
"geopandas": true,
"yolo": false,
"sam": false,
"grb": "planned",
"sentinel": "planned",
"providers": [
{
"provider_name": "grb",
"display_name": "GRB",
"authority_level": "authoritative",
"supported_layers": ["buildings", "roads", "parcels"],
"supported_geometry_types": ["Polygon", "MultiPolygon", "LineString", "MultiLineString"],
"supported_query_modes": ["area"],
"fetch_signature": "POST /api/v1/external/grb/fetch",
"configured": false,
"status": "not_configured",
"limitation_message": "GRB live WFS/download integration is not configured in Sprint 7B.",
"attribution": "Digitaal Vlaanderen - Basiskaart Vlaanderen (GRB)",
"license_note": "Use must follow Digitaal Vlaanderen open data and attribution terms.",
"not_configured_reason": "Provider integration is not configured yet"
}
]
}
```
## Projects
### GET `/api/v1/projects`
Returns all projects.
### POST `/api/v1/projects`
Request:
```json
{
"name": "Geel building detection demo",
"description": "Detect buildings and validate against GRB",
"region": "Kempen"
}
```
Response: `ProjectRead`.
### GET `/api/v1/projects/{project_id}`
Returns one project with summary counts.
### PATCH `/api/v1/projects/{project_id}`
Updates name/description/region.
### DELETE `/api/v1/projects/{project_id}`
Soft-delete in V1 preferred. Hard-delete only if storage cleanup is also implemented.
## Areas
### GET `/api/v1/projects/{project_id}/areas`
Returns areas for a project.
### POST `/api/v1/projects/{project_id}/areas`
Request:
```json
{
"name": "Geel Centrum AOI",
"geometry": {"type": "Polygon", "coordinates": []},
"crs": "EPSG:4326"
}
```
Backend responsibilities:
- Validate geometry.
- Repair trivial polygon issues if safe.
- Store geometry in PostGIS.
- Calculate area in square meters using projected CRS.
- Store bbox.
## Datasets
### POST `/api/v1/projects/{project_id}/datasets/upload`
Multipart upload.
Fields:
- `file`: dataset file.
- `dataset_type`: `vector`, `geojson` (legacy), `raster`.
- `source`: free text, e.g. `user_upload`, `grb`, `osm`.
- `dataset_role`: `source`, `derived`, or `reference` (default `source`).
- `source_name`: optional source identity, e.g. `manual`, `grb`, `osm`; reference uploads default to `manual` when omitted.
- `reference_layer_name`: optional reference layer label, e.g. `buildings`; only retained for reference datasets.
- `area_id`: optional.
Response: `DatasetRead` with extracted metadata if supported.
Vector uploads remain stored as original files and are also persisted into `vector_features` as queryable PostGIS state.
### GET `/api/v1/projects/{project_id}/datasets`
List datasets.
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}`
Return metadata.
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/metadata/refresh`
Re-extract metadata.
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/inspect`
Return a wrapped vector inspection payload with metadata, storage summary and feature summary.
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/summary`
Return vector summary data only.
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/metadata`
Return raster metadata profile for supported raster uploads.
If raster processing is unavailable:
```text
code: RASTER_PROCESSING_UNAVAILABLE
message: Raster processing unavailable. Install rasterio and GDAL-compatible drivers to enable raster metadata extraction.
```
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/inspect`
Return raster inspect wrapper payload.
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/stats`
Return raster band statistics payload.
If raster processing dependencies are unavailable:
- code: `RASTER_PROCESSING_UNAVAILABLE`
- message: dependency-specific unavailable message.
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/preview`
Preview readiness for raster layers.
If preview dependencies are unavailable:
- code: `RASTER_PROCESSING_UNAVAILABLE`
- message: `Raster preview unavailable...`
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/clip`
Clip raster by selected area. Returns a `202`-style accepted job payload through the job wrapper (`jobs` create/read flow).
If raster processing dependencies are unavailable:
- code: `RASTER_PROCESSING_UNAVAILABLE`
- message: `Raster processing unavailable. Install rasterio and GDAL-compatible drivers to enable raster processing operations.`
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/reproject`
Reproject raster dataset to another CRS.
Input:
- `target_crs` (default: `EPSG:31370`)
- `resampling` (`nearest`, `bilinear`, `cubic`; default `nearest`)
- `output_name`
Returns a job payload with derived dataset id in `result.output_dataset_id`.
Failure modes:
- code: `INVALID_PARAMETERS` for bad CRS or resampling
- code: `INVALID_DATASET_CRS` when source raster CRS is missing
- code: `RASTER_PROCESSING_UNAVAILABLE` when rasterio is unavailable
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/indices/ndvi`
Compute NDVI from raster band pairs.
Input:
- `nir_band` (positive integer, 1-based)
- `red_band` (positive integer, 1-based)
- `output_name` (optional)
Returns a job payload with derived dataset id in `result.output_dataset_id`.
Failure modes:
- code: `INVALID_PARAMETERS` for non-positive/non-integer band indices
- code: `INVALID_PARAMETERS` for band index outside source band count
- code: `INVALID_DATASET_TYPE` when source is not raster
- code: `RASTER_PROCESSING_UNAVAILABLE` when rasterio or numpy is unavailable
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/indices/ndwi`
Compute NDWI from raster band pairs.
Input:
- `nir_band` (positive integer, 1-based)
- `green_band` (positive integer, 1-based)
- `output_name` (optional)
Returns a job payload with derived dataset id in `result.output_dataset_id`.
Failure modes:
- code: `INVALID_PARAMETERS` for non-positive/non-integer band indices
- code: `INVALID_PARAMETERS` for band index outside source band count
- code: `INVALID_DATASET_TYPE` when source is not raster
- code: `RASTER_PROCESSING_UNAVAILABLE` when rasterio or numpy is unavailable
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/indices/ndbi`
Compute NDBI from raster band pairs.
Input:
- `nir_band` (positive integer, 1-based)
- `swir_band` (positive integer, 1-based)
- `output_name` (optional)
Returns a job payload with derived dataset id in `result.output_dataset_id`.
Failure modes:
- code: `INVALID_PARAMETERS` for non-positive/non-integer band indices
- code: `INVALID_PARAMETERS` for band index outside source band count
- code: `INVALID_DATASET_TYPE` when source is not raster
- code: `RASTER_PROCESSING_UNAVAILABLE` when rasterio or numpy is unavailable
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/raster/tile`
Generate raster tiles and a manifest for downstream processing. Returns a job payload with `tile_set_id` and manifest metadata.
If raster processing dependencies are unavailable:
- code: `RASTER_PROCESSING_UNAVAILABLE`
- message: `Raster processing unavailable. Install rasterio and GDAL-compatible drivers to enable raster processing operations.`
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/clip`
Clip vector dataset to selected area.
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/buffer`
Apply buffer distance to vector features.
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/intersect`
Intersect source vector dataset with another vector dataset.
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/stats`
Return vector stats (feature counts and geometry summary).
### GET `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/bbox`
Return vector bounds and feature count.
## Jobs
### POST `/api/v1/projects/{project_id}/jobs`
Create a job.
### GET `/api/v1/projects/{project_id}/jobs`
List jobs.
### GET `/api/v1/projects/{project_id}/jobs/{job_id}`
Read job detail.
### GET `/api/v1/projects/{project_id}/jobs/{job_id}/status`
Read simplified job status payload.
## Provider registry
### GET `/api/v1/external/providers`
Returns all configured provider capability descriptors.
### GET `/api/v1/external/providers/capabilities`
Compatibility alias for listing provider capability descriptors.
### GET `/api/v1/external/providers/{provider_name}`
Returns one provider capability descriptor.
### GET `/api/v1/external/providers/{provider_name}/layers`
Returns the supported provider layers.
### GET `/api/v1/external/providers/{provider_name}/status`
Returns configured/status/limitation fields.
### POST `/api/v1/external/providers/{provider_name}/import`
Defines the future provider import contract. Sprint 7B does not perform live imports or write datasets.
Request:
```json
{
"project_id": "uuid-or-local-id",
"area_id": "optional uuid-or-local-id",
"layers": ["buildings"],
"dataset_role": "optional source|reference"
}
```
GRB/OSM response:
```json
{
"provider_name": "grb",
"status": "not_configured",
"message": "No live GRB import is configured in Sprint 7B.",
"requested_layers": ["buildings"],
"dataset_id": null,
"dataset_role": "reference",
"source_name": "grb"
}
```
Manual and fixture providers point callers to existing upload/fixture flows. No provider writes directly to `vector_features`; all future provider output must flow through `DatasetService` and `VectorFeatureService`.
## External data fetchers
### POST `/api/v1/external/osm/fetch`
Request:
```json
{
"project_id": "uuid",
"area_id": "uuid",
"layers": ["buildings", "roads", "water", "green"]
}
```
### POST `/api/v1/external/grb/fetch`
Request:
```json
{
"project_id": "uuid",
"area_id": "uuid",
"layers": ["buildings"]
}
```
V1 may initially implement this as a service interface with a clear `not_configured` response until the exact WFS endpoint is wired.
Sprint 7B provider contract responses expose capabilities only. Providers must report:
```json
{
"provider_name": "osm",
"display_name": "OpenStreetMap",
"authority_level": "contextual",
"supported_layers": ["buildings", "roads", "water", "landuse"],
"supported_geometry_types": ["Polygon", "MultiPolygon", "LineString", "MultiLineString"],
"supported_query_modes": ["area"],
"configured": false,
"status": "not_configured",
"limitation_message": "OSM live Overpass/download integration is not configured in Sprint 7B.",
"attribution": "OpenStreetMap contributors",
"license_note": "OpenStreetMap data is available under ODbL; attribution is required."
}
```
No GRB WFS, OSM Overpass or provider downloads are implemented in Sprint 7B.
## Demo workflow
### POST `/api/v1/demo/workflow`
Seeds an explicit offline demo workflow from local fixture files. This endpoint
does not fetch live GRB/OSM data and does not run AI inference. It creates or
returns:
- one demo project
- one demo AOI
- one fixture reference building dataset
- one fixture candidate/predicted building dataset
- one persisted QA/QC result with metric rows
The endpoint is idempotent for the named demo project.
Response:
```json
{
"project_id": "uuid",
"area_id": "uuid",
"reference_dataset_id": "uuid",
"candidate_dataset_id": "uuid",
"quality_check_id": "uuid",
"metric_count": 6,
"status": "ready",
"message": "Demo workflow seeded from explicit local fixtures.",
"created": true
}
```
## Analysis
## Detection Lab
Sprint 8 implements Detection Lab foundation only. YOLO/PyTorch real inference is not enabled, no model is downloaded, and fixture detections require explicit fixture mode.
### GET `/api/v1/detection/models`
Returns object-detection model capability descriptors.
```json
{
"models": [
{
"model_id": "yolo-placeholder",
"display_name": "YOLO detector placeholder",
"framework": "ultralytics/pytorch",
"task_type": "object_detection",
"supported_classes": ["building", "road", "water", "landuse"],
"configured": false,
"status": "not_configured",
"limitation_message": "YOLO/PyTorch inference is not configured in Sprint 8; no model is downloaded or executed.",
"version": null
},
{
"model_id": "yolo-configured",
"display_name": "Configured YOLO detector",
"framework": "ultralytics/pytorch",
"task_type": "object_detection",
"supported_classes": ["building", "road", "water", "landuse"],
"configured": false,
"status": "not_configured",
"limitation_message": "YOLO is disabled. Set YOLO_ENABLED=true and YOLO_MODEL_PATH to a local model file to enable inference.",
"version": null
}
]
}
```
### POST `/api/v1/detection/run`
Creates a detection job and detection analysis run. If the requested model is unavailable, the job and analysis run are marked `failed` with `DETECTION_MODEL_UNAVAILABLE` or `DETECTION_DEPENDENCY_UNAVAILABLE`.
Request:
```json
{
"project_id": "uuid",
"dataset_id": "uuid",
"model_id": "yolo-placeholder",
"confidence_threshold": 0.5,
"class_filter": ["building"],
"tile_manifest_path": null,
"parameters_json": {}
}
```
Sprint 8B configured YOLO mode uses `model_id: "yolo-configured"`. It requires:
- `YOLO_ENABLED=true`
- `YOLO_MODEL_PATH` pointing to an existing local model file
- backend optional AI dependencies installed with `geointel-backend[ai]`
- `tile_manifest_path` pointing to an existing raster tile manifest generated by the raster tile operation
GeoIntel does not download model weights automatically. Configured YOLO runs read existing tile files from the manifest, convert YOLO pixel-space boxes to EPSG:4326 detection polygons and persist detections as first-class records.
Unavailable model response:
```json
{
"analysis_run_id": "uuid",
"job_id": "uuid",
"project_id": "uuid",
"dataset_id": "uuid",
"model_id": "yolo-placeholder",
"status": "failed",
"detection_count": 0,
"error_code": "DETECTION_MODEL_UNAVAILABLE",
"message": "YOLO/PyTorch inference is not configured in Sprint 8; no model is downloaded or executed."
}
```
Validation errors:
- `INVALID_DATASET_TYPE` when the dataset is not raster.
- `DETECTION_MODEL_NOT_FOUND` when the model id is unknown.
- `FIXTURE_MODE_REQUIRED` when `manual-fixture-detector` is requested without `parameters_json.fixture_mode=true`.
- `DETECTION_TILE_MANIFEST_REQUIRED` when `yolo-configured` is requested without `tile_manifest_path`.
- `DETECTION_TILE_MANIFEST_NOT_FOUND` when the provided manifest path does not exist.
- `DETECTION_TILE_MANIFEST_INVALID` when the manifest cannot be parsed or lacks tile metadata.
- `DETECTION_TILE_LIMIT_EXCEEDED` when the manifest exceeds `YOLO_MAX_TILES`.
- `DETECTION_DEPENDENCY_UNAVAILABLE` when YOLO dependencies are not installed.
- `DETECTION_MODEL_LOAD_FAILED` when the local model file exists but cannot be loaded.
Fixture detector mode is test/demo-only. It persists only explicit `parameters_json.fixture_detections` entries and is never invoked automatically.
### GET `/api/v1/detection/runs/{analysis_run_id}`
Returns one detection analysis run.
### GET `/api/v1/detection/runs`
Returns detection analysis runs, optionally filtered by `project_id` and `dataset_id`.
### GET `/api/v1/detection/runs/{analysis_run_id}/detections`
Returns persisted detections for a detection analysis run. Optional filters:
- `dataset_id`
- `class_name`
- `min_confidence`
### GET `/api/v1/detection/datasets/{dataset_id}/detections`
Returns persisted detections for a raster dataset. Optional filters:
- `analysis_run_id`
- `class_name`
- `min_confidence`
### GET `/api/v1/detection/detections/{detection_id}`
Returns one persisted detection.
### GET `/api/v1/detection/runs/{analysis_run_id}/geojson`
Returns persisted detections for a run as a GeoJSON FeatureCollection. Geometry comes from persisted PostGIS detection geometry in EPSG:4326.
Each feature includes:
- `detection_id`
- `class_name`
- `confidence`
- `model_name`
- `model_version`
- `analysis_run_id`
- `dataset_id`
- `job_id`
- `source_tile_path`
- `bbox_json`
### GET `/api/v1/detection/datasets/{dataset_id}/geojson`
Returns persisted detections for a dataset as a GeoJSON FeatureCollection. Optional filters match the detection list endpoint.
### POST `/api/v1/detection/runs/{analysis_run_id}/qa/reference`
Compares persisted detection geometries from an analysis run against persisted `vector_features` from a reference vector dataset.
Request:
```json
{
"reference_dataset_id": "uuid",
"iou_threshold": 0.5,
"class_name": "building",
"min_confidence": 0.5
}
```
Response persists a `quality_check` and `metrics` rows through the existing QA/QC persistence architecture and returns:
- `precision`
- `recall`
- `f1_score`
- `mean_iou`
- `false_positives`
- `false_negatives`
- `quality_check_id`
If the reference dataset has no persisted vector features, the endpoint returns `REFERENCE_FEATURES_NOT_FOUND`. It does not calculate fake QA metrics.
### POST `/api/v1/analysis/building-stats`
Input: area + vector building layer.
### POST `/api/v1/analysis/object-detection`
Request:
```json
{
"project_id": "uuid",
"area_id": "uuid",
"dataset_id": "uuid",
"model_id": "optional uuid",
"classes": ["building"],
"confidence_threshold": 0.35,
"tile_size": 640,
"overlap": 64
}
```
Response: `AnalysisRunRead`.
### POST `/api/v1/analysis/segmentation`
Same pattern as object detection, but output includes masks and polygonized geometries.
## Segmentation Lab
Sprint 9 implements Segmentation Lab foundation only. Real SAM and YOLO-seg inference are not enabled, no model is downloaded, and fixture segmentations require explicit fixture mode.
### GET `/api/v1/segmentation/models`
Returns segmentation model capability descriptors:
- `segmentation-placeholder`: `not_configured`
- `fixture-segmenter`: configured for explicit test/demo fixtures only
- `yolo-seg-configured`: `not_configured`
- `sam-configured`: `not_configured`
### POST `/api/v1/segmentation/run`
Creates a segmentation job and segmentation analysis run. If the requested model is unavailable, the job and analysis run are marked `failed` with `SEGMENTATION_MODEL_UNAVAILABLE`.
Request:
```json
{
"project_id": "uuid",
"dataset_id": "uuid",
"model_id": "segmentation-placeholder",
"confidence_threshold": 0.5,
"class_filter": ["vegetation"],
"tile_manifest_path": null,
"parameters_json": {}
}
```
Fixture segmenter mode is test/demo-only. It persists only explicit `parameters_json.fixture_segmentations` entries when `parameters_json.fixture_mode=true`; it is never invoked automatically and does not represent production inference.
Validation errors:
- `INVALID_DATASET_TYPE` when the dataset is not raster.
- `SEGMENTATION_MODEL_NOT_FOUND` when the model id is unknown.
- `FIXTURE_MODE_REQUIRED` when `fixture-segmenter` is requested without `parameters_json.fixture_mode=true`.
- `INVALID_FIXTURE_SEGMENTATIONS` when fixture payloads are not a list.
- `INVALID_FIXTURE_GEOMETRY` when fixture geometry is empty, invalid or not Polygon/MultiPolygon.
### GET `/api/v1/segmentation/runs`
Returns segmentation analysis runs, optionally filtered by `project_id` and `dataset_id`.
### GET `/api/v1/segmentation/runs/{analysis_run_id}`
Returns one segmentation analysis run.
### GET `/api/v1/segmentation/runs/{analysis_run_id}/segmentations`
Returns persisted segmentation records for a segmentation analysis run. Optional filters:
- `dataset_id`
- `class_name`
- `min_confidence`
### GET `/api/v1/segmentation/datasets/{dataset_id}/segmentations`
Returns persisted segmentation records for a raster dataset. Optional filters:
- `analysis_run_id`
- `class_name`
- `min_confidence`
### GET `/api/v1/segmentation/segmentations/{segmentation_id}`
Returns one persisted segmentation record.
### GET `/api/v1/segmentation/runs/{analysis_run_id}/geojson`
Returns persisted segmentations for a run as a GeoJSON FeatureCollection. Geometry comes from persisted PostGIS segmentation geometry in EPSG:4326.
Each feature includes:
- `segmentation_id`
- `class_name`
- `confidence`
- `area_m2`
- `model_name`
- `model_version`
- `analysis_run_id`
- `dataset_id`
- `job_id`
- `source_tile_path`
- `tile_index`
- `mask_path`
- `bbox_json`
- `provenance_json`
### GET `/api/v1/segmentation/datasets/{dataset_id}/geojson`
Returns persisted segmentations for a dataset as a GeoJSON FeatureCollection. Optional filters match the segmentation list endpoint.
### POST `/api/v1/segmentation/runs/{analysis_run_id}/qa/reference`
Compares persisted segmentation geometries from an analysis run against persisted `vector_features` from a reference vector dataset.
Request:
```json
{
"reference_dataset_id": "uuid",
"iou_threshold": 0.5,
"class_name": "vegetation",
"min_confidence": 0.5
}
```
Response persists a `quality_check` and `metrics` rows through the existing QA/QC persistence architecture and returns precision, recall, F1, mean IoU and false positive/negative counts.
If the segmentation run has no persisted geometries, the endpoint returns `SEGMENTATIONS_NOT_FOUND`. If the reference dataset has no persisted vector features, it returns `REFERENCE_FEATURES_NOT_FOUND`. It does not calculate fake QA metrics.
### POST `/api/v1/analysis/change-detection`
Request contains source analysis or datasets A/B and method.
## QA/QC
### POST `/api/v1/qa/detections-vs-reference`
Request:
```json
{
"candidate_dataset_id": "uuid",
"reference_dataset_id": "uuid",
"iou_threshold": 0.5,
"area_id": "optional uuid"
}
```
Response is wrapped in the job envelope. On success, `result_json` includes precision, recall, F1, mean IoU, false positives, false negatives and `quality_check_id`.
Sprint 7A persists the QA/QC result as:
- `jobs`: execution state.
- `quality_checks`: domain result.
- `metrics`: individual measurements.
Future Detection and Segmentation flows may add an `analysis_run_id` path without replacing persisted quality checks.
### GET `/api/v1/projects/{project_id}/quality-checks`
Lists persisted QA/QC quality checks for a project with metric rows.
Response:
```json
{
"items": [
{
"id": "uuid",
"project_id": "uuid",
"job_id": "uuid-or-null",
"analysis_run_id": "uuid-or-null",
"candidate_dataset_id": "uuid-or-null",
"reference_dataset_id": "uuid",
"check_type": "demo_candidate_vs_reference",
"status": "ok",
"score": 0.5,
"parameters_json": {},
"findings_json": {},
"metrics": [
{
"metric_key": "precision",
"metric_value": 0.5
}
]
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
## Exports
### POST `/api/v1/exports/geojson`
Export detections, segmentations or vector layer to GeoJSON.
Dataset vector export request:
```json
{
"export_kind": "dataset",
"dataset_id": "uuid",
"name": "optional-basename"
}
```
Detection run export request:
```json
{
"export_kind": "detection_run",
"analysis_run_id": "uuid",
"name": "optional-basename"
}
```
Segmentation run export request:
```json
{
"export_kind": "segmentation_run",
"analysis_run_id": "uuid",
"name": "optional-basename"
}
```
Response persists an `exports` row and writes a deterministic JSON artifact:
```json
{
"export_id": "uuid",
"path": "storage/exports/{project_id}/datasets/{target}/{name}.geojson",
"status": "ready",
"export_type": "dataset_geojson",
"metadata_json": {
"source": "dataset",
"feature_count": 0
}
}
```
Vector dataset exports use the stored dataset GeoJSON. Detection and
segmentation exports use persisted first-class geometry records and the
existing Detection/Segmentation GeoJSON conversion services. Raster datasets
are rejected for dataset GeoJSON export.
### POST `/api/v1/exports/metadata`
Exports project metadata JSON for projects, datasets, persisted QA/QC summary
rows and existing export history.
```json
{
"project_id": "uuid",
"name": "optional-basename"
}
```
### GET `/api/v1/exports/projects/{project_id}/exports`
Lists persisted export records for a project.
### GET `/api/v1/exports/{export_id}`
Returns one persisted export record.
### GET `/api/v1/exports/{export_id}/content`
Returns the stored JSON artifact content through the standard API envelope.
### GET `/api/v1/exports/{export_id}/download`
Downloads the stored JSON/GeoJSON export artifact as a raw file response with
`application/json` content type and a `Content-Disposition` attachment
filename. This endpoint intentionally does not use the JSON envelope because
it is a browser/file-download path; callers that need canonical API JSON should
use `/content`.
### POST `/api/v1/exports/yolo`
Export annotations/detections to YOLO format.
### POST `/api/v1/exports/report`
Creates a lightweight HTML project report artifact from persisted project,
dataset, QA/QC summary and export history state. This does not create a PDF
and does not introduce a report designer.
```json
{
"project_id": "uuid",
"name": "optional-basename"
}
```
Response persists an `exports` row with `export_type:
project_report_html`. Download the report through:
```text
GET /api/v1/exports/{export_id}/download
```
PDF/report-designer functionality can be added after core GeoAI workflows work.
+90
View File
@@ -0,0 +1,90 @@
# API Contract Freeze M2
## Required V1 endpoints
### Health
`GET /health`
Response:
```json
{"status":"ok","service":"geointel-backend"}
```
### Projects
`POST /projects`
Request:
```json
{"name":"Geel Building Detection","description":"Demo project","region":"Kempen"}
```
Response: project object.
`GET /projects`
Response: paginated projects.
### Areas
`POST /projects/{project_id}/areas`
Request must contain GeoJSON polygon.
### Datasets
`POST /projects/{project_id}/datasets/upload`
Multipart upload. Returns dataset object and metadata status.
`GET /projects/{project_id}/datasets`
Returns datasets.
### Analysis runs
`POST /analysis/object-detection`
Request:
```json
{
"project_id": "uuid",
"dataset_id": "uuid",
"area_id": "uuid",
"model_id": "yolov8n-building-demo",
"confidence_threshold": 0.5
}
```
Response: job envelope.
`GET /analysis-runs/{id}`
Returns run status, metrics, outputs.
### QA/QC
`POST /analysis/qaqc/building-detection-vs-reference`
Request:
```json
{
"project_id": "uuid",
"prediction_run_id": "uuid",
"reference_dataset_id": "uuid",
"iou_threshold": 0.5
}
```
Response: job envelope.
### Exports
`POST /exports/geojson`
Exports detections, segmentations, QA findings, or vector layers.
+113
View File
@@ -0,0 +1,113 @@
# API Example Responses
## Error Envelope
```json
{
"error": {
"code": "DATASET_UNSUPPORTED_FORMAT",
"message": "The uploaded file extension is not supported.",
"details": {"extension": ".txt"},
"request_id": "req_01HY"
}
}
```
## Health
```json
{
"status": "ok",
"services": {
"database": "ok",
"redis": "ok",
"storage": "ok"
},
"version": "0.1.0"
}
```
## Project
```json
{
"id": "prj_geel_demo",
"name": "Geel Building Detection Demo",
"description": "Portfolio demo for GeoAI object detection and GRB QA.",
"region": "Kempen",
"created_at": "2026-06-10T00:00:00Z"
}
```
## Area FeatureCollection
```json
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": "area_geel_center",
"name": "Geel Centrum",
"area_m2": 1250000
},
"geometry": {
"type": "Polygon",
"coordinates": [[[4.98,51.16],[5.00,51.16],[5.00,51.18],[4.98,51.18],[4.98,51.16]]]
}
}
]
}
```
## Dataset Metadata
```json
{
"id": "ds_grb_buildings_geel",
"project_id": "prj_geel_demo",
"name": "GRB Buildings Geel Demo",
"dataset_type": "vector",
"source": "demo_fixture",
"status": "ready",
"crs": "EPSG:4326",
"bounds": [4.98, 51.16, 5.00, 51.18],
"metadata": {
"feature_count": 12,
"geometry_types": ["Polygon"]
}
}
```
## Detection Run
```json
{
"id": "run_detection_001",
"project_id": "prj_geel_demo",
"analysis_type": "object_detection",
"status": "completed",
"parameters": {
"model_id": "demo-yolo-buildings-v1",
"confidence_threshold": 0.35,
"tile_size": 512
},
"metrics": {
"detection_count": 14,
"mean_confidence": 0.82
}
}
```
## QA/QC Result
```json
{
"id": "qc_001",
"analysis_run_id": "run_detection_001",
"reference_dataset_id": "ds_grb_buildings_geel",
"iou_threshold": 0.5,
"metrics": {
"true_positive": 11,
"false_positive": 3,
"false_negative": 1,
"precision": 0.7857,
"recall": 0.9167,
"f1": 0.8462
}
}
```
+229
View File
@@ -0,0 +1,229 @@
# API Specification v1.0
Basispad: `/api/v1`
## Projects
### GET /projects
Geeft alle projecten terug.
### POST /projects
Maakt een project aan.
Body:
```json
{
"name": "Geel gebouwdetectie demo",
"description": "Detectie en QA/QC van gebouwen in Geel",
"region": "Kempen"
}
```
### GET /projects/{project_id}
Geeft projectdetails terug.
### DELETE /projects/{project_id}
Verwijdert een project en gekoppelde metadata. Bestanden moeten veilig afgehandeld worden.
## Areas
### GET /projects/{project_id}/areas
Geeft analysegebieden van een project.
### POST /projects/{project_id}/areas
Maakt analysegebied aan.
Body:
```json
{
"name": "Geel Centrum",
"geometry": { "type": "Polygon", "coordinates": [] }
}
```
### GET /areas/{area_id}
Geeft gebieddetails.
## Datasets
### POST /projects/{project_id}/datasets/upload
Uploadt raster of vector dataset.
Multipart:
- file
- name
- dataset_type
- source
### GET /projects/{project_id}/datasets
Lijst datasets.
### GET /datasets/{dataset_id}
Datasetdetails.
### GET /datasets/{dataset_id}/metadata
Metadata.
### POST /datasets/{dataset_id}/extract-metadata
Start metadata extraction job.
## Reference Data
### POST /projects/{project_id}/reference/grb/fetch
Haalt GRB-data op voor een area.
Body:
```json
{
"area_id": "uuid",
"layers": ["buildings"]
}
```
### POST /projects/{project_id}/reference/osm/fetch
Haalt OSM-data op voor een area.
## Raster
### POST /datasets/{dataset_id}/raster/clip
Clipt raster op area.
### POST /datasets/{dataset_id}/raster/tile
Maakt tiles voor AI-inference.
Body:
```json
{
"tile_size": 640,
"overlap": 64,
"area_id": "uuid"
}
```
### POST /datasets/{dataset_id}/raster/indices/ndvi
V2: berekent NDVI.
## Vector
### POST /datasets/{dataset_id}/vector/clip
Clipt vectorlaag op area.
### POST /datasets/{dataset_id}/vector/buffer
Maakt buffers.
### POST /datasets/{dataset_id}/vector/validate
Valideert geometrieën.
## Analysis
### POST /analysis/object-detection
Start objectdetectie.
Body:
```json
{
"project_id": "uuid",
"area_id": "uuid",
"dataset_id": "uuid",
"model_id": "uuid-or-default",
"classes": ["building"],
"confidence_threshold": 0.35
}
```
### POST /analysis/segmentation
Start segmentatie.
### POST /analysis/change-detection
Start change detection.
### GET /analysis/{analysis_run_id}
Geeft runstatus en resultaten.
### GET /analysis/{analysis_run_id}/detections
Geeft detecties als GeoJSON FeatureCollection.
### GET /analysis/{analysis_run_id}/segmentations
Geeft segmentaties als GeoJSON FeatureCollection.
## QA/QC
### POST /analysis/{analysis_run_id}/quality-check
Vergelijkt AI-resultaten met referentiedataset.
Body:
```json
{
"reference_dataset_id": "uuid",
"iou_threshold": 0.5,
"class_mapping": {
"building": "building"
}
}
```
### GET /quality-checks/{quality_check_id}
Geeft QA/QC-resultaten.
## Exports
### POST /exports/geojson
Exporteert analysis output naar GeoJSON.
### POST /exports/yolo
Exporteert annotaties naar YOLO-formaat.
### POST /exports/coco
Exporteert annotaties naar COCO-formaat.
### GET /exports/{export_id}/download
Download exportbestand.
## Jobs
### GET /jobs/{job_id}
Geeft jobstatus.
### GET /projects/{project_id}/jobs
Geeft jobs van een project.
+148
View File
@@ -0,0 +1,148 @@
# Architecture
## 1. Overzicht
GeoIntel bestaat uit:
- React/TypeScript frontend
- FastAPI backend
- PostgreSQL/PostGIS database
- background job queue
- file/object storage
- GIS processing services
- AI inference services
## 2. Hoofdcomponenten
```text
Frontend
↓ REST/WebSocket
FastAPI Backend
↓
PostgreSQL + PostGIS
↓
Storage: uploads, processed rasters, tiles, masks, exports
↓
Workers: GIS processing, AI inference, QA/QC, export
```
## 3. Frontend
Aanbevolen stack:
- React
- TypeScript
- MapLibre GL
- Deck.gl
- Tailwind
- TanStack Query
- Zustand of vergelijkbare lichte state store
- Recharts voor eenvoudige grafieken
Belangrijke principes:
- kaart centraal, maar analysepanelen even belangrijk
- labs per workflow
- duidelijke jobstatus
- outputs altijd exporteerbaar
- geen verborgen mockgedrag
## 4. Backend
Aanbevolen stack:
- FastAPI
- SQLAlchemy 2.x
- GeoAlchemy2
- Alembic
- Pydantic
- RQ/Celery
- Rasterio
- GeoPandas
- Shapely
- PyProj
- NumPy
- OpenCV
- Ultralytics/PyTorch
## 5. Database
PostgreSQL met PostGIS is verplicht voor:
- projectgebieden
- vectorfeatures
- detectiepolygonen
- segmentatiepolygonen
- spatial joins
- intersects
- IoU berekeningen
- bounds queries
## 6. Storage
Bewaar grote bestanden niet in de database.
Opslagcategorieën:
- originele uploads
- verwerkte rasters
- raster tiles
- masks
- model outputs
- exports
- rapporten
Database bewaart metadata en paden.
## 7. Jobs
Langlopende processen moeten via background jobs:
- raster metadata extraction
- raster clipping
- raster tiling
- vector import
- AI inference
- segmentation polygonize
- QA/QC
- change detection
- export generation
## 8. AI Inference
Inference pipeline:
```text
Raster dataset
→ clip to area
→ tile raster
→ normalize/preprocess
→ model inference
→ convert pixel coords to geospatial coords
→ merge/filter outputs
→ save detections/segmentations
→ expose as map layer
```
## 9. CRS-regels
- Alle interne geometrieën worden opgeslagen in PostGIS met bekende SRID.
- Voor metrische berekeningen wordt een geschikte projectie gebruikt.
- API-output naar frontend mag in EPSG:4326 of WebMercator-compatible formaat.
- Elke dataset zonder CRS krijgt status `needs_crs_review`.
## 10. Developmentstrategie
Bouwvolgorde:
1. backend foundation
2. database schema
3. project/area API
4. dataset upload en metadata
5. frontend workspace en kaart
6. vector import
7. raster import
8. processing jobs
9. detection lab
10. QA/QC
11. export
+80
View File
@@ -0,0 +1,80 @@
# Backend Package Map
Target backend layout:
```text
backend/
app/
main.py
api/
router.py
routes/
health.py
projects.py
areas.py
datasets.py
raster.py
vector.py
analysis.py
qaqc.py
exports.py
core/
config.py
database.py
logging.py
security.py
errors.py
models/
project.py
area.py
dataset.py
layer.py
analysis.py
detection.py
segmentation.py
quality.py
export.py
job.py
event.py
schemas/
common.py
project.py
area.py
dataset.py
analysis.py
quality.py
export.py
services/
project_service.py
area_service.py
dataset_service.py
raster_service.py
vector_service.py
grb_service.py
detection_service.py
segmentation_service.py
qaqc_service.py
export_service.py
event_service.py
workers/
queue.py
jobs.py
repositories/
base.py
projects.py
areas.py
datasets.py
analysis_runs.py
scripts/
seed_demo.py
tests/
```
## Rules
- API routes should be thin.
- Business logic belongs in services.
- SQLAlchemy query composition belongs in repositories where useful.
- Pydantic schemas are the API contract.
- Models are persistence structures, not API response structures.
- GIS processing functions must be testable outside HTTP handlers.
+9
View File
@@ -0,0 +1,9 @@
# Build Governance
Elke pass heeft doel, inputdocumenten, taken, niet-doen lijst, acceptatiecriteria, testcommando's en handoff-output.
Codex werkt altijd bij: `CHANGELOG.md`, `docs/TODO.md`, relevante contractdocs en `docs/CODEX_EXECUTION_LOG.md`.
Stopregels: backend start niet, frontend buildt niet, migrations falen, API-contracten inconsistent, demo-flow breekt.
Visuele polish pas na werkende dataflow, API en tests/smoke checks.
+38
View File
@@ -0,0 +1,38 @@
# GeoIntel Build Status
Current preparation milestone: M7 Implementation Control Layer.
## Done
- Product blueprint.
- Data specifications.
- Architecture specifications.
- API/database/service documentation.
- Codex build plans and prompts.
- Operational readiness docs.
- Autonomy pack.
- M7 build control, regression traps and self-review layer.
## Ready for Codex
Codex can begin with repository verification and backend foundation using the locked build sequence.
## Must Preserve
- GeoIntel is a GeoAI Workbench for the Kempen.
- GRB-first reference strategy.
- FastAPI + React + PostGIS.
- API-driven frontend.
- CRS-aware geospatial processing.
- Fixture mode must be clearly labeled.
## Known Limitations Before Code Build
- Real GRB WFS integration still needs implementation.
- Real YOLO/SAM inference should follow fixture boundary first.
- Sentinel and LiDAR remain post-foundation roadmap items.
- No production authentication in V1.
## Next Recommended Codex Pass
Run `prompts/codex/PASS_00_REPO_AUDIT.md`, then implement backend foundation according to `docs/12-build-control/BUILD_SEQUENCE_LOCK.md`.
+203
View File
@@ -0,0 +1,203 @@
# Build Tickets M3
This file converts the implementation epics into concrete Codex-ready tickets.
## Ticket format
Each ticket must be implemented with:
- backend changes if applicable
- frontend changes if applicable
- tests where applicable
- documentation updates
- changelog entry
## T-001 Backend package scaffold
Create FastAPI package structure:
```text
backend/app/main.py
backend/app/api/router.py
backend/app/core/config.py
backend/app/core/database.py
backend/app/models/
backend/app/schemas/
backend/app/services/
backend/app/workers/
backend/tests/
```
Acceptance:
- `GET /health` returns status ok.
- backend imports cleanly.
- tests can run without external geospatial data.
## T-002 Database and Alembic scaffold
Add SQLAlchemy and Alembic setup for PostgreSQL/PostGIS.
Acceptance:
- database URL comes from environment.
- migrations directory exists.
- first migration creates PostGIS extension if available.
- migration plan documented.
## T-003 Project model and API
Implement project entity.
Acceptance:
- create project
- list projects
- read project
- update project
- soft delete or archive project
- response envelope followed
## T-004 Area model and geometry API
Implement areas linked to projects.
Acceptance:
- create polygon area as GeoJSON
- validate geometry
- store geometry in PostGIS
- calculate area in square meters using projected CRS
- return bounds and centroid
## T-005 Frontend foundation
Create React + TypeScript app structure.
Acceptance:
- app boots
- route layout exists
- API client exists
- error/loading components exist
- navigation includes Workspace, Map, Datasets, Raster, Vector, Detection, QA/QC, Exports
## T-006 Map workbench foundation
Implement map page and area drawing contract.
Acceptance:
- map displays Kempen default viewport
- user can draw or load an example polygon
- polygon can be submitted to backend as area
- active area can be selected
## T-007 Dataset upload API
Implement dataset registration and upload.
Acceptance:
- accepts GeoTIFF, GeoJSON, ZIP shapefile, GPKG placeholder handling
- stores original file under storage/originals
- creates dataset row
- status starts as uploaded
- returns metadata extraction job status
## T-008 Raster metadata service
Implement Rasterio metadata extraction.
Acceptance:
- CRS
- bounds
- width/height
- band count
- resolution
- nodata
- dtype
- transform
- summary stats for small rasters or sampled stats for large rasters
## T-009 Vector metadata service
Implement GeoPandas metadata extraction.
Acceptance:
- CRS
- bounds
- feature count
- geometry types
- columns
- invalid geometry count
- area summary where applicable
## T-010 GRB reference fetcher skeleton
Implement service contract for GRB WFS fetch.
Acceptance:
- service accepts area geometry
- builds BBOX or polygon filter request
- stores retrieved features as dataset/layer
- if live WFS unavailable, returns a clear source_unavailable status without crashing
## T-011 Detection pipeline interface
Implement detection run model and interface.
Acceptance:
- request creates analysis_run
- job lifecycle status exists
- deterministic fixture inference can populate detections for demo fixtures
- output geometries are stored and exported as GeoJSON
## T-012 QA/QC engine v1
Implement reference-vs-prediction matching.
Acceptance:
- IoU threshold configurable, default 0.5
- precision, recall, F1 calculated
- false positives and false negatives classified
- QA result stored
- fixture test passes with known expected metrics
## T-013 Export API
Implement export registry and GeoJSON export.
Acceptance:
- export detection results as FeatureCollection
- export QA false positives/negatives as FeatureCollection
- export analysis summary JSON
- exports have stable file paths under storage/exports
## T-014 Frontend dataset and analysis panels
Implement visible pages for dataset, detection and QA workflows.
Acceptance:
- dataset list shows status and metadata
- detection page starts run and shows result state
- QA page shows metrics and error classes
- map overlays are connected to available GeoJSON outputs
## T-015 Stabilization pass
Acceptance:
- no broken navigation
- no unhandled promise rejections
- backend health green
- core tests green
- README quickstart updated
- CHANGELOG updated
+18
View File
@@ -0,0 +1,18 @@
# Changelog M4
## Added
- Autonomous build readiness specification.
- M4 sprint board.
- Module build contracts.
- Acceptance test catalog.
- API example response contracts.
- Job lifecycle contract.
- Frontend state and route contracts.
- Backend service IO contracts.
- Model registry seed specification.
- Demo fixture manifest.
- Codex autonomous runbook.
- Codex pass prompts for backend, database, dataset manager, map workspace, AI demo pipelines and QA/QC exports.
## Intent
M4 prepares the repository for long Codex implementation sessions with minimal human intervention.
+116
View File
@@ -0,0 +1,116 @@
# GeoIntel Kempen — Change Detection Specification v1.0
Change Detection is a major showcase workflow combining raster, vector, AI and QA/QC.
## Goal
Compare two datasets or analysis runs for the same area and detect additions, removals and significant changes.
## Supported methods
## Method A — Vector change detection V1
Compare two vector layers or two analysis outputs.
Examples:
- GRB buildings snapshot A vs snapshot B.
- AI detections from raster A vs AI detections from raster B.
- OSM buildings from run A vs OSM buildings from run B.
### Inputs
- layer A
- layer B
- area polygon
- class filter optional
- matching threshold
### Algorithm
1. Normalize CRS.
2. Clip both layers to area.
3. Match features using IoU or spatial overlap.
4. Classify:
- added: feature in B without match in A
- removed: feature in A without match in B
- unchanged: matched with stable geometry
- modified: matched but area or geometry changed above threshold
### Metrics
- added count
- removed count
- modified count
- added area m²
- removed area m²
- net area change m²
- percentage change
## Method B — Raster index change V2
Compare NDVI/NDWI/NDBI rasters.
### Inputs
- index raster A
- index raster B
- threshold
### Algorithm
```text
delta = index_B - index_A
classify pixels by threshold
polygonize changed zones
```
### Outputs
- change raster
- changed polygons
- summary statistics
## Method C — AI segmentation change V3
Run segmentation on both images and compare class polygons.
Examples:
- vegetation loss
- new buildings
- water change
## Output layers
- `change_added`
- `change_removed`
- `change_modified`
- `change_heatmap`
- `change_uncertain`
## API
```http
POST /analysis/change-detection
GET /analysis/{id}/changes
POST /analysis/{id}/exports/change-geojson
```
## UI requirements
Change Lab must support:
- dataset/layer A selector
- dataset/layer B selector
- method selector
- area selector
- threshold controls
- timeline labels
- map overlays for added/removed/modified
- metrics cards
- export
## V1 target
Implement vector change detection. Raster and AI-based change detection are later phases.
+68
View File
@@ -0,0 +1,68 @@
# CI/CD Specification
## Doel
De CI/CD-pipeline moet elke wijziging snel valideren zonder zware AI- of GIS-jobs verplicht te maken. Zware checks krijgen aparte profielen.
## Checkprofielen
### `quick`
Moet lokaal binnen enkele minuten kunnen draaien.
- Backend import check.
- Python lint/type smoke.
- Frontend install/build smoke.
- API schema consistency check.
- Geen ontbrekende verplichte documentatie.
### `integration`
Draait met Docker Compose.
- PostgreSQL/PostGIS start.
- Redis start.
- Backend start.
- Health endpoint geeft OK.
- Alembic migrations kunnen naar laatste versie.
- Test fixtures kunnen worden ingeladen.
### `geospatial`
Draait alleen wanneer GDAL/Rasterio/GeoPandas beschikbaar zijn.
- Raster metadata fixture.
- Vector fixture import.
- CRS-transformatie fixture.
- Clip operatie fixture.
### `ai-light`
Draait zonder groot model.
- Model registry laadt.
- Detection pipeline accepteert dummy model adapter.
- Outputcontract voor detections klopt.
- GeoJSON exportcontract klopt.
### `ai-full`
Optioneel en niet verplicht voor elke commit.
- YOLO/SAM echte modelrun op kleine fixture.
- Output wordt geprojecteerd naar kaartcoördinaten.
- QA/QC tegen referentievector draait.
## Verplichte CI-stappen voor M1-builds
1. `scripts/check_repo_structure.sh`
2. `scripts/smoke_backend_import.sh`
3. `scripts/smoke_contracts.py`
4. `scripts/smoke_docs.py`
## Verplichte CI-stappen zodra code bestaat
1. `pytest backend/tests`
2. `npm run typecheck`
3. `npm run build`
4. `alembic upgrade head`
5. `python scripts/validate_fixtures.py`
## Build failure policy
Een build mag alleen als groen worden beschouwd wanneer:
- Alle quick checks slagen.
- Bekende failures expliciet in `docs/KNOWN_LIMITATIONS_M3.md` of nieuwere limitation doc staan.
- Geen nieuwe regressies zonder vermelding in changelog.
+46
View File
@@ -0,0 +1,46 @@
# Codex Autonomous Runbook M4
Use this runbook when starting an autonomous implementation session.
## Before Coding
1. Read `README.md`.
2. Read `AGENTS.md`.
3. Read `docs/DEVELOPMENT_RULES.md`.
4. Read `docs/M4_AUTONOMOUS_BUILD_READINESS.md`.
5. Read `docs/SPRINT_BOARD_M4.md`.
6. Read module contract for the sprint being implemented.
## Implementation Rules
- Build in the sprint order unless explicitly instructed otherwise.
- Do not skip backend tests for frontend work.
- Do not add a new dependency without updating dependency documentation.
- Do not invent new architecture where a contract already exists.
- Preserve fixture determinism.
- Update TODO and changelog after each pass.
## End-of-Pass Report Format
Each Codex pass must end with:
```md
## Completed
- ...
## Tests Run
- ...
## Changed Files
- ...
## Remaining TODO
- ...
## Risks / Blockers
- ...
```
## Stop Conditions
Stop and ask for human direction only if:
- A required external credential is missing.
- A core architecture decision conflicts across documents.
- A dependency cannot be installed or replaced safely.
- Data license terms are unclear for a live connector.
+49
View File
@@ -0,0 +1,49 @@
# Codex Bootstrap Prompt — GeoIntel Kempen
You are building GeoIntel Kempen, a GeoAI Workbench for the Belgian Kempen region. The repository already contains the specification set. Read these documents before editing code:
1. `docs/SPECIFICATION_FREEZE_M0.md`
2. `docs/V1_SCOPE_FREEZE.md`
3. `docs/DEVELOPMENT_RULES.md`
4. `docs/REPOSITORY_CONVENTIONS.md`
5. `docs/SERVICE_ARCHITECTURE.md`
6. `docs/API_CONTRACTS.md`
7. `docs/DATABASE_IMPLEMENTATION_PLAN.md`
8. `docs/CODEX_EXECUTION_PLAN.md`
9. `docs/TEST_STRATEGY.md`
10. `docs/DEFINITION_OF_DONE.md`
## Non-negotiable build rules
- Build backend-first and API-driven.
- Do not silently replace geospatial logic with fake logic.
- Mock data is allowed only as explicit fixtures in `fixtures/` or `tests/fixtures/`.
- Every implemented endpoint must have request/response schemas.
- Every implemented service must have at least one focused test or a documented reason why it cannot yet be tested.
- Every feature must expose error states, loading states and empty states in the frontend.
- Do not introduce new major dependencies without adding them to `docs/DEPENDENCY_POLICY.md` and explaining why they are needed.
- Do not expand V1 scope beyond `docs/V1_SCOPE_FREEZE.md`.
- Preserve existing docs and update them when implementation diverges.
## First build objective
Create a runnable foundation with:
- FastAPI backend skeleton.
- React + TypeScript frontend skeleton.
- Docker Compose with PostGIS, backend and frontend.
- Health endpoints.
- Project and Area CRUD.
- Dataset metadata model.
- Repository/service structure matching `docs/REPOSITORY_CONVENTIONS.md`.
- Initial tests and lint commands.
## Required handoff after every pass
Update `docs/CODEX_EXECUTION_LOG.md` with:
- What changed.
- What was tested.
- What remains open.
- Known limitations.
- Next recommended pass.

Some files were not shown because too many files have changed in this diff Show More