Keep orthophoto release evidence immutable
This commit is contained in:
@@ -446,6 +446,10 @@ def stage_artifacts(
|
||||
geotiff_path = directory / f"orthophoto_{edition}_{selection_key(list(args.bbox))}.tif"
|
||||
preview_path = directory / "review-preview.png"
|
||||
manifest_path = directory / "staged-manifest.json"
|
||||
if directory.exists() and any(directory.iterdir()):
|
||||
raise RuntimeError(
|
||||
f"Governed orthophoto evidence already exists and will not be overwritten: {directory}"
|
||||
)
|
||||
max_bytes = args.max_response_mb * 1024 * 1024
|
||||
content, content_type, final_url = fetch_map(
|
||||
request_identity,
|
||||
@@ -888,6 +892,22 @@ def applied_evidence(
|
||||
*,
|
||||
reused: bool,
|
||||
) -> tuple[Path, dict[str, Any]]:
|
||||
path = plan_path.with_name("applied-evidence.json")
|
||||
if path.is_file():
|
||||
existing = json.loads(path.read_text(encoding="utf-8"))
|
||||
if existing.get("applied_evidence_sha256") != canonical_sha256(existing, "applied_evidence_sha256"):
|
||||
raise RuntimeError("Existing orthophoto applied evidence checksum is invalid")
|
||||
if (
|
||||
existing.get("project_id") != args.project_id
|
||||
or existing.get("scope") != args.scope
|
||||
or existing.get("edition") != plan["edition"]
|
||||
or existing.get("staged_plan_sha256") != plan["plan_sha256"]
|
||||
or existing.get("review_sha256") != review["review_sha256"]
|
||||
or existing.get("dataset_id") != dataset["id"]
|
||||
or existing.get("dataset_checksum_sha256") != dataset["checksum_sha256"]
|
||||
):
|
||||
raise RuntimeError("Existing orthophoto applied evidence does not match this approved Dataset")
|
||||
return path, existing
|
||||
payload: dict[str, Any] = {
|
||||
"schema_version": 1,
|
||||
"status": "applied",
|
||||
@@ -908,7 +928,6 @@ def applied_evidence(
|
||||
"existing_snapshots_retained": True,
|
||||
}
|
||||
payload["applied_evidence_sha256"] = canonical_sha256(payload, "applied_evidence_sha256")
|
||||
path = plan_path.with_name("applied-evidence.json")
|
||||
write_json(path, payload)
|
||||
return path, payload
|
||||
|
||||
@@ -939,10 +958,12 @@ def main() -> int:
|
||||
edition = require_edition(args, report)
|
||||
if args.action == "stage":
|
||||
authorization = authorize_stage(args, report)
|
||||
plan_path = governed_path(args, args.plan_path or default_plan_path(args, edition))
|
||||
if plan_path.exists():
|
||||
raise RuntimeError(f"Governed orthophoto plan already exists and will not be overwritten: {plan_path}")
|
||||
request_identity = map_request(report)
|
||||
staged = stage_artifacts(args, report, request_identity)
|
||||
plan = build_staged_plan(args, report, authorization, staged)
|
||||
plan_path = governed_path(args, args.plan_path or default_plan_path(args, edition))
|
||||
write_json(plan_path, plan)
|
||||
print(
|
||||
json.dumps(
|
||||
@@ -958,6 +979,10 @@ def main() -> int:
|
||||
if args.action == "review":
|
||||
review = build_review_evidence(args, plan_path, plan, manifest)
|
||||
review_path = governed_path(args, args.review_path or default_review_path(args, edition))
|
||||
if review_path.exists():
|
||||
raise RuntimeError(
|
||||
f"Governed orthophoto review already exists and will not be overwritten: {review_path}"
|
||||
)
|
||||
write_json(review_path, review)
|
||||
print(json.dumps({"status": "approved", "review_path": str(review_path), **review}, ensure_ascii=False, indent=2))
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user