consume only artifacts the runtime produced

tile_manifest_path arrives in the detection and segmentation request and was
read straight off disk, and a manifest entry may name an absolute tile path.
That makes an API field an unbounded reference to the host filesystem, and it
contradicts the rule the persistence model rests on: only a governed,
runtime-produced artifact may be consumed, and a file outside the storage root
is not one.

Both the manifest and every tile it names now resolve under STORAGE_ROOT.
Resolution happens before the comparison, so ".." cannot climb out and a
sibling that merely shares a name prefix does not pass.
GEOINTEL_ALLOW_EXTERNAL_ARTIFACT_PATHS opts out for provisioning workflows that
stage tiles before ingest.

The check honours the Settings the caller is operating under rather than the
process-wide ones, because every analysis path already threads its own.

The affected tests write manifests into tmp_path, so they now declare tmp_path
as the storage root — which is what a deployment does, and makes the fixtures
more honest than they were.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Jens
2026-08-22 16:16:25 +02:00
co-authored by Claude Opus 5
parent 16dedeb670
commit e2f586c029
14 changed files with 243 additions and 21 deletions
@@ -460,7 +460,10 @@ def _coverage_manifest(tmp_path, dataset_id, bounds=(-1.0, -1.0, 3.0, 3.0)):
return manifest_path
def test_detection_qa_excludes_references_outside_persisted_tile_coverage(tmp_path) -> None:
def test_detection_qa_excludes_references_outside_persisted_tile_coverage(tmp_path, monkeypatch) -> None:
# QA reads process settings; a manifest written into tmp_path is only a
# governed artifact if tmp_path is the storage root.
monkeypatch.setenv("STORAGE_ROOT", str(tmp_path))
project_id = uuid4()
dataset_id = uuid4()
reference_dataset_id = uuid4()
@@ -525,7 +528,10 @@ def test_detection_qa_excludes_references_outside_persisted_tile_coverage(tmp_pa
assert quality_check.findings_json["coverage"] == result["coverage"]
def test_detection_qa_reports_box_to_footprint_diagnostic_without_changing_strict_metrics(tmp_path) -> None:
def test_detection_qa_reports_box_to_footprint_diagnostic_without_changing_strict_metrics(tmp_path, monkeypatch) -> None:
# QA reads process settings; a manifest written into tmp_path is only a
# governed artifact if tmp_path is the storage root.
monkeypatch.setenv("STORAGE_ROOT", str(tmp_path))
project_id = uuid4()
dataset_id = uuid4()
reference_dataset_id = uuid4()