Files
geointel/docs/CODEX_EXECUTION_LOG.md
T
Codex ea8dcb2bdd
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled
Add detection calibration evidence export
2026-07-07 02:30:30 +02:00

4655 lines
327 KiB
Markdown

## Sprint 125 Detection calibration evidence bundle (2026-07-07)
Changed:
- Added `scripts/export_detection_calibration_evidence.sh` to turn a persisted detection calibration summary into visual QA evidence artifacts.
- The script reads `calibration_summary.json`, fetches the existing project quality-check evidence GeoJSON endpoint for each `quality_check_id`, enriches features with threshold/score/provenance and writes:
- `calibration_evidence.geojson`
- `calibration_evidence_summary.json`
- `calibration_evidence_review.html`
- The HTML review artifact renders a simple SVG overview with distinct roles for `match_candidate`, `match_reference`, `false_positive` and `false_negative`.
- Registered the script in `scripts/run_readiness_check.sh` as a syntax check.
- Added regression coverage in `backend/tests/test_sprint125_detection_calibration_evidence_bundle.py`.
- Updated `scripts/README.md`, `backend/README.md`, `docs/AI_PIPELINES.md`, `docs/TODO.md` and `CHANGELOG.md`.
Validation:
- RED: `python -m pytest backend/tests/test_sprint125_detection_calibration_evidence_bundle.py -q` failed because `scripts/export_detection_calibration_evidence.sh` did not exist.
- `python -m pytest backend/tests/test_sprint125_detection_calibration_evidence_bundle.py -q` passed.
- `bash -n scripts/export_detection_calibration_evidence.sh` passed.
- `bash scripts/export_detection_calibration_evidence.sh --help` passed.
- Missing-input guard printed usage and did not fetch evidence.
Open:
- Pull the script to Tower and export evidence for the latest Geel calibration summary.
Limitations:
- This is operator tooling only. It does not rerun inference, change API behavior, add UI behavior, fetch providers, seed demo data or download models.
- The SVG review is a lightweight geometry overview, not a replacement for full MapLibre evidence review in the workbench.
Next recommended pass:
- Run the evidence export on Tower, inspect the role distribution and use the artifacts to decide whether the current model is worth further threshold tuning or should be replaced.
## Sprint 124 Detection calibration sweep tooling (2026-07-07)
Changed:
- Added `scripts/run_detection_calibration_sweep.sh` as an operator-facing confidence-threshold sweep for the configured-YOLO real-data path.
- The sweep reuses `scripts/verify_real_data_detection_qa_workflow.sh` once per threshold, so each row is backed by persisted Project, Dataset, AnalysisRun, Detection, QualityCheck, Metric and export records.
- The sweep fetches project `quality-checks` after each run and writes per-threshold summaries plus `calibration_summary.json` with detection count, QA score, precision, recall, F1, mean IoU, matches, false positives and false negatives.
- Registered the sweep in `scripts/run_readiness_check.sh` as a syntax check.
- Added regression coverage in `backend/tests/test_sprint124_detection_calibration_sweep.py`.
- Updated `scripts/README.md`, `backend/README.md`, `docs/AI_PIPELINES.md`, `docs/TODO.md` and `CHANGELOG.md`.
Validation:
- RED: `python -m pytest backend/tests/test_sprint124_detection_calibration_sweep.py -q` failed because `scripts/run_detection_calibration_sweep.sh` did not exist.
- `python -m pytest backend/tests/test_sprint124_detection_calibration_sweep.py -q` passed.
- `bash -n scripts/run_detection_calibration_sweep.sh` passed.
- `bash scripts/run_detection_calibration_sweep.sh --help` passed.
- Missing-input guard printed usage and did not start a live workflow.
- `bash scripts/run_readiness_check.sh` passed: 388 backend tests, Alembic head check, frontend typecheck/build and shell syntax checks.
- Tower pulled commit `590e597` with `git pull --ff-only origin main` and ran the default Geel calibration sweep.
- The first Tower sweep exposed that the summary script looked for `f1_score` while persisted metrics use `f1`; the script was patched with a `metrics.get("f1")` fallback and regression coverage.
- RED: `python -m pytest backend/tests/test_sprint124_detection_calibration_sweep.py -q` failed while the script lacked the `f1` fallback.
- `python -m pytest backend/tests/test_sprint124_detection_calibration_sweep.py -q` passed after the fallback.
- Tower pulled commit `e8cd463` and reran the Geel calibration sweep successfully:
- output: `artifacts/detection-calibration/20260707T002103Z/calibration_summary.json`
- threshold `0.50`: 4 detections, score/F1 `0.0032206119162640897`, precision `0.25`, recall `0.0016207455429497568`, 1 match, 3 false positives, 616 false negatives
- threshold `0.35`: 9 detections, score/F1 `0.003194888178913738`, precision `0.1111111111111111`, recall `0.0016207455429497568`, 1 match, 8 false positives, 616 false negatives
- threshold `0.25`: 20 detections, score/F1 `0.0031397174254317113`, precision `0.05`, recall `0.0016207455429497568`, 1 match, 19 false positives, 616 false negatives
- threshold `0.15`: 54 detections, score/F1 `0.014903129657228018`, precision `0.09259259259259259`, recall `0.008103727714748784`, 5 matches, 49 false positives, 612 false negatives
- best by score for this sample: threshold `0.15`
Open:
- None for calibration tooling.
Limitations:
- The sweep is intentionally mutating and creates one real workflow run per threshold.
- It is calibration tooling only; it does not change inference, add model downloads, fetch providers, seed demo detections or change API/UI behavior.
- The current active building model still performs poorly on the Geel validation sample. Threshold `0.15` is best among the tested values, but recall remains under 1%; this is model/data-quality evidence, not a production-ready extraction baseline.
Next recommended pass:
- Inspect false-positive/false-negative evidence for the Geel runs, then add at least two more local orthophoto/reference samples before choosing V1 default confidence/IoU guidance.
## Sprint 123 YOLO class and tile CRS normalization (2026-07-07)
Changed:
- Investigated the Geel real-data smoke that persisted zero detections despite the configured building model being available.
- Confirmed on Tower that `/app/models/yolov8n-building-segmentation.pt` reports model class `Building` and returns 4 raw detections at confidence `0.5` on the same real Geel tile manifest.
- Fixed configured-YOLO detection persistence so model class names are compared case-insensitively against `class_filter`, persisted as canonical lowercase domain classes, and preserve the original model class name in `properties_json.model_class_name`.
- Found a second live GIS correctness issue: generated tile manifests carried Lambert bounds/transforms but no CRS, so detection GeoJSON could expose EPSG:31370 coordinates as if they were EPSG:4326.
- Fixed raster tile manifest generation to include `crs`, `source_crs` and `dataset_crs` on the manifest and `crs` on each tile entry when the source raster CRS is known.
- Added regression coverage in `backend/tests/test_sprint8b_yolo_foundation.py` and `backend/tests/test_raster_operations_service.py`.
Validation:
- RED: `python -m pytest backend/tests/test_sprint8b_yolo_foundation.py::test_yolo_class_filter_is_case_insensitive_and_persists_canonical_class -q` failed with `detection_count=0` because `Building` did not match `building`.
- `python -m pytest backend/tests/test_sprint8b_yolo_foundation.py::test_yolo_class_filter_is_case_insensitive_and_persists_canonical_class -q` passed.
- `python -m pytest backend/tests/test_sprint8b_yolo_foundation.py backend/tests/test_model_asset_catalog.py backend/tests/test_sprint121_real_data_detection_qa_smoke.py backend/tests/test_sprint122_raster_upload_metadata_mapping.py -q` passed: 20 tests.
- RED: `python -m pytest backend/tests/test_raster_operations_service.py::test_raster_tile_returns_manifest_payload -q` failed because the tile manifest had no `crs`.
- `python -m pytest backend/tests/test_raster_operations_service.py::test_raster_tile_returns_manifest_payload -q` passed.
- `python -m compileall backend/app` passed.
- `bash scripts/run_readiness_check.sh` passed: 387 backend tests, Alembic head check, frontend typecheck/build and shell syntax checks.
- Tower deploy from commit `71c2cd9` passed with `GEOINTEL_INSTALL_AI=true`.
- Deploy-time live migration smoke passed; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`.
- Real-data smoke after the class-normalization deploy passed and persisted 4 detections:
- project: `cb80638d-dbef-48ac-b19c-cec7c3efc96e`
- raster dataset: `ae0ff76d-70c0-404f-b777-54d14517179a`
- reference dataset: `8ac01b4f-bd6a-4d6a-b625-a0950ae0f3eb`
- analysis run: `7ba34274-411d-45e3-8f54-c37baec598b1`
- quality check: `66907e6a-9ed7-4b0c-976f-5ad1ba9b8b7a`
- detection export: `516d37a3-2305-48a2-a3dd-b56f70eb055e`
- persisted detections used canonical `class_name=building` and preserved `model_class_name=Building`.
- Tower deploy from commit `bc87681` passed with `GEOINTEL_INSTALL_AI=true`.
- Deploy-time live migration smoke passed; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`.
- Real-data smoke after the tile-CRS deploy passed and persisted 4 detections:
- project: `6ced26f3-4486-451e-a05e-26a8f859e361`
- raster dataset: `d54c3420-03d4-45a2-9501-bf1cce165a89`
- reference dataset: `319dad51-15e9-4ae6-815b-8e39023ed962`
- manifest: `/app/storage/tiles/6ced26f3-4486-451e-a05e-26a8f859e361/d54c3420-03d4-45a2-9501-bf1cce165a89/721c9557-5910-4994-b0ac-ba3418d12246/manifest.json`
- analysis run: `e99bcd07-ba48-4ebe-9ba9-24a94a8c1dcb`
- quality check: `32c8252b-fe60-4062-9639-125c62ca677f`
- detection export: `9d3a7f60-07a2-415c-9f75-a3c1988d0904`
- Verified the new tile manifest now carries `crs=EPSG:31370`, `source_crs=EPSG:31370`, `dataset_crs=EPSG:31370` and per-tile `crs=EPSG:31370`.
- Verified Detection GeoJSON now returns WGS84 coordinates around Geel instead of raw Belgian Lambert coordinates.
- Live detection QA persisted honest metrics for the Geel sample: 1 match, 3 false positives, 616 false negatives and score `0.0032206119162640897`.
Open:
- None for availability, persistence and CRS propagation.
Limitations:
- This fixes class routing, persistence and future tile manifest CRS propagation. Existing tile manifests generated before this fix remain missing CRS and should be regenerated before AI runs.
- The active building model is operational but not calibrated for production-quality local Belgian/Kempen orthophoto extraction. The Geel sample proves end-to-end persistence and QA, while the 1/617 reference match result shows that confidence thresholds, tiling strategy, class mapping and IoU defaults still need model-quality calibration.
Next recommended pass:
- Run a detection calibration pass on several local orthophoto/reference samples: sweep confidence thresholds, inspect false positives/false negatives, tune tile size/overlap where needed and record a practical V1 baseline.
## Sprint 122 Real operator data availability and raster metadata fix (2026-07-07)
Changed:
- Created real operator validation files on Tower under `/mnt/user/appdata/geointel/storage/operator-data`.
- Generated `/mnt/user/appdata/geointel/storage/operator-data/geel_orthophoto_wms_512.tif` from the official Digitaal Vlaanderen OMWRGBMRVL WMS `Ortho` layer for a 500 m x 500 m AOI around Geel.
- Generated `/mnt/user/appdata/geointel/storage/operator-data/geel_grb_gbg_buildings.geojson` from the official Digitaal Vlaanderen GRB OGC API Features `GBG` building collection for the same AOI; it contained 617 features.
- Fixed `DatasetService` raster upload metadata mapping so extracted `bounds`, `resolution` and `dtype` populate persisted `bounds_json`, `resolution_json` and `bands_json`.
- Added `backend/tests/test_sprint122_raster_upload_metadata_mapping.py`.
Validation:
- RED: `python -m pytest backend/tests/test_sprint122_raster_upload_metadata_mapping.py -q` failed because uploaded raster `bounds_json` was `None`.
- `python -m pytest backend/tests/test_sprint122_raster_upload_metadata_mapping.py -q` passed.
- `python -m compileall backend/app` passed.
- `bash scripts/run_readiness_check.sh` passed: 386 backend tests, Alembic head check, frontend typecheck/build and shell syntax checks.
- Tower deploy from commit `2468945` passed with `GEOINTEL_INSTALL_AI=true`.
- Deploy-time live migration smoke passed; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`.
- Real-data smoke passed:
- command: `REAL_RASTER_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_orthophoto_wms_512.tif REAL_REFERENCE_VECTOR_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel_grb_gbg_buildings.geojson bash scripts/verify_real_data_detection_qa_workflow.sh http://192.168.10.150:1202`
- project: `e1ec201b-bd83-4c95-be5a-f7225902d3c5`
- raster dataset: `fca14d23-bc0c-4b1f-8bfa-ba968f2e05d0`
- reference dataset: `5bb4a9b4-2a4e-4680-a729-777a75ecd51f`
- model asset: `yolov8n-building-segmentation-pt`
- manifest: `/app/storage/tiles/e1ec201b-bd83-4c95-be5a-f7225902d3c5/fca14d23-bc0c-4b1f-8bfa-ba968f2e05d0/0f29f110-951f-48eb-a2fb-636b587e31ee/manifest.json`
- analysis run: `c6798559-590c-42e3-a192-45a2409fa832`
- detections: `0`
- quality check: `cd0d13f9-f6ce-4acf-8859-7cb7aa666125`
- detection export: `0081c230-1766-4ff3-8df0-e47236f529d1`
Limitations:
- The workflow is operational against real operator data. A follow-up class-normalization pass found that the active evaluation model returned `Building` while the workflow filtered on `building`; see Sprint 123.
- The prepared files are runtime artifacts on Tower, not repository fixtures.
Next recommended pass:
- Redeploy the class-normalization fix, rerun the real-data smoke and calibrate confidence/IoU thresholds against persisted detection and QA metrics.
## Sprint 121 Real data detection and QA workflow smoke (2026-07-07)
Changed:
- Added `scripts/verify_real_data_detection_qa_workflow.sh` for live-runtime validation with operator-provided real GIS inputs.
- The smoke creates a project, uploads a real GeoTIFF-style raster as a source dataset, uploads a real reference-building GeoJSON/JSON as `dataset_role=reference`, validates CRS/bounds/features, tiles the raster, selects a mounted local model asset, runs read-only YOLO preflight, runs configured YOLO detection, runs detection QA against persisted `vector_features`, and exports the detection run GeoJSON.
- Registered the smoke in `scripts/run_readiness_check.sh` as a syntax check only, so normal readiness does not require real orthophotos, reference vectors, optional AI dependencies or model files.
- Documented Tower usage and limitations in `scripts/README.md`, `backend/README.md`, `docs/AI_PIPELINES.md`, `docs/TODO.md` and `CHANGELOG.md`.
Validation:
- RED: `python -m pytest backend/tests/test_sprint121_real_data_detection_qa_smoke.py -q` failed while `scripts/verify_real_data_detection_qa_workflow.sh` did not exist.
- `python -m pytest backend/tests/test_sprint121_real_data_detection_qa_smoke.py -q` passed: 1 test.
- `bash -n scripts/verify_real_data_detection_qa_workflow.sh` passed.
- `bash scripts/verify_real_data_detection_qa_workflow.sh --help` passed and printed required `REAL_RASTER_PATH` and `REAL_REFERENCE_VECTOR_PATH` usage.
- `python -m compileall backend/app` passed.
- `python scripts/smoke_docs.py` passed.
- `bash scripts/run_readiness_check.sh` passed: 385 backend tests, Alembic head check, frontend typecheck, frontend production build and shell syntax checks.
- `cd backend && python -m alembic upgrade head --sql` passed.
- Missing-input guard passed: `bash scripts/verify_real_data_detection_qa_workflow.sh http://localhost:1202` returned exit code 2 and printed usage.
- Local `docker compose config` could not run in this Windows Codex environment because the `docker` command is not installed.
Limitations:
- The full real-data smoke was not executed in this Codex workspace because no operator-provided real GeoTIFF and reference GeoJSON were found locally.
- The script enforces real inputs and never seeds demo data, enables fixture detections, fetches live GRB/OSM/Sentinel data or downloads model weights.
Next recommended pass:
- Place a target orthophoto/GeoTIFF and matching reference-building GeoJSON under the Tower appdata path and run `REAL_RASTER_PATH=... REAL_REFERENCE_VECTOR_PATH=... bash scripts/verify_real_data_detection_qa_workflow.sh http://192.168.10.150:1202`.
## Sprint 120 Model asset detection workflow smoke (2026-07-06)
Changed:
- Added `scripts/verify_model_asset_detection_workflow.sh` to validate the configured-YOLO runtime path against a live Docker/Tower deployment.
- The smoke seeds the explicit offline demo workflow, creates a raster tile manifest, selects the active local model asset from `GET /api/v1/detection/model-assets`, verifies read-only YOLO preflight, submits the existing detection run endpoint and checks persisted AnalysisRun, Detection list and Detection GeoJSON outputs.
- Registered the script in `scripts/run_readiness_check.sh` as a syntax check only, so ordinary readiness runs remain valid on machines without optional AI dependencies or mounted model files.
- Documented the smoke in `scripts/README.md`, `backend/README.md`, `docs/AI_PIPELINES.md`, `docs/TODO.md` and `CHANGELOG.md`.
Validation:
- RED: `python -m pytest backend/tests/test_sprint120_model_asset_detection_workflow_smoke.py -q` failed because `scripts/verify_model_asset_detection_workflow.sh` did not exist yet.
- `python -m pytest backend/tests/test_sprint120_model_asset_detection_workflow_smoke.py -q` passed: 1 test.
- `bash -n scripts/verify_model_asset_detection_workflow.sh` passed.
- Live Tower smoke passed: `bash scripts/verify_model_asset_detection_workflow.sh http://192.168.10.150:1202`.
- Live smoke selected `model_asset_id=yolov8n-building-segmentation-pt`, generated manifest `/app/storage/tiles/c0b00f1f-80bf-4992-be94-f5e5e6f6bf63/f9160f51-ee78-43b3-9353-d5390576fa1d/e9acd488-c376-45ed-b259-0dd79886f21e/manifest.json`, persisted analysis run `7f9e7ecb-c43d-4ed3-9f98-424bc0317805` and returned `detection_count=0`.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 384 tests with the existing Pydantic `model_*` namespace warnings.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash scripts/run_readiness_check.sh` passed: 384 backend tests, frontend typecheck/build, API contract audit, Alembic head and shell syntax checks.
- Live browser/API smoke passed: `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`.
- Live GIS capability smoke passed: `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202`.
- Live raster workflow smoke passed: `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202`.
- Live workbench default-state smoke passed: `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202`.
- Live workbench backing-state smoke passed: `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202`.
- Live demo/export workflow smoke passed: `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202`.
- `bash scripts/verify_ai_handoff_interactions.sh http://192.168.10.150:1202` could not run in this local Codex shell because Node cannot import Playwright; the script remains syntax-checked in readiness and the internal browser was used for live visual verification instead.
- Internal browser validation passed on `http://192.168.10.150:1202`: AI Labs rendered Detection Lab and Segmentation Lab, selecting `yolo-configured` showed the Local model assets selector with `yolov8n-building-segmentation (active)` and `yolov8n`, no-download copy was visible and no console errors were emitted.
- `git push origin main` pushed commit `b2fe7fa`.
- Tower deploy from commit `b2fe7fa` completed with `GEOINTEL_INSTALL_AI=true`; the all-in-one container is published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`, API proxy and icon.
- Post-deploy live model asset detection workflow smoke passed: `bash scripts/verify_model_asset_detection_workflow.sh http://192.168.10.150:1202` selected `yolov8n-building-segmentation-pt`, persisted analysis run `f758c992-4fb8-4dca-ab29-5c216cb14078` and returned `detection_count=0`.
Limitations:
- The smoke proves the configured-YOLO runtime path, provenance and persistence. It does not prove production model quality because it runs against the synthetic demo raster.
- Real operational validation still requires uploading a georeferenced Kempen orthophoto/GeoTIFF, running the configured building model on that raster and comparing persisted detections against reference building vectors through QA/QC.
Next recommended pass:
- Create the real-data validation path for orthophoto upload, tile generation, configured building-model run and reference-vector QA/QC.
## Sprint 118 Local model and reference catalog clarity (2026-07-06)
Changed:
- Added a read-only backend model asset catalog through `GET /api/v1/detection/model-assets`.
- Added `YOLO_MODELS_DIR` to backend settings, Compose, Unraid env examples and all-in-one runtime startup so `/app/models` is the explicit model catalog directory.
- Extended configured YOLO preflight and detection runs with optional `model_asset_id`, resolved server-side against the model asset catalog.
- Detection jobs and analysis runs now persist selected model asset ID, path and SHA-256 in parameters for reproducibility.
- Detection Lab now loads local model assets, selects the active model by default and lets operators choose a cataloged local model file for `yolo-configured`.
- Provider Capabilities now distinguishes GRB/OSM/manual/fixture reference-data sources from AI model choices.
- Updated `docs/API_CONTRACTS.md`, `docs/AI_PIPELINES.md`, `backend/README.md`, `frontend/README.md`, `deploy/unraid/README.md`, `scripts/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
- Added design/plan documents under `docs/superpowers/`.
Validation:
- RED: `python -m pytest backend/tests/test_model_asset_catalog.py -q` failed before implementation because `app.services.model_asset_catalog_service` did not exist.
- `python -m pytest backend/tests/test_model_asset_catalog.py -q` passed: 5 tests.
- RED: `python -m pytest backend/tests/test_sprint118_yolo_preflight_ui.py -q` failed before frontend wiring because the model asset types/API/hook/UI were absent.
- `python -m pytest backend/tests/test_sprint118_yolo_preflight_ui.py -q` passed: 2 tests.
- RED: runtime config tests failed before `YOLO_MODELS_DIR` was added to env examples, Unraid runtime and `scripts/configure_yolo_model.py`.
- `python -m pytest backend/tests/test_docker_runtime_config.py::test_env_example_uses_runtime_env_names_read_by_backend_and_frontend backend/tests/test_docker_runtime_config.py::test_unraid_deploy_passes_ai_build_arg_and_yolo_runtime_env backend/tests/test_sprint119_yolo_model_configuration.py -q` passed: 6 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 383 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `python scripts/audit_api_contracts.py` passed: 81 implemented routes match docs; 2 explicit non-envelope endpoints tracked.
- `bash scripts/run_readiness_check.sh` passed: 383 backend tests plus frontend typecheck/build, API contract audit, Alembic head and shell syntax checks.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh; bash -n deploy/unraid/run-dockerman-container.sh; bash -n deploy/unraid/all-in-one-start.sh; bash -n scripts/deploy_tower.sh` passed.
- Local `docker compose config` could not run because Docker is not installed in this Windows Codex environment; Tower deploy validation remains required.
- `git push origin main` passed and pushed commits through `6e2a8cb`.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` with `GEOINTEL_INSTALL_AI=true` passed and redeployed Tower from commit `6e2a8cb`.
- Deploy-time live migration smoke passed on Tower; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`, API proxy and icon.
- Live `GET http://192.168.10.150:1202/api/v1/detection/model-assets` returned two cataloged local assets: `yolov8n-building-segmentation-pt` active with SHA-256 `152d6a9c5c76c9f2fd2fd5cc167efaed7c8c02e31002b15415899710f1d71f98`, and `yolov8n-pt`.
- Live `GET /api/v1/detection/yolo/preflight?model_asset_id=yolov8n-pt` resolved `/app/models/yolov8n.pt`, reported dependencies available, no downloads and no inference.
- Live `GET /api/v1/detection/yolo/preflight?model_asset_id=yolov8n-building-segmentation-pt&check_model_load=true` passed model load smoke with `model_load_ok=true`, `torch_version=2.12.1`, `ultralytics_version=8.4.89`, no downloads and no inference.
- Internal browser validation passed on `http://192.168.10.150:1202`: Detection Lab showed `Local model assets`, listed `yolov8n-building-segmentation (active)` and `yolov8n`, auto-selected the active asset, showed no-download copy, and emitted no console errors.
- Internal browser validation passed for System/Provider Capabilities: `Official reference sources`, GRB, OSM and `not AI model choices` copy were visible with no console errors.
Limitations:
- The catalog is intentionally filesystem-backed and read-only. It does not download, validate semantic class metadata, train models or manage model lifecycle records in the database.
- GRB/OSM remain provider capabilities only; no live external fetching was added.
Next recommended pass:
- Redeploy Tower, verify `/api/v1/detection/model-assets`, confirm Detection Lab shows the local model picker, then continue with real raster/model workflow validation on non-synthetic imagery.
## Sprint 117 Reusable GIS run and AI runtime opt-in (2026-07-05)
Changed:
- Added a Map workspace full-run mode selector with `Create new dataset/export` and `Reuse latest saved dataset for QA`.
- Reuse mode runs QA/QC against the latest saved derived map-selection dataset without creating another derived dataset/export pair.
- Added opt-in Docker and Unraid AI build support through `GEOINTEL_INSTALL_AI=true`; default builds still install only the GIS runtime.
- Passed YOLO runtime environment variables and a `/app/models` volume into the all-in-one Unraid container so local PyTorch/Ultralytics models can be mounted explicitly.
- Hardened the AI image path after Tower validation showed `torch` imported but `ultralytics` failed on a missing OpenCV native library. The Dockerfiles now include the required OpenCV runtime shared libraries and YOLO dependency detection performs real imports instead of `find_spec` checks.
- Added a writable `YOLO_CONFIG_DIR` default under application storage after Tower validation showed Ultralytics otherwise falls back to `/tmp` because root config is not writable in the container.
- Added YOLO preflight runtime diagnostics so operators can see dependency assumption state, model directory, `YOLO_CONFIG_DIR`, installed `torch`/`ultralytics` package versions and CUDA availability without loading a model, running inference or downloading weights.
- Added a read-only `GET /api/v1/detection/yolo/preflight` endpoint and Detection Lab YOLO runtime preflight panel so browser operators can inspect live AI runtime readiness without loading a model, running inference or downloading weights.
- Updated `.env.example`, `backend/README.md`, `frontend/README.md`, `scripts/README.md`, `docs/AI_PIPELINES.md`, `docs/TODO.md` and `CHANGELOG.md`.
- Added regression coverage in `backend/tests/test_sprint116_operational_gis_map_workflow.py`, `backend/tests/test_sprint8b_yolo_foundation.py` and `backend/tests/test_docker_runtime_config.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py backend\tests\test_docker_runtime_config.py -q` failed before implementation because `fullWorkflowMode`, AI build args and YOLO runtime env wiring were absent.
- `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py backend\tests\test_docker_runtime_config.py -q` passed: 22 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `python -m compileall backend/app` passed.
- `python -m py_compile scripts\yolo_preflight.py backend\scripts\yolo_preflight.py` passed.
- `python -m pytest backend\tests\test_sprint31_unraid_template.py backend\tests\test_docker_runtime_config.py -q` passed: 27 tests.
- RED: `python -m pytest backend\tests\test_sprint8b_yolo_foundation.py backend\tests\test_docker_runtime_config.py -q` failed before the runtime hardening because YOLO dependency detection still used `find_spec` and the Dockerfiles lacked OpenCV native runtime libraries.
- `python -m pytest backend\tests\test_sprint8b_yolo_foundation.py backend\tests\test_docker_runtime_config.py -q` passed: 30 tests.
- RED: `python -m pytest backend\tests\test_docker_runtime_config.py -q` failed before `YOLO_CONFIG_DIR` wiring because the Compose, Unraid and startup paths did not define a writable Ultralytics config directory.
- `python -m pytest backend\tests\test_docker_runtime_config.py -q` passed: 21 tests.
- `python -m compileall backend/app` passed after the AI runtime hardening.
- `cd backend && python -m pytest -q` passed: 367 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 367 backend tests plus frontend typecheck/build.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh; bash -n scripts/deploy_tower.sh; bash -n deploy/unraid/run-dockerman-container.sh` passed.
- Local Codex host could not run `docker compose config` because Docker is not installed in this Windows environment; Tower Docker validation is required after push/deploy.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` with `GEOINTEL_INSTALL_AI=true` passed after the AI runtime hardening and redeployed Tower from commit `9cad8d4`.
- Deploy-time live migration smoke passed on Tower; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`, API proxy and icon.
- Tower container check passed: `torch` imported as `2.12.1+cu130`, `torch.cuda.is_available()` returned `False`, `ultralytics` imported as `8.4.87`, and `scripts/yolo_preflight.py --enabled --json` returned `dependencies_available=true`, `status=not_configured`, `will_download_models=false`, `will_run_inference=false` because no local model path is configured yet.
- Tower runtime `YOLO_CONFIG_DIR` is `/app/storage/ultralytics`; the directory exists, is writable and Ultralytics writes settings there instead of root config.
- Internal browser validation passed against `http://192.168.10.150:1202`: the live shell and Map workspace rendered without console errors, with database layer selection, Operational GIS controls, and both full-run modes visible.
- RED: `python -m pytest backend\tests\test_sprint13_yolo_preflight.py -q` failed before runtime diagnostics were implemented because `runtime` was absent from preflight output.
- `python -m pytest backend\tests\test_sprint13_yolo_preflight.py -q` passed: 8 tests.
- `python -m pytest backend\tests\test_sprint13_yolo_preflight.py backend\tests\test_sprint8b_yolo_foundation.py backend\tests\test_docker_runtime_config.py -q` passed: 39 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 369 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 369 backend tests plus frontend typecheck/build and Alembic head.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh`, `bash -n scripts/deploy_tower.sh`, `bash -n deploy/unraid/run-dockerman-container.sh` and `bash -n deploy/unraid/all-in-one-start.sh` passed.
- Local Codex host still cannot run `docker compose config` because Docker is not installed in this Windows environment; Tower Docker validation is required after push/deploy.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` with `GEOINTEL_INSTALL_AI=true` passed and redeployed Tower from commit `7a29e78`.
- Deploy-time live migration smoke passed on Tower; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`, API proxy and icon.
- Tower container check passed: remote checkout is `7a29e78`, `geointel` is healthy on `0.0.0.0:1202->80/tcp`, and `scripts/yolo_preflight.py --enabled --json` reports `dependencies_available=true`, `torch_version=2.12.1`, `ultralytics_version=8.4.88`, `cuda_available=false`, `yolo_config_dir=/app/storage/ultralytics`, `status=not_configured`, `will_download_models=false` and `will_run_inference=false`.
- RED: `python -m pytest backend\tests\test_sprint13_yolo_preflight.py::test_yolo_preflight_api_returns_canonical_envelope backend\tests\test_sprint118_yolo_preflight_ui.py -q` failed before implementation because `/api/v1/detection/yolo/preflight` returned 404 and the Detection Lab did not surface a YOLO runtime preflight panel.
- `python -m pytest backend\tests\test_sprint13_yolo_preflight.py::test_yolo_preflight_api_returns_canonical_envelope backend\tests\test_sprint118_yolo_preflight_ui.py -q` passed: 2 tests.
- `cd frontend && npm run typecheck` passed after adding the preflight API client and Detection Lab panel.
- `python -m pytest backend\tests\test_sprint13_yolo_preflight.py backend\tests\test_sprint118_yolo_preflight_ui.py backend\tests\test_sprint48_api_contract_audit.py -q` passed: 13 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 371 tests.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 371 backend tests plus frontend typecheck/build and API contract audit for 80 documented routes.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` and `bash -n scripts/deploy_tower.sh` passed.
- `git push` passed after Tower/Gitea became reachable again and pushed commit `7aa9382`.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` with `GEOINTEL_INSTALL_AI=true` passed and redeployed Tower from commit `7aa9382`.
- Deploy-time live migration smoke passed on Tower; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for `http://192.168.10.150:1202`, API proxy and icon.
- Live API check passed for `GET http://192.168.10.150:1202/api/v1/detection/yolo/preflight`: it returned the canonical `data` envelope, `status=not_configured`, `YOLO_ENABLED=false`, `torch_version=2.12.1`, `ultralytics_version=8.4.89`, `yolo_config_dir=/app/storage/ultralytics`, `will_download_models=false` and `will_run_inference=false`.
- Tower container check passed with explicit CLI `--enabled`: `dependencies_available=true`, `torch_version=2.12.1`, `ultralytics_version=8.4.89`, `cuda_available=false`, `status=not_configured`, `will_download_models=false` and `will_run_inference=false` because no local model path is configured yet.
Limitations:
- `GEOINTEL_INSTALL_AI=true` installs optional PyTorch/Ultralytics dependencies but still requires a user-provided local model file; GeoIntel does not download weights.
- Reuse mode intentionally reuses only the latest saved map-selection dataset for QA/QC. It does not delete or mutate older derived datasets/exports.
Next recommended pass:
- Run full readiness, deploy Tower, and browser-verify both Map run modes plus configured-YOLO preflight status in the live container.
## Sprint 116 Operational GIS map workflow (2026-07-04)
Changed:
- Switched the default MapLibre basemap to an OpenStreetMap road raster style with visible attribution while preserving `VITE_MAP_STYLE_URL` as the override for managed/production map styles.
- Added a persisted database layer selector to the Map workspace so ready vector datasets can be opened directly from stored project data.
- Added an Operational GIS run panel that reuses the selected AOI bbox or active layer bbox and calls the existing persisted `vector_features` bbox selection workflow.
- Added a visible basemap policy notice when the public OpenStreetMap fallback is active.
- Added a guided operational workflow that brings query, derived dataset save, GeoJSON export, reference selection, QA/QC run and evidence handoff into the Map workspace.
- Added a one-click full GIS workflow action that runs persisted selection, saves the derived dataset, saves a GeoJSON export and optionally runs QA/QC against the selected reference dataset.
- Updated `.env.example`, `CHANGELOG.md`, `docs/TODO.md`, `docs/ENVIRONMENT_SPEC.md` and `frontend/README.md`.
- Added regression coverage in `backend/tests/test_sprint116_operational_gis_map_workflow.py`.
Validation:
- `cd frontend && npm run typecheck` passed.
- `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py backend\tests\test_sprint85_map_workspace_density.py backend\tests\test_sprint106_map_bbox_extract.py backend\tests\test_sprint107_map_selection_export.py backend\tests\test_sprint108_map_selection_derived_dataset.py -q` passed: 18 tests.
- `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py backend\tests\test_sprint109_map_selection_qa_shortcut.py backend\tests\test_sprint107_map_selection_export.py backend\tests\test_sprint108_map_selection_derived_dataset.py -q` passed: 11 tests.
- `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py -q` passed: 2 tests after aligning `.env.example` with the managed-style override policy.
- RED: `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py -q` failed before implementation because `Run full GIS workflow`, `runFullGisWorkflow` and `fullWorkflowStatus` were not present.
- `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py -q` passed: 2 tests after adding the full GIS workflow action.
- `python -m pytest backend\tests\test_sprint116_operational_gis_map_workflow.py backend\tests\test_sprint106_map_bbox_extract.py backend\tests\test_sprint107_map_selection_export.py backend\tests\test_sprint108_map_selection_derived_dataset.py backend\tests\test_sprint109_map_selection_qa_shortcut.py backend\tests\test_sprint110_map_qa_evidence_drilldown.py -q` passed: 18 tests.
- `cd frontend && npm run build` passed.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 364 tests.
- `bash scripts/run_readiness_check.sh` passed: 364 backend tests plus frontend typecheck/build.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202` from commit `350d50a`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Internal Codex browser validation passed against `http://192.168.10.150:1202`: the Map workspace rendered a nonblank road basemap, persisted vector layer selector, operational GIS run panel and bbox query action with no console errors.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed again after the guided workflow update; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202` from commit `14b66e6`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Internal Codex browser validation passed: the Map workspace showed the basemap policy notice, database layer selector, guided operational GIS steps/actions and nonblank map canvas with no console errors.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed after aligning `.env.example`; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202` from commit `fc88ceb`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Tower runtime check passed after the one-click GIS workflow update: remote checkout is commit `5331358`, the `geointel` all-in-one container is healthy and published on `0.0.0.0:1202->80/tcp`.
- `LIVE_SMOKE_CONTAINER=geointel bash scripts/live_migration_smoke.sh` passed on Tower; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202` passed on Tower for frontend, API proxy and icon.
- Internal Codex browser validation passed against `http://192.168.10.150:1202`: the Map workspace rendered without console warnings/errors or horizontal overflow, the `Run full GIS workflow` action was present, and a live run produced the persisted query/save/export status `Dataset/export complete. Select a reference dataset to add QA/QC.`
Limitations:
- The default OpenStreetMap tile service is appropriate for local V1 testing and demos, but production or heavier deployments should set `VITE_MAP_STYLE_URL` to a managed tile/style provider.
- This pass does not add live GRB/OSM fetching, new API routes, new migrations or fake data.
- The one-click workflow can still create a new derived dataset/export each time it is clicked; a future polish pass should add explicit reuse/replace behavior for repeated operator runs.
Next recommended pass:
- Add reuse/replace behavior for repeated map workflow runs and make reference selection for QA/QC more guided in the Map workspace.
## Sprint 115 QA/QC and Exports usability layout pass (2026-07-04)
Changed:
- Added a QA/Exports usability layer to the frontend shell CSS to reduce evidence/history density without changing behavior.
- Rebalanced QA/QC and Exports workspace columns for review-first usage.
- Made QA/QC summary, handoff, drilldown, feature evidence, metric history and raw provenance surfaces more compact.
- Reduced raw QA provenance height so JSON evidence remains available but no longer dominates the page.
- Made export handoff cards, latest-artifact cards, action cards and export history controls denser and easier to scan.
- Updated `CHANGELOG.md`, `docs/TODO.md` and `frontend/README.md`.
- Added regression coverage in `backend/tests/test_sprint115_quality_export_usability_layout.py`.
Validation:
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `python -m pytest backend\tests\test_sprint115_quality_export_usability_layout.py backend\tests\test_sprint86_quality_workspace_density.py backend\tests\test_sprint89_export_system_density.py backend\tests\test_sprint70_quality_handoff_polish.py backend\tests\test_sprint78_export_preview_readability.py -q` passed: 15 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 362 tests.
- `bash scripts/run_readiness_check.sh` passed: 362 backend tests plus frontend typecheck/build.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202` from commit `915b34c`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
Limitations:
- This pass is visual/layout only; it does not change API contracts, persistence, export generation, QA metrics or map behavior.
- Live Tower redeploy has been run; the QA/QC and Exports usability layout pass is available at `http://192.168.10.150:1202`.
Next recommended pass:
- Run a live visual audit after redeploy, then refine AI Labs/System or address any remaining visual rough edges found in the browser.
## Sprint 114 Data and Map usability layout pass (2026-07-04)
Changed:
- Added a Data/Map usability layer to the frontend shell CSS to improve the core select-and-extract workflow without changing behavior.
- Rebalanced the Data workspace columns and made dataset upload, role summaries, catalog cards, metrics and actions more compact.
- Made the Map workspace more map-first by ordering the MapLibre frame before dense controls and increasing desktop map height.
- Compressed map context, provenance, layer controls, bbox selection, selected-feature extraction and inspector surfaces.
- Updated `CHANGELOG.md`, `docs/TODO.md` and `frontend/README.md`.
- Added regression coverage in `backend/tests/test_sprint114_data_map_usability_layout.py`.
Validation:
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `python -m pytest backend\tests\test_sprint113_calm_workbench_layout.py backend\tests\test_sprint114_data_map_usability_layout.py backend\tests\test_sprint74_data_map_mobile_polish.py backend\tests\test_sprint85_map_workspace_density.py -q` passed: 10 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 360 tests.
- `bash scripts/run_readiness_check.sh` passed: 360 backend tests plus frontend typecheck/build.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202` from commit `9721937`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
Limitations:
- This pass is visual/layout only; it does not change API contracts, persistence, map query behavior, exports or QA logic.
- Live Tower redeploy has been run; the Data and Map usability layout pass is available at `http://192.168.10.150:1202`.
Next recommended pass:
- Run a live visual audit after redeploy and then refine QA/QC and Exports in the same quieter style.
## Sprint 113 calm workbench layout pass (2026-07-04)
Changed:
- Added a calm-density layer to the frontend shell CSS to reduce visual pressure without changing workflows.
- Softened the base palette, borders and shadows.
- Made the top context bar, left workspace navigation, main heading, readiness tiles and inspector surfaces more compact.
- Hid the duplicated workspace command bar because the sidebar remains the primary persistent navigation.
- Updated `CHANGELOG.md`, `docs/TODO.md` and `frontend/README.md`.
- Added regression coverage in `backend/tests/test_sprint113_calm_workbench_layout.py`.
Validation:
- `cd frontend && npm run typecheck` passed.
- `python -m pytest backend\tests\test_sprint49_workbench_shell_refactor.py backend\tests\test_sprint62_frontend_visual_polish.py backend\tests\test_sprint82_shell_density_polish.py backend\tests\test_sprint83_workspace_panel_hierarchy.py -q` passed: 10 tests.
- `cd frontend && npm run build` passed.
- `python -m pytest backend\tests\test_sprint113_calm_workbench_layout.py -q` passed: 2 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 358 tests.
- `bash scripts/run_readiness_check.sh` passed: 358 backend tests plus frontend typecheck/build.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202` from commit `0355a3d`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
Limitations:
- This pass improves visual density and hierarchy only; no API, persistence, workflow or map behavior changed.
- Live Tower redeploy has been run; the calmer layout is available at `http://192.168.10.150:1202`.
Next recommended pass:
- Do a live visual audit after redeploy and then tune individual workspaces, starting with Data and Map, based on actual screenshots.
## Sprint 112 QA evidence map overlay (2026-06-25)
Changed:
- Added `QualityEvidenceService` to resolve persisted QA/QC evidence ids back to stored geometries.
- Added `GET /api/v1/projects/{project_id}/quality-checks/{quality_check_id}/evidence/geojson`.
- The endpoint returns a canonical envelope with `quality_check_id`, dataset/run provenance, warnings and a GeoJSON FeatureCollection.
- Evidence resolution supports candidate dataset `vector_features`, candidate persisted `detections`/`segmentations` for analysis-run QA, and reference `vector_features`.
- Added QA/QC panel actions to show selected or latest evidence on the Map workspace.
- Added a MapLibre QA evidence source/layers with distinct match candidate, match reference, false-positive and false-negative styling.
- Added map overlay loading/error/clear state and a compact legend.
- Updated `docs/API_CONTRACTS.md`, `frontend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added regression coverage in `backend/tests/test_sprint112_qa_evidence_overlay.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint112_qa_evidence_overlay.py -q` failed before implementation because `app.services.quality_evidence_service` did not exist.
- RED: after backend implementation, the same test failed until frontend `qaEvidenceData`/API wiring existed.
- `python -m pytest backend\tests\test_sprint112_qa_evidence_overlay.py -q` passed: 4 tests.
- `cd frontend && npm run typecheck` passed after making the MapLibre expression type explicit.
- `python -m pytest backend\tests\test_sprint112_qa_evidence_overlay.py backend\tests\test_qa_service.py backend\tests\test_sprint8c_detection_visualization_qa.py backend\tests\test_sprint9_segmentation_foundation.py -q` passed: 25 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 356 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `bash scripts/run_readiness_check.sh` passed: 356 backend tests plus frontend typecheck/build.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202` from commit `b9674a0`.
- Deploy-time live migration smoke passed against the container database after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live QA evidence API smoke passed: `GET /api/v1/projects/c0b00f1f-80bf-4992-be94-f5e5e6f6bf63/quality-checks/2a291f88-5ed1-4110-ba6b-d200ec722098/evidence/geojson` returned a GeoJSON FeatureCollection with 4 persisted evidence features and 0 warnings.
- Internal Codex browser validation passed against `http://192.168.10.150:1202`: the QA/QC evidence drilldown rendered, `Show evidence overlay` opened the Map workspace, MapLibre canvas was present, the QA/QC evidence overlay reported 4 rendered features, and the mobile viewport had no horizontal overflow.
Limitations:
- The overlay is generated read-only from existing persisted evidence and geometries; no new evidence table or migration was introduced.
- Missing evidence ids are reported as warnings and do not create fake geometries.
- No provider fetching, AI dependency, real model behavior or new product domain was added.
Next recommended pass:
- Consider a small export/handoff action for the evidence overlay GeoJSON or a reusable browser smoke script that verifies the QA evidence overlay after deploy.
## Sprint 111 QA feature evidence persistence (2026-06-25)
Changed:
- Added feature-level evidence extraction to the shared QA IoU matcher.
- Dataset QA now returns and persists `match_evidence`, `false_positive_evidence` and `false_negative_evidence`.
- Detection QA and segmentation QA now use the same evidence-aware matcher and persist the same evidence keys in `quality_checks.findings_json`.
- Extended the QA/QC drilldown with compact matched, false-positive and false-negative feature id lists before the raw findings JSON.
- Updated `docs/API_CONTRACTS.md`, `frontend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added/extended regression coverage in `backend/tests/test_qa_service.py`, `backend/tests/test_sprint7a_persistence_foundation.py` and `backend/tests/test_sprint111_qa_feature_evidence.py`.
Validation:
- RED: `python -m pytest backend\tests\test_qa_service.py -q` failed before implementation because `QaProviderComparisonResult` had no `match_evidence`.
- RED: `python -m pytest backend\tests\test_sprint111_qa_feature_evidence.py -q` failed before docs were updated because `docs/API_CONTRACTS.md` did not document the evidence keys.
- `python -m pytest backend\tests\test_qa_service.py -q` passed: 3 tests.
- `python -m pytest backend\tests\test_sprint8c_detection_visualization_qa.py backend\tests\test_sprint9_segmentation_foundation.py -q` passed: 18 tests.
- `python -m pytest backend\tests\test_sprint111_qa_feature_evidence.py -q` passed: 2 tests.
- `python -m pytest backend\tests\test_qa_service.py backend\tests\test_sprint7a_persistence_foundation.py -q` passed: 10 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 352 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202`.
- Deploy-time live migration smoke passed against the container database, including PostGIS/version/schema checks.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live QA API smoke passed: `POST /api/v1/qa/detections-vs-reference` returned `match_evidence`, `false_positive_evidence` and `false_negative_evidence`.
- Live persisted quality-check smoke passed: `GET /api/v1/projects/c0b00f1f-80bf-4992-be94-f5e5e6f6bf63/quality-checks` returned the evidence arrays in `findings_json`.
Limitations:
- Feature-level evidence is persisted as ids/IoU metadata in `quality_checks.findings_json`; no `quality_check_items` table or first-class evidence geometry table was introduced.
- Evidence map overlays can now be built from persisted ids, but overlay generation remains future work.
- No migration, provider fetching, AI dependency, real model behavior or new product domain was added.
Next recommended pass:
- Add QA evidence overlay generation by resolving persisted evidence ids back to candidate/reference geometries and rendering false positives/false negatives as MapLibre layers.
## Sprint 110 Map QA evidence drilldown (2026-06-25)
Changed:
- Extended `QaComparisonResult` frontend typing with optional `quality_check_id`, matching the existing backend QA result payload.
- Updated `useMapSelectionQa` to keep the latest persisted map-selection quality-check id after a successful QA/QC comparison.
- Extended the Map workspace QA/QC result state with inline evidence: quality-check id, matches, false positives, false negatives, mean IoU and QA warnings.
- Added `Open QA/QC evidence` handoff from Map workspace to the existing QA/QC workspace drilldown, avoiding a parallel QA detail system.
- Added compact styling for the Map QA evidence and warning surface.
- Updated `frontend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added regression coverage in `backend/tests/test_sprint110_map_qa_evidence_drilldown.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint110_map_qa_evidence_drilldown.py -q` failed before implementation because the hook/evidence wiring was absent.
- `python -m pytest backend\tests\test_sprint110_map_qa_evidence_drilldown.py -q` passed: 2 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 349 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202`.
- Deploy-time live migration smoke passed against the container database, including PostGIS/version/schema checks.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live API proxy smoke passed: `GET http://192.168.10.150:1202/api/v1/projects` returned the demo project envelope.
Limitations:
- The Map evidence handoff opens the existing QA/QC workspace; selecting a specific historical check inside that workspace remains governed by the QA/QC panel's own latest-check behavior.
- False-positive and false-negative geometries are summarized by persisted metrics/findings; dedicated map overlays for unmatched evidence remain future work.
- No backend API contract, migration, provider fetching, AI dependency, real model behavior or new product domain was added.
Next recommended pass:
- Add optional unmatched-evidence map overlays once the QA persistence model stores explicit matched/unmatched feature ids or geometries.
## Sprint 109 Map selection QA shortcut (2026-06-25)
Changed:
- Added `useMapSelectionQa` to keep Map workspace QA/QC orchestration out of `App.tsx`.
- Added a Map workspace QA/QC shortcut after `Save as dataset`, allowing the latest derived map selection dataset to be compared against a selected reference dataset.
- The shortcut reuses the existing `qaApi.runQa` flow and refreshes persisted quality checks/project data after completion.
- Added inline precision, recall, F1 and quality-check status feedback in the Map workspace.
- Added compact styling for the Map selection QA surface.
- Updated `frontend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added regression coverage in `backend/tests/test_sprint109_map_selection_qa_shortcut.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint109_map_selection_qa_shortcut.py -q` failed before implementation because the hook and wiring were absent.
- `python -m pytest backend\tests\test_sprint109_map_selection_qa_shortcut.py -q` passed: 2 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 347 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202`.
- Deploy-time live migration smoke passed against the container database, including PostGIS/version/schema checks.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live API QA smoke passed: `POST /api/v1/qa/detections-vs-reference` compared derived map selection dataset `266aa1de-908e-4bc4-987e-996374ad747b` against reference dataset `21dd968a-2ba4-4798-89d4-f3af91f9d24c`, returned `precision=0.5`, `recall=0.5`, `f1_score=0.5`, `mean_iou=0.8339768339652592` and persisted quality check `1730c270-6dee-4000-8813-12aa91df6b33`.
- Live quality-check list smoke passed: `GET /api/v1/projects/c0b00f1f-80bf-4992-be94-f5e5e6f6bf63/quality-checks` returned the persisted map-selection QA check with precision, recall, F1, mean IoU, false-positive and false-negative metrics.
Limitations:
- The Map shortcut currently uses the existing QA comparison defaults with IoU threshold `0.5`.
- QA results are summarized inline; detailed false-positive/false-negative evidence remains in the QA/QC workspace.
- No backend API contract, migration, provider fetching, AI dependency, real model behavior or new product domain was added.
Next recommended pass:
- Add a QA result drilldown/handoff from the Map workspace so operators can inspect persisted false-positive and false-negative evidence directly after running selection QA/QC.
## Sprint 108 Map selection derived datasets (2026-06-25)
Changed:
- Added `POST /api/v1/projects/{project_id}/datasets/{dataset_id}/vector/select/derive`.
- Added `VectorSelectionDeriveRequest` for bbox selection-to-derived-dataset requests.
- Added `VectorOperationsService.derive_selection_dataset`, which selects persisted PostGIS `vector_features`, writes a derived GeoJSON dataset artifact, stores source provenance and re-indexes the derived features into `vector_features`.
- Added `Save as dataset` to the Map workspace selection result state with loading/error/latest-dataset feedback.
- Updated frontend dataset API typing and wiring for selection-derived datasets.
- Updated `docs/API_CONTRACTS.md`, `backend/README.md`, `frontend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added regression coverage in `backend/tests/test_sprint108_map_selection_derived_dataset.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint108_map_selection_derived_dataset.py -q` failed before implementation because the service, route and frontend contracts were absent.
- `python -m pytest backend\tests\test_sprint108_map_selection_derived_dataset.py -q` passed: 4 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 345 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202`.
- Deploy-time live migration smoke passed against the container database, including PostGIS/version/schema checks.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live API smoke passed: `POST /api/v1/projects/c0b00f1f-80bf-4992-be94-f5e5e6f6bf63/datasets/6e5a3926-1a15-4136-b54f-ba5de9ec0e84/vector/select/derive` created derived dataset `266aa1de-908e-4bc4-987e-996374ad747b` with `dataset_role="derived"`, `source_name="map_selection"` and 2 features.
- Live API content smoke passed: `GET /api/v1/projects/c0b00f1f-80bf-4992-be94-f5e5e6f6bf63/datasets/266aa1de-908e-4bc4-987e-996374ad747b/content` returned a GeoJSON `FeatureCollection` with 2 features.
- Live PostGIS query smoke passed: `POST /api/v1/projects/c0b00f1f-80bf-4992-be94-f5e5e6f6bf63/datasets/266aa1de-908e-4bc4-987e-996374ad747b/vector/select` returned 2 features from the derived dataset's persisted `vector_features`.
Limitations:
- Selection-derived datasets are bbox-only and use EPSG:4326 coordinates.
- Empty selections are rejected with `VECTOR_OPERATION_EMPTY_RESULT`.
- No migrations, live provider fetching, AI dependency, real model behavior or new product domain were added.
Next recommended pass:
- Add an explicit QA/QC shortcut from a selected derived map dataset to compare it against a reference dataset without leaving the Map workspace.
## Sprint 107 Map selection export handoff (2026-06-25)
Changed:
- Added `vector_selection` to the GeoJSON export contract.
- Added `ExportService.export_vector_selection_geojson`, which queries persisted PostGIS `vector_features` through `VectorFeatureService.select_features_by_bbox`, writes the selected FeatureCollection and persists an `exports` row with `export_type="vector_selection_geojson"`.
- Extended `POST /api/v1/exports/geojson` to accept `export_kind="vector_selection"` with EPSG:4326 bbox and feature limit.
- Added frontend export API typing for bbox/limit and `useExportWorkflow.exportMapSelectionGeoJson`.
- Added `Save area export` to the Map workspace selection result state with loading/error/latest-path feedback.
- Updated `docs/API_CONTRACTS.md`, `backend/README.md`, `frontend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added regression coverage in `backend/tests/test_sprint107_map_selection_export.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint107_map_selection_export.py -q` failed before implementation because the selection export service, route contract and frontend wiring were absent.
- `python -m pytest backend\tests\test_sprint107_map_selection_export.py -q` passed: 3 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 341 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed; rebuilt and redeployed the all-in-one container on `http://192.168.10.150:1202`.
- Deploy-time live migration smoke passed against the container database, including PostGIS/version/schema checks.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live API smoke passed: `POST /api/v1/exports/geojson` with `export_kind="vector_selection"` created export `1d16c78b-7e8c-4081-8edc-5be38811b50e` with `export_type="vector_selection_geojson"`, `feature_count=2` and `source_table="vector_features"`.
- Live API content smoke passed: `GET /api/v1/exports/1d16c78b-7e8c-4081-8edc-5be38811b50e/content` returned a GeoJSON `FeatureCollection` with 2 persisted vector features.
Limitations:
- Selection exports are bbox-only and reuse the same EPSG:4326 constraints as the Map area selection endpoint.
- Saving a selection creates an export artifact, not a derived dataset.
- No migrations, live provider fetching, AI dependency, real model behavior or new product domain were added.
Next recommended pass:
- Add a live browser smoke that exercises `Save area export`, confirms the export appears in Export Center history and previews/downloads the persisted `vector_selection_geojson` artifact.
## Sprint 106 Map area selection extract (2026-06-25)
Changed:
- Added `POST /api/v1/projects/{project_id}/datasets/{dataset_id}/vector/select` for read-only bbox selection over persisted PostGIS `vector_features`.
- Added `VectorSelectionBBox`, `VectorSelectionRequest` and `VectorSelectionResponse` schemas and exported them through the backend schema module.
- Added `VectorFeatureService.select_features_by_bbox`, including EPSG:4326 bbox validation, feature limit capping, PostGIS `ST_Intersects` query and GeoJSON FeatureCollection conversion from persisted geometries.
- Added frontend `selectVectorFeatures` API client support and `useMapSelectionExtract`.
- Extended the Map workspace with an `Area selection` panel, two-click map bbox selection, manual bbox inputs, selected-feature/AOI/active-layer bbox shortcuts, area GeoJSON download/copy actions and a compact selected-feature table.
- Extended `GeoMap` with `selection-bbox` and `selection-result` MapLibre GeoJSON overlays.
- Updated `docs/API_CONTRACTS.md`, `frontend/README.md`, `backend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added regression coverage in `backend/tests/test_sprint106_map_bbox_extract.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint106_map_bbox_extract.py -q` failed before implementation because the vector selection service, route and frontend contracts were absent.
- `python -m pytest backend\tests\test_sprint106_map_bbox_extract.py -q` passed: 5 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 338 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed commit `851d722` to Tower on port 1202.
- Deploy-time live migration smoke passed after database readiness attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed with demo project, AOI, 3/3 ready datasets and seeded QA/QC.
- Live API smoke passed against `POST /api/v1/projects/{project_id}/datasets/{dataset_id}/vector/select`: demo vector dataset returned 2 persisted features as a GeoJSON FeatureCollection.
- Internal browser validation passed against `http://192.168.10.150:1202`: Map workspace rendered `Area selection`, `Start map bbox` and `Run area extract`; `Use layer bbox` filled EPSG:4326 bbox values; `Run area extract` returned 2 features, showed `vector_features` source plus `Download area GeoJSON` and `Copy area GeoJSON`; console warnings/errors were empty.
Limitations:
- Selection shape is bbox-only in EPSG:4326. Polygon/lasso selection remains future work.
- The endpoint is read-only and does not create exports or derived datasets; operators can download the selected GeoJSON client-side.
- No migrations, live provider fetching, AI dependency, real model behavior or new product domain were added.
Next recommended pass:
- Add a browser/live smoke around the area selection panel after deploy, then consider export-center handoff for persisted selection artifacts if V1 needs server-side audit retention.
## Sprint 105 Map feature extract (2026-06-25)
Changed:
- Added a `Selection & extract` surface to `frontend/src/components/map/MapWorkspace.tsx`.
- Clicking a visible map feature now gives operators a focused extraction panel with geometry type, coordinate count, EPSG:4326 bbox, property count and property table.
- Added client-side `Download selected GeoJSON`, `Copy selected properties` and `Clear selection` actions for the clicked feature.
- Added a dedicated `selected-feature` MapLibre source with fill/line/circle highlight layers in `frontend/src/components/GeoMap.tsx`.
- Wired the selected feature highlight through `frontend/src/App.tsx`.
- Added responsive selection/extract CSS in `frontend/src/styles/app.css`.
- Updated `frontend/README.md`, `CHANGELOG.md` and `docs/TODO.md`.
- Added `backend/tests/test_sprint105_map_feature_extract.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint105_map_feature_extract.py -q` failed before implementation because the extract panel, selected-feature highlight layer and CSS contracts were absent.
- `python -m pytest backend\tests\test_sprint105_map_feature_extract.py backend\tests\test_sprint19_map_workbench.py backend\tests\test_sprint85_map_workspace_density.py -q` passed: 9 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -q` passed: 333 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed commit `561304c` to Tower on port 1202.
- Deploy-time live migration smoke passed after database readiness attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Internal browser live check confirmed the Map workspace renders the `Selection & extract` panel and empty selection guidance at `http://192.168.10.150:1202`.
- Live frontend bundle check confirmed `Selection & extract`, `selected-feature` and `Download selected GeoJSON` markers in `/assets/index-DVYT-JPu.js`.
Limitations:
- This pass extracts the single currently clicked and loaded map feature only.
- Rectangle, lasso or polygon selection over persisted PostGIS `vector_features` still requires a backend spatial query endpoint and drawing workflow.
- Internal browser canvas clicks did not reliably hit the small demo polygon features during validation; static regression tests, TypeScript build and live bundle markers verify the MapLibre selection wiring, and the live UI panel is present.
- No backend API contract, migration, provider fetching, AI dependency or persistence behavior changed.
Next recommended pass:
- Add map area/rectangle selection backed by a PostGIS spatial-query endpoint for multi-feature extraction, then expose export handoff for the selected result set.
## Sprint 100 raster tile Segmentation Lab handoff (2026-06-24)
Changed:
- Added `segmentationTileManifestPath` state to `frontend/src/hooks/useSegmentationWorkflow.ts`.
- Sent `tile_manifest_path` in existing segmentation run requests when the field is populated.
- Added a `Tile manifest` input to `frontend/src/components/segmentation/SegmentationLab.tsx`.
- Added a `Use in Segmentation Lab` handoff beside the existing Detection Lab handoff in `frontend/src/components/datasets/RasterControls.tsx`.
- Wired the handoff through `frontend/src/components/datasets/DatasetDetailPanel.tsx` and `frontend/src/App.tsx`.
- Updated `frontend/README.md` and `CHANGELOG.md`.
- Added `backend/tests/test_sprint100_segmentation_manifest_handoff.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint100_segmentation_manifest_handoff.py -q` failed before implementation because segmentation manifest state and handoff wiring did not exist.
- `python -m pytest backend\tests\test_sprint100_segmentation_manifest_handoff.py -q` passed.
- `cd frontend && npm run typecheck` passed.
- `python -m pytest backend\tests\test_sprint100_segmentation_manifest_handoff.py backend\tests\test_sprint99_raster_ui_handoff.py backend\tests\test_sprint88_ai_lab_density.py backend\tests\test_sprint9_segmentation_foundation.py -q` passed: 17 tests.
- `cd frontend && npm run build` passed.
- `python -m compileall backend/app` passed.
- `python -m pytest -q` from `backend/` passed: 323 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `140314a` to Tower on port 1202.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202` passed: inspect, preview, stats and `raster.tile`.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed with `3/3 ready` datasets.
- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed.
- Live frontend bundle check confirmed `Latest tile manifest`, `Use in Detection Lab`, `Use in Segmentation Lab` and `Raster tile manifest path` markers in `/assets/index-DygxAZpB.js`.
Limitations:
- Frontend handoff only; no backend route, migration, provider fetching, AI dependency or model behavior changes.
- Segmentation remains governed by the existing model registry and explicit-run controls.
Next recommended pass:
- Add a real browser interaction smoke for clicking both raster manifest handoff buttons into AI Labs, then continue with small usability polish around AI model readiness.
## Sprint 99 raster tile Detection Lab handoff (2026-06-23)
Changed:
- Added latest raster tile manifest tracking to `frontend/src/hooks/useDatasetWorkflow.ts` from persisted `raster.tile` job results and direct tile generation responses.
- Surfaced the latest manifest path in `frontend/src/components/datasets/RasterControls.tsx`.
- Added a `Use in Detection Lab` handoff that fills the selected raster dataset and tile manifest path in the existing Detection Lab state.
- Updated `frontend/src/components/datasets/DatasetDetailPanel.tsx`, `frontend/src/App.tsx`, `frontend/README.md` and `CHANGELOG.md`.
- Added `backend/tests/test_sprint99_raster_ui_handoff.py`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py -q` failed before implementation because the raster tile manifest state and handoff wiring did not exist.
- `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py -q` passed.
- `cd frontend && npm run typecheck` passed.
- `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py backend\tests\test_sprint95_raster_pipeline_hardening.py backend\tests\test_sprint28_dataset_workflow_hook.py -q` passed: 6 tests.
- `cd frontend && npm run build` passed.
- `python -m compileall backend/app` passed.
- `python -m pytest -q` from `backend/` passed: 322 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `aa41dfa` to Tower on port 1202.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202` passed: inspect, preview, stats and `raster.tile`.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed with `3/3 ready` datasets.
- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed.
- Live frontend bundle check confirmed `Latest tile manifest` and `Use in Detection Lab` markers in `/assets/index-gJWV1CAi.js`.
Limitations:
- Frontend handoff only; no API contract, migration, provider fetching, AI inference or model behavior changes.
- The Detection Lab still follows the existing model availability and explicit-run constraints.
Next recommended pass:
- Add a browser interaction smoke for clicking the raster manifest handoff into Detection Lab, or continue with segmentation tile-manifest prefill parity.
## Sprint 98 demo raster workflow smoke (2026-06-23)
Changed:
- Added `scripts/verify_demo_raster_workflow.sh`, a browser-facing runtime smoke for the seeded `demo_context_raster.tif` fixture.
- Added the new smoke to readiness syntax checks.
- Hardened `RasterOperationsService.tile` so tile manifest bounds accept both Rasterio tuple bounds and object bounds.
- Updated `backend/tests/test_raster_operations_service.py` to cover tuple-based window bounds.
- Added `backend/tests/test_sprint98_raster_workflow_smoke.py`.
- Updated `scripts/README.md` and `CHANGELOG.md`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint98_raster_workflow_smoke.py -q` failed before implementation because `scripts/verify_demo_raster_workflow.sh` did not exist.
- `python -m pytest backend\tests\test_sprint98_raster_workflow_smoke.py backend\tests\test_readiness_gate.py -q` passed: 14 tests.
- `bash -n scripts/verify_demo_raster_workflow.sh` passed.
- Live diagnostic run of `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202` showed inspect, preview and stats passed, then raster tile failed with HTTP 500.
- Tower backend logs identified the root cause: `rasterio.windows.bounds(...)` returned a tuple, while tile manifest generation expected `.left/.bottom/.right/.top` attributes.
- RED: `python -m pytest backend\tests\test_raster_operations_service.py::test_raster_tile_returns_manifest_payload -q` reproduced the live `AttributeError` after updating the fixture to tuple bounds.
- `python -m pytest backend\tests\test_raster_operations_service.py::test_raster_tile_returns_manifest_payload backend\tests\test_sprint98_raster_workflow_smoke.py -q` passed: 2 tests.
- `python -m compileall backend/app` passed.
- `python -m pytest -q` from `backend/` passed: 321 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `7b093c0` to Tower on port 1202.
- `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202` initially proved the tile fix but exposed the existing job terminal status convention as `success` rather than `completed`; the smoke now accepts `success` and `completed`.
- `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202` passed after the smoke status fix: inspect, preview, stats and raster tile manifest all succeeded.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/run_readiness_check.sh` passed again after the smoke status update.
Limitations:
- The raster smoke creates a small tile set each run. It is appropriate for local/runtime validation, not high-volume benchmarking.
- The smoke intentionally does not run AI inference or external imagery/provider fetching.
Next recommended pass:
- Run full readiness, redeploy, then verify the raster smoke live against `http://192.168.10.150:1202`.
## Sprint 97 demo raster fixture workflow (2026-06-23)
Changed:
- Added `raster_dataset_id` to the demo workflow response contract.
- Extended `DemoWorkflowService` with a deterministic in-memory `demo_context_raster.tif` GeoTIFF fixture persisted through `StorageService` and the existing `datasets` table as a ready `raster`/`fixture` source dataset.
- Updated the frontend demo workflow hook so Detection and Segmentation Labs receive the seeded raster dataset while the candidate vector remains selected for Data, Map and Export review.
- Updated default-state and interaction smokes to require candidate vector, reference vector and raster fixture datasets as `3/3 ready`.
- Updated `scripts/README.md`, `frontend/README.md` and `CHANGELOG.md`.
Validation:
- RED: `python -m pytest backend\tests\test_sprint97_demo_raster_fixture.py -q` failed before implementation because the demo schema/service and frontend hook did not expose or select a raster fixture.
- `python -m pytest backend\tests\test_sprint97_demo_raster_fixture.py -q` passed: 2 tests.
- `python -m compileall backend/app` passed.
- `python -m pytest backend\tests\test_sprint97_demo_raster_fixture.py backend\tests\test_sprint15_demo_workflow.py backend\tests\test_sprint21_demo_workflow_smoke.py backend\tests\test_readiness_gate.py -q` passed: 21 tests.
- `bash -n scripts/verify_workbench_default_state.sh` passed.
- `bash -n scripts/verify_workbench_interactions.sh` passed.
- `cd frontend && npm run typecheck` passed.
- `python -m pytest backend\tests\test_sprint96_useful_default_context.py backend\tests\test_sprint39_frontend_orchestration_hooks.py -q` passed: 11 tests.
- `python -m pytest -q` from `backend/` passed: 320 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `ca730ed` to Tower on port 1202.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed and reported `Datasets: 3/3 ready`.
- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed and verified candidate, reference and raster fixture datasets.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202` passed.
- Live API check confirmed `demo_context_raster.tif` as `raster`/`fixture`/`ready` with `EPSG:4326`.
- Chrome headless screenshot of `http://192.168.10.150:1202` showed the populated Overview workspace, selected demo context and no obvious desktop horizontal overflow.
Limitations:
- The raster fixture is a tiny generated local GeoTIFF for V1 workflow validation only. It does not represent external imagery and does not enable real AI inference.
- No migrations, provider fetching, real YOLO/SAM behavior or product scope beyond the existing offline demo workflow changed.
- Optional `scripts/capture_workbench_screenshots.sh` could not run in this Windows runner because Playwright is not installed; Chrome headless was used for the live visual check instead.
Next recommended pass:
- Continue with a focused raster operation happy-path smoke against the seeded raster fixture: inspect, preview, stats and tiling through the browser-facing API.
## Sprint 48 Backend API contract audit (2026-06-17)
Changed:
- Added `scripts/audit_api_contracts.py` to import the FastAPI app, enumerate the implemented `GET`/`POST`/`PATCH`/`DELETE` route surface and compare it with active `### METHOD route` headings in `docs/API_CONTRACTS.md`.
- Added the API contract audit to `scripts/run_readiness_check.sh`.
- Corrected contract drift in `docs/API_CONTRACTS.md`:
- documented `GET/PATCH /api/v1/projects/{project_id}/areas/{area_id}`;
- corrected vector stats from `POST` to implemented `GET`;
- documented `GET /api/v1/projects/{project_id}/datasets/{dataset_id}/content`;
- changed non-implemented building-stats, legacy analysis object-detection/segmentation and YOLO export entries from active route headings to future-route notes.
- Added `backend/tests/test_sprint48_api_contract_audit.py`.
- Updated `scripts/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Validation:
- RED: `cd backend && python -m pytest tests/test_sprint48_api_contract_audit.py -q` failed before implementation because the audit script, readiness integration and route docs were missing.
- RED: `python scripts/audit_api_contracts.py` reported missing docs for 4 implemented routes and 5 stale documented routes.
- `python scripts/audit_api_contracts.py` passed: 76 implemented routes matched docs and 2 explicit non-envelope endpoints were tracked.
- `cd backend && python -m pytest tests/test_sprint48_api_contract_audit.py tests/test_readiness_gate.py -q` passed: 12 tests.
- `python -m py_compile scripts/audit_api_contracts.py` passed.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 201 tests.
- `bash scripts/run_readiness_check.sh` passed and included `API contract audit OK`.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed the all-in-one container to Tower on port 1202.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed after redeploy.
Limitations:
- This pass audits route documentation presence, implemented/stale route drift and explicit non-envelope exceptions. It does not yet exercise every error path response body at runtime.
- No API behavior, migrations, provider fetching, AI behavior or product capabilities changed.
Next recommended pass:
- Add an error-envelope runtime audit for representative invalid/missing-resource paths across projects, datasets, providers, detection, segmentation, QA and exports.
## Sprint 47 Workbench interaction smoke (2026-06-17)
Changed:
- Added stable `data-testid` anchors to the existing project, area, map, dataset, QA/QC and export controls so browser checks can target real controls instead of brittle text/layout selectors.
- Added `scripts/verify_workbench_interactions.sh`, a dependency-light runtime smoke that verifies the backing state for project switching, AOI/map selection, dataset selection, QA refresh and export refresh through the browser-facing API proxy.
- Added the script syntax check to `scripts/run_readiness_check.sh`.
- Added `backend/tests/test_sprint47_workbench_interaction_smoke.py` to keep the UI anchors, readiness gate and interaction smoke contract in place.
- Updated `scripts/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Validation:
- RED: `cd backend && python -m pytest tests/test_sprint47_workbench_interaction_smoke.py -q` failed before implementation because the UI anchors, readiness script reference and interaction smoke script were missing.
- `cd backend && python -m pytest tests/test_sprint47_workbench_interaction_smoke.py -q` passed: 3 tests.
- `cd frontend && npm run typecheck` passed.
- `bash -n scripts/verify_workbench_interactions.sh` passed.
- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed against the pre-deploy runtime API surface.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 198 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed the all-in-one container to Tower on port 1202.
- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed after redeploy.
- Live browser check against `http://192.168.10.150:1202` passed using the new anchors: project, map, dataset, QA/QC and export panels were present; QA refresh and export metadata actions worked; latest export updated; no horizontal overflow was detected.
Limitations:
- The shell smoke validates the state behind the controls but does not click rendered controls by itself. The added `data-testid` anchors are intended for Codex/browser click checks and future browser artifact automation.
- No API contracts, migrations, provider fetching, AI behavior or product capabilities changed.
Next recommended pass:
- Add persisted screenshot artifact automation for the anchored browser pass, or move to a backend service contract audit if UI stabilization is sufficient.
## Sprint 46 Workbench default-state smoke (2026-06-17)
Changed:
- Added `scripts/verify_workbench_default_state.sh`, a dependency-light runtime smoke for the browser-facing workbench default demo state.
- The smoke calls the offline demo workflow, then verifies `GeoIntel Demo - Building QA`, `Demo AOI - Geel buildings`, `2/2 ready` datasets and a persisted QA/QC result through canonical `data.items` envelopes.
- Added the script syntax check to `scripts/run_readiness_check.sh`.
- Extended `backend/tests/test_readiness_gate.py` so the readiness gate and script keep covering the default-state smoke contract.
- Updated `scripts/README.md` and `CHANGELOG.md`.
Validation:
- RED: `cd backend && python -m pytest tests/test_readiness_gate.py -q` failed before implementation because `verify_workbench_default_state.sh` was missing and readiness did not reference it.
- `cd backend && python -m pytest tests/test_readiness_gate.py -q` passed: 9 tests.
- `bash -n scripts/verify_workbench_default_state.sh` passed.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 195 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed the all-in-one container to Tower on port 1202.
- `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed after redeploy.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed after redeploy.
- Live browser check against `http://192.168.10.150:1202` passed at 1280x720: selected project `GeoIntel Demo - Building QA`, status showed `1 area`, `2/2 ready` datasets and `2 checks`, map workspace rendered and no horizontal overflow was detected.
Limitations:
- The committed smoke validates the connected default workbench state through HTTP/API contracts, not pixel layout. Browser screenshot and overflow validation remain a Codex/browser verification step.
- No API contracts, migrations, provider fetching, AI behavior or product capabilities changed.
Next recommended pass:
- Add a deeper browser interaction smoke for core controls, starting with project switching, area selection and map layer opacity.
## Sprint 45 Default demo selection polish (2026-06-17)
Changed:
- Updated `frontend/src/hooks/useProjectWorkspace.ts` so cold-start project selection preserves an existing selected project, honors an explicit preferred project and otherwise prefers a populated demo/workbench project over an empty first project.
- New project creation now selects the newly created project immediately after creation.
- Updated `frontend/src/hooks/useDemoWorkflow.ts` so demo seed refresh passes the seeded project id to `loadProjects`.
- Extended orchestration tests to cover preferred demo selection and project creation selection behavior.
Validation:
- `cd backend && python -m pytest tests/test_sprint39_frontend_orchestration_hooks.py tests/test_sprint21_demo_workflow_smoke.py -q` passed: 11 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 194 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Browser check against local Vite preview with live backend passed after async settle: selected project `GeoIntel Demo - Building QA`, status showed `1 area`, `2/2 ready` datasets and `2 checks`.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed the all-in-one container to Tower on port 1202.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
- Live browser check against `http://192.168.10.150:1202` passed after async settle: selected project `GeoIntel Demo - Building QA`, status showed `1 area`, `2/2 ready` datasets and `2 checks`, with no horizontal overflow.
Limitations:
- No API contracts, migrations, provider fetching, AI behavior or product capabilities changed.
- The heuristic probes up to eight project candidates on cold start; a future backend list endpoint with area/dataset counts would make this cleaner.
Next recommended pass:
- Add a lightweight browser regression script for the demo start page once the UI state is stable enough to automate end to end.
## Sprint 44 Workbench UI polish pass (2026-06-17)
Changed:
- Reworked `frontend/src/styles/app.css` from a minimal browser-default stylesheet into a compact GIS workbench skin with modern controls, restrained neutral/green accents, scroll-contained long panels and responsive layout rules.
- Promoted `MapWorkspace` above the dense workflow grid in `frontend/src/App.tsx` so GIS context is visible before lower-detail provider, AI, QA and export panels.
- Moved `DatasetPanel` into the first workflow row beside project/area/provider setup.
- Added a static layout regression test in `backend/tests/test_sprint30_workbench_components.py` for map-first ordering and scroll-contained workflow panels.
- Updated frontend README and changelog.
Validation:
- Browser visual check against local Vite preview passed at desktop width: map-first layout visible, workflow panels scroll-contained, page height reduced from roughly 14.9k px to roughly 3.2k px.
- Browser responsive check at 390px width passed with no horizontal overflow.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 194 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `geointel-all-in-one:latest` to Tower on port 1202.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
- Live browser check against `http://192.168.10.150:1202` passed: map-first layout rendered, scroll height roughly 3.2k px and no desktop horizontal overflow detected.
Limitations:
- No API contracts, migrations, provider fetching, AI behavior or product capabilities changed.
- This is still a dense operational workbench rather than a designed product shell with navigation or tabs.
- The live default selected project can still be an empty project with the demo name; project selection polish remains a separate follow-up.
Next recommended pass:
- Add UI browser regression coverage for the map-first demo workflow and polish the default project/demo selection state.
## Sprint 43 Workbench bootstrap hook decomposition (2026-06-17)
Changed:
- Moved frontend bootstrap, project-change reload/reset and detection/segmentation result reload effects from `frontend/src/App.tsx` into `frontend/src/hooks/useWorkbenchBootstrap.ts`.
- Kept `App.tsx` as a composition root that wires hook outputs into panels; it no longer imports `useEffect`.
- Extended orchestration tests so lifecycle side effects stay in the bootstrap hook.
- Updated frontend README, changelog and TODO status.
Validation:
- `cd backend && python -m pytest tests/test_sprint39_frontend_orchestration_hooks.py -q` passed: 9 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 193 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `geointel-all-in-one:latest` to Tower on port 1202.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
- `App.tsx` size audit after extraction: 621 lines; `useWorkbenchBootstrap.ts`: 81 lines.
Limitations:
- No UX behavior, API contracts, migrations, provider fetching or AI behavior changed.
- `App.tsx` line count remains high because it explicitly wires many panel props; the remaining size is primarily composition.
Next recommended pass:
- Pick the next V1 stabilization focus: UI browser regression coverage, backend service contract audit, or golden dataset expansion.
## Sprint 42 App entrypoint cleanup (2026-06-17)
Changed:
- Removed the stale `FormEvent`/`useState` React imports from `frontend/src/App.tsx`.
- Removed the UTF-8 BOM from `App.tsx` so patches and static checks use normal UTF-8 text.
- Added a regression test that verifies the clean entrypoint encoding and React import set.
- Recorded the current `App.tsx` size audit: 622 lines after the orchestration hook decomposition passes.
Validation:
- `cd backend && python -m pytest tests/test_sprint39_frontend_orchestration_hooks.py -q` passed: 8 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 192 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `geointel-all-in-one:latest` to Tower on port 1202.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
Limitations:
- No UX behavior, API contracts, migrations, provider fetching or AI behavior changed.
- `App.tsx` remains a large composition root; the remaining size is primarily panel wiring and hook outputs.
Next recommended pass:
- Optional bootstrap-effect extraction if another no-behavior size reduction is useful.
## Sprint 41 Demo workflow hook decomposition (2026-06-17)
Changed:
- Moved offline demo workflow orchestration from `frontend/src/App.tsx` into `frontend/src/hooks/useDemoWorkflow.ts`.
- Preserved the existing backend fixture seed flow and all cross-module selection updates for project, candidate/reference datasets, map AOI, QA/QC, detection, segmentation and exports.
- Extended static frontend orchestration tests so `demoApi.seedWorkflow` is owned by the new hook and not `App.tsx`.
- Updated frontend README, changelog and TODO status.
Validation:
- `cd backend && python -m pytest tests/test_sprint21_demo_workflow_smoke.py tests/test_sprint39_frontend_orchestration_hooks.py -q` passed: 9 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 191 tests.
- `bash scripts/run_readiness_check.sh` passed.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1` passed and redeployed `geointel-all-in-one:latest` to Tower on port 1202.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
Limitations:
- No UX behavior, API contracts, migrations, provider fetching or AI behavior changed.
- `App.tsx` still has a UTF-8 BOM and a stale React import cleanup opportunity; TypeScript build is unaffected.
Next recommended pass:
- Do a final `App.tsx` size/import cleanup pass.
## Sprint 40 Project workspace hook decomposition (2026-06-17)
Changed:
- Moved project list/create state, area create state and project-scoped area/dataset loading into `frontend/src/hooks/useProjectWorkspace.ts`.
- Kept demo workflow orchestration in `App.tsx` because it coordinates project, dataset, QA/QC, detection, segmentation and export selections across multiple hooks.
- Moved default clip-area fallback selection into `frontend/src/hooks/useDatasetWorkflow.ts`.
- Moved default map-area fallback selection into `frontend/src/hooks/useMapWorkspaceState.ts`.
- Extended static frontend orchestration tests to lock these ownership boundaries.
- Updated frontend README, changelog and TODO status.
Validation:
- `cd backend && python -m pytest tests/test_sprint39_frontend_orchestration_hooks.py -q` passed: 6 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 190 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the all-in-one Tower container at `http://192.168.10.150:1202`.
- Tower live migration smoke passed and reported `Database collation version: ok`.
- Tower browser runtime verification passed.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
Open:
- None for this pass.
Limitations:
- No UX behavior, API contracts, migrations, provider fetching or AI behavior changed.
- Demo workflow orchestration remains in `App.tsx` until it can be safely split without obscuring cross-module state updates.
Next recommended pass:
- Run full readiness and Tower deploy verification, then consider extracting the demo workflow coordinator into a dedicated hook.
## Sprint 39 Frontend orchestration decomposition (2026-06-17)
Changed:
- Moved provider capability loading state and `externalApi.listProviders` calls into `frontend/src/hooks/useProviderCapabilities.ts`.
- Moved change-detection state, validation and `analysisApi.runChangeDetection` calls into `frontend/src/hooks/useChangeDetectionWorkflow.ts`.
- Moved map-layer derived state, area GeoJSON feature construction and selected-feature reset behavior into `frontend/src/hooks/useMapWorkspaceState.ts`.
- Kept `App.tsx` as the cross-module composition layer without changing panel props, API contracts, migrations or product behavior.
- Added static regression tests for the extracted orchestration hooks.
- Updated frontend README, changelog and TODO status.
Validation:
- `cd backend && python -m pytest tests/test_sprint39_frontend_orchestration_hooks.py -q` passed: 4 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 188 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the all-in-one Tower container at `http://192.168.10.150:1202`.
- Tower live migration smoke passed and reported `Database collation version: ok`.
- Tower browser runtime verification passed.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
Open:
- None for this pass.
Limitations:
- Project/area/dataset cross-load orchestration still lives in `App.tsx`; it is a good next low-risk decomposition target.
Next recommended pass:
- Run full readiness and Tower deploy verification, then extract project/area loading into a dedicated hook if behavior remains stable.
## Sprint 38 Export Center preview hardening (2026-06-17)
Changed:
- Hardened the export content preview path so HTML report artifacts return `EXPORT_CONTENT_UNSUPPORTED` instead of a generic JSON parse failure.
- Updated the frontend Export Center to offer JSON preview only for JSON/GeoJSON artifacts.
- HTML project report artifacts now display as download-only in the export list.
- Extracted export preview rendering from `frontend/src/App.tsx` into `frontend/src/components/exports/ExportPreview.tsx`.
- Updated API/frontend docs, changelog and TODO status.
Validation:
- `cd backend && python -m pytest tests/test_sprint17_export_foundation.py -q` passed: 10 tests.
- `cd frontend && npm run typecheck` passed.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 184 tests.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed.
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql` passed.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the all-in-one Tower container at `http://192.168.10.150:1202`.
- Tower live migration smoke passed and reported `Database collation version: ok`.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
Open:
- None for this pass.
Limitations:
- This pass does not add new export formats, PDF reports, provider fetching, AI inference or migrations.
Next recommended pass:
- Run the full readiness gate, frontend build and Tower deploy smoke; then continue with shared workbench orchestration decomposition or export cleanup/history filtering.
## Sprint 37 Tower PostgreSQL collation maintenance (2026-06-17)
Changed:
- Performed the manual PostgreSQL collation maintenance action reported by the live migration smoke on the Tower all-in-one runtime.
- Created a pre-maintenance custom-format database backup at `backups/geointel-before-collation-refresh-20260617-065707.dump`.
- Ran `REINDEX DATABASE geointel;` followed by `ALTER DATABASE "geointel" REFRESH COLLATION VERSION;`.
- Confirmed the database collation metadata now matches the runtime collation version: `geointel stored=2.36 actual=2.36`.
Validation:
- `LIVE_SMOKE_CONTAINER=geointel bash scripts/live_migration_smoke.sh` passed on Tower and reported `Database collation version: ok`.
- `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202` passed.
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202` passed.
Notes:
- An initial SSH script attempt was interrupted by PowerShell BOM/stdin handling before reindex or refresh executed; the subsequent base64-delivered script ran without `docker exec -i` stdin interference.
- Earlier backup attempts were left in `backups/` alongside the final validated backup.
- No code, API contracts, migrations, product features, provider fetching or AI behavior changed.
Next recommended pass:
- Continue with export/download polish or frontend export center hardening, using the now-clean Tower runtime as the validation target.
## Sprint 32 Unraid all-in-one runtime (2026-06-17)
Changed:
- Added `docker-compose.unraid.yml` for a single editable `geointel` container on Unraid.
- Added `deploy/unraid/Dockerfile.all-in-one` to build one image containing embedded PostGIS, backend GIS runtime, nginx and frontend static assets.
- Added `deploy/unraid/all-in-one-start.sh` to start embedded PostGIS, apply Alembic migrations, start FastAPI on internal localhost and serve nginx on container port 80.
- Added `deploy/unraid/nginx-all-in-one.conf` so `/api` and `/health` proxy to `127.0.0.1:8000` inside the same container.
- Updated `deploy/unraid/geointel.env.example`, Unraid XML template and README for one-container operation and editable web/storage/database paths.
- Updated Tower deploy scripts to stop the old multi-container stack without deleting volumes and start `docker-compose.unraid.yml`.
- Updated `scripts/live_migration_smoke.sh` to support both all-in-one `geointel` and legacy `backend` Compose services.
- Added root `.dockerignore` for all-in-one builds.
- Updated Sprint 31 tests to cover the all-in-one Dockerfile, startscript, nginx config, deploy scripts and template metadata.
Validation:
- `python -m pytest backend/tests/test_sprint31_unraid_template.py backend/tests/test_live_migration_smoke_script.py backend/tests/test_docker_runtime_config.py` passed: 26 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest` passed: 179 tests.
- `bash scripts/run_readiness_check.sh` passed: 179 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `cd backend && python -m alembic heads` passed: single head `202606120900`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- `bash -n deploy/unraid/all-in-one-start.sh` passed.
Notes:
- No API contracts, migrations, product features, provider fetching or AI behavior changed.
- Local Windows environment does not have `docker` in PATH; Tower deployment should provide the live all-in-one Docker validation.
## Sprint 31 Unraid deployment template (2026-06-17)
Changed:
- Made `docker-compose.yml` configurable through `.env` defaults for frontend port, backend port, storage path, PostGIS database/user/password, CORS origins and upload limit.
- Added `deploy/unraid/geointel.env.example` for Unraid/Tower runtime configuration.
- Added `deploy/unraid/geointel-unraid-template.xml` as Unraid/DockerMan-style metadata for the editable Compose stack settings.
- Added `deploy/unraid/geointel-icon.svg` and `deploy/unraid/geointel-icon.png`, served through matching `frontend/public` assets.
- Added the frontend favicon link for the GeoIntel icon.
- Added Sprint 31 tests for Unraid template coverage, compose variable coverage, docs and icon availability.
- Updated root README, TODO and changelog docs.
Validation:
- `python -m pytest backend/tests/test_sprint31_unraid_template.py backend/tests/test_docker_runtime_config.py` passed: 22 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest` passed: 177 tests.
- `bash scripts/run_readiness_check.sh` passed: 177 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `cd backend && python -m alembic heads` passed: single head `202606120900`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Tower deploy via `scripts/deploy_tower.ps1` passed after commit `3a8b82f`.
- Tower Docker Compose config/build/up passed with the env-default compose file.
- Tower live migration smoke passed with PostGIS 3.4 and Alembic head `202606120900`.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Additional HTTP smoke passed for frontend HTML, `GET /api/v1/projects`, `/geointel-icon.svg` and `/geointel-icon.png`.
Notes:
- Local Windows environment does not have `docker` in PATH, so local `docker compose config` could not be run from this machine.
- Tower deployment validated Docker Compose config and live runtime after commit.
- No API contracts, backend behavior, migrations, product features, provider fetching or AI behavior changed.
## Sprint 30 workbench component decomposition (2026-06-17)
Changed:
- Moved persisted QA/QC result rendering from `frontend/src/App.tsx` into `frontend/src/components/quality/QualityResultsPanel.tsx`.
- Moved map layer controls, MapLibre composition and feature inspector rendering into `frontend/src/components/map/MapWorkspace.tsx`.
- Updated map/workbench and QA regression tests for the new component boundaries.
- Added Sprint 30 component wiring tests to keep QA and map markup out of `App.tsx`.
- Updated frontend README, TODO and changelog docs.
Validation:
- `python -m pytest backend/tests/test_sprint30_workbench_components.py backend/tests/test_sprint27_frontend_workflow_hooks.py backend/tests/test_sprint19_map_workbench.py` passed: 9 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest` passed: 173 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 173 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `cd backend && python -m alembic heads` passed: single head `202606120900`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Tower deploy via `scripts/deploy_tower.ps1` passed after commit `acf9590`.
- Tower live migration smoke passed with PostGIS 3.4 and Alembic head `202606120900`.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Additional HTTP smoke passed for frontend HTML and `GET /api/v1/projects` through the frontend proxy.
Notes:
- No API contracts, backend behavior, migrations, product features, provider fetching, AI behavior or UI redesign changed.
- Next maintainability pass should split export preview and remaining shared workbench orchestration into focused components/hooks.
## Sprint 29 dataset component decomposition (2026-06-17)
Changed:
- Moved dataset upload/list rendering from `frontend/src/App.tsx` into `frontend/src/components/datasets/DatasetPanel.tsx`.
- Moved dataset detail and job-list rendering into `frontend/src/components/datasets/DatasetDetailPanel.tsx`.
- Split raster controls and vector controls into `frontend/src/components/datasets/RasterControls.tsx` and `frontend/src/components/datasets/VectorControls.tsx`.
- Updated Sprint 28 regression tests for the new component boundary and added Sprint 29 component wiring tests.
- Updated frontend README, TODO and changelog docs.
Validation:
- `python -m pytest backend/tests/test_sprint29_dataset_components.py backend/tests/test_sprint28_dataset_workflow_hook.py backend/tests/test_sprint27_frontend_workflow_hooks.py` passed: 10 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest` passed: 170 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 170 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `cd backend && python -m alembic heads` passed: single head `202606120900`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Tower deploy via `scripts/deploy_tower.ps1` passed after commit `1cbb356`.
- Tower live migration smoke passed with PostGIS 3.4 and Alembic head `202606120900`.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Additional HTTP smoke passed for frontend HTML and `GET /api/v1/projects` through the frontend proxy.
Notes:
- No API contracts, backend behavior, migrations, product features, provider fetching, AI behavior or UI redesign changed.
- Next maintainability pass should split change detection, QA/QC results and map workspace controls into focused presentational components.
## Sprint 28 dataset workflow hook hardening (2026-06-17)
Changed:
- Moved dataset selection, upload form state, dataset detail loading, dataset jobs and raster/vector operation orchestration from `frontend/src/App.tsx` into `frontend/src/hooks/useDatasetWorkflow.ts`.
- Kept project dataset listing in `App.tsx` so project/area loading remains the shared workbench boundary.
- Added regression tests to verify App uses the dataset workflow hook and still wires dataset, raster and vector callbacks.
- Updated frontend README, TODO and changelog docs.
Validation:
- `python -m pytest backend/tests/test_sprint28_dataset_workflow_hook.py backend/tests/test_sprint27_frontend_workflow_hooks.py backend/tests/test_sprint26_frontend_workflow_hooks.py` passed: 11 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest` passed: 167 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 167 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `cd backend && python -m alembic heads` passed: single head `202606120900`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Initial Tower rebuild hit Docker btrfs storage exhaustion; safely reclaimed build cache only with `docker builder prune -af` without pruning volumes.
- Tower Docker storage recovered from `/var/lib/docker` 94% used to 58% used after cleanup and rebuild.
- Tower deploy via `scripts/deploy_tower.ps1` passed after commit `361776c`.
- Tower live migration smoke passed with PostGIS 3.4 and Alembic head `202606120900`.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Additional HTTP smoke passed for frontend HTML and `GET /api/v1/projects` through the frontend proxy.
Notes:
- No API contracts, backend behavior, migrations, product features, provider fetching, AI behavior or UI redesign changed.
- Next maintainability pass should split dataset detail, raster controls and vector controls into presentational components fed by the hook state.
## Sprint 27 export and QA workflow hook hardening (2026-06-17)
Changed:
- Moved Export Center orchestration state and API calls from `frontend/src/App.tsx` into `frontend/src/hooks/useExportWorkflow.ts`.
- Moved QA/QC comparison state and persisted quality-check listing from `frontend/src/App.tsx` into `frontend/src/hooks/useQualityWorkflow.ts`.
- Added regression tests to verify App uses export/quality hooks and still wires QA/QC results plus ExportCenter callbacks.
- Updated frontend README, TODO and changelog docs.
Validation:
- `python -m pytest backend/tests/test_sprint27_frontend_workflow_hooks.py backend/tests/test_sprint26_frontend_workflow_hooks.py` passed: 8 tests.
- `python -m compileall backend/app` passed.
- `cd backend && python -m pytest` passed: 164 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 164 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `cd backend && python -m alembic heads` passed: single head `202606120900`.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Tower deploy via `scripts/deploy_tower.ps1` passed after commit `fd0000f`.
- Tower live migration smoke passed with PostGIS 3.4 and Alembic head `202606120900`.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Additional HTTP smoke passed for frontend HTML and `GET /api/v1/projects` through the frontend proxy.
Notes:
- No API contracts, backend behavior, migrations, product features, provider fetching, AI behavior or UI redesign changed.
- Local Windows Docker CLI was unavailable (`docker` command not found); Tower deployment remains handled through `scripts/deploy_tower.ps1`.
- Next maintainability pass should extract dataset/raster/vector operation workflows from `App.tsx`.
## Sprint 26 frontend workflow hook hardening (2026-06-17)
Changed:
- Moved Detection Lab orchestration state and API calls from `frontend/src/App.tsx` into `frontend/src/hooks/useDetectionWorkflow.ts`.
- Moved Segmentation Lab orchestration state and API calls from `frontend/src/App.tsx` into `frontend/src/hooks/useSegmentationWorkflow.ts`.
- Added shared frontend `formatError` helper under `frontend/src/lib/formatError.ts`.
- Added regression tests to verify App uses workflow hooks and still wires DetectionLab/SegmentationLab callbacks.
- Updated frontend README, TODO and changelog docs.
Validation:
- `python -m pytest backend/tests/test_sprint26_frontend_workflow_hooks.py backend/tests/test_sprint22_workbench_status_strip.py` passed: 6 tests.
- `cd frontend && npm run typecheck` passed.
- `cd frontend && npm run build` passed.
- `bash scripts/run_readiness_check.sh` passed: 160 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `python -m compileall backend/app` passed.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Tower deploy/live migration/browser runtime passed after commit `6c32f29`.
- In-app browser check passed on `http://192.168.10.150:1202`: workbench, status strip, Detection Lab, Segmentation Lab and Export Center visible with no console error logs.
Notes:
- No API contracts, backend behavior, migrations, product features, provider fetching, AI behavior or UI redesign changed.
## Sprint 25 YOLO compatibility smoke hardening (2026-06-17)
Changed:
- Added explicit `--check-model-load` support to `scripts/yolo_preflight.py`, `backend/scripts/yolo_preflight.py` and `YoloPreflightService`.
- The model-load smoke requires real optional AI dependencies, loads only an existing local model file, runs no inference and does not download weights.
- The CLI rejects `--check-model-load` with `--assume-dependencies` to avoid false-positive AI readiness.
- Added regression tests for mocked successful load, load failure reporting and CLI guard behavior.
- Added Python compile validation for both YOLO preflight entrypoints to the readiness gate.
- Updated AI pipeline, scripts, backend, TODO and changelog docs, including Docker runtime usage.
Validation:
- `python -m py_compile scripts/yolo_preflight.py` passed.
- `python -m pytest backend/tests/test_sprint13_yolo_preflight.py backend/tests/test_readiness_gate.py` passed: 14 tests.
- `bash scripts/run_readiness_check.sh` passed: 156 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `python -m compileall backend/app` passed.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` passed.
- Tower deploy/live migration/browser runtime passed after commit `6c32f29`.
- In-app browser check passed on `http://192.168.10.150:1202`: workbench, status strip, Detection Lab, Segmentation Lab and Export Center visible with no console error logs.
- Tower deploy/live migration/browser runtime passed after commit `382dcad`.
- Backend-container YOLO preflight sanity passed: default status `not_configured`, `will_download_models=false`, `will_run_inference=false`.
- Backend-container CLI guard passed: `--check-model-load` with `--assume-dependencies` is rejected.
Notes:
- No base dependencies, API contracts, migrations, product features, provider fetching or detection persistence behavior changed.
## Sprint 24 demo/export artifact cleanup tooling (2026-06-17)
Changed:
- Added `scripts/cleanup_demo_artifacts.py` for dry-run-first cleanup of old offline demo export artifacts.
- Added `backend/scripts/cleanup_demo_artifacts.py` so the same cleanup can run inside the backend Docker container.
- Cleanup is constrained to an exact demo project name by default, keeps the newest exports per project and refuses file deletion outside `STORAGE_ROOT`.
- Added regression tests for cleanup selection, path safety, dry-run candidate reporting and readiness gate coverage.
- Added Python compile validation for the cleanup script to `scripts/run_readiness_check.sh`.
- Documented cleanup usage in `scripts/README.md`, `docs/STORAGE_ARCHITECTURE.md`, `backend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Validation:
- `python -m py_compile scripts/cleanup_demo_artifacts.py` passed.
- `python -m pytest backend/tests/test_sprint24_cleanup_demo_artifacts.py backend/tests/test_readiness_gate.py` passed: 10 tests.
- `bash scripts/run_readiness_check.sh` passed twice after adding the backend container entrypoint: 152 backend tests, frontend typecheck/build, Alembic head check and script syntax checks.
- `python -m compileall backend/app` passed.
- `cd backend && python -m alembic upgrade head --sql` passed.
- `bash -n scripts/live_migration_smoke.sh` and `bash -n scripts/verify_demo_export_workflow.sh` passed.
- Local `docker compose config` could not run because the Windows Docker CLI is not installed in this Codex environment.
- Tower deploy/live migration/browser runtime passed after final commit `2d4e6bd`.
- Live backend-container cleanup dry-run exposed and then fixed confusing dry-run labeling so candidates are reported as `candidate_files`, not `deleted_files`; final dry-run reported 2 candidate files, 0 deleted files and 0 deleted export rows.
Notes:
- No API contracts, migrations, product features, provider fetching, AI inference or source dataset cleanup behavior changed.
## Sprint 23 V1 report handoff summary (2026-06-17)
Changed:
- Added V1 readiness summary data to project metadata exports.
- Added V1 Readiness Summary and Known Limitations sections to lightweight HTML project report exports.
- Included persisted AOI, dataset readiness, QA/QC and export-history counts in the handoff summary.
- Updated export tests, API contract docs, frontend README, TODO and changelog.
Tested:
- Passed: backend compile, export tests through full readiness, full backend pytest, frontend typecheck/build, Alembic heads, Alembic SQL upgrade, live smoke syntax check, Tower deploy, live migration smoke and live project report smoke.
Known limitations:
- Report export remains a lightweight HTML artifact, not a PDF designer or custom report builder.
Next recommended pass:
- Add optional cleanup tooling for stale demo/export artifacts if repeated smoke runs keep accumulating local artifacts.
## Sprint 22 V1 workbench status strip (2026-06-17)
Changed:
- Added `frontend/src/components/WorkbenchStatusStrip.tsx` to summarize existing V1 state for project, AOI, datasets, active map layer, QA/QC and exports.
- Wired the status strip into `frontend/src/App.tsx` using existing orchestration state only.
- Added compact status-strip styling and regression tests for the frontend wiring contract.`n- Hardened `frontend/src/components/GeoMap.tsx` so MapLibre source/layer updates wait for style readiness before adding sources.`n- Hardened demo project lookup so duplicate historical demo projects prefer complete fixture state before repairing incomplete state.
- Updated frontend README, TODO and changelog.
Tested:
- Passed: backend compile, focused pytest, full backend pytest with DeprecationWarning as error, frontend typecheck/build, Alembic heads, Alembic SQL upgrade, readiness via Git Bash and live smoke syntax check via Git Bash.
Known limitations:
- The strip is a read-only operator summary; it intentionally does not add new backend status APIs or product workflows.
Next recommended pass:
- Add a compact project handoff summary in exports/report output if the browser-facing V1 workflow remains green.
## Sprint 21 V1 demo workflow smoke hardening (2026-06-17)
Changed:
- Hardened `scripts/verify_demo_export_workflow.sh` so the explicit offline demo smoke validates area GeoJSON, fixture datasets, vector FeatureCollection content, vector feature summaries, persisted QA/QC metrics and export downloads through the frontend proxy.
- Updated the frontend demo workflow action to open the candidate vector fixture dataset after seeding/loading the demo, so the Map Workbench is populated without a manual dataset click.
- Added regression tests for the strengthened smoke script and frontend demo loading contract.
- Updated scripts/frontend documentation, changelog and TODO status.
Tested:
- Passed: backend compile, backend pytest with DeprecationWarning as error, readiness, frontend typecheck/build, Alembic heads, Alembic SQL upgrade, Tower deploy, live migration smoke, browser-runtime smoke and expanded demo/export workflow smoke.
Known limitations:
- The demo smoke intentionally seeds fixture demo data when run; it should be used as an explicit verification command, not as an implicit healthcheck.
Next recommended pass:
- Add a compact V1 dashboard/status strip for project, AOI, datasets, QA and exports so operators can see readiness at a glance after opening a project.
## Sprint 20 V1 selected area map overlay (2026-06-17)
Changed:
- Added GeoJSON geometry serialization for project areas so persisted AOIs can be displayed by the map workbench.
- Added a dedicated MapLibre area overlay layer with separate visibility and opacity controls.
- Added area list actions and map workspace controls to select the active AOI.
- Updated API/frontend docs, changelog and TODO status for selected area display.
Tested:
- Passed: backend compile, backend pytest with DeprecationWarning as error, readiness, frontend typecheck/build, Alembic heads, Alembic SQL upgrade, Tower deploy, live migration smoke, browser-runtime smoke and browser UI audit.
Known limitations:
- Area geometry is displayed as a simple filled/outlined GeoJSON overlay; no drawing/editing workflow is introduced in this pass.
Next recommended pass:
- Add a small V1 workflow polish pass for richer dataset/area empty states and a fixture-driven end-to-end browser smoke once the new build is deployed.
## Sprint 19 V1 map workbench controls (2026-06-17)
Changed:
- Added active MapLibre layer visibility and opacity controls.
- Added click-to-inspect feature property display for the active GeoJSON workbench layer.
- Added active layer label and feature count to the Map workspace panel.
- Updated the app header from the stale Sprint 9 label to the GeoIntel Kempen V1 Workbench identity.
- Added regression tests for the frontend map control and feature inspection wiring.
Limitations:
- The current workbench still shows one active GeoJSON overlay at a time; multi-layer stack ordering remains a later UI enhancement.
- Raster preview display still remains metadata/path-oriented unless the backend exposes a browser-safe raster image/tile URL.
- No API contracts, migrations, backend behavior, provider fetching, AI inference or new dependencies were introduced.
Validation planned:
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` via Git Bash on Windows
- Tower redeploy through `scripts/deploy_tower.ps1`
## Sprint 18 vector change detection foundation (2026-06-16)
Changed:
- Added `POST /api/v1/analysis/change-detection` for comparing two vector datasets in the same project through the existing synchronous job envelope.
- Added `ChangeDetectionService` with persisted `vector_features` as the primary source of comparable geometries and explicit stored-GeoJSON fallback warnings for older datasets.
- Added frontend Change Detection controls, summary counts and MapLibre overlay styling for `added`, `removed` and `unchanged` feature properties.
- Added nginx no-cache headers for frontend HTML/assets after browser verification exposed stale cached modules on the LAN deployment.
- Added backend tests for persisted-vector comparison and canonical API envelope behavior.
Limitations:
- The foundation classifies `added`, `removed` and `unchanged` only. It does not emit fake `changed` objects without durable object ids/versioning.
- No migrations, live GRB/OSM/Sentinel fetching, AI inference, new dependencies, LiDAR, Copilot, Training Studio or separate Reports module were introduced.
Validation:
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` via Git Bash on Windows
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql`
# Codex Execution Log
This file must be updated by Codex after each implementation pass.
## Format
```md
## Pass X — Title
Date:
### Completed
- ...
### Files changed
- ...
### Tests run
- ...
### Known limitations
- ...
### Next recommended pass
- ...
```
## Initial status
Specification phase completed through M0. No code foundation has been implemented yet.
## M2 Engineering Package
- [x] Add ADR decision records.
- [x] Add RFC placeholders for future modules.
- [x] Add API/database/event contracts.
- [x] Add model registry and class catalogs.
- [x] Add queue architecture.
- [x] Add acceptance matrix and test catalog.
- [x] Add Codex M2 build prompts.
- [ ] Start Codex Pass 01 backend foundation.
## M8 preparation
Added the tomorrow execution layer for Codex autonomy: Day 1 master prompt, pass prompts, failure recovery, quality gates, operator checklist and smoke script scaffold.
## Sprint 1 readiness hardening (2026-06-11)
Date: 2026-06-11
### Completed
- Hardened backend dependency declarations for Sprint 1 runtime modules in `backend/pyproject.toml`.
- Normalized helper scripts for backend/frontend install/test/dev/readiness across `python`/`python3` interpreter availability.
- Fixed PostGIS/geospatial stack compatibility issues (`geojson_service` import path, package config).
- Updated backend/frontend/docs/readme commands for import smoke, setup, and readiness verification.
- Fixed frontend shell script line-ending parsing failures and added `npm` availability checks.
- Added missing frontend type path fixes and TypeScript typing corrections.
- Added/verified minimal Sprint 1 tests for health and GeoJSON parsing/rejection behaviors.
### Files changed
- `backend/pyproject.toml`
- `backend/app/core/config.py`
- `backend/app/services/geojson_service.py`
- `backend/tests/test_health.py`
- `backend/tests/test_geojson_dataset_service.py`
- `backend/README.md`
- `frontend/package.json`
- `frontend/tsconfig.json`
- `frontend/src/components/GeoMap.tsx`
- `frontend/src/services/api/areas.ts`
- `frontend/src/services/api/projects.ts`
- `frontend/src/services/api/datasets.ts`
- `frontend/src/App.tsx`
- `frontend/README.md`
- `scripts/run_readiness_check.sh`
- `scripts/backend_install.sh`
- `scripts/backend_test.sh`
- `scripts/backend_dev.sh`
- `scripts/codex_pass_end_check.sh`
- `scripts/smoke_backend_import.sh`
- `scripts/frontend_install.sh`
- `scripts/frontend_typecheck.sh`
- `scripts/frontend_build.sh`
- `scripts/frontend_dev.sh`
- `README.md`
- `.env.example`
- `CHANGELOG.md`
- `Makefile`
### Tests run
- `python -m compileall backend/app` (pass)
- `cd backend; python -m pytest` (pass, 5 tests)
- `cd backend; python -c "from app.main import app; print(app.title)"` (pass)
- `bash scripts/run_readiness_check.sh` (pass)
- `bash scripts/smoke_backend_import.sh` (pass)
- `bash scripts/frontend_install.sh` (pass)
- `bash scripts/frontend_typecheck.sh` (pass)
- `bash scripts/frontend_build.sh` (pass)
- `make`-based targets not runnable in this environment (`make` command missing)
- `docker compose config` not runnable in this environment (`docker` command missing)
- `python3` commands fail in this environment because `python3` maps to Microsoft Store stub; use `python` instead.
### Known limitations
- `docker` and `make` are not installed in the current local shell environment.
- `python3` is not a usable interpreter in this environment; `python` must be used for all backend runtime/tests.
### Next recommended pass
- Run `docker compose` validation and DB-backed migration checks in an environment with Docker + PostGIS service available.
## Pass 12 — Sprint 2 Foundation
Date: 2026-06-11
### Completed
- Added vector/raster dataset typing and lifecycle states (`uploaded`, `validating`, `ready`, `failed`) in dataset service.
- Added vector metadata extraction details (feature counts, geometry types, bounds, area, CRS assumptions).
- Added raster metadata service with dependency-aware unavailable behavior and explicit `RASTER_PROCESSING_UNAVAILABLE` handling.
- Added dataset vector inspect/summary and raster metadata endpoints for project-scoped datasets.
- Persisted deterministic storage metadata for uploads (original/stored filename, MIME, size, checksum).
- Extended frontend dataset manager details panel with type/status/file metadata/feature counts and raster summary readiness.
- Added minimal Sprint 2 tests for vector metadata, legacy `geojson` compatibility, storage metadata persistence, and raster dependency fallback.
### Files changed
- `backend/app/services/dataset_service.py`
- `backend/app/services/raster_service.py`
- `backend/app/services/geojson_service.py`
- `backend/app/schemas/dataset.py`
- `backend/app/api/routes/datasets.py`
- `backend/app/services/storage_service.py`
- `backend/tests/test_geojson_dataset_service.py`
- `backend/tests/test_raster_service.py`
- `backend/tests/test_storage_service.py`
- `backend/README.md`
- `frontend/src/App.tsx`
- `frontend/src/services/api/datasets.ts`
- `frontend/src/types.ts`
- `docs/API_CONTRACTS.md`
- `docs/CODEX_EXECUTION_LOG.md`
- `.env.example`
- `backend/README.md`
- `frontend/README.md`
- `CHANGELOG.md`
- `README.md`
### Tests run
- Sprint 2 tests to be executed via readiness commands (see below).
### Known limitations
- `rasterio` is not required by default; raster metadata extraction is unavailable until installed in the environment.
- Docker and PostGIS validation still depends on local availability of Docker/DB runtime.
### Next recommended pass
- Keep Sprint 1/2 architecture; implement raster clipping/tiling APIs and status jobs before Detection/Segmentation modules.
## Pass 13 — Sprint 2 validation and legacy compatibility hardening
Date: 2026-06-11
### Completed
- Verified Sprint 2 readiness commands in current environment (where tools are available).
- Revalidated backend tests and frontend typecheck/build after a Sprint 2 compatibility patch.
- Added frontend vector-detail compatibility for legacy `geojson` dataset rows in Sprint 1 records.
- Confirmed backend import smoke and dataset/raster/vector service behavior remain intact.
### Files changed
- `frontend/src/App.tsx`
- `docs/CODEX_EXECUTION_LOG.md`
### Tests run
- `python -m compileall backend/app` (pass)
- `cd backend && python -m pytest` (pass, 11 tests)
- `bash scripts/run_readiness_check.sh` (pass)
- `bash scripts/smoke_backend_import.sh` (pass)
- `cd frontend && npm run typecheck` (pass)
- `cd frontend && npm run build` (pass)
- `cd backend; python3 -m compileall backend/app` (fails: python3 shim unavailable in this shell)
- `cd backend; python3 -c "from app.main import app; print(app.title)"` (fails: python3 shim unavailable in this shell)
- `docker compose config` (fails: docker command unavailable in this shell)
### Known limitations
- `python3` is not available in the current environment; use `python` commands for verification.
- `docker` is not available in the current environment.
### Next recommended pass
- Run the same sprint verification commands in an environment with `python3` and `docker` installed.
## Pass 14 — Sprint 3 operations + job foundation
Date: 2026-06-11
### Completed
- Added lightweight job model/migration and service layer with statuses `queued`, `running`, `success`, `failed`.
- Added job API endpoints for create/list/read/status under project scope.
- Added vector operation service foundation:
- inspect
- bbox
- stats
- clip by area
- buffer
- intersect
- Added raster operation foundation:
- inspect
- metadata
- preview readiness
- clip placeholder (dependency-aware)
- tile placeholder (dependency-aware)
- Added job-based execution wrappers for vector/raster operation endpoints.
- Updated dataset detail UI with available operations, job list/status, and derived output navigation.
- Added/updated Sprint 3 API contract and backend/frontend documentation updates.
### Files changed
- `backend/app/schemas/operations.py`
- `backend/app/schemas/__init__.py`
- `backend/app/services/vector_operations_service.py`
- `backend/app/services/raster_operations_service.py`
- `backend/app/services/job_service.py`
- `backend/app/api/routes/jobs.py`
- `backend/app/models/entities.py`
- `backend/app/models/__init__.py`
- `backend/alembic/versions/20260611212435_add_jobs_table.py`
- `backend/tests/test_vector_operations_service.py`
- `backend/tests/test_raster_operations_service.py`
- `backend/tests/test_storage_service.py`
- `frontend/src/App.tsx`
- `frontend/src/services/api/datasets.ts`
- `frontend/src/services/api/jobs.ts`
- `frontend/src/types.ts`
- `backend/README.md`
- `frontend/README.md`
- `docs/API_CONTRACTS.md`
- `docs/CODEX_EXECUTION_LOG.md`
- `CHANGELOG.md`
### Tests run
- `python -m compileall backend/app` (pass)
- `cd backend && python -m pytest` (pass)
- `bash scripts/run_readiness_check.sh` (pass)
- `bash scripts/smoke_backend_import.sh` (pass)
- `cd frontend && npm run typecheck` (pass)
- `cd frontend && npm run build` (pass)
### Known limitations
- Raster processing beyond readiness/metadata is intentionally dependency-aware placeholder in Sprint 3.
- `docker` remains unavailable in this environment.
- `python3` still resolves to Windows Store stub; use `python` for verification.
### Next recommended pass
- Install rasterio/GDAL for real raster clipping/tile implementations.
- Add queue-backed worker (Redis/RQ) behind existing synchronous job facade.
- Add deeper operation acceptance tests for output dataset geometry correctness and persisted metadata.
## Pass 15 — Sprint 4 raster foundation
Date: 2026-06-11
### Completed
- Finalized dependency-aware raster processing behavior for clip/tile/preview and improved metadata enrichment.
- Ensured raster metadata and preview responses include deterministic file metadata (`size_bytes`, `checksum_sha256`, `path`) where available.
- Added raster tile manifest generation with deterministic storage paths and returned manifest payload.
- Updated API contracts and execution documentation from placeholder wording to actual raster-op foundations.
- Added targeted Sprint 4 tests for missing-area clip behavior and tile manifest payload shape.
### Files changed
- `backend/app/services/raster_operations_service.py`
- `backend/app/api/routes/health.py`
- `backend/tests/test_raster_operations_service.py`
- `docs/API_CONTRACTS.md`
- `docs/CODEX_EXECUTION_LOG.md`
- `backend/README.md`
- `frontend/README.md`
- `README.md`
- `CHANGELOG.md`
### Tests run
- `python -m compileall backend/app`
- `cd backend && python -m pytest`
- `bash scripts/run_readiness_check.sh`
- `bash scripts/smoke_backend_import.sh`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
### Known limitations
- Raster dependency packages remain optional and will report `RASTER_PROCESSING_UNAVAILABLE` if absent.
- Raster clip/tile remain synchronous under the current in-process job wrapper.
### Next recommended pass
- Run full raster end-to-end tests with real GeoTIFF fixtures and validate output dataset metadata persistence.
## Pass 16 Sprint 4 raster operations foundation hardening
Date: 2026-06-11
### Completed
- Realized the Sprint 4 raster foundation readiness in implementation and docs alignment:
- metadata extraction now returns real raster profile fields when rasterio is available
- preview generation writes deterministic PNG artifacts and reuses cached previews
- clip and tile operations persist deterministic outputs and manifest structure
- all raster processing paths now use explicit dependency-aware errors when rasterio/numpy/pillow are missing
- Fixed remaining frontend render/type issues introduced during raster path handling.
- Strengthened raster tests for tile manifest minimum size and dependency-aware behavior.
- Updated sprint milestone docs to reflect Sprint 4 status:
- `backend/README.md`
- `frontend/README.md`
### Files changed
- `backend/app/services/raster_operations_service.py`
- `backend/tests/test_raster_operations_service.py`
- `backend/app/api/routes/datasets.py`
- `backend/app/schemas/operations.py`
- `frontend/src/App.tsx`
- `backend/README.md`
- `frontend/README.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Tests run
- `python -m compileall backend/app` (pass)
- `cd backend && python -m pytest` (pass, 26 tests)
- `bash scripts/run_readiness_check.sh` (pass)
- `bash scripts/smoke_backend_import.sh` (pass)
- `cd frontend && npm run typecheck` (pass)
- `cd frontend && npm run build` (pass)
### Known limitations
- `docker` command is unavailable in this environment, so `docker compose config` could not be executed.
- `python3` command is unavailable as an alias in this environment; use `python` instead.
- Full raster dependency stack may be unavailable in some dev environments; those cases intentionally return structured `RASTER_PROCESSING_UNAVAILABLE` responses.
### Next recommended pass
- Sprint 5: add end-to-end RasterOps coverage for CRS-preserving re-projection, export-quality metadata policy, and tile set artifact cleanup lifecycle.
## Pass 17 — Sprint 5 raster analytics hardening
Date: 2026-06-11
### Completed
- Implemented Sprint 5 raster analytics foundation:
- band statistics endpoint and service with dependency-aware unavailable mode.
- reproject operation with CRS validation and reprojection metadata persistence.
- clip/tile hardening for missing/invalid geometry and empty clip output handling.
- enriched tile manifest fields (`tile_set_id`, `tile_size`, `overlap`, `source_dataset_id`, `source_raster_id`, `bounds`, `count`, `tile_paths`, `ai_inference`, `tile_server`, `created_at`, parameters).
- Updated raster stats/job error tests:
- dependency-aware stats failure coverage.
- invalid CRS request validation for reproject.
- persisted derived dataset assertions for reproject and clip.
- failure persistence test for failed raster jobs (`_run_job_sync`).
- Strengthened raster frontend detail panel rendering:
- job result JSON is visible for raster/vector operations.
- clearer raster metadata/status visibility retained for CRS/bounds/resolution display.
- Updated docs:
- backend/README Sprint 5 section.
- frontend/README Sprint 5 section.
- CHANGELOG entry for Sprint 5.
### Files changed
- `backend/app/services/raster_operations_service.py` (final reproject and manifest hardening alignment)
- `backend/tests/test_raster_operations_service.py`
- `frontend/src/App.tsx`
- `backend/README.md`
- `frontend/README.md`
- `docs/API_CONTRACTS.md`
- `docs/RASTER_OPERATIONS_SPEC.md`
- `docs/CODEX_EXECUTION_LOG.md`
- `CHANGELOG.md`
### Tests run
- `python -m compileall backend/app` (pass)
- `cd backend && python -m pytest` (pass)
- `bash scripts/run_readiness_check.sh` (pass)
- `bash scripts/smoke_backend_import.sh` (pass)
- `cd frontend && npm run typecheck` (pass)
- `cd frontend && npm run build` (pass)
### Known limitations
- Raster statistics and reproject operations still depend on environment availability of `rasterio`/`numpy`.
- Raster dependency checks and operation errors remain dependency-aware when libraries are unavailable.
### Next recommended pass
- Sprint 6: add raster index/mask workflows (NDVI/NDWI/NDBI), tile serving or export packaging, and AI-ready dataset linking.
## Pass 18 - Sprint 6 spectral indices
### Completed
- Added local raster index operations (`ndvi`, `ndwi`, `ndbi`) under the existing raster operation architecture.
- Added typed band payload validation and explicit `INVALID_PARAMETERS` handling for missing/invalid band indexes.
- Implemented dependency-aware failure behavior for index execution (`RASTER_PROCESSING_UNAVAILABLE`) when `rasterio` or `numpy` are unavailable.
- Implemented local index output generation with float32 raster derivation and persisted provenance metadata on derived datasets.
- Extended dataset detail UI with spectral index controls (NDVI/NDWI/NDBI), run actions, and output dataset navigation from jobs.
- Updated API contracts, raster operation spec, and project documentation for Sprint 6 behavior.
### Files changed
- `backend/app/schemas/operations.py`
- `backend/app/services/raster_operations_service.py`
- `backend/app/api/routes/datasets.py`
- `backend/tests/test_raster_operations_service.py`
- `frontend/src/services/api/datasets.ts`
- `frontend/src/App.tsx`
- `frontend/src/types.ts`
- `docs/API_CONTRACTS.md`
- `docs/RASTER_OPERATIONS_SPEC.md`
- `backend/README.md`
- `frontend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Tests run
- `python -m compileall backend/app`
- `cd backend && python -m pytest`
- `bash scripts/run_readiness_check.sh`
- `bash scripts/smoke_backend_import.sh`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
### Known limitations
- Raster dependency checks remain optional; missing raster packages return explicit `RASTER_PROCESSING_UNAVAILABLE` results.
- Job execution remains synchronous under current Sprint 3 job facade.
- `docker` and `python3` availability still depend on developer environment.
### Next recommended pass
- Keep operation architecture stable, then add threshold/mask workflows and output export packaging in a follow-up pass.
## Pass 19 - RC-2 stabilization
Date: 2026-06-12
### Completed
- Fixed backend compile/import blockers identified in RC-1:
- corrected dataset upload parameter ordering.
- corrected schema package re-exports for area schemas.
- Fixed frontend typecheck/build blockers in `App.tsx`.
- Added Alembic migration for dataset reference/provenance metadata columns required by current ORM models.
- Fixed QA comparison runtime crash and added focused QA service coverage.
- Corrected envelope response-model mismatches for vector inspect and raster stats endpoints.
- Strengthened `scripts/run_readiness_check.sh` so readiness runs backend compile, backend tests, frontend typecheck and frontend build.
- Improved readiness Python interpreter selection so it chooses an interpreter capable of running pytest.
### Files changed
- `backend/app/services/dataset_service.py`
- `backend/app/schemas/__init__.py`
- `backend/app/api/routes/datasets.py`
- `backend/app/services/qa_service.py`
- `backend/alembic/versions/202606120001_add_dataset_reference_metadata.py`
- `backend/tests/test_qa_service.py`
- `frontend/src/App.tsx`
- `scripts/run_readiness_check.sh`
- `docs/CODEX_EXECUTION_LOG.md`
### Tests run
- `python -m compileall backend\\app` (pass)
- `cd backend && python -m pytest` (pass, 40 tests)
- `cd frontend && npm run typecheck` (pass)
- `cd frontend && npm run build` (pass; bundle-size warning only)
- `bash scripts/run_readiness_check.sh` (pass)
- `cd backend && python -m alembic heads` (pass, single head `202606120001`)
- `cd backend && python -m alembic upgrade head --sql` (pass, generated SQL includes required dataset metadata columns)
- `docker compose config` not runnable in this environment because `docker` is not installed.
### Known limitations
- Fresh online database migration was validated only as generated Alembic SQL in this environment; run `cd backend && python -m alembic upgrade head` against a live PostgreSQL/PostGIS database on a machine with Docker or Postgres available.
- Existing non-RC architecture limitations from RC-1 remain intentionally unfixed: synchronous job facade, file-first vector outputs, monolithic frontend component, and incomplete future AI/storage architecture.
### Next recommended pass
- Do not start Sprint 7 until RC-2 verification is repeated against a live Docker/PostGIS environment.
## Pass 20 - Sprint 7A persistence and QA foundation
Date: 2026-06-12
### Completed
- Added first-class `vector_features` ORM model and Alembic migration with dataset and GiST geometry indexes.
- Persisted uploaded vector GeoJSON features into PostGIS-backed `vector_features` while keeping original file storage intact.
- Added first-class `quality_checks` and `metrics` ORM models and Alembic migration indexes.
- Added `QualityService` for persisted QA/QC domain records and metric rows.
- Updated QA candidate-vs-reference route so successful QA jobs also persist a `QualityCheck` and metrics, and return `quality_check_id` in `result_json`.
- Hardened provider capability contracts for GRB and OSM as `not_configured` stubs with supported layers, geometry types and query modes.
- Added Sprint 7A tests for vector feature persistence, quality check persistence, metrics persistence, dataset role validation, provider contracts, migration integrity and QA route persistence.
- Updated database/API documentation for Vector Features Architecture, Quality Check Architecture, Metrics Architecture and Provider Architecture.
### Files changed
- `backend/app/models/entities.py`
- `backend/app/models/__init__.py`
- `backend/app/services/dataset_service.py`
- `backend/app/services/vector_feature_service.py`
- `backend/app/services/quality_service.py`
- `backend/app/api/routes/qa.py`
- `backend/app/providers/base.py`
- `backend/app/providers/grb.py`
- `backend/app/providers/osm.py`
- `backend/app/schemas/health.py`
- `backend/alembic/versions/202606120700_sprint7a_persistence_foundation.py`
- `backend/tests/test_sprint7a_persistence_foundation.py`
- `docs/DATABASE_IMPLEMENTATION_PLAN.md`
- `docs/API_CONTRACTS.md`
- `docs/CODEX_EXECUTION_LOG.md`
- `CHANGELOG.md`
### Tests run
- `python -m compileall backend/app` (pass)
- `python -m pytest backend -q` (pass, 47 tests)
### Known limitations
- Sprint 7A intentionally does not implement GRB downloads, OSM downloads, Detection Lab, Segmentation Lab, LiDAR, AI Copilot, Training Studio or Reports.
- Job execution remains the existing synchronous facade.
- Live database migration still needs validation against a running PostgreSQL/PostGIS service in an environment with Docker or Postgres available.
### Next recommended pass
- Complete full release validation commands, including Alembic heads/SQL generation, readiness script, frontend typecheck/build and Docker config if Docker is available.
### Validation addendum
Date: 2026-06-12
Additional Sprint 7A validation completed after migration index cleanup:
- `python -m compileall backend/app` (pass)
- `cd backend && python -m pytest` (pass, 47 tests)
- `bash scripts/run_readiness_check.sh` (pass)
- `cd frontend && npm run typecheck` (pass)
- `cd frontend && npm run build` (pass; Vite chunk-size warning only)
- `cd backend && python -m alembic heads` (pass, single head `202606120700`)
- `cd backend && python -m alembic upgrade head --sql` (pass; generated SQL includes `vector_features`, `quality_checks`, `metrics` and the named GiST index `ix_vector_features_geometry`)
- `docker compose config` could not run because Docker is not installed in this shell.
## Pass 21 - Sprint 7B provider integration skeleton (2026-06-12)
- Implemented central provider registry for `grb`, `osm`, `manual` and `fixture`.
- Added provider capability, layer, status and future import-contract endpoints using the existing response envelope style.
- Preserved GRB and OSM as explicit `not_configured` providers; no live WFS, Overpass, download or fake provider data was introduced.
- Documented and tested provider-to-dataset mapping rules; future provider output must flow through `DatasetService` / `VectorFeatureService` rather than direct `vector_features` writes.
- Added frontend Provider Capabilities panel without live import buttons for GRB/OSM.
- Added opt-in `scripts/live_migration_smoke.sh` for real PostGIS migration smoke checks.
- Added Sprint 7B tests for provider registry, API envelopes, invalid provider handling, import contract and smoke script presence.
## Pass 22 - Sprint 8 Detection Lab foundation (2026-06-12)
### Completed
- Added first-class `detections` ORM model and Alembic migration with project, dataset, analysis run, class and GiST geometry indexes.
- Hardened `analysis_runs` with dataset, job, model, result and created-at fields while keeping jobs conceptually separate from analysis lifecycle.
- Added model registry capability service for `yolo-placeholder` (`not_configured`) and `manual-fixture-detector` (explicit fixture/demo only).
- Added `DetectionService` boundary for model listing, request validation, analysis run creation, job creation, unavailable model responses and explicit fixture persistence.
- Added Detection Lab API endpoints under `/api/v1/detection` using the existing response envelope style.
- Added minimal frontend Detection Lab panel for model capability status, raster dataset selection, confidence threshold and run result/error display.
- Updated database, API, AI pipeline, backend/frontend README, TODO and changelog docs.
### Known limitations
- Real YOLO/PyTorch inference is not enabled and no model downloads are performed.
- Fixture detector requires `fixture_mode=true` and explicit fixture detections; it is not production inference.
- Segmentation, LiDAR, AI Copilot, Training Studio and Reports remain out of scope.
### Next recommended pass
- Verify Sprint 8 with full backend/frontend/readiness/Alembic gates, then perform a Sprint 8 verification audit before Sprint 8B real YOLO integration.
## Pass 23 - Sprint 8B configured YOLO foundation (2026-06-12)
### Completed
- Added optional backend `ai` dependency group for `ultralytics` and `torch`; normal backend startup remains import-safe without those packages.
- Added YOLO configuration settings:
- `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`
- Added `yolo-configured` model registry capability with honest `not_configured`, `dependency_unavailable` and `configured` states.
- Added `YoloDetectionAdapter` that imports Ultralytics only in the load path and refuses missing local model files before model construction.
- Added raster tile manifest validation and configured tile-limit enforcement for real YOLO runs.
- Added pixel bbox to EPSG:4326 polygon georeferencing from tile transform or bounds metadata.
- Routed configured YOLO outputs through existing `DetectionService`, `Job`, `AnalysisRun` and first-class `Detection` persistence.
- Added Detection Lab tile manifest path input for the configured YOLO model.
- Added mocked Sprint 8B tests for model registry status, dependency-unavailable behavior, tile manifest validation, georeferencing and persisted detections.
- Updated API, AI pipeline, backend/frontend README and changelog documentation.
### Known limitations
- Sprint 8B does not add workers/queues; configured YOLO runs remain synchronous behind the existing job abstraction.
- Real model loading is validated at execution time. The registry reports configured when dependencies and local model path are present.
- No model weights are downloaded by GeoIntel.
- Detection visualization/map overlays are deferred.
- Segmentation, LiDAR, AI Copilot, Training Studio and Reports remain out of scope.
### Next recommended pass
- Run full Sprint 8B validation and then perform a Sprint 8B verification audit before advancing to detection visualization/QA or segmentation planning.
## Pass 24 - Sprint 8C detection visualization and QA integration (2026-06-12)
### Completed
- Added detection result review endpoints for listing runs, listing detections by run/dataset, retrieving detection detail and returning persisted detections as GeoJSON FeatureCollections.
- Added lightweight detection filters for class name and minimum confidence.
- Added detection QA against persisted reference `vector_features` using the existing `QualityService`, `quality_checks` and `metrics` persistence path.
- Added frontend Detection Lab run selection, detection table, class/confidence filters and MapLibre detection GeoJSON overlay via the existing map component.
- Added frontend detection QA controls and metric summary display.
- Added Sprint 8C tests for GeoJSON output, list/filter behavior, detection detail, API envelope shape, QA persistence and no-match QA behavior.
- Added direct Sprint 8B tests for missing and invalid tile manifest files.
- Updated API, AI pipeline, backend/frontend README and changelog documentation.
### Known limitations
- Detection QA requires reference datasets to have persisted `vector_features`; unsupported references return a clear error instead of fake metrics.
- Detection overlays reuse the existing single GeoJSON map layer styling; complex class-based map styling is deferred.
- Segmentation, LiDAR, AI Copilot, Training Studio and Reports remain out of scope.
### Next recommended pass
- Run full Sprint 8C validation and perform a Sprint 8C verification audit before starting Sprint 9 Segmentation Lab.
## Pass 25 - Sprint 9 Segmentation Lab foundation (2026-06-12)
### Completed
- Added first-class `segmentations` ORM model and Alembic migration with project, dataset, job, analysis run, class and GiST geometry indexes.
- Added segmentation model registry capabilities for `segmentation-placeholder`, `fixture-segmenter`, `yolo-seg-configured` and `sam-configured`.
- Added `SegmentationService` boundary for raster validation, job/analysis-run lifecycle, unavailable model responses and explicit fixture-only persistence.
- Added segmentation adapter placeholder module with no SAM, YOLO-seg, torch or ultralytics imports.
- Added persisted segmentation GeoJSON output generated from PostGIS geometry and provenance properties.
- Added segmentation QA against persisted reference `vector_features` using existing `quality_checks` and `metrics`.
- Added minimal frontend Segmentation Lab panel for model states, raster selection, runs/results, GeoJSON map overlay and QA metric display.
- Updated API, AI pipeline, storage, database, backend/frontend README and changelog documentation.
### Files changed
- `backend/app/models/entities.py`
- `backend/app/models/__init__.py`
- `backend/alembic/versions/202606120900_sprint9_segmentation_foundation.py`
- `backend/app/schemas/segmentation.py`
- `backend/app/schemas/__init__.py`
- `backend/app/services/model_registry_service.py`
- `backend/app/services/segmentation_adapter.py`
- `backend/app/services/segmentation_service.py`
- `backend/app/api/routes/segmentation.py`
- `backend/app/main.py`
- `backend/tests/test_sprint9_segmentation_foundation.py`
- `frontend/src/types.ts`
- `frontend/src/services/api/segmentation.ts`
- `frontend/src/services/api/index.ts`
- `frontend/src/App.tsx`
- `docs/API_CONTRACTS.md`
- `docs/AI_PIPELINES.md`
- `docs/STORAGE_ARCHITECTURE.md`
- `docs/DATABASE_IMPLEMENTATION_PLAN.md`
- `backend/README.md`
- `frontend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Tests run
- `python -m pytest backend/tests/test_sprint9_segmentation_foundation.py -q` (red first: missing `Segmentation` import, then pass)
- `cd backend && python -m pytest` (pass, 88 tests)
- `cd frontend && npm run typecheck` (pass)
### Known limitations
- Sprint 9 intentionally does not implement real SAM, real YOLO-seg, model downloads, new AI dependencies or production-scale async inference.
- Fixture segmenter requires explicit `fixture_mode=true` and explicit fixture segmentations; it is not production inference.
- Metric area is only persisted when provided by the fixture/output payload; Sprint 9 does not compute authoritative area from masks.
### Next recommended pass
- Run full Sprint 9 validation and then perform Sprint 9 Verification Audit before considering future real SAM/YOLO-seg integration.
### Validation addendum
- `python -m compileall backend/app` (pass)
- `cd backend && python -m pytest` (pass, 88 tests)
- `bash scripts/run_readiness_check.sh` (pass)
- `cd frontend && npm run typecheck` (pass)
- `cd frontend && npm run build` (pass; existing Vite chunk-size warning only)
- `cd backend && python -m alembic heads` (pass, single head `202606120900`)
- `cd backend && python -m alembic upgrade head --sql` (pass; generated SQL includes `segmentations` and GiST index)
- `bash -n scripts/live_migration_smoke.sh` (pass)
- `docker compose config` could not run because Docker is not installed in this shell.
## Pass 26 - Sprint 10 release hardening and frontend modularization (2026-06-13)
### Completed
- Extracted Provider Capabilities, Detection Lab and Segmentation Lab sections from `frontend/src/App.tsx` into focused frontend components.
- Preserved existing workbench state ownership, API client calls, map overlay behavior and UI copy.
- Hardened `scripts/run_readiness_check.sh` with Alembic head verification and live migration smoke script syntax validation.
- Updated frontend README and changelog documentation for Sprint 10 maintainability work.
### Files changed
- `frontend/src/App.tsx`
- `frontend/src/components/providers/ProviderPanel.tsx`
- `frontend/src/components/detection/DetectionLab.tsx`
- `frontend/src/components/segmentation/SegmentationLab.tsx`
- `scripts/run_readiness_check.sh`
- `frontend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Sprint 10 intentionally does not add new backend capabilities, migrations, product features, AI dependencies or live provider fetching.
- `App.tsx` still owns shared workbench state orchestration; further extraction can be considered in a later maintainability pass if needed.
### Sprint 10 addendum - additional frontend extraction
- Extracted `frontend/src/components/project/ProjectPanel.tsx` and `frontend/src/components/project/AreaPanel.tsx` from `frontend/src/App.tsx`.
- Kept project and area form state owned by `App.tsx`; extracted components receive state and callbacks only.
- `cd frontend && npm run typecheck` passed after the additional extraction.
## Pass 27 - Sprint 11 Live Docker/PostGIS Runtime Validation (2026-06-13)
### Completed
- Hardened `scripts/live_migration_smoke.sh` so it runs `SELECT 1`, applies `alembic upgrade head`, then checks `PostGIS_Version()`.
- Added migrated schema-object checks for core tables and geometry indexes after the live migration step.
- Added `backend/tests/test_live_migration_smoke_script.py` to lock the smoke-script ordering and schema-check contract.
- Documented the Docker/PostGIS validation command sequence, expected local `DATABASE_URL` and cleanup commands in `backend/README.md`.
### Files changed
- `scripts/live_migration_smoke.sh`
- `backend/tests/test_live_migration_smoke_script.py`
- `backend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Runtime status
- Docker is not installed or not available in this shell, so `docker compose config`, `docker compose up -d db` and the live container-backed smoke could not be completed here.
- On a Docker-enabled machine, run:
- `docker compose config`
- `docker compose up -d db`
- `DATABASE_URL=postgresql+psycopg://geointel:geointel@localhost:5432/geointel bash scripts/live_migration_smoke.sh`
### Known limitations
- Sprint 11 did not add product behavior, API contracts, migrations, AI dependencies or provider fetching.
- Live runtime validation is partially blocked until Docker/PostGIS is available in the execution environment.
## Pass 28 - Sprint 12 QA/QC golden dataset and benchmarking (2026-06-15)
### Completed
- Added deterministic golden QA/QC fixtures for reference and predicted building polygons.
- Added `fixtures/golden/expected_qa_metrics.json` with the expected partial-match baseline.
- Added `scripts/run_golden_qa_benchmark.py` to run existing `QaService` logic and verify `QualityService` persistence output.
- Added backend tests for expected golden metrics, benchmark command output and persisted metric keys.
- Updated QA/QC specification, backend README and changelog documentation.
### Files changed
- `fixtures/golden/reference_buildings.geojson`
- `fixtures/golden/predicted_buildings.geojson`
- `fixtures/golden/expected_qa_metrics.json`
- `scripts/run_golden_qa_benchmark.py`
- `backend/tests/test_sprint12_golden_qa_benchmark.py`
- `docs/QA_QC_SPECIFICATION.md`
- `backend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Expected benchmark metrics
- precision: `0.5`
- recall: `0.5`
- F1: `0.5`
- mean IoU: `0.8339768339761133`
- false positives: `1`
- false negatives: `1`
### Known limitations
- The benchmark uses explicit fixture/demo data and an in-memory persistence session; it does not replace the pending Docker/PostGIS live smoke.
- Sprint 12 does not add product features, API contracts, migrations, live providers, AI model execution or new dependencies.
## Pass 29 - Sprint 13 Real YOLO operational hardening (2026-06-15)
### Completed
- Added `YoloPreflightService` for local configured-YOLO readiness checks without model loading, inference or downloads.
- Added `scripts/yolo_preflight.py` for CLI checks of enabled state, dependencies, local model file, tile manifest validity, tile limit and tile paths.
- Added Sprint 13 backend tests for disabled, dependency-unavailable and ready preflight states plus CLI JSON output.
- Updated AI pipeline, backend README and changelog documentation.
### Files changed
- `backend/app/services/yolo_preflight_service.py`
- `scripts/yolo_preflight.py`
- `backend/tests/test_sprint13_yolo_preflight.py`
- `docs/AI_PIPELINES.md`
- `backend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Preflight does not prove model compatibility or inference correctness; it intentionally avoids loading YOLO models.
- Optional AI dependencies are still not installed by default.
- Docker/PostGIS live validation remains pending until Docker is available.
## Pass 30 - Release hardening audit pass (2026-06-15)
### Completed
- Audited release-readiness signals after Sprint 13, including timestamp warnings, frontend bundle output, migration SQL rendering and readiness coverage.
- Replaced backend `datetime.utcnow()` calls with timezone-aware UTC timestamps in service paths.
- Verified the affected backend tests with `DeprecationWarning` promoted to errors.
- Split frontend production output into app, React vendor and MapLibre vendor chunks, with an explicit chunk warning threshold for the known MapLibre GIS runtime.
- Updated backend/frontend README, TODO and changelog documentation.
### Files changed
- `backend/app/services/dataset_service.py`
- `backend/app/services/geojson_service.py`
- `backend/app/services/job_service.py`
- `backend/app/services/qa_service.py`
- `backend/app/services/quality_service.py`
- `frontend/vite.config.ts`
- `backend/README.md`
- `frontend/README.md`
- `docs/TODO.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- This pass does not add product features, migrations, API contracts, AI dependencies, provider fetching or model execution.
- Docker/PostGIS live validation still requires a Docker-enabled machine.
- Larger frontend architectural decomposition remains a separate low-risk planning item; this pass only hardened build output.
## Pass 31 - Extended release hardening sweep (2026-06-15)
### Completed
- Promoted the backend readiness gate to run `pytest` with `-W error::DeprecationWarning`.
- Added backend tests that verify readiness and pass-end scripts keep the stricter release checks in place.
- Hardened `scripts/codex_pass_end_check.sh` so placeholder scans skip `node_modules`, `dist` and `__pycache__` folders.
- Updated `docs/TODO.md` with a current implementation status layer while preserving older planning context.
- Re-ran pass-end checks and strict backend warning checks.
### Files changed
- `scripts/run_readiness_check.sh`
- `scripts/codex_pass_end_check.sh`
- `backend/tests/test_readiness_gate.py`
- `backend/README.md`
- `docs/TODO.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- This pass still does not add API contracts, migrations, product features, provider fetching, AI dependencies or model execution.
- Docker/PostGIS live validation remains blocked in this local environment because Docker is unavailable.
## Pass 32 - Readiness contract gate hardening (2026-06-15)
### Completed
- Added API contract smoke validation to `scripts/run_readiness_check.sh`.
- Added a regression test that requires the readiness gate to keep running `scripts/smoke_contracts.py`.
- Re-ran the full readiness gate after the change.
### Files changed
- `scripts/run_readiness_check.sh`
- `backend/tests/test_readiness_gate.py`
- `backend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Docker/PostGIS live validation remains blocked in this local environment because Docker is unavailable.
## Pass 33 - Docker runtime build hardening (2026-06-15)
### Completed
- Investigated Unraid/Tower Docker build failure from pasted server output.
- Fixed backend Docker build ordering so `README.md` and `app/` exist before `pip install .`.
- Removed mandatory root `.env` references from Compose; default local runtime now uses checked-in environment values.
- Added PostGIS healthcheck and backend `depends_on` health condition.
- Made the backend container run `python -m alembic upgrade head` before starting Uvicorn.
- Added backend and frontend `.dockerignore` files to reduce Docker build context and exclude dependency/build/cache outputs.
- Added regression tests for Dockerfile package-source ordering, Compose env behavior, DB health/migration startup and Docker ignore coverage.
### Files changed
- `backend/Dockerfile`
- `docker-compose.yml`
- `backend/.dockerignore`
- `frontend/.dockerignore`
- `backend/tests/test_docker_runtime_config.py`
- `README.md`
- `backend/README.md`
- `docs/TODO.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Docker commands still cannot be executed in this local Codex environment because Docker is unavailable here.
- The server should rerun `docker compose build --no-cache && docker compose up -d` to verify the real Docker runtime.
## Pass 34 - Docker browser port 1202 (2026-06-15)
### Completed
- Changed Docker Compose frontend host publishing from `5173:5173` to `1202:5173`.
- Added backend Docker CORS defaults for `http://localhost:1202` and `http://127.0.0.1:1202`.
- Updated `.env.example` and local/Docker documentation to point browser users to `http://localhost:1202` for Docker Compose.
- Added a regression assertion to Docker runtime config tests.
### Files changed
- `docker-compose.yml`
- `.env.example`
- `backend/tests/test_docker_runtime_config.py`
- `README.md`
- `backend/README.md`
- `frontend/README.md`
- `docs/LOCAL_DEVELOPMENT_RUNBOOK.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Docker commands still cannot be executed in this local Codex environment because Docker is unavailable here.
## Pass 35 - Docker backend database startup retry (2026-06-16)
### Completed
- Investigated Tower runtime logs showing backend Alembic startup failed with `connection refused` even after the db container reported healthy.
- Added `backend/docker_start.sh` to retry a real SQLAlchemy `SELECT 1` connection before migrations.
- Updated Compose to run `sh /app/docker_start.sh` for backend startup.
- Added regression tests that require the Docker start script and SQL readiness retry before migrations.
### Files changed
- `backend/docker_start.sh`
- `docker-compose.yml`
- `backend/tests/test_docker_runtime_config.py`
- `backend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Docker commands still cannot be executed in this local Codex environment because Docker is unavailable here.
## Pass 36 - Alembic Docker log formatting fix (2026-06-16)
### Completed
- Investigated backend Docker logs showing repeated literal `%(levelname)-5.5s [%(name)s] %(message)s` lines during migrations.
- Fixed `backend/alembic.ini` logging formatter from escaped `%%(...)` tokens to runtime interpolation `%(...)` tokens.
- Added a regression test for Alembic logging formatter correctness.
- Verified Alembic SQL rendering no longer emits literal formatter spam.
### Files changed
- `backend/alembic.ini`
- `backend/tests/test_alembic_logging_config.py`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
## Pass 37 - Frontend same-origin API proxy for Docker LAN access (2026-06-16)
### Completed
- Audited the running app at `http://192.168.10.150:1202` from Codex: frontend HTML and backend `/health` were reachable, but `/api/v1/projects` on the frontend origin returned the frontend HTML fallback.
- Changed the frontend API client default from `http://localhost:8000` to same-origin requests.
- Added Vite proxy routes for `/api` and `/health`.
- Added Docker Compose `VITE_API_PROXY_TARGET=http://backend:8000` so LAN browsers use `http://192.168.10.150:1202` only and the frontend container proxies API calls internally.
- Added regression tests for same-origin API/proxy behavior.
### Files changed
- `frontend/src/services/api/client.ts`
- `frontend/vite.config.ts`
- `docker-compose.yml`
- `backend/tests/test_docker_runtime_config.py`
- `README.md`
- `frontend/README.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- The running Tower deployment needs a rebuild/restart before this fix is active.
## Pass 38 - Browser runtime proxy guard (2026-06-16)
### Completed
- Added `scripts/verify_browser_runtime.sh` to verify the browser-facing frontend URL, `/api/v1/projects` proxy behavior and optional backend health endpoint.
- Added readiness syntax validation for the browser runtime verification script.
- Updated environment and local development documentation to prefer same-origin frontend API calls with Vite proxying in Docker/LAN deployments.
### Files changed
- `scripts/verify_browser_runtime.sh`
- `scripts/run_readiness_check.sh`
- `backend/tests/test_docker_runtime_config.py`
- `README.md`
- `docs/ENVIRONMENT_SPEC.md`
- `docs/LOCAL_DEVELOPMENT_RUNBOOK.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- The currently running Tower deployment at `http://192.168.10.150:1202` still returns frontend HTML for `/api/v1/projects` until the frontend image is rebuilt and restarted.
## Pass 39 - Environment contract cleanup (2026-06-16)
### Completed
- Corrected `.env.example` and `docs/ENVIRONMENT_SPEC.md` to use the YOLO environment variable names read by backend settings: `YOLO_ENABLED`, `YOLO_MODEL_PATH`, `YOLO_MODEL_VERSION` and `YOLO_MAX_TILES`.
- Updated frontend example settings to keep `VITE_API_BASE_URL` empty by default and expose `VITE_API_PROXY_TARGET` for Vite proxy routing.
- Added regression coverage for example environment names and browser runtime proxy verification.
### Files changed
- `.env.example`
- `docs/ENVIRONMENT_SPEC.md`
- `backend/tests/test_docker_runtime_config.py`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Docker cannot be executed in this local Codex environment; Tower still needs an image rebuild/restart to activate the frontend proxy fix.
## Pass 40 - Frontend Docker nginx reverse proxy (2026-06-16)
### Completed
- Replaced the Docker frontend runtime with a production Vite build served by nginx.
- Added `frontend/nginx.conf` with explicit reverse proxy rules for `/api/` and `/health` to `backend:8000`.
- Changed Docker Compose frontend publishing from `1202:5173` to `1202:80`.
- Updated Docker runtime regression tests and documentation so the browser-facing API path is no longer dependent on Vite dev-server proxy behavior.
### Files changed
- `frontend/Dockerfile`
- `frontend/nginx.conf`
- `docker-compose.yml`
- `backend/tests/test_docker_runtime_config.py`
- `README.md`
- `frontend/README.md`
- `docs/ENVIRONMENT_SPEC.md`
- `docs/LOCAL_DEVELOPMENT_RUNBOOK.md`
- `CHANGELOG.md`
- `docs/CODEX_EXECUTION_LOG.md`
### Known limitations
- Docker still cannot be executed in this local Codex environment. Tower must rebuild the frontend image to activate the nginx runtime.
## Sprint 14 - Docker GIS runtime enablement (2026-06-16)
- Added backend `gis` optional dependency group for the approved Rasterio/GeoPandas runtime stack.
- Updated backend Docker image to install `.[gis]` and GDAL/GEOS/PROJ system packages.
- Added `scripts/verify_gis_runtime.sh` to verify PostGIS, Rasterio and GeoPandas capabilities through the browser-facing frontend proxy.
- Added readiness syntax coverage for the GIS runtime verification script.
- Added regression tests for Docker GIS dependency installation and capability verification coverage.
- Updated backend, environment, root README and changelog documentation with local/LAN verification commands.
- No API contracts, migrations, AI dependencies, provider fetching or product features were changed.
- Added `scripts/gis_import_smoke.py` and wired it into the backend Docker build so broken Rasterio/GeoPandas/pyogrio imports fail during image build.
- Added Docker Compose healthchecks for backend and frontend; frontend now waits for backend service health before starting.
- Corrected the GIS import smoke placement so the backend Docker build can access it inside the `./backend` build context; the root script now wraps the backend script.
## Sprint 15 - Explicit demo workflow seed (2026-06-16)
- Added `POST /api/v1/demo/workflow` for an explicit offline demo workflow seed.
- Added `DemoWorkflowService` to create or return a demo project, AOI, fixture reference dataset, fixture candidate dataset and persisted QA/QC metrics.
- Added `scripts/seed_demo_workflow.py` for terminal-based demo seeding.
- Added frontend `Load demo workflow` action in the Projects panel.
- Added endpoint/fixture-contract tests and readiness compile coverage for the demo seed script.
- No live GRB/OSM fetching, AI inference, migrations or new dependencies were introduced.
## Sprint 16 - QA/QC result visibility (2026-06-16)
- Added `GET /api/v1/projects/{project_id}/quality-checks` for read-only project QA/QC result listing.
- Added `QualityCheckService` to return persisted `quality_checks` with metric rows.
- Added frontend QA/QC Results panel and API client support.
- Demo workflow loading and QA actions now refresh persisted QA/QC results in the UI.
- Added backend tests for quality check listing and canonical envelopes.
- No migrations, live provider fetching, AI inference or new dependencies were introduced.
## Sprint 17 export foundation (2026-06-16)
Changed:
- Hardened GeoJSON exports so vector dataset, detection run and segmentation run exports persist `exports` rows and write JSON artifacts.
- Added project metadata JSON export plus export list/read/content endpoints.
- Added a frontend Export Center panel for creating exports, listing export records and previewing JSON content.
- Added backend tests for export persistence, artifact writing, raster rejection and canonical envelope behavior.
Tested:
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh && bash -n scripts/verify_browser_runtime.sh && bash -n scripts/verify_gis_runtime.sh`
Open:
- Docker/live browser validation must be rerun on the deployment host after rebuild.
- YOLO-format export and report export remain documented future work; this pass only implements JSON/GeoJSON export foundation.
Limitations:
- Export artifacts are returned through API JSON content preview; browser file-download UX is not implemented yet.
- Detection and segmentation exports require existing persisted runs; no inference or fake output generation is introduced.
Next recommended pass:
- Rebuild/redeploy the Docker stack and verify `/api/v1/exports/*` through the LAN frontend proxy, then consider a lightweight file-download endpoint or report artifact pass.
## Sprint 17 export download hardening (2026-06-16)
Changed:
- Added `GET /api/v1/exports/{export_id}/download` as a raw file response for stored JSON/GeoJSON export artifacts.
- Reused the same export artifact existence validation for content preview and downloads.
- Added frontend Export Center download buttons using the configured/same-origin API base URL.
- Added backend tests for missing artifacts and file download response headers/content.
Tested:
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh && bash -n scripts/verify_browser_runtime.sh && bash -n scripts/verify_gis_runtime.sh`
Open:
- Docker/LAN validation should be rerun after redeploy on the Tower host.
Limitations:
- Download endpoint is intentionally a raw file response, not a canonical JSON envelope, because it is a browser/file artifact path.
Next recommended pass:
- Rebuild Docker and verify Export Center create/preview/download against `http://192.168.10.150:1202`.
## Sprint 17 lightweight report artifact export (2026-06-16)
Changed:
- Added `POST /api/v1/exports/report` to create a lightweight HTML project report artifact from persisted project, dataset and QA/QC summary state.
- Added HTML escaping for report-rendered project and dataset values.
- Updated export downloads to return `text/html` for HTML report artifacts and `application/json` for JSON/GeoJSON artifacts.
- Added a frontend Export Center action for project report HTML export.
- Added backend tests for HTML report artifact creation and HTML download response behavior.
Tested:
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh && bash -n scripts/verify_browser_runtime.sh && bash -n scripts/verify_gis_runtime.sh`
Open:
- Docker/LAN verification should be rerun after deployment rebuild.
Limitations:
- Report export is intentionally a simple HTML artifact, not a PDF designer or standalone Reports module.
- Report content is summary-only and uses existing persisted project, dataset and QA/QC rows.
Next recommended pass:
- Rebuild Docker and verify Export Center metadata, GeoJSON, report HTML and download flows through the LAN URL.
## Sprint 17 export audit trail and LAN demo/export smoke (2026-06-16)
Changed:
- Added export history to project metadata JSON and lightweight HTML report artifacts.
- Added `scripts/verify_demo_export_workflow.sh` to verify the browser-facing demo workflow, persisted QA/QC listing, metadata export, report export, vector GeoJSON export, export listing and artifact downloads.
- Included the demo/export workflow script in the main readiness syntax gate.
- Added backend tests to lock export-history content and demo/export script coverage.
Tested:
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh && bash -n scripts/verify_browser_runtime.sh && bash -n scripts/verify_gis_runtime.sh && bash -n scripts/verify_demo_export_workflow.sh`
Open:
- `scripts/verify_demo_export_workflow.sh` still needs to be run against the rebuilt Tower deployment URL.
Limitations:
- The smoke script intentionally uses explicit fixture demo data and does not fetch live GRB/OSM or run AI inference.
Next recommended pass:
- Rebuild Docker on the Tower host and run `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202`.
## Sprint 32 Unraid all-in-one runtime verification (2026-06-17)
Changed:
- Converted the Unraid/Tower runtime to a single editable `geointel` Docker container via `docker-compose.unraid.yml`.
- Built the all-in-one image from `postgres:16-bookworm` with PostgreSQL 16/PostGIS packages, the FastAPI backend, nginx and the React frontend.
- Removed the default nginx site from the image so `/api/v1/*` is proxied to the embedded backend instead of returning nginx 404s.
- Hardened live migration smoke and browser runtime verification with startup retries.
- Browser runtime verification now checks the frontend, `/api/v1/projects` canonical JSON envelope and `/geointel-icon.png`.
Tested:
- `python -m pytest backend\tests\test_sprint31_unraid_template.py`
- `bash -n deploy/unraid/all-in-one-start.sh`
- `bash -n scripts/live_migration_smoke.sh`
- `bash -n scripts/verify_browser_runtime.sh`
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\deploy_tower.ps1`
- `docker compose -f docker-compose.unraid.yml ps` on Tower
- `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`
Verified runtime:
- Tower runs one GeoIntel app container: `geointel`.
- Published browser port is `0.0.0.0:1202->80/tcp`.
- Container health is `healthy`.
- Live migration smoke passed with PostGIS available and one Alembic head.
- Frontend, API proxy and icon are reachable at `http://192.168.10.150:1202`.
Open:
- Existing reused PostgreSQL volume logs a collation version mismatch because the old database was created on Debian glibc 2.31 and the all-in-one runtime uses glibc 2.36. Runtime and migrations pass; a future maintenance pass can rebuild/refresh collation metadata if needed.
## Sprint 32 DockerMan template/icon follow-up (2026-06-17)
Changed:
- Added a PNG icon for Unraid/DockerMan because DockerMan may not reliably render app-served SVG icons.
- Changed the Unraid template `<Name>` to `geointel` so it matches the running all-in-one container name.
- Changed the template icon URL to the absolute PNG URL `http://192.168.10.150:1202/geointel-icon.png`.
- Added DockerMan labels to `docker-compose.unraid.yml` so the running Compose container exposes Unraid managed/webui/icon metadata.
- Updated Tower deploy scripts to copy the editable template to `/boot/config/plugins/dockerMan/templates-user/my-geointel.xml`.
- Updated Tower deploy scripts to copy the PNG icon to `/boot/config/plugins/dockerMan/images/geointel-icon.png`.
Expected Unraid behavior:
- Refresh the Unraid Docker page after deploy so DockerMan reloads the user template metadata.
- The running `geointel` container should have template-backed editable fields and a PNG icon.
## Sprint 32 automatic DockerMan-native deploy follow-up (2026-06-17)
Changed:
- Added `deploy/unraid/run-dockerman-container.sh` as the single source of truth for the final Unraid container launch.
- Updated Tower deploy scripts so repository deploys validate the Compose reference, build the image with plain `docker build` and start the final container with `docker run` plus DockerMan labels.
- The launch script installs the DockerMan template/icon, removes old `geointel` containers, preserves/migrates the old Compose PostGIS volume when needed and starts the final `geointel` container as DockerMan-managed.
- Updated live migration smoke to support direct container execution through `LIVE_SMOKE_CONTAINER=geointel`.
Expected Unraid behavior:
- A deploy from the repo should no longer leave the final app as a plain Compose-owned container.
- The final image/container should avoid Compose metadata labels that can confuse Unraid's Docker page.
- The running `geointel` container should expose `net.unraid.docker.managed=dockerman`, web UI metadata and icon metadata immediately after deploy.
## Sprint 33 QA/QC benchmark readiness hardening (2026-06-17)
Changed:
- Added `scripts/verify_golden_qa_benchmark.sh` as a shell wrapper for the deterministic QA/QC golden benchmark.
- Made `scripts/run_readiness_check.sh` run `scripts/run_golden_qa_benchmark.py --json` so QA/QC metric drift fails the main release gate.
- Added a readiness syntax check for the golden benchmark wrapper.
- Hardened `scripts/validate_fixtures.py` so `fixtures/golden` GeoJSON files and expected fixture paths are validated alongside the general GeoJSON fixtures.
- Added backend regression tests that keep the golden benchmark wired into readiness.
- Updated script/backend docs, TODO and changelog.
Tested:
- `python scripts/validate_fixtures.py`
- `python scripts/run_golden_qa_benchmark.py --json`
- `bash -n scripts/verify_golden_qa_benchmark.sh`
- `bash scripts/verify_golden_qa_benchmark.sh`
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
Open:
- None for this pass.
Limitations:
- The benchmark intentionally uses explicit local fixtures only. It does not fetch live GRB/OSM data and does not run AI inference.
Next recommended pass:
- Continue with broader QA/QC golden demo coverage or frontend export preview decomposition.
## Sprint 34 browser-facing golden QA demo hardening (2026-06-17)
Changed:
- Hardened `scripts/verify_demo_export_workflow.sh` so the browser-facing demo/export smoke loads `fixtures/golden/expected_qa_metrics.json`.
- The smoke now verifies persisted QA/QC status, F1 score, precision, recall, mean IoU, false positives, false negatives and match counts against the golden baseline.
- Corrected the offline demo AOI to cover the golden fixture geometries instead of an older broad Kempen placeholder outside the fixture coordinates.
- Made existing demo workflows self-heal stale/unsupported QA checks by syncing the demo AOI and persisting a fresh golden QA/QC result.
- Added regression checks in backend tests so the demo/export smoke cannot regress back to key-existence-only QA/QC validation.
- Updated script documentation, TODO and changelog.
Tested:
- `python -m compileall backend/app`
- `cd backend && python -m pytest tests/test_sprint15_demo_workflow.py tests/test_sprint21_demo_workflow_smoke.py tests/test_readiness_gate.py -q`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202`
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202`
Open:
- Docker build still emits a warning about `GEOINTEL_POSTGRES_PASSWORD` being present as an image `ENV`; runtime behavior is green, but a future secret-hygiene pass should move that default out of the Dockerfile.
Limitations:
- The demo/export smoke remains intentionally fixture-based and idempotent. It does not fetch live providers and does not run AI inference.
Next recommended pass:
- Run the full release-readiness gate and then rebuild/deploy to Tower for browser-facing verification.
## Sprint 35 Docker runtime secret hygiene (2026-06-17)
Changed:
- Removed embedded PostGIS database name/user/password defaults from `deploy/unraid/Dockerfile.all-in-one` image metadata.
- Kept database credentials as runtime configuration supplied by `.env`, the Unraid template, Compose or `docker run -e`.
- Added regression coverage so `GEOINTEL_POSTGRES_PASSWORD` is not baked into the all-in-one Dockerfile again.
- Updated Unraid runtime documentation and changelog.
Tested:
- `cd backend && python -m pytest tests/test_sprint31_unraid_template.py tests/test_docker_runtime_config.py -q`
- `bash -n deploy/unraid/all-in-one-start.sh`
- `bash -n deploy/unraid/run-dockerman-container.sh`
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `cd backend && python -m alembic heads && python -m alembic upgrade head --sql`
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202`
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202`
Open:
- Local Windows shell has no `docker` command in PATH, so Docker build/config verification must run on Tower during deploy.
- Tower rebuild completed and the previous Docker BuildKit `SecretsUsedInArgOrEnv` warning no longer appears.
Limitations:
- The start script still has safe local defaults for standalone/dev startup. Shared deployments should set `GEOINTEL_POSTGRES_PASSWORD` via runtime configuration.
Next recommended pass:
- Run release readiness, rebuild/deploy Tower and verify browser/GIS/demo smoke again.
## Sprint 36 PostgreSQL collation maintenance visibility (2026-06-17)
Changed:
- Added PostgreSQL database collation version reporting to `scripts/live_migration_smoke.sh`.
- The live smoke now prints `COLLATION_VERSION_MISMATCH` with stored and actual versions when a reused PostGIS volume was created under an older libc/collation runtime.
- The smoke also prints the exact `ALTER DATABASE "... " REFRESH COLLATION VERSION;` acknowledgement command, but does not run it automatically.
- Documented the Unraid maintenance procedure and backup/index review guidance.
- Added regression coverage for the collation reporting path.
Tested:
- `cd backend && python -m pytest tests/test_live_migration_smoke_script.py -q`
- `bash -n scripts/live_migration_smoke.sh`
- `python -m compileall backend/app`
- `cd backend && python -m pytest -W error::DeprecationWarning`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh`
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`
- `bash scripts/verify_gis_runtime.sh http://192.168.10.150:1202`
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202`
Open:
- Tower live smoke reports `COLLATION_VERSION_MISMATCH: database=geointel stored=2.31 actual=2.36`.
- Runtime remains green. The next maintenance action is optional/manual acknowledgement after backup/index review: `ALTER DATABASE "geointel" REFRESH COLLATION VERSION;`.
Limitations:
- The smoke reports and documents the maintenance action. It intentionally does not mutate collation metadata automatically.
Next recommended pass:
- Run release readiness, deploy Tower and decide whether to manually acknowledge the current collation version.
## Sprint 49 Workbench shell UI refactor (2026-06-17)
Changed:
- Audited the live workbench UI and confirmed the main usability issue was information architecture: all V1 workflows were mounted as one long vertical panel stack.
- Refactored the frontend into a task-based workbench shell with Overview, Data, Map, QA/QC, AI Labs, Exports and System workspaces.
- Added a persistent top context bar for active project, AOI, dataset and layer state.
- Moved selected dataset details into a persistent right-side inspector while keeping the same dataset/raster/vector operation callbacks.
- Added stable primary navigation test anchors.
- Documented the new frontend shell structure and updated the changelog.
Tested:
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local Vite visual audit on `http://127.0.0.1:5175`
Open:
- Local Vite visual audit shows `Request failed (404)` when no local backend/proxy target is available. Docker/nginx same-origin proxy behavior remains the production path.
- The next pass should run full release readiness and deploy to Tower for browser-facing verification on `http://192.168.10.150:1202`.
Limitations:
- This pass intentionally changes UI structure only. It does not add product capabilities, alter API contracts, change migrations, fetch live providers or enable new AI models.
Next recommended pass:
- Run full readiness, rebuild/deploy Tower, then perform a live browser smoke through the new workbench navigation.
## Sprint 50 Workspace usability polish (2026-06-17)
Changed:
- Refined the task-based shell workspaces after the first UI refactor.
- Converted Project, AOI and Dataset panels into compact forms and card-based lists for faster scanning.
- Converted the Map workspace controls into a toolbar with dedicated AOI/layer controls and status.
- Converted Detection Lab and Segmentation Lab into model, run, result and QA blocks.
- Added CSS utilities for entity cards, dataset cards, model cards, lab blocks, primary/secondary actions and responsive nested forms.
- Added regression coverage for the polished workspace structure.
Tested:
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `cd backend && python -m pytest tests/test_sprint47_workbench_interaction_smoke.py tests/test_sprint49_workbench_shell_refactor.py -q`
Open:
- Run full release readiness and deploy the polish to Tower.
Limitations:
- This pass remains frontend-only. It does not add features, change API contracts, alter migrations, fetch live providers or enable new AI models.
Next recommended pass:
- Deploy to Tower and verify the Data, Map and AI Labs workspaces on `http://192.168.10.150:1202`.
## Sprint 51 QA/QC and export workspace polish (2026-06-17)
Changed:
- Refined the QA/QC workspace so persisted checks are shown as summary tiles, quality-check cards and metric chips instead of a raw nested list.
- Refined the Exports workspace with grouped export actions, latest-export status, artifact history cards and a framed JSON/GeoJSON preview panel.
- Kept the existing `useQualityWorkflow` and `useExportWorkflow` dataflow intact; no API client calls or backend contracts changed.
- Added regression coverage for the polished QA/QC and Exports workspace structure.
Tested:
- `cd frontend && npm run typecheck`
- `cd backend && python -m pytest tests/test_sprint27_frontend_workflow_hooks.py tests/test_sprint30_workbench_components.py tests/test_sprint47_workbench_interaction_smoke.py -q`
- `cd backend && python -m pytest tests/test_sprint51_quality_export_polish.py -q`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`207 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- Tower live migration smoke passed.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
Open:
- Manual visual review of populated QA/QC and Exports states with real project artifacts remains useful after the next demo workflow run.
Limitations:
- This pass remains UI polish only. It does not add product capabilities, change API contracts, alter migrations, fetch live providers or enable new AI models.
Next recommended pass:
- Verify QA/QC and Exports on the deployed Tower workbench, then continue with selected-object inspector detail tabs.
## Sprint 52 selected context inspector tabs (2026-06-17)
Changed:
- Replaced the dataset-only right inspector with a tabbed `WorkbenchInspector`.
- Added Context, Dataset, QA/Exports and AI Runs tabs using existing project, AOI, dataset, QA, export and AI-run state.
- Kept the existing `DatasetDetailPanel` as the Dataset tab so raster/vector operations and callbacks remain behavior-compatible.
- Added inspector cards for selected map feature properties, latest QA/QC, latest export and selected detection/segmentation run summaries.
- Added regression coverage for inspector wiring and tab structure.
Tested:
- `cd frontend && npm run typecheck`
- `cd backend && python -m pytest tests/test_sprint49_workbench_shell_refactor.py tests/test_sprint50_workspace_usability_polish.py tests/test_sprint51_quality_export_polish.py -q`
- `cd backend && python -m pytest tests/test_sprint28_dataset_workflow_hook.py tests/test_sprint29_dataset_components.py tests/test_sprint52_workbench_inspector_tabs.py -q`
- `cd backend && python -m pytest tests/test_sprint52_workbench_inspector_tabs.py -q`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`210 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- Tower live migration smoke passed.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
Open:
- Manual click-through of each inspector tab with populated demo data remains useful for visual fine-tuning.
Limitations:
- This pass remains UI orchestration only. It does not add features, change API contracts, alter migrations, fetch live providers or enable new AI models.
Next recommended pass:
- Verify the tabbed inspector live on Tower, then continue with map/dataset selection ergonomics.
## Sprint 53 map/dataset selection ergonomics (2026-06-17)
Changed:
- Added active-state styling to dataset cards so the selected dataset is visibly anchored in the catalog.
- Added dataset quick actions to open a dataset directly in the Map workspace or Exports workspace after loading details.
- Added inspector navigation actions to jump to Data, Map, QA/QC, Exports and AI Labs without hunting through the left navigation.
- Kept the existing dataset loading, map layer state, export flow and API clients unchanged.
- Added regression coverage for selection quick actions and inspector navigation wiring.
Tested:
- `cd frontend && npm run typecheck`
- `cd backend && python -m pytest tests/test_sprint28_dataset_workflow_hook.py tests/test_sprint29_dataset_components.py tests/test_sprint52_workbench_inspector_tabs.py -q`
- `cd backend && python -m pytest tests/test_sprint53_selection_ergonomics.py -q`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`213 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- Tower live migration smoke passed.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
Open:
- Manual demo-data click-through can still tune copy/density after real populated cards are visible.
Limitations:
- This pass remains UI orchestration only. It does not add features, change API contracts, alter migrations, fetch live providers or enable new AI models.
Next recommended pass:
- Verify dataset quick actions with demo data on Tower, then improve populated map/detail readability if needed.
## Sprint 54 populated-state UI polish (2026-06-17)
Changed:
- Ran the live demo/export workflow against the Tower deployment to inspect real populated workbench states.
- Adjusted the Data workspace so Project and AOI remain side by side while the Dataset catalog spans the full row for readable populated dataset cards.
- Made dataset-card action rows responsive so Map/Exports/detail actions do not crowd or clip on populated cards.
- Limited the Exports artifact history to the latest 10 entries by default with an explicit show-all toggle.
- Kept the Export Preview panel visible even before an artifact is selected, avoiding a blank middle column in the Exports workspace.
- Shortened displayed export storage paths while keeping the full path available in the title attribute.
- Added regression coverage for the populated Data layout and Exports populated-state behavior.
Tested:
- `bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202`
- Local Vite visual audit using the live Tower API proxy on `http://127.0.0.1:5176`
- `cd frontend && npm run typecheck`
- `cd backend && python -m pytest tests/test_sprint51_quality_export_polish.py tests/test_sprint53_selection_ergonomics.py -q`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`214 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- Tower live migration smoke passed.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Direct HTTP check passed for `http://192.168.10.150:1202` and `http://192.168.10.150:1202/api/v1/projects`.
Open:
- Continue monitoring export history growth during repeated demo workflow runs.
Limitations:
- This pass remains UI polish only. It does not add features, change API contracts, alter migrations, fetch live providers or enable new AI models.
Next recommended pass:
- Add export history filtering or retention controls if artifact history continues to grow during demo runs.
## Sprint 55 live visual shell polish (2026-06-17)
Changed:
- Performed a Browser-based visual audit of the live Tower workbench at `http://192.168.10.150:1202`.
- Confirmed the main visual defect was the cramped three-column desktop shell: left navigation, central workspace and inspector competed for width at 1280px.
- Compacted the sticky top context bar and left navigation.
- Changed the standard desktop breakpoint so the inspector moves below the workspace up to 1360px, while remaining a side panel on wider displays.
- Made the Map toolbar wrap responsively instead of forcing four controls into a narrow row.
- Added a workspace-change scroll reset so switching pages starts at the workspace heading instead of inheriting stale scroll position.
- Added regression coverage for the standard desktop shell width and scroll-reset behavior.
Tested:
- Local Browser visual audit against `http://127.0.0.1:5177` using the live Tower API proxy.
- Verified Overview, Data, Map and Exports workspaces visually after the shell changes.
- Browser console error/warning check returned no entries.
- `cd frontend && npm run typecheck`
- `cd backend && python -m pytest tests/test_sprint53_selection_ergonomics.py tests/test_sprint50_workspace_usability_polish.py -q`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`215 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- Tower live migration smoke passed.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Live Browser visual verification passed for Overview and Map on `http://192.168.10.150:1202`.
Open:
- Export history still grows during repeated demo runs and should get filtering or retention controls.
Limitations:
- This pass remains UI shell polish only. It does not add features, change API contracts, alter migrations, fetch live providers or enable new AI models.
Next recommended pass:
- Continue with export history filtering or retention controls if repeated demo runs keep growing artifact history.
## Sprint 56 export history controls (2026-06-17)
Changed:
- Added frontend-only search for export type, status, id and storage path in the Exports workspace.
- Added export type and status filters generated from the loaded export records.
- Made the latest-10 limiter apply after filtering so large histories stay manageable without hiding matching records unexpectedly.
- Added a clear no-match empty state and reset view action.
- Slightly compacted export action buttons so the history controls are visible earlier on standard desktop viewports.
- Added regression coverage for the export history controls, filtered list limiting and no-match state.
Tested:
- `cd frontend && npm run typecheck`
- `cd backend && python -m pytest tests/test_sprint51_quality_export_polish.py -q`
- `cd frontend && npm run build`
- Local Browser visual audit against `http://127.0.0.1:5178` using the live Tower API proxy.
- Verified Exports history controls render with 50 live artifacts and a `report` search narrows the list to 17 matching artifacts.
- Browser console error/warning check returned no entries.
Open:
- Run full readiness, deploy Tower and verify the live Exports filters on `http://192.168.10.150:1202`.
Limitations:
- This pass remains frontend UI hardening only. It does not add backend filtering, retention deletion, API changes, migrations, live provider fetching or AI model behavior.
Next recommended pass:
- Consider a safe export retention/cleanup command if the artifact table keeps growing beyond demo needs.
## Sprint 57 safer demo export cleanup (2026-06-17)
Changed:
- Hardened the existing dry-run-first demo export cleanup command instead of creating a parallel cleanup path.
- Added `--max-delete` with a default cap of 25 so large `--apply` runs are blocked until explicitly reviewed and raised.
- Added repeatable `--export-type` filters for targeted cleanup, e.g. reports only.
- Extended the cleanup summary with `keep_latest`, `max_delete`, `export_types`, `type_filtered_export_count`, `candidate_exports` and `blocked_reason`.
- Updated the root wrapper to expose the new filter helper.
- Updated `scripts/README.md`, `docs/STORAGE_ARCHITECTURE.md`, `backend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
- Added regression coverage for export-type filtering, parser defaults and max-delete options.
Tested:
- `python -m py_compile scripts/cleanup_demo_artifacts.py backend/scripts/cleanup_demo_artifacts.py`
- `cd backend && python -m pytest tests/test_sprint24_cleanup_demo_artifacts.py tests/test_readiness_gate.py -q` (`16 passed`)
- Tower dry-run command passed without deleting data:
`docker exec geointel /opt/geointel/venv/bin/python /app/scripts/cleanup_demo_artifacts.py --keep-latest 10 --max-delete 100 --export-type project_report_html`
- Tower dry-run reported `matched_export_count=51`, `type_filtered_export_count=17`, `selected_export_count=7`, `deleted_export_count=0`.
Open:
- Run full readiness and redeploy Tower with the clearer `candidate_exports` dry-run output.
Limitations:
- Cleanup still targets demo export records/files only. It does not delete source uploads, vector features, projects, AOIs, QA/QC records, rasters, tiles, masks or production data.
Next recommended pass:
- Add a small live maintenance smoke that runs cleanup in dry-run mode through the deployed all-in-one container.
## Sprint 58 demo cleanup dry-run smoke (2026-06-18)
Changed:
- Added `scripts/verify_demo_cleanup_dry_run.sh` as a live maintenance smoke for the demo export cleanup path.
- The smoke auto-detects a running compose backend or all-in-one `geointel` container, with explicit `CLEANUP_MODE=local|compose|container` overrides.
- The smoke runs cleanup without `--apply`, then verifies `dry_run=true`, `deleted_export_count=0`, `deleted_files=[]`, expected filter settings and candidate dry-run fields.
- Added the smoke syntax check to `scripts/run_readiness_check.sh`.
- Added regression coverage that the readiness gate checks the smoke and that the smoke contract remains non-mutating.
- Updated `scripts/README.md`, `docs/STORAGE_ARCHITECTURE.md`, `backend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- `bash -n scripts/verify_demo_cleanup_dry_run.sh`
- `python -m py_compile scripts/cleanup_demo_artifacts.py backend/scripts/cleanup_demo_artifacts.py`
- `cd backend && python -m pytest tests/test_readiness_gate.py tests/test_sprint24_cleanup_demo_artifacts.py -q` (`18 passed`)
- `bash scripts/run_readiness_check.sh` (`219 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- Tower live migration smoke passed.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Tower cleanup dry-run smoke passed with `matched=51`, `type_filtered=17`, `selected=7`, `deleted=0`.
Open:
- None for this pass.
Limitations:
- The readiness gate checks this live smoke's syntax only. The actual cleanup dry-run still requires a running backend/PostGIS runtime.
Next recommended pass:
- Add browser screenshot artifact automation for visual regression handoff.
## Sprint 59 workbench screenshot artifacts (2026-06-18)
Changed:
- Added `scripts/capture_workbench_screenshots.sh` for optional visual regression handoff screenshots.
- The script seeds the explicit offline demo workflow, opens Overview, Data, Map, QA/QC, AI Labs, Exports and System, then writes viewport screenshots plus `manifest.json`.
- Desktop capture is always enabled; mobile capture is enabled by default and can be disabled with `CAPTURE_MOBILE=0`.
- Added `/artifacts/` to `.gitignore` so screenshot outputs stay local.
- Added readiness syntax coverage and regression checks for the screenshot capture contract.
- Updated `scripts/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- `bash -n scripts/capture_workbench_screenshots.sh`
- `cd backend && python -m pytest tests/test_readiness_gate.py -q` (`13 passed`)
- `bash scripts/run_readiness_check.sh` (`221 passed`)
- Local script execution without Playwright fails cleanly with setup instructions instead of producing partial artifacts.
- Browser-plugin visual capture against `http://192.168.10.150:1202` created viewport screenshots for all seven workspaces with no console errors or warnings.
Open:
- Commit, deploy Tower and keep the visual artifact script available for future Playwright-enabled runners.
Limitations:
- Playwright/Chromium is intentionally optional and not added to the frontend dependency set. The readiness gate checks script syntax only.
Next recommended pass:
- Run a backend error-envelope audit for expected user-error paths.
## Sprint 60 API error-envelope contract hardening (2026-06-18)
Changed:
- Audited the backend error payload shape against `docs/API_CONTRACTS.md`.
- Changed central FastAPI error serialization to return top-level `error`, `message`, `details` and `request_id` fields.
- Preserved HTTPException detail dict support for future explicit error codes.
- Updated the frontend API client to parse the canonical top-level error contract while remaining tolerant of the older nested `error.code/message/details` shape.
- Added regression tests for AppError, HTTPException and validation-error envelopes.
- Updated provider-registry error assertions to the canonical top-level schema.
- Added static frontend parser coverage for canonical and legacy error payloads.
- Updated `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- `cd backend && python -m pytest tests/test_error_envelope_contract.py tests/test_sprint7b_provider_registry.py::test_provider_api_envelopes_and_invalid_provider -q` (`4 passed`)
- `python -m compileall backend/app`
- `cd frontend && npm run typecheck`
- `cd backend && python -m pytest -q` (`224 passed`)
- `cd frontend && npm run build`
- `cd backend && python -m pytest tests/test_error_envelope_contract.py tests/test_frontend_api_client_error_parser.py tests/test_sprint7b_provider_registry.py::test_provider_api_envelopes_and_invalid_provider -q` (`6 passed`)
- `bash scripts/run_readiness_check.sh` (`226 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1`
- Tower live migration smoke passed.
- Tower browser runtime verification passed on `http://192.168.10.150:1202`.
- Live `GET /api/v1/external/providers/unknown` returned `{"error":"PROVIDER_NOT_FOUND","message":"Provider not found","details":{},"request_id":null}`.
- Live `GET /api/v1/projects/not-a-uuid` returned top-level `VALIDATION_ERROR`.
Open:
- None for this pass.
Limitations:
- This pass changes only the centralized response envelope and frontend parser. It does not rename route-level error codes or change product behavior.
Next recommended pass:
- Expand golden datasets beyond the current building QA fixtures.
## Sprint 61 Golden QA scenario expansion (2026-06-18)
Changed:
- Added `fixtures/golden/golden_qa_benchmarks.json` as the explicit scenario manifest for deterministic QA/QC regression coverage.
- Added local golden fixture pairs for perfect-match, no-overlap and MultiPolygon building comparisons.
- Updated `scripts/run_golden_qa_benchmark.py` to execute all manifest scenarios, assert expected metric drift, persist simulated `QualityCheck`/`Metric` rows for each scenario and report aggregate persistence totals.
- Preserved backward-compatible top-level benchmark fields for scripts that still read the original single-scenario output shape.
- Updated `scripts/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `cd backend && python -m pytest tests/test_sprint12_golden_qa_benchmark.py -q` failed on missing multi-scenario manifest/output.
- `cd backend && python -m pytest tests/test_sprint12_golden_qa_benchmark.py -q` (`4 passed`)
- `python scripts/run_golden_qa_benchmark.py --json`
Open:
- Run full readiness and deploy Tower after the expanded golden benchmark passes the release gate.
Limitations:
- These are deterministic local QA/QC fixtures only. They do not introduce new production QA metrics or provider data.
Next recommended pass:
- Continue with frontend visual polish backlog or add a live golden benchmark smoke only if a running PostGIS environment needs that extra release signal.
## Sprint 62 Workbench visual polish (2026-06-18)
Changed:
- Added a compact workspace command bar under the active workspace heading for quick movement between the main workbench surfaces.
- Polished the shared frontend visual system with raised/sunken surface tokens, softer shadows, tighter topbar spacing and consistent workspace panel styling.
- Replaced raw project/dataset empty-state text with structured empty-state blocks.
- Wrapped Detection Lab and Segmentation Lab result summaries in scan-friendly result cards and long result tables in scroll-safe containers.
- Improved mobile navigation density by making the primary nav and command chips horizontal rails on narrow screens.
- Added `backend/tests/test_sprint62_frontend_visual_polish.py` to guard the visual polish contracts.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `cd backend && python -m pytest tests/test_sprint62_frontend_visual_polish.py -q` failed on missing command bar, panel polish and empty/result wrappers.
- `cd backend && python -m pytest tests/test_sprint62_frontend_visual_polish.py tests/test_sprint49_workbench_shell_refactor.py tests/test_sprint50_workspace_usability_polish.py -q` (`6 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local Chrome/Playwright visual check against `http://127.0.0.1:5175` with live API proxy: desktop and mobile screenshots captured, no console warnings/errors, no horizontal page overflow.
Open:
- Run full readiness and deploy Tower after this visual polish pass.
Limitations:
- This is a frontend usability polish pass only. It does not add new API behavior, data processing, provider fetching or AI model functionality.
Next recommended pass:
- Continue with map/result overlay ergonomics, especially making selected dataset/result provenance easier to see beside the map.
## Sprint 63 Map overlay ergonomics (2026-06-18)
Changed:
- Added active map layer source/provenance/draw-state context in the Map workspace using existing selected dataset, detection, segmentation and change-detection frontend state.
- Added a clear map empty-state when no vector/result layer is active.
- Added selected-feature property chips before the raw JSON feature inspector so common properties are scan-friendly.
- Tightened panel-title alignment with a scoped CSS override after the broader visual polish exposed a specificity issue in the existing `section > div:not(...)` rule.
- Added `backend/tests/test_sprint63_map_overlay_ergonomics.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `cd backend && python -m pytest tests/test_sprint63_map_overlay_ergonomics.py -q` failed on missing map provenance/feature-summary UI.
- `cd backend && python -m pytest tests/test_sprint63_map_overlay_ergonomics.py tests/test_sprint30_workbench_components.py tests/test_sprint53_selection_ergonomics.py -q` (`11 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local Chrome/Playwright check against `http://127.0.0.1:5175` with live API proxy: Map workspace opened, provenance rail present, no console warnings/errors, no horizontal page overflow.
Open:
- Run full readiness and deploy Tower after this pass.
Limitations:
- This is a frontend ergonomics pass only. It does not add new map layers, backend endpoints, provider fetching or geospatial processing.
Next recommended pass:
- Continue with export/report handoff polish or add a live browser smoke that explicitly visits every workspace after deployment.
## Sprint 64 Export/report handoff polish (2026-06-18)
Changed:
- Added a handoff readiness card to the Export Center using existing project, selected dataset, selected detection run, selected segmentation run and latest export state.
- Reworked existing export actions into artifact cards for refresh, project report, project metadata, selected vector GeoJSON, detection GeoJSON and segmentation GeoJSON.
- Added formatted export-type badges and extra export-card provenance for analysis-run ids and created timestamps when those fields are available.
- Added responsive styling for handoff summary/action cards.
- Added `backend/tests/test_sprint64_export_handoff_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint64_export_handoff_polish.py -q` failed on missing handoff summary/action structure and styles.
- `python -m pytest backend/tests/test_sprint64_export_handoff_polish.py backend/tests/test_sprint51_quality_export_polish.py -q` (`4 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local Chrome/Playwright check against `http://127.0.0.1:5175` with live API proxy: Exports workspace opened, handoff summary/actions present, no console warnings/errors, no horizontal page overflow on desktop or mobile.
- `bash scripts/run_readiness_check.sh` (`233 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the all-in-one container on Tower, with live migration smoke and browser runtime verification passing.
- Live Chrome/Playwright check against `http://192.168.10.150:1202`: Exports workspace opened, 6 handoff action cards present, no console warnings/errors, no horizontal page overflow on desktop or mobile.
Open:
- None for this pass.
Limitations:
- This is a frontend handoff usability pass only. It does not add export endpoints, change export persistence, introduce provider fetching or add AI/model behavior.
Next recommended pass:
- Run a live browser smoke across Exports and Overview after deployment, then continue with report artifact readability if the exported HTML itself needs visual polish.
## Sprint 65 Project report readability polish (2026-06-18)
Changed:
- Reworked the lightweight `project_report_html` renderer into a self-contained handoff layout with hero, readiness pill, scorecards and sectioned report content.
- Added print-friendly CSS and scroll-safe table wrappers to the HTML artifact.
- Added source and CRS columns to the dataset inventory section.
- Preserved existing export type, endpoint behavior, download behavior and storage flow.
- Added `backend/tests/test_sprint65_project_report_polish.py`.
- Updated `backend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint65_project_report_polish.py -q` failed on missing report shell, scorecards, print styles and readiness pill classes.
- `python -m pytest backend/tests/test_sprint65_project_report_polish.py backend/tests/test_sprint17_export_foundation.py -q` (`12 passed`)
- `python -m compileall backend/app`
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`235 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live report smoke through `http://192.168.10.150:1202`: seeded explicit demo workflow, created `project_report_html`, downloaded the HTML artifact and verified it in Chrome with 5 scorecards, 5 report sections, no console warnings/errors and no horizontal overflow on desktop or mobile.
Open:
- None for this pass.
Limitations:
- This remains a lightweight HTML handoff artifact. It does not add PDF generation, a report designer, new endpoints, live provider fetching or AI/model behavior.
Next recommended pass:
- Continue with a full-workspace browser smoke and then refine any remaining dense panels found during populated-state review.
## Sprint 66 Live workspace smoke polish (2026-06-19)
Changed:
- Ran a live browser smoke against `http://192.168.10.150:1202` across Overview, Data, Map, QA/QC, AI Labs, Exports and System.
- Captured desktop and mobile screenshots under `artifacts/sprint66-live-workspace-smoke/`.
- Confirmed all primary workspaces load with no console warnings/errors and no page-level horizontal overflow.
- Tightened Export Center handoff card CSS so action cards and readiness cells wrap by available width instead of forcing cramped three/four-column layouts in the populated Exports workspace.
- Added `backend/tests/test_sprint66_live_workspace_smoke_polish.py`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint66_live_workspace_smoke_polish.py -q` failed on missing width-aware export grid CSS and Sprint 66 log entry.
- Live desktop browser smoke: all seven primary workspaces opened, screenshots captured, no console warnings/errors, no horizontal page overflow.
- Live mobile browser smoke: all seven primary workspaces opened, screenshots captured, no console warnings/errors, no page-level horizontal overflow. The mobile primary nav intentionally remains a horizontal rail.
- Local post-fix browser check against `http://127.0.0.1:5175` with live API proxy: Exports handoff action cards wrap to 2 desktop columns and 1 mobile column, no console warnings/errors and no horizontal page overflow.
- `bash scripts/run_readiness_check.sh` (`237 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy Exports check on `http://192.168.10.150:1202`: handoff action cards render as 2 usable columns at desktop width, no console warnings/errors and no horizontal overflow.
Open:
- None for this pass.
Limitations:
- This is a visual ergonomics hardening pass only. It does not add endpoints, migrations, provider fetching, AI/model behavior or new product capabilities.
Next recommended pass:
- Continue with populated Map/Data interaction polish, especially making it easier to activate the demo vector layer from the map empty state.
## Sprint 67 Map empty-state quick actions (2026-06-19)
Changed:
- Added ready vector/GeoJSON dataset quick actions to the Map workspace empty state.
- Reused the existing `openDatasetInMap` frontend flow so quick actions load the same persisted dataset layer as the Data workspace button.
- Added width-aware `.map-empty-action-grid` styling for desktop and mobile.
- Added `backend/tests/test_sprint67_map_empty_state_quick_actions.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint67_map_empty_state_quick_actions.py -q` failed on missing Map quick-action props, App wiring and CSS.
- `python -m pytest backend/tests/test_sprint67_map_empty_state_quick_actions.py backend/tests/test_sprint63_map_overlay_ergonomics.py backend/tests/test_sprint30_workbench_components.py -q` (`9 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local Chrome/Playwright check against `http://127.0.0.1:5175` with live API proxy: Map empty state showed 2 ready dataset actions, clicking the first loaded `demo_predicted_buildings.geojson` as a 2-feature active layer, no console warnings/errors and no horizontal overflow.
- `bash scripts/run_readiness_check.sh` (`240 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy Map quick-action check on `http://192.168.10.150:1202`: Map empty state showed 2 ready dataset actions, clicking the first loaded `demo_predicted_buildings.geojson` as a 2-feature active layer, no console warnings/errors and no horizontal overflow.
Open:
- None for this pass.
Limitations:
- This is a frontend interaction polish pass only. It does not add map layers, backend endpoints, migrations, provider fetching or geospatial processing.
Next recommended pass:
- Continue with Data catalog density polish, especially making selected/reference/candidate dataset roles easier to scan in populated demo projects.
## Sprint 68 Data catalog density polish (2026-06-19)
Changed:
- Added a compact role summary to the Data catalog for Selected, Reference, Candidate and Source datasets.
- Added scan-friendly dataset card badges plus source, reference layer and CRS context.
- Treated non-reference vector/GeoJSON datasets as QA Candidate display roles in the frontend only, preserving persisted `dataset_role` values and API contracts.
- Added responsive role-summary and role-badge CSS.
- Added `backend/tests/test_sprint68_dataset_catalog_density.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint68_dataset_catalog_density.py -q` failed on missing role summary, role badges and responsive CSS.
- `python -m pytest backend/tests/test_sprint68_dataset_catalog_density.py backend/tests/test_sprint67_map_empty_state_quick_actions.py backend/tests/test_sprint30_workbench_components.py -q` (`10 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5175` with live API proxy: Data workspace showed Selected, Reference, Candidate and Source summary cards, with 1 Reference, 1 Candidate and 0 Source in the demo catalog; dataset badges rendered correctly on desktop and mobile, no console warnings/errors and no horizontal overflow.
- Screenshots captured under `artifacts/sprint68-dataset-catalog-density/`.
- `bash scripts/run_readiness_check.sh` (`243 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy Data catalog check on `http://192.168.10.150:1202`: Data workspace showed Selected, Reference, Candidate and Source summary cards, candidate/reference badges rendered, no console warnings/errors and no horizontal overflow on desktop or mobile.
Open:
- None for this pass.
Limitations:
- This is a frontend density/readability pass only. It does not change dataset persistence, backend role validation, API contracts, migrations, provider fetching or AI/model behavior.
Next recommended pass:
- Continue with Data workspace action polish, especially making QA/export affordances clearer once candidate and reference layers are present.
## Sprint 69 Data catalog action polish (2026-06-19)
Changed:
- Added role-aware recommended action hints to dataset cards.
- Reworked dataset card actions into compact two-line buttons for Inspect, Map, Export / QA and Metadata.
- Kept all existing Data workspace handlers and API calls unchanged.
- Added disabled-action explanation copy for unsupported export/QA and raster metadata refresh cases.
- Added responsive `.dataset-action-grid` and `.dataset-action-button` CSS.
- Added `backend/tests/test_sprint69_dataset_action_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint69_dataset_action_polish.py -q` failed on missing action hints, action grid and responsive styles.
- `python -m pytest backend/tests/test_sprint69_dataset_action_polish.py backend/tests/test_sprint68_dataset_catalog_density.py backend/tests/test_sprint29_dataset_components.py -q` (`9 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5175` with live API proxy: Data workspace rendered 2 role-aware hints and 8 compact dataset actions across the demo candidate/reference datasets, no console warnings/errors and no horizontal overflow on desktop or mobile.
- Screenshots captured under `artifacts/sprint69-dataset-action-polish/`.
- `bash scripts/run_readiness_check.sh` (`246 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy Data action check on `http://192.168.10.150:1202`: Data workspace rendered 2 role-aware hints and 8 compact dataset actions across the demo candidate/reference datasets, no console warnings/errors and no horizontal overflow on desktop or mobile.
Open:
- None for this pass.
Limitations:
- This is a frontend affordance/readability pass only. It does not add new workflows, change dataset persistence, change API contracts, add migrations, fetch providers or alter AI/model behavior.
Next recommended pass:
- Continue with QA/QC workspace handoff polish, especially linking the existing candidate/reference dataset context more clearly to persisted QA results.
## Sprint 70 QA/QC handoff polish (2026-06-19)
Changed:
- Added candidate/reference handoff cards to the QA/QC results panel.
- Resolved persisted quality-check candidate/reference dataset IDs to loaded dataset names when available.
- Passed `candidateDatasets` and `referenceDatasets` from `App.tsx` into `QualityResultsPanel`.
- Tightened QA candidate context to non-reference vector/GeoJSON datasets while preserving persisted `dataset_role` values.
- Added responsive `.quality-handoff-grid`, `.quality-dataset-name` and `.quality-check-dataset-link` CSS.
- Added `backend/tests/test_sprint70_quality_handoff_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint70_quality_handoff_polish.py -q` failed on missing dataset context props, handoff markup, App wiring and styles.
- `python -m pytest backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint39_frontend_orchestration_hooks.py backend/tests/test_sprint51_quality_export_polish.py -q` (`15 passed`)
- `python -m pytest backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint51_quality_export_polish.py backend/tests/test_sprint30_workbench_components.py backend/tests/test_sprint27_frontend_workflow_hooks.py -q` (`14 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5175` with live API proxy: QA/QC workspace showed 1 candidate layer, 1 reference layer, latest comparison names and named dataset links inside persisted quality-check cards, with no console warnings/errors and no horizontal overflow.
- Screenshots captured under `artifacts/sprint70-quality-handoff-polish/`.
- `bash scripts/run_readiness_check.sh` (`250 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy QA/QC handoff check on `http://192.168.10.150:1202`: QA/QC workspace showed 1 candidate layer, 1 reference layer, latest comparison names and named dataset links inside persisted quality-check cards, with no console warnings/errors and no horizontal overflow on desktop or mobile.
Open:
- None for this pass.
Limitations:
- This is a frontend handoff/readability pass only. It does not change QA persistence, metric calculations, API contracts, migrations, provider fetching or AI/model behavior.
Next recommended pass:
- Continue with QA/QC result card polish, especially making metric groups easier to scan in long-lived demo projects.
## Sprint 71 QA/QC metric card polish (2026-06-19)
Changed:
- Added core metric evidence cards to QA/QC result cards for precision, recall, F1, mean IoU, false positives and false negatives.
- Kept the raw persisted metric list visible below the promoted evidence cards.
- Added compact metric label/value formatting in `QualityResultsPanel`.
- Added responsive `.quality-metric-grid`, `.quality-metric-card` and `.quality-metric-card-critical` CSS.
- Added `backend/tests/test_sprint71_quality_metric_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint71_quality_metric_polish.py -q` failed on missing metric promotion helpers, markup and styles.
- `python -m pytest backend/tests/test_sprint71_quality_metric_polish.py backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint51_quality_export_polish.py backend/tests/test_sprint30_workbench_components.py -q` (`13 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5175` with live API proxy: QA/QC workspace rendered 12 promoted metric cards across 2 persisted quality checks, retained 2 raw metric sections, no console warnings/errors and no horizontal overflow on desktop or mobile.
- Screenshots captured under `artifacts/sprint71-quality-metric-polish/`.
- `bash scripts/run_readiness_check.sh` (`253 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy QA/QC metric check on `http://192.168.10.150:1202`: QA/QC workspace rendered 12 promoted metric cards across 2 persisted quality checks, retained 2 raw metric sections, no console warnings/errors and no body-level horizontal overflow on desktop or mobile.
- Live mobile screenshot captured at `artifacts/sprint71-quality-metric-polish/live-qa-metrics-mobile.png`.
Open:
- None for this pass.
Limitations:
- Frontend readability pass only; no QA calculation, persistence, API, migrations, provider or AI/model changes.
Next recommended pass:
- Continue with QA/QC metric/result filtering or result-card density for long-lived demo projects.
## Sprint 72 Mobile overflow hardening (2026-06-20)
Changed:
- Clamped page-level horizontal overflow for `html`, `body` and the workbench shell.
- Kept mobile sidebar navigation and workspace shortcut chips as contained horizontal scroll regions with overscroll containment.
- Added min-width/max-width containment for the workbench layout, main area, inspector panel and card surfaces.
- Allowed long QA check IDs, dataset links and inspector values to wrap instead of widening result cards.
- Switched inspector tabs to a two-column layout on narrow screens.
- Added `backend/tests/test_sprint72_mobile_overflow_hardening.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint72_mobile_overflow_hardening.py -q` failed on missing mobile overflow and identifier wrapping contracts.
- `python -m pytest backend/tests/test_sprint72_mobile_overflow_hardening.py backend/tests/test_sprint71_quality_metric_polish.py backend/tests/test_sprint62_frontend_visual_polish.py backend/tests/test_sprint30_workbench_components.py -q` (`11 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5176` with live API proxy at a 390px viewport: QA/QC workspace rendered 2 quality cards and 12 metric cards; body, shell, inspector, inspector panel and inspector tabs stayed within viewport width; sidebar/workspace nav retained contained horizontal scrolling; no console warnings/errors.
- Screenshot captured under `artifacts/sprint72-mobile-overflow-hardening/`.
- `bash scripts/run_readiness_check.sh` (`255 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy mobile check on `http://192.168.10.150:1202` at a 390px viewport: QA/QC workspace rendered 2 quality cards and 12 metric cards; body, shell, inspector, inspector panel and inspector tabs stayed within viewport width; sidebar/workspace nav retained contained horizontal scrolling; no console warnings/errors.
- Live screenshot captured at `artifacts/sprint72-mobile-overflow-hardening/live-mobile-qa.png`.
Open:
- None for this pass.
Limitations:
- Frontend CSS hardening only; no UI flow, API, persistence, migration, provider or AI/model changes.
Next recommended pass:
- Continue with QA/QC result filtering/density for long-lived demo projects, or a broader mobile visual pass across Data and Map once the overflow baseline is stable.
## Sprint 73 QA/QC result filtering (2026-06-20)
Changed:
- Added client-side QA/QC result search across check id, type, status, candidate/reference dataset ids, analysis/job ids and resolved dataset names.
- Added status and check-type filters derived from the loaded quality-check list.
- Added latest-eight result density control with a show-all toggle.
- Added a no-match empty state and reset action for filtered result views.
- Reused the dense history control styling pattern while allowing the QA/QC controls to wrap inside narrower workspace columns.
- Added `backend/tests/test_sprint73_quality_result_filtering.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint73_quality_result_filtering.py -q` failed on missing filter state, filtered list logic and styles.
- `python -m pytest backend/tests/test_sprint73_quality_result_filtering.py backend/tests/test_sprint72_mobile_overflow_hardening.py backend/tests/test_sprint71_quality_metric_polish.py backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint51_quality_export_polish.py -q` (`13 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5177` with live API proxy: QA/QC filters rendered against 2 persisted demo checks; search/status conflict showed the no-match state; reset restored 2 checks and 12 metric cards; no console warnings/errors and no body-level overflow.
- Local mobile browser check at a 390px viewport: filter controls stayed within viewport width, with 2 checks and 12 metric cards visible.
- Screenshots captured under `artifacts/sprint73-quality-result-filtering/`.
- `bash scripts/run_readiness_check.sh` (`257 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container, with live migration smoke and browser runtime verification passing.
- Live post-deploy QA/QC filtering check on `http://192.168.10.150:1202`: search/status conflict showed the no-match state; reset restored 2 checks and 12 metric cards; no console warnings/errors and no body-level overflow.
- Live mobile check at a 390px viewport: QA/QC filter controls stayed within viewport width, with 2 checks and 12 metric cards visible.
- Live screenshots captured at `artifacts/sprint73-quality-result-filtering/live-qa-filtering.png` and `artifacts/sprint73-quality-result-filtering/live-qa-filtering-mobile.png`.
Open:
- None for this pass.
Limitations:
- Frontend filtering/density pass only; filtering is client-side over already-loaded persisted checks and does not change API pagination, persistence, QA calculations, migrations, provider behavior or AI/model behavior.
Next recommended pass:
- Continue with Data/Map mobile visual polish, especially dataset upload/action forms and map toolbar density on narrow screens.
## Sprint 74 Data/Map mobile visual polish (2026-06-20)
Changed:
- Added mobile-density CSS for Data workspace upload forms, file input sizing and dataset action grids.
- Kept the desktop dataset action grid width contract intact while adding compact mobile tracks.
- Added touch/width containment for map toolbar controls, range sliders and empty-map quick actions.
- Reduced mobile map container height to keep controls and map visible together on narrow screens.
- Added `backend/tests/test_sprint74_data_map_mobile_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint74_data_map_mobile_polish.py -q` failed on missing mobile Data/Map CSS contracts.
- `python -m pytest backend/tests/test_sprint74_data_map_mobile_polish.py backend/tests/test_sprint72_mobile_overflow_hardening.py backend/tests/test_sprint69_dataset_action_polish.py backend/tests/test_sprint68_dataset_catalog_density.py backend/tests/test_sprint67_map_empty_state_quick_actions.py backend/tests/test_sprint63_map_overlay_ergonomics.py backend/tests/test_sprint50_workspace_usability_polish.py backend/tests/test_sprint30_workbench_components.py -q` (`21 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5178` with live API proxy at a 390px viewport: Data upload form, file input and 8 dataset action buttons stayed within the viewport with no body-level horizontal overflow; Map toolbar, 2 layer controls, range sliders and empty-map quick actions also stayed within the viewport.
- Screenshots captured under `artifacts/sprint74-data-map-mobile-polish/`.
- `bash scripts/run_readiness_check.sh` (`259 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, with live migration smoke and browser runtime verification passing.
- Live post-deploy browser check on `http://192.168.10.150:1202` at a 390px viewport: Data upload form, file input and 8 dataset action buttons stayed within the viewport; Map toolbar, 2 layer controls, range sliders and empty-map quick actions stayed within the viewport; no body-level horizontal overflow was detected.
- Live screenshots captured at `artifacts/sprint74-data-map-mobile-polish/live-data-mobile.png` and `artifacts/sprint74-data-map-mobile-polish/live-map-mobile.png`.
Open:
- None for this pass.
Limitations:
- Frontend CSS polish only; no Data/Map workflow, API, persistence, migration, provider or AI/model changes.
Next recommended pass:
- Continue with AI Labs mobile/density polish, especially detection and segmentation forms/tables.
## Sprint 75 AI Labs mobile visual polish (2026-06-20)
Changed:
- Added mobile-density CSS for Detection and Segmentation Lab model cards, run forms and result summaries.
- Added overflow wrapping for long model ids, source tile paths, mask paths and QA summary values.
- Kept AI result tables scroll-contained while reducing their mobile minimum width.
- Added `backend/tests/test_sprint75_ai_labs_mobile_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint75_ai_labs_mobile_polish.py -q` failed on missing AI Labs mobile CSS contracts.
- `python -m pytest backend/tests/test_sprint75_ai_labs_mobile_polish.py backend/tests/test_sprint74_data_map_mobile_polish.py backend/tests/test_sprint72_mobile_overflow_hardening.py backend/tests/test_sprint62_frontend_visual_polish.py backend/tests/test_sprint30_workbench_components.py backend/tests/test_sprint8c_detection_visualization_qa.py backend/tests/test_sprint9_segmentation_foundation.py -q` (`30 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser check against `http://127.0.0.1:5179` with live API proxy at a 390px viewport: AI Labs rendered 2 panels, 7 model cards, 6 lab blocks and 4 lab forms with no body-level horizontal overflow.
- Screenshot captured under `artifacts/sprint75-ai-labs-mobile-polish/`.
- `bash scripts/run_readiness_check.sh` (`261 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, with live migration smoke and browser runtime verification passing.
- Live post-deploy browser check on `http://192.168.10.150:1202` at a 390px viewport: AI Labs rendered 2 panels, 7 model cards, 6 lab blocks and 4 lab forms with no body-level horizontal overflow.
- Live screenshot captured at `artifacts/sprint75-ai-labs-mobile-polish/live-ai-labs-mobile.png`.
Open:
- None for this pass.
Limitations:
- Frontend CSS polish only; no Detection/Segmentation workflow, API, persistence, migration, provider or AI/model changes.
Next recommended pass:
- Continue with Export/System mobile-density polish, especially export action cards and provider capability lists.
## Sprint 76 Export/System mobile visual polish (2026-06-20)
Changed:
- Added scan-friendly Provider Capabilities cards with structured provider header, status badge, authority/configuration/geometry/query mode fields and layer chips.
- Added mobile-density CSS for provider cards, export action cards, export history controls and export card headers.
- Added overflow wrapping for long provider limitations, attribution/license notes, export ids and artifact paths.
- Added `backend/tests/test_sprint76_export_system_mobile_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint76_export_system_mobile_polish.py -q` failed on missing Export/System mobile CSS and provider markup contracts.
- `python -m pytest backend/tests/test_sprint76_export_system_mobile_polish.py backend/tests/test_sprint75_ai_labs_mobile_polish.py backend/tests/test_sprint74_data_map_mobile_polish.py backend/tests/test_sprint31_unraid_template.py backend/tests/test_sprint64_export_handoff_polish.py backend/tests/test_sprint7b_provider_registry.py backend/tests/test_sprint30_workbench_components.py -q` (`27 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`263 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, with live migration smoke and browser runtime verification passing.
Open:
- None for this pass.
Limitations:
- Frontend presentation polish only; no export workflow, provider API, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with right-side inspector mobile polish, especially long dataset/vector/raster metadata and action groups.
## Sprint 77 Inspector mobile visual polish (2026-06-20)
Changed:
- Added compact inspector action button grids and mobile-safe wrapping for long inspector values.
- Added scroll/wrap containment for dataset detail text, job JSON and loaded feature metadata.
- Added `dataset-tool-panel` and `dataset-tool-group` classes to raster/vector operation controls.
- Added CSS containment for raster/vector tool labels, inputs, selects and buttons inside the inspector.
- Added `backend/tests/test_sprint77_inspector_mobile_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint77_inspector_mobile_polish.py -q` failed on missing inspector mobile CSS and dataset tool markup contracts.
- `python -m pytest backend/tests/test_sprint77_inspector_mobile_polish.py backend/tests/test_sprint76_export_system_mobile_polish.py backend/tests/test_sprint75_ai_labs_mobile_polish.py backend/tests/test_sprint72_mobile_overflow_hardening.py backend/tests/test_sprint52_workbench_inspector_tabs.py backend/tests/test_sprint30_workbench_components.py backend/tests/test_sprint29_dataset_components.py -q` (`18 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`265 passed`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, with live migration smoke and browser runtime verification passing.
Open:
- None for this pass.
Limitations:
- Frontend presentation polish only; no dataset workflow, raster/vector operation behavior, API, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with report/export preview readability polish, especially large JSON/HTML handoff artifacts.
## Sprint 78 Export preview readability polish (2026-06-20)
Changed:
- Added preview summary cards for JSON/GeoJSON export payload root type, root key count and rendered preview size.
- Added a scroll-contained export preview JSON shell and toolbar around the existing stored payload preview.
- Added wrapping for long JSON keys/values inside the preview body.
- Added `backend/tests/test_sprint78_export_preview_readability.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint78_export_preview_readability.py -q` failed on missing preview summary/shell CSS and markup contracts.
- `python -m pytest backend/tests/test_sprint78_export_preview_readability.py backend/tests/test_sprint77_inspector_mobile_polish.py backend/tests/test_sprint76_export_system_mobile_polish.py backend/tests/test_sprint51_quality_export_polish.py backend/tests/test_sprint64_export_handoff_polish.py backend/tests/test_sprint17_export_foundation.py -q` (`20 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`267 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
Open:
- None for this pass.
Limitations:
- Frontend presentation polish only; no export content, export API, artifact storage, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with accessibility/keyboard focus polish across primary workbench controls.
## Sprint 79 Accessibility focus polish (2026-06-20)
Changed:
- Added a shared visible keyboard focus contract for primary buttons, workspace navigation, command chips, inspector tabs and dataset action buttons.
- Added explicit ARIA labels for workspace sidebar navigation, workspace command chips and overview quick actions.
- Bound inspector tabs to active tab panels with `aria-controls`, tab ids, `tabpanel` role and `aria-labelledby`.
- Added `backend/tests/test_sprint79_accessibility_focus_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint79_accessibility_focus_polish.py -q` failed on missing focus-visible CSS, navigation labels and inspector tab/panel bindings.
- `python -m pytest backend/tests/test_sprint79_accessibility_focus_polish.py backend/tests/test_sprint77_inspector_mobile_polish.py backend/tests/test_sprint53_selection_ergonomics.py backend/tests/test_sprint49_workbench_shell_refactor.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`15 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`270 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
Open:
- None for this pass.
Limitations:
- Frontend accessibility/presentation polish only; no workflow behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with form-level validation/readability polish for dense raster/vector operation panels.
## Sprint 80 Operation form readability polish (2026-06-20)
Changed:
- Added structured headings, helper text, field wrappers, responsive field grids and action rows to raster operation controls.
- Added equivalent readability structure to vector clip, buffer and intersect controls.
- Added inline dataset tool error styling for raster clip/tile validation messages.
- Added `backend/tests/test_sprint80_operation_form_readability.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint80_operation_form_readability.py -q` failed on missing form readability CSS and markup contracts.
- `python -m pytest backend/tests/test_sprint80_operation_form_readability.py -q` (`3 passed`)
- `python -m pytest backend/tests/test_sprint80_operation_form_readability.py backend/tests/test_sprint77_inspector_mobile_polish.py backend/tests/test_sprint29_dataset_components.py backend/tests/test_sprint28_dataset_workflow_hook.py backend/tests/test_vector_operations_service.py backend/tests/test_raster_operations_service.py -q` (`37 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`273 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
Open:
- None for this pass.
Limitations:
- Frontend readability/presentation polish only; no raster/vector operation behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with compact empty/error-state polish across QA, exports and AI lab result panels.
## Sprint 81 Result state consistency polish (2026-06-20)
Changed:
- Added shared `result-state` CSS variants for loading, error, empty and ready states.
- Applied result-state blocks to QA/QC error/empty/filter-empty states.
- Applied result-state blocks to export loading, error and empty/filter-empty states.
- Applied result-state blocks to Detection and Segmentation model loading/errors, empty registries, result counts and QA/run errors.
- Added `backend/tests/test_sprint81_result_state_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint81_result_state_polish.py -q` failed on missing result-state CSS and panel markup contracts.
- `python -m pytest backend/tests/test_sprint81_result_state_polish.py -q` (`3 passed`)
- `python -m pytest backend/tests/test_sprint81_result_state_polish.py backend/tests/test_sprint80_operation_form_readability.py backend/tests/test_sprint75_ai_labs_mobile_polish.py backend/tests/test_sprint76_export_system_mobile_polish.py backend/tests/test_sprint73_quality_result_filtering.py backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint8c_detection_visualization_qa.py backend/tests/test_sprint9_segmentation_foundation.py -q` (`34 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`276 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
Open:
- None for this pass.
Limitations:
- Frontend presentation/state polish only; no workflow behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with visual density review for topbar/sidebar/responsive shell after another live browser pass.
## Sprint 82 Shell density polish (2026-06-20)
Changed:
- Added a keyboard skip link that targets the active workspace main region.
- Added an explicit `Primary workspaces` label to the sidebar navigation and a focusable `workspace-main` target.
- Tightened narrow-screen topbar, context chip, sidebar nav and workspace shortcut density while keeping intentional horizontal rails scroll-safe.
- Added `backend/tests/test_sprint82_shell_density_polish.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live browser pre-check against `http://192.168.10.150:1202` showed no console errors, no horizontal document overflow and a too-tall narrow viewport topbar/context stack.
- Red step: `python -m pytest backend/tests/test_sprint82_shell_density_polish.py -q` failed on missing skip-link, main focus target and compact mobile shell CSS contracts.
- `python -m pytest backend/tests/test_sprint82_shell_density_polish.py -q` (`3 passed`)
- `python -m pytest backend/tests/test_sprint82_shell_density_polish.py backend/tests/test_sprint79_accessibility_focus_polish.py backend/tests/test_sprint72_mobile_overflow_hardening.py backend/tests/test_sprint49_workbench_shell_refactor.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`13 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`279 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- Live post-deploy browser check found a narrow-screen cascade override that made `.context-bar` one-column again; tightened the regression test and kept the context rail scrollable through the smallest breakpoint.
- Re-ran `python -m pytest backend/tests/test_sprint82_shell_density_polish.py -q`, `cd frontend && npm run typecheck`, `cd frontend && npm run build` and `bash scripts/run_readiness_check.sh` (`279 passed`) after that fix.
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
- Final live browser check against `http://192.168.10.150:1202` passed on desktop and mobile viewports: no console warnings/errors, no horizontal document overflow, skip link/main target present, `Primary workspaces` nav label present and mobile context bar stayed compact at 64px tall.
Open:
- None for this pass.
Limitations:
- Frontend shell presentation/accessibility polish only; no workflow behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with a live visual review of dense workspace panel hierarchy after the shell density changes are deployed.
## Sprint 83 Workspace panel hierarchy polish (2026-06-20)
Changed:
- Made the Overview readiness strip visually calmer with a compact section surface and tighter status tiles.
- Added explicit `overview-action-copy`, `overview-quick-actions` and `quick-action-button` regions to the recommended-action block.
- Restyled the recommended flow block as a lighter accent callout so it no longer competes visually with the readiness strip.
- Added `backend/tests/test_sprint83_workspace_panel_hierarchy.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live browser pre-check against `http://192.168.10.150:1202` showed no console errors or horizontal overflow, but the first workspace viewport still had several equally weighted white cards.
- Red step: `python -m pytest backend/tests/test_sprint83_workspace_panel_hierarchy.py -q` failed on missing Overview hierarchy regions and compact section-surface CSS contracts.
- `python -m pytest backend/tests/test_sprint83_workspace_panel_hierarchy.py -q` (`3 passed`)
- `python -m pytest backend/tests/test_sprint83_workspace_panel_hierarchy.py backend/tests/test_sprint82_shell_density_polish.py backend/tests/test_sprint62_frontend_visual_polish.py backend/tests/test_sprint50_workspace_usability_polish.py backend/tests/test_sprint22_workbench_status_strip.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`15 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`282 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
- Final live browser check against `http://192.168.10.150:1202` passed on desktop and mobile viewports: no console warnings/errors, no horizontal document overflow, Overview hierarchy regions present and four recommended-action buttons rendered.
Open:
- None for this pass.
Limitations:
- Frontend Overview presentation hierarchy only; no workflow behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with Data workspace panel hierarchy and selected-item density after this pass is deployed and visually checked.
## Sprint 84 Data workspace density polish (2026-06-20)
Changed:
- Added selected-summary regions to Project, AOI and Dataset panels so the active data context appears before creation/upload forms.
- Split Project and AOI panels into `data-panel-form-block` and `data-panel-list-block` regions.
- Split Dataset catalog into selected dataset, upload source data and available dataset regions.
- Restyled dataset upload as an embedded source-data block while preserving the existing upload flow.
- Added `backend/tests/test_sprint84_data_workspace_density.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live browser pre-check against `http://192.168.10.150:1202` showed Data workspace had no console errors or horizontal overflow, but the first Data viewport was still form-first and visually heavy.
- Red step: `python -m pytest backend/tests/test_sprint84_data_workspace_density.py -q` failed on missing selected-summary and named form/list/catalog regions.
- `python -m pytest backend/tests/test_sprint84_data_workspace_density.py -q` (`3 passed`)
- `python -m pytest backend/tests/test_sprint84_data_workspace_density.py backend/tests/test_sprint83_workspace_panel_hierarchy.py backend/tests/test_sprint50_workspace_usability_polish.py backend/tests/test_sprint29_dataset_components.py backend/tests/test_sprint68_dataset_catalog_density.py backend/tests/test_sprint69_dataset_action_polish.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`20 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`285 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
- Final live browser DOM/console check against `http://192.168.10.150:1202` passed on desktop and mobile viewports: Data workspace active, no console warnings/errors, no horizontal document overflow, three selected-summary regions, three form blocks and three list/catalog blocks rendered.
Open:
- None for this pass.
Limitations:
- Frontend Data workspace presentation hierarchy only; no upload behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with Map workspace panel hierarchy and layer-control density after this pass is deployed and visually checked.
## Sprint 85 Map workspace density polish (2026-06-20)
Changed:
- Added a compact Map workspace context summary for selected AOI, active layer and rendered feature state.
- Wrapped existing layer controls and provenance in a dedicated `map-control-surface`.
- Wrapped the existing MapLibre component in a `map-frame-surface` and the selected-feature inspector in a `map-inspection-surface`.
- Added `backend/tests/test_sprint85_map_workspace_density.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live browser pre-check against `http://192.168.10.150:1202` showed Map workspace had no console errors or horizontal overflow, but controls, provenance, map frame and inspector still read as a loose vertical stack.
- Red step: `python -m pytest backend/tests/test_sprint85_map_workspace_density.py -q` failed on missing Map workspace surface and context-summary contracts.
- `python -m pytest backend/tests/test_sprint85_map_workspace_density.py -q` (`3 passed`)
- `python -m pytest backend/tests/test_sprint85_map_workspace_density.py backend/tests/test_sprint63_map_overlay_ergonomics.py backend/tests/test_sprint67_map_empty_state_quick_actions.py backend/tests/test_sprint74_data_map_mobile_polish.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`13 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Live browser post-deploy check showed desktop Map workspace was structured and overflow-free, but the mobile breakpoint still stacked controls too tall above the map.
- Red step: `python -m pytest backend/tests/test_sprint85_map_workspace_density.py -q` then failed on missing compact mobile Map workspace breakpoint contracts.
- `python -m pytest backend/tests/test_sprint85_map_workspace_density.py -q` (`4 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`289 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
- Final live browser check against `http://192.168.10.150:1202` passed on desktop and mobile viewports: no console warnings/errors, no horizontal document overflow, three Map context summary cards, two layer control cards, separated control/map/inspector surfaces and mobile control preamble reduced after the compact breakpoint correction.
Open:
- None for this pass.
Limitations:
- Frontend Map workspace presentation hierarchy only; no overlay behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with QA/QC workspace result hierarchy and filter density after this pass is deployed and visually checked.
## Sprint 86 QA/QC workspace density polish (2026-06-20)
Changed:
- Wrapped QA/QC summary metrics in `quality-summary-surface`.
- Wrapped candidate/reference/latest comparison context in `quality-evidence-surface`.
- Wrapped refresh, result states, filters and list limit controls in `quality-control-surface`.
- Wrapped persisted quality check cards in `quality-history-surface`.
- Added compact mobile CSS contracts for QA/QC summary, handoff, filter, score, metric and raw metric grids.
- Added `backend/tests/test_sprint86_quality_workspace_density.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live browser pre-check against `http://192.168.10.150:1202` showed QA/QC workspace had no console errors or horizontal overflow, but summary, handoff, filters and history were still visually stacked at equal weight. Mobile measured summary at 210px, handoff at 295px and filters at 278px before the result history.
- Red step: `python -m pytest backend/tests/test_sprint86_quality_workspace_density.py -q` failed on missing QA/QC surface and density CSS contracts.
- `python -m pytest backend/tests/test_sprint86_quality_workspace_density.py -q` (`3 passed`)
- `python -m pytest backend/tests/test_sprint86_quality_workspace_density.py backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint71_quality_metric_polish.py backend/tests/test_sprint73_quality_result_filtering.py backend/tests/test_sprint81_result_state_polish.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`18 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- First full readiness run caught a compatibility regression in `backend/tests/test_sprint51_quality_export_polish.py`: the root `quality-results-panel` class was no longer exact. Kept the old root class and moved the new shell into a wrapper.
- `python -m pytest backend/tests/test_sprint51_quality_export_polish.py backend/tests/test_sprint86_quality_workspace_density.py backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint73_quality_result_filtering.py -q` (`11 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`292 passed`; frontend typecheck/build passed; Alembic single head `202606120900`)
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_tower.ps1` rebuilt and redeployed the Tower all-in-one container on port 1202, then passed live migration smoke and browser runtime verification.
- Final live browser check against `http://192.168.10.150:1202` passed on desktop and mobile viewports: no console warnings/errors, no horizontal document overflow, QA/QC shell/surfaces present and two persisted quality check cards rendered.
Open:
- None for this pass.
Limitations:
- Frontend QA/QC workspace presentation hierarchy only; no quality-check behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with Change Detection panel hierarchy and analysis workspace balance after this pass is deployed and visually checked.
## Sprint 87 Change Detection density polish (2026-06-20)
Changed:
- Wrapped Change Detection input controls in `change-detection-input-surface`.
- Replaced loose error/empty text with shared `result-state` cards inside `change-detection-state-stack`.
- Wrapped result metrics in `change-detection-result-surface`.
- Wrapped warning output in `change-detection-warning-surface`.
- Added compact responsive CSS contracts for Change Detection form and summary grids.
- Added `backend/tests/test_sprint87_change_detection_density.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live browser pre-check attempt against `http://192.168.10.150:1202` hit a transient browser automation click timeout on the QA/QC workspace nav; source review showed Change Detection was still the older header/form/summary stack.
- Red step: `python -m pytest backend/tests/test_sprint87_change_detection_density.py -q` failed on missing Change Detection surface and density CSS contracts.
- `python -m pytest backend/tests/test_sprint87_change_detection_density.py backend/tests/test_sprint18_change_detection.py backend/tests/test_sprint39_frontend_orchestration_hooks.py backend/tests/test_sprint86_quality_workspace_density.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`20 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`295 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Tower deploy via `scripts/deploy_tower.ps1` rebuilt and restarted the all-in-one container on `http://192.168.10.150:1202`.
- Tower deploy live migration smoke passed with PostGIS `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and required runtime schema objects present.
- Browser runtime verification passed for frontend, proxied API and icon.
- Direct Chrome live UI check passed on desktop `1440x1000` and mobile `390x844`: Change Detection shell/input surface rendered, no horizontal overflow and no console warnings/errors.
Open:
- None known after full readiness, Tower deploy and live browser validation.
Limitations:
- Frontend Change Detection presentation hierarchy only; no change-detection behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with AI Labs run-form hierarchy and detection/segmentation result density after this pass is deployed and visually checked.
## Sprint 88 AI Labs density polish (2026-06-20)
Changed:
- Wrapped Detection Lab and Segmentation Lab in shared `ai-lab-shell` workspace shells.
- Grouped model registry states into `ai-lab-model-surface` with a shared `ai-lab-state-stack`.
- Grouped run controls into `ai-lab-run-surface`.
- Grouped persisted detection/segmentation result loading and tables into `ai-lab-results-surface`.
- Grouped QA controls and metric summaries into `ai-lab-qa-surface`.
- Added shared AI Lab CSS contracts for compact model grids, form grids and summary grids.
- Added `backend/tests/test_sprint88_ai_lab_density.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint88_ai_lab_density.py -q` failed on missing AI Lab shells/surfaces and CSS contracts.
- `python -m pytest backend/tests/test_sprint88_ai_lab_density.py backend/tests/test_sprint8c_detection_visualization_qa.py backend/tests/test_sprint9_segmentation_foundation.py backend/tests/test_sprint39_frontend_orchestration_hooks.py backend/tests/test_sprint47_workbench_interaction_smoke.py -q` (`34 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser UI check against `http://127.0.0.1:5174` passed on desktop and mobile: Detection/Segmentation shells and model/run/result/QA surfaces rendered, no horizontal overflow and no console warnings/errors. The local-only screenshot showed expected API 500 states because only the frontend Vite server was running.
- First full readiness run caught legacy AI Lab static contract expectations for exact `lab-block` and `result-summary-card` class names. Kept those compatibility anchors while preserving the new AI Lab surfaces.
- `python -m pytest backend/tests/test_sprint50_workspace_usability_polish.py backend/tests/test_sprint75_ai_labs_mobile_polish.py backend/tests/test_sprint88_ai_lab_density.py -q` (`8 passed`)
- `bash scripts/run_readiness_check.sh` (`299 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Tower deploy via `scripts/deploy_tower.ps1` rebuilt and restarted the all-in-one container on `http://192.168.10.150:1202`.
- Tower deploy live migration smoke passed with PostGIS `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and required runtime schema objects present.
- Browser runtime verification passed for frontend, proxied API and icon.
- Live browser AI Labs check against `http://192.168.10.150:1202` passed on desktop and mobile: Detection/Segmentation shells and model/run/result/QA surfaces rendered, no horizontal overflow and no console warnings/errors.
Open:
- None known after full readiness, Tower deploy and live browser validation.
Limitations:
- Frontend AI Labs presentation hierarchy only; no detection/segmentation behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with export/system final visual consistency or live workflow guidance once this pass is deployed and visually checked.
## Sprint 89 Export/System density polish (2026-06-20)
Changed:
- Wrapped Export Center content in `export-center-shell`.
- Grouped export summary, handoff readiness, artifact actions, current state cards and history into focused `export-*` surfaces.
- Wrapped Provider Capabilities content in `system-provider-shell`.
- Replaced loose provider loading/error/empty text with shared `result-state` cards.
- Grouped provider registry content into `system-provider-capability-surface`.
- Split provider limitation/reason text and attribution/license data into `provider-detail-stack` and provenance cards.
- Added shared Export/System density CSS for compact summary, handoff, action, history and provider provenance grids.
- Added `backend/tests/test_sprint89_export_system_density.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint89_export_system_density.py -q` failed on missing Export/System shells, surfaces and CSS contracts.
- `python -m pytest backend/tests/test_sprint89_export_system_density.py backend/tests/test_sprint51_quality_export_polish.py backend/tests/test_sprint64_export_handoff_polish.py backend/tests/test_sprint76_export_system_mobile_polish.py backend/tests/test_sprint78_export_preview_readability.py -q` (`12 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- In-app browser fallback note: the Browser click path timed out on the local workspace navigation CDP command, so rendered validation used local Chrome via Playwright.
- Local Chrome UI check against `http://127.0.0.1:5174` passed on desktop and mobile: Export/System shells and surfaces rendered with no horizontal overflow. Local console showed expected Vite proxy 500s because only the frontend server was running.
- `bash scripts/run_readiness_check.sh` (`303 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Tower deploy via `scripts/deploy_tower.ps1` rebuilt and restarted the all-in-one container on `http://192.168.10.150:1202`.
- Tower deploy live migration smoke passed with PostGIS `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and required runtime schema objects present.
- Browser runtime verification passed for frontend, proxied API and icon.
- Live Chrome UI check against `http://192.168.10.150:1202` passed on desktop and mobile: Export/System shells and surfaces rendered, four provider cards and eight provider provenance cards were visible, no horizontal overflow and no console warnings/errors.
Open:
- None known after full readiness, Tower deploy and live browser validation.
Limitations:
- Frontend Export/System presentation hierarchy only; no export behavior, API contract, persistence, migration, provider fetching or AI/model changes.
Next recommended pass:
- Continue with end-to-end workflow guidance after this pass is deployed and visually checked.
## Sprint 90 workflow guidance polish (2026-06-20)
Changed:
- Added an Overview `workflow-guidance-panel` that shows the V1 flow from Project & AOI through Data, Map, QA / AI and Export.
- Added ready/waiting/next state labels from existing loaded project, dataset, map, QA/AI and export state.
- Routed the guidance cards through the existing `setActiveWorkspace` navigation only.
- Added compact responsive CSS for the guidance rail.
- Added `backend/tests/test_sprint90_workflow_guidance.py`.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend/tests/test_sprint90_workflow_guidance.py -q` failed on missing workflow guidance App and CSS contracts.
- `python -m pytest backend/tests/test_sprint90_workflow_guidance.py backend/tests/test_sprint83_workspace_panel_hierarchy.py backend/tests/test_sprint49_workbench_shell_refactor.py backend/tests/test_sprint62_frontend_visual_polish.py backend/tests/test_sprint82_shell_density_polish.py -q` (`13 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`306 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Local browser UI check against `http://127.0.0.1:5174` passed on desktop and mobile: workflow guidance panel rendered with five steps and no horizontal overflow. Local console showed expected Vite proxy 500s because only the frontend server was running.
- Tower deploy via `scripts/deploy_tower.ps1` rebuilt and restarted the all-in-one container on `http://192.168.10.150:1202` from commit `2a0e7e7`.
- Tower deploy live migration smoke passed with PostGIS `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and required runtime schema objects present.
- Browser runtime verification passed for frontend, proxied API and icon.
- Live browser UI check against `http://192.168.10.150:1202` passed on desktop and mobile: workflow guidance panel rendered with five steps, no horizontal overflow and no console warnings/errors.
Open:
- None known after full readiness, Tower deploy and live browser validation.
Limitations:
- Frontend Overview workflow guidance only; no API contract, persistence, migration, provider fetching or AI/model behavior changes.
Next recommended pass:
- After deploy and visual validation, continue with any remaining end-to-end workflow handoff polish surfaced by the live audit.
## Sprint 91 populated workflow audit polish (2026-06-21)
Changed:
- Audited the live populated demo state on `http://192.168.10.150:1202` across Overview, Data, Map, QA/QC, AI Labs and Exports.
- Changed the Overview workflow guidance badge to show `Ready for handoff` when project, dataset, map, QA/AI and export state are all present.
- Clarified the Map workflow step so it reports layer feature count separately from AOI context and shows `AOI loaded` for AOI-only map context.
- Extended `backend/tests/test_sprint90_workflow_guidance.py` with complete-state and Map-copy regression coverage.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live pre-change browser audit passed for the populated demo workflow: Data had 2 ready datasets, Map rendered `demo_predicted_buildings.geojson` with 2 layer features, QA/QC showed 2 checks, AI Labs showed model/result/QA surfaces, Exports showed 50 artifacts, and no checked workspace had console warnings/errors or horizontal overflow.
- Red step: `python -m pytest backend/tests/test_sprint90_workflow_guidance.py -q` failed on missing `workflowGuidanceComplete` / `Ready for handoff` / precise Map copy contracts.
- Post-deploy live check found the AOI-only reload state rendered `0 layer features + AOI`; a second red step failed on missing `AOI loaded` copy before the fix.
- `python -m pytest backend/tests/test_sprint90_workflow_guidance.py -q` (`4 passed`)
- `python -m pytest backend/tests/test_sprint90_workflow_guidance.py backend/tests/test_sprint83_workspace_panel_hierarchy.py backend/tests/test_sprint82_shell_density_polish.py -q` (`10 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser UI check against `http://127.0.0.1:5174` passed for the Overview guidance panel with no horizontal overflow. Local console showed expected Vite proxy 500s because only the frontend server was running.
- `bash scripts/run_readiness_check.sh` (`307 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Tower deploy via `scripts/deploy_tower.ps1` rebuilt and restarted the all-in-one container on `http://192.168.10.150:1202` from commit `97b943d`.
- Tower deploy live migration smoke passed with PostGIS `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1` and required runtime schema objects present.
- Browser runtime verification passed for frontend, proxied API and icon.
- Live post-change browser check passed: AOI-only Overview state showed `Map AOI loaded`; after opening `demo_predicted_buildings.geojson` on the map, Overview showed `Map 2 layer features + AOI`; both states showed `Ready for handoff`, no horizontal overflow and no console warnings/errors.
Open:
- None known after full readiness, Tower deploy and live browser validation.
Limitations:
- Frontend Overview copy/state polish only; no API contract, persistence, migration, provider fetching or AI/model behavior changes.
Next recommended pass:
- After deploy and live validation, continue with any remaining populated-state visual issues found in the next audit.
## Sprint 92 workflow rail interaction polish (2026-06-21)
Changed:
- Audited the live Overview workflow rail click path on `http://192.168.10.150:1202`.
- Added `openWorkflowGuidanceStep` so Map and Export rail clicks can reuse existing dataset context flows.
- Map rail click now opens the first ready vector/GeoJSON dataset through `openDatasetInMap` when no layer is active.
- Export rail click now opens the first ready vector/GeoJSON dataset through `openDatasetExport` when no dataset is selected.
- Extended `backend/tests/test_sprint90_workflow_guidance.py` with regression coverage for the context-aware rail handler.
- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Live pre-change browser audit showed the rail navigated correctly but Map landed with no active layer and Exports landed with `Selected dataset: none`.
- Red step: `python -m pytest backend/tests/test_sprint90_workflow_guidance.py -q` failed on missing `openWorkflowGuidanceStep` / dataset-context handler contracts.
- `python -m pytest backend/tests/test_sprint90_workflow_guidance.py backend/tests/test_sprint53_selection_ergonomics.py backend/tests/test_sprint67_map_empty_state_quick_actions.py backend/tests/test_sprint64_export_handoff_polish.py -q` (`15 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- Local browser UI check against `http://127.0.0.1:5174` passed for rail rendering with no horizontal overflow. Local console showed expected Vite proxy 500s because only the frontend server was running.
- `bash scripts/run_readiness_check.sh` (`308 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Tower deploy from commit `1872c60` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live targeted browser validation against `http://192.168.10.150:1202` passed for `Open Map step`: `demo_predicted_buildings.geojson` became active, `2 features` rendered, no horizontal overflow and no console/page errors.
- Live targeted browser validation against `http://192.168.10.150:1202` passed for `Open Export step`: `demo_predicted_buildings.geojson` became the selected export dataset, no horizontal overflow and no console/page errors.
Open:
- None for this pass.
Limitations:
- Frontend workflow navigation polish only; no API contract, persistence, migration, provider fetching or AI/model behavior changes.
Next recommended pass:
- After deploy and live validation, continue with export artifact action ergonomics or QA result drill-down, depending on the next live friction point.
## Sprint 93 export handoff artifact polish (2026-06-21)
Changed:
- Added a `Latest handoff artifacts` section to `frontend/src/components/exports/ExportCenter.tsx`.
- Grouped newest persisted artifacts for project report, project metadata, dataset GeoJSON, detection GeoJSON and segmentation GeoJSON.
- Reused existing JSON preview and artifact download callbacks from latest artifact cards.
- Added responsive latest artifact card styling in `frontend/src/styles/app.css`.
- Added `backend/tests/test_sprint93_export_handoff_completion.py` to lock the grouped handoff surface, actions and responsive CSS.
- Updated `CHANGELOG.md`, `docs/TODO.md` and `frontend/README.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint93_export_handoff_completion.py -q` failed on missing latest artifact grouping/actions/styles.
- `python -m pytest backend\tests\test_sprint93_export_handoff_completion.py -q` (`3 passed`)
- `python -m pytest backend\tests\test_sprint93_export_handoff_completion.py backend\tests\test_sprint64_export_handoff_polish.py backend\tests\test_sprint89_export_system_density.py backend\tests\test_sprint51_quality_export_polish.py backend\tests\test_sprint78_export_preview_readability.py -q` (`13 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`311 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Tower deploy from commit `0a9054c` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live browser validation against `http://192.168.10.150:1202` passed for `Open Export step`: selected dataset stayed `demo_predicted_buildings.geojson`, `Latest handoff artifacts` rendered, project report/project metadata/dataset GeoJSON cards were present, detection/segmentation cards showed `No artifact yet`, preview opened from the latest artifact card, no horizontal overflow and no console/page errors.
Open:
- None for this pass.
Limitations:
- Export Center frontend handoff polish only; no API contract, persistence, migration, provider fetching or AI/model behavior changes.
Next recommended pass:
- After deploy and live validation, continue with QA/QC drilldown and map evidence layers.
## Sprint 94 QA/QC evidence drilldown (2026-06-22)
Changed:
- Added selected-check drilldown state to `frontend/src/components/quality/QualityResultsPanel.tsx`.
- Added a `QA/QC evidence drilldown` surface with selected check, candidate/reference layer, analysis run, job, status, score and timestamp provenance.
- Added false-positive evidence, false-negative evidence and map evidence handoff cards using persisted metric rows and dataset names.
- Added parameter and findings JSON panes for persisted QA/QC provenance.
- Added `Inspect latest check` and per-result `Inspect check` controls.
- Added responsive QA drilldown styles to `frontend/src/styles/app.css`.
- Added `backend/tests/test_sprint94_quality_drilldown.py`.
- Updated `CHANGELOG.md`, `docs/TODO.md` and `frontend/README.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint94_quality_drilldown.py -q` failed on missing drilldown state/surfaces/styles.
- `python -m pytest backend\tests\test_sprint94_quality_drilldown.py backend\tests\test_sprint70_quality_handoff_polish.py backend\tests\test_sprint71_quality_metric_polish.py backend\tests\test_sprint73_quality_result_filtering.py backend\tests\test_sprint86_quality_workspace_density.py -q` (`15 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`314 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- Tower deploy from commit `f3ad9c3` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live browser validation against `http://192.168.10.150:1202` passed for `Open QA / AI step`: QA/QC evidence drilldown rendered, candidate/reference names resolved, false-positive/negative evidence rendered, parameters/findings JSON rendered, per-result `Inspect check` controls were available, no horizontal overflow and no console/page errors.
Open:
- None for this pass.
Limitations:
- QA/QC frontend drilldown only; no API contract, persistence, migration, provider fetching or AI/model behavior changes.
- Map evidence handoff points reviewers to candidate/reference datasets already persisted in the workbench; it does not create a new matched/unmatched geometry export.
Next recommended pass:
- After deploy and live validation, continue with QA map overlay affordances or raster pipeline hardening.
## Sprint 95 raster pipeline hardening (2026-06-22)
Changed:
- Added a `Raster pipeline readiness` surface to `frontend/src/components/datasets/RasterControls.tsx`.
- Surfaced metadata profile, CRS readiness, preview artifact, tile manifest handoff and clip AOI state before raster operations.
- Added `Processing guardrails` for missing selected dataset, unavailable raster processing, missing metadata, missing CRS, missing preview, invalid tile parameters and missing clip areas.
- Added responsive raster readiness, guardrail and manifest-handoff styles to `frontend/src/styles/app.css`.
- Added `backend/tests/test_sprint95_raster_pipeline_hardening.py`.
- Updated `CHANGELOG.md`, `docs/TODO.md` and `frontend/README.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint95_raster_pipeline_hardening.py -q` failed on missing readiness/handoff component structure and CSS.
- `python -m pytest backend\tests\test_sprint95_raster_pipeline_hardening.py -q` (`2 passed`)
- `python -m pytest backend\tests\test_sprint80_operation_form_readability.py backend\tests\test_sprint77_inspector_mobile_polish.py -q` (`5 passed`)
- `python -m compileall backend/app`
- `cd backend && python -m pytest -q` (`316 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`316 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- `cd backend && python -m alembic heads` (`202606120900 (head)`)
- `cd backend && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
- Tower deploy from commit `330b677` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live browser validation against `http://192.168.10.150:1202` passed for the workbench shell: Overview/Data/Map/QA/QC/AI Labs/Exports markers were present, no horizontal overflow and no console/page errors.
- Live dataset API validation confirmed the default demo currently contains vector fixtures only, so the raster-specific panel is not visible in the default live state without a raster upload.
Open:
- None for this pass.
Limitations:
- Frontend raster inspector hardening only; no API contract, persistence, migration, provider fetching or AI/model behavior changes.
- The panel explains the existing tile manifest handoff but does not create a new manifest picker or new detection/segmentation behavior.
- Raster-specific live visual validation requires a raster dataset in the live project; the current offline demo seed contains vector fixtures only.
Next recommended pass:
- After deploy and live validation, add a raster fixture/demo upload smoke or continue with map evidence overlay affordances for QA/QC.
## Sprint 96 useful default context (2026-06-22)
Changed:
- Added a guarded default dataset effect in `frontend/src/hooks/useDatasetWorkflow.ts`.
- When project data loads and no dataset is selected, the workbench now auto-opens the first ready vector dataset, falling back to any ready dataset and then the first dataset.
- This gives Data, Map and Exports an immediately useful selected dataset/map layer context for the populated demo flow.
- Added explicit no-raster guidance cards to Detection Lab and Segmentation Lab run controls.
- Added `backend/tests/test_sprint96_useful_default_context.py`.
- Updated `CHANGELOG.md`, `docs/TODO.md` and `frontend/README.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint96_useful_default_context.py -q` failed on missing default dataset selection and no-raster AI Lab guidance.
- `python -m pytest backend\tests\test_sprint96_useful_default_context.py -q` (`2 passed`)
- `python -m pytest backend\tests\test_sprint39_frontend_orchestration_hooks.py backend\tests\test_sprint29_dataset_components.py backend\tests\test_sprint88_ai_lab_density.py -q` (`16 passed`)
- `python -m compileall backend/app`
- `cd backend && python -m pytest -q` (`318 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`318 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- `cd backend && python -m alembic heads` (`202606120900 (head)`)
- `cd backend && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
- Tower deploy from commit `aaf1299` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live browser validation against `http://192.168.10.150:1202` passed: Data auto-selected `demo_predicted_buildings.geojson`, Map rendered `2 features`, Exports showed the same selected dataset, AI Labs showed no-raster guidance for detection and segmentation, desktop/mobile had no horizontal overflow and no console/page errors.
Open:
- None for this pass.
Limitations:
- Frontend usability/default-context hardening only; no API contract, persistence, migration, provider fetching or AI/model behavior changes.
- Detection and segmentation remain correctly blocked without a raster dataset.
Next recommended pass:
- After deploy and live validation, add a raster fixture/demo upload smoke so AI Labs and raster controls can be validated with a connected raster state.
## Sprint 101 AI Lab handoff browser smoke (2026-06-24)
Changed:
- Added `scripts/verify_ai_handoff_interactions.sh`.
- The script seeds the explicit offline demo workflow through the frontend-facing API, creates a small raster tile manifest, opens the browser workbench with Playwright/Chromium, clicks `Use in Detection Lab` and `Use in Segmentation Lab`, and verifies both AI Lab forms receive the selected raster dataset plus `Raster tile manifest path`.
- Added syntax coverage for the new script to `scripts/run_readiness_check.sh`.
- Added `backend/tests/test_sprint101_ai_handoff_interaction_smoke.py`.
- Updated `scripts/README.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint101_ai_handoff_interaction_smoke.py -q` failed while `scripts/verify_ai_handoff_interactions.sh` was absent.
- `python -m pytest backend\tests\test_sprint101_ai_handoff_interaction_smoke.py -q` (`1 passed`)
- `bash -n scripts/verify_ai_handoff_interactions.sh`
- Local Node Playwright availability check failed with `ERR_MODULE_NOT_FOUND`, so live browser-click execution requires Playwright to be installed or exposed in the runner environment.
- `python -m compileall backend/app`
- `cd backend && python -m pytest -q` (`324 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`324 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- `cd backend && python -m alembic heads` (`202606120900 (head)`)
- `cd backend && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
- Tower deploy from commit `aab51ed` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live smoke passed: `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`.
- Live browser-click validation with Codex Playwright plus installed Chrome passed against `http://192.168.10.150:1202`: the smoke seeded the demo workflow, generated a raster tile manifest, selected the raster in Data, opened the Dataset inspector tab, clicked `Use in Detection Lab`, selected `yolo-configured`, verified Detection Lab dataset and manifest values, clicked `Use in Segmentation Lab`, verified Segmentation Lab dataset and manifest values, and observed no console/page errors.
Open:
- None for this pass.
Limitations:
- Test/smoke tooling only; no product behavior, API contract, migration, AI dependency, provider fetching or model behavior changes.
- `scripts/verify_ai_handoff_interactions.sh` requires a runner with Playwright plus a browser. This Codex environment had Playwright available through the Node REPL and used installed Chrome; plain local `node` still reports `ERR_MODULE_NOT_FOUND` for `playwright`.
Next recommended pass:
- After validation and deploy, keep using the AI handoff smoke as the browser-level regression guard for raster-to-AI workspace wiring.
## Sprint 102 Detection Lab handoff polish (2026-06-24)
Changed:
- Updated `useRasterTileManifestForDetection` in `frontend/src/App.tsx` to set `selectedDetectionModelId` to `yolo-configured` when a raster tile manifest is handed off from the dataset inspector.
- Tightened `scripts/verify_ai_handoff_interactions.sh` so it verifies that Detection Lab is already on `yolo-configured` after the handoff instead of selecting that model inside the smoke.
- Updated `backend/tests/test_sprint99_raster_ui_handoff.py` and `backend/tests/test_sprint101_ai_handoff_interaction_smoke.py`.
- Updated `CHANGELOG.md` and `docs/TODO.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py -q` failed while the detection handoff did not set `yolo-configured`.
- `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py backend\tests\test_sprint101_ai_handoff_interaction_smoke.py -q` (`2 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash -n scripts/verify_ai_handoff_interactions.sh`
- `python -m compileall backend/app`
- `cd backend && python -m pytest -q` (`324 passed`)
- `bash scripts/run_readiness_check.sh` (`324 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- `cd backend && python -m alembic heads` (`202606120900 (head)`)
- `cd backend && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
- First Tower redeploy attempt failed with Docker btrfs `no space left on device` while writing build context files.
- Remote Docker diagnosis showed `/var/lib/docker` had ordinary free space but btrfs metadata was 94.80% used with the 300GB docker image fully allocated.
- Removed dangling Docker images and cleared orphaned hung Docker CLI processes from prior inspection/prune attempts.
- Ran a limited Docker btrfs balance: `btrfs balance start -dusage=40 -musage=80 /var/lib/docker`; metadata improved to 75.63% used and 94.95GiB became unallocated.
- Tower deploy from commit `4367400` then completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live smoke passed: `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`.
- Internal Codex browser validation passed against `http://192.168.10.150:1202`: Data workspace selected the raster fixture, Dataset inspector handoff clicked `Use in Detection Lab`, Detection Lab auto-selected `yolo-configured`, the raster dataset and tile manifest matched the generated manifest, the manifest input was visible, and no console/page errors were reported.
Open:
- None for this pass.
Limitations:
- Frontend handoff polish only; no backend API, persistence, migration, provider fetching, AI dependency or model execution behavior changed.
- The Tower Docker image required btrfs metadata balancing before redeploy. If this recurs, inspect `btrfs filesystem usage /var/lib/docker`; metadata near full can fail builds even when `df` reports free GB.
Next recommended pass:
- After live validation, continue with the next V1 usability gap from the workbench flow rather than adding new model/provider scope.
## Sprint 103 AI Lab run readiness (2026-06-24)
Changed:
- Added compact run-readiness panels to Detection Lab and Segmentation Lab.
- Detection readiness now checks selected raster dataset, selected model availability and the configured-YOLO tile manifest requirement before a run is submitted.
- Segmentation readiness now checks selected raster dataset, configured segmentation model state and whether a tile manifest is present for provenance.
- Added shared AI Lab readiness styling and regression coverage in `backend/tests/test_sprint103_ai_lab_run_readiness.py`.
- Updated `CHANGELOG.md` and `docs/TODO.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint103_ai_lab_run_readiness.py -q` failed while the readiness panels and CSS contracts were absent.
- `python -m pytest backend\tests\test_sprint103_ai_lab_run_readiness.py -q` (`3 passed`)
- `python -m compileall backend/app`
- `cd backend && python -m pytest -q` (`327 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`327 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- `cd backend && python -m alembic heads` (`202606120900 (head)`)
- `cd backend && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
- Tower deploy from commit `98fff63` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live smoke passed: `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`.
- Internal Codex browser validation passed against `http://192.168.10.150:1202`: AI Labs rendered Detection and Segmentation run-readiness panels; Detection stayed blocked when `Configured YOLO detector` had no local YOLO configuration but marked dataset and tile manifest as provided; Segmentation became ready with the explicit fixture segmenter and manifest; desktop and mobile viewports had no horizontal overflow and no console warnings/errors.
Open:
- None for this pass.
Limitations:
- Frontend readiness guidance only; no backend API, persistence, migration, provider fetching, AI dependency or model execution behavior changed.
Next recommended pass:
- Continue with V1 usability work that reduces operator confusion without expanding frozen product scope.
## Sprint 117 Safe local YOLO model activation (2026-07-06)
Changed:
- Added `scripts/configure_yolo_model.py` to configure an existing local YOLO model into the deployment `.env` file without downloading model weights, loading a model or running inference.
- The helper scans a mounted model directory for `.pt`, `.onnx` and `.engine` files, refuses no-model and ambiguous multi-model states, and writes env updates only when `--apply` is provided.
- Added regression coverage in `backend/tests/test_sprint119_yolo_model_configuration.py` for no local model, ambiguous model selection, dry-run single model selection and env-file apply behavior.
- Downloaded the official Ultralytics `yolov8n.pt` smoke model to Tower under `/mnt/user/appdata/geointel/models/yolov8n.pt`, recorded checksum `f59b3d833e2ff32e194b5bb8e08d211dc7c5bdf144b90d2c8412c47ccfc83b36`, and applied the env configuration with the local helper.
- Hardened `YoloDetectionAdapter.predict_tile` so non-RGB raster tile artifacts are converted to a temporary RGB image before YOLO inference while georeferencing remains driven by the tile manifest.
- Wrapped YOLO prediction runtime errors as typed `DETECTION_INFERENCE_FAILED` `AppError`s instead of leaking raw runtime exceptions through FastAPI.
- Updated `scripts/README.md`, `deploy/unraid/README.md`, `backend/README.md`, `docs/AI_PIPELINES.md`, `docs/TODO.md` and `CHANGELOG.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint119_yolo_model_configuration.py -q` failed while `scripts/configure_yolo_model.py` was absent.
- Red step: `python -m pytest backend\tests\test_sprint8b_yolo_foundation.py -q` failed because single-band TIFF tiles were passed through as mode `L` and prediction runtime errors leaked as raw `RuntimeError`.
- `python -m pytest backend\tests\test_sprint119_yolo_model_configuration.py -q` (`4 passed`)
- `python -m pytest backend\tests\test_sprint8b_yolo_foundation.py -q` (`12 passed`)
- `python -m py_compile scripts\configure_yolo_model.py`
- `python -m compileall backend/app`
- `cd backend && python -m pytest -q` (`377 passed`, existing Pydantic protected-namespace warnings remain)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`Run readiness check passed`)
- `cd backend && python -m alembic heads` (`202606120900 (head)`)
- `cd backend && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
- `bash -n scripts/deploy_tower.sh`
- Tower deploy from commit `72ee623` completed with `GEOINTEL_INSTALL_AI=true`; the all-in-one container is published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live API check passed: `GET /api/v1/detection/yolo/preflight` returned canonical `data` with `status=not_configured`, `YOLO_ENABLED=false`, `torch_version=2.12.1`, `ultralytics_version=8.4.89`, `will_download_models=false` and `will_run_inference=false`.
- Tower helper dry-run passed: `python scripts/configure_yolo_model.py --models-dir /mnt/user/appdata/geointel/models --env-file .env --json` returned `status=no_model_found`, empty candidates and no env updates.
- Tower model apply passed: `python scripts/configure_yolo_model.py --models-dir /mnt/user/appdata/geointel/models --env-file .env --model-file /mnt/user/appdata/geointel/models/yolov8n.pt --apply --json` returned `status=applied`, `YOLO_ENABLED=true` and `YOLO_MODEL_PATH=/app/models/yolov8n.pt`.
- Live YOLO preflight with generated demo raster tile manifest passed with `status=ready`, `model_load_ok=true`, `manifest_valid=true`, `tile_paths_exist=true`, `tile_count=1`, `will_download_models=false` and `will_run_inference=false`.
- Live inference smoke before the RGB adapter fix reproduced the runtime bug: YOLOv8n expected 3 channels but the demo tile was single-band (`input[1, 1, 480, 640]`).
- Tower deploy from commit `add4768` completed with `GEOINTEL_INSTALL_AI=true`; the all-in-one container is published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live YOLO preflight after the RGB adapter fix passed with generated demo raster tile manifest and `status=ready`.
- Live real YOLO inference smoke after the RGB adapter fix passed: `POST /api/v1/detection/run` returned `status=success`, analysis run `bbd80690-baf3-4e83-8ffb-fdcb07a70c0c`, job `9636ed10-bbde-463f-a47a-6d7706c81e19`, `detection_count=0` and no error code. Zero detections is expected for the generic COCO smoke model on the synthetic demo raster.
- Downloaded `keremberke/yolov8n-building-segmentation` from Hugging Face as an explicit Tower runtime artifact at `/mnt/user/appdata/geointel/models/yolov8n-building-segmentation.pt`.
- Recorded building-model checksum `152d6a9c5c76c9f2fd2fd5cc167efaed7c8c02e31002b15415899710f1d71f98`, matching the Hugging Face file metadata for `best.pt`.
- Applied `.env` with `YOLO_MODEL_PATH=/app/models/yolov8n-building-segmentation.pt` through `scripts/configure_yolo_model.py --model-file ... --apply`.
- Restarted the all-in-one container without rebuild; it remained healthy and published on `0.0.0.0:1202->80/tcp`.
- Live building-model preflight passed with `model_load_ok=true`, `dependencies_available=true`, `torch_version=2.12.1`, `ultralytics_version=8.4.89`, `will_download_models=false` and `will_run_inference=false`.
- Live building-model preflight with generated demo raster tile manifest passed with `status=ready`.
- Live real building-model YOLO inference smoke passed: `POST /api/v1/detection/run` returned `status=success`, analysis run `be609d4a-3e01-42df-bca8-0d5a2289120d`, job `9c8bc26d-7753-4537-ab98-dc31b9029450`, `detection_count=0` and no error code. Zero detections remains expected on the synthetic demo raster.
Open:
- A local YOLO smoke model is now present and configured on Tower, but it is the generic COCO `yolov8n.pt` model. It proves the runtime path, not production-quality aerial building detection.
Limitations:
- The bundled Tower model file was placed as an operator/runtime artifact under appdata, not committed to Git.
- The configured model is a generic COCO model and should be replaced by a suitable aerial/building detector for meaningful GIS output.
- The active configured model is now a building segmentation YOLO model trained for satellite-building segmentation, but it is still a third-party Hugging Face PyTorch `.pt` artifact and should be treated as an evaluation model until validated on local Belgian/Kempen orthophotos.
- No model download behavior was added to the application; the manual operator placement remains explicit.
- If multiple local model files are present, the operator must choose one with `--model-file` so GeoIntel does not silently activate the wrong model.
Next recommended pass:
- Load a real georeferenced orthophoto/GeoTIFF for the target area, generate raster tiles, run the active building YOLO model and compare persisted detections against reference vector buildings through QA/QC.
## Sprint 104 AI Lab action guardrails (2026-06-24)
Changed:
- Added explicit action guardrails below the Detection Lab and Segmentation Lab run-readiness panels.
- Detection now distinguishes `configured` model registry state from UI-runnable action state, blocking the explicit test/demo-only `manual-fixture-detector` in the normal workbench run form.
- Segmentation now distinguishes `configured` model registry state from UI-runnable action state, blocking the explicit test/demo-only `fixture-segmenter` in the normal workbench run form.
- Updated run button disabled conditions to use the new readiness/action state.
- Added compact guardrail styling and regression coverage in `backend/tests/test_sprint104_ai_lab_action_guardrails.py`.
- Updated `CHANGELOG.md` and `docs/TODO.md`.
Tested:
- Red step: `python -m pytest backend\tests\test_sprint104_ai_lab_action_guardrails.py -q` failed while the action guardrails and CSS contracts were absent.
- `python -m pytest backend\tests\test_sprint104_ai_lab_action_guardrails.py -q` (`3 passed`)
- `python -m pytest backend\tests\test_sprint103_ai_lab_run_readiness.py backend\tests\test_sprint104_ai_lab_action_guardrails.py -q` (`6 passed`)
- `python -m compileall backend/app`
- `cd backend && python -m pytest -q` (`330 passed`)
- `cd frontend && npm run typecheck`
- `cd frontend && npm run build`
- `bash scripts/run_readiness_check.sh` (`330 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed)
- `cd backend && python -m alembic heads` (`202606120900 (head)`)
- `cd backend && python -m alembic upgrade head --sql`
- `bash -n scripts/live_migration_smoke.sh`
- Tower deploy from commit `0bc3b2f` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`.
- Deploy-time live migration smoke passed after the database became ready on attempt 2; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`.
- Deploy-time browser runtime verification passed for frontend, API proxy and icon.
- Live smoke passed: `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202`.
- Live smoke passed: `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`.
- Internal Codex browser validation passed against `http://192.168.10.150:1202`: AI Labs opened cleanly; run action guardrails rendered; Detection and Segmentation run buttons were disabled without a raster dataset; selecting explicit fixture models kept both run buttons disabled with `Fixture model is explicit test/demo-only` and `Fixture segmenter is explicit test/demo-only`; desktop and mobile viewports had no horizontal overflow and no console warnings/errors.
Open:
- None for this pass.
Limitations:
- Frontend action-guardrail guidance only; no backend API, persistence, migration, provider fetching, AI dependency or model execution behavior changed.
Next recommended pass:
- Continue with V1 usability work that reduces operator confusion without expanding frozen product scope.