From edb762219c3bae8d60be4d70b4df347dcec877d9 Mon Sep 17 00:00:00 2001
From: NuklearRabbit <145918611+NuklearRabbit@users.noreply.github.com>
Date: Sat, 29 Aug 2026 02:00:23 +0200
Subject: [PATCH] fix(ci): restore release gates and contract baseline (fixes
#4)
---
.gitea/workflows/release-gates.yml | 9 ++++---
.github/workflows/release-gates.yml | 9 ++++---
README.md | 4 +++
.../tests/test_sprint106_map_bbox_extract.py | 2 +-
...est_sprint109_map_selection_qa_shortcut.py | 4 +--
...est_sprint110_map_qa_evidence_drilldown.py | 4 +--
...t133_detection_threshold_calibration_ux.py | 4 +--
...134_guided_detection_calibration_runner.py | 20 +++++++--------
..._sprint135_calibration_evidence_handoff.py | 4 +--
...test_sprint159_split_promotion_workflow.py | 25 +++++++------------
...sprint186_map_first_geographic_explorer.py | 3 ++-
.../test_sprint194_regional_timeseries.py | 2 +-
backend/tests/test_sprint19_map_workbench.py | 3 ++-
...est_sprint212_platform_source_portfolio.py | 2 +-
.../test_sprint21_demo_workflow_smoke.py | 2 +-
.../test_sprint232_v1_completion_flow.py | 2 +-
.../test_sprint26_frontend_workflow_hooks.py | 4 +--
.../test_sprint27_frontend_workflow_hooks.py | 4 +--
.../test_sprint28_dataset_workflow_hook.py | 4 +--
.../tests/test_sprint29_dataset_components.py | 2 +-
.../test_sprint30_workbench_components.py | 4 +--
.../tests/test_sprint31_unraid_template.py | 3 ---
...t_sprint39_frontend_orchestration_hooks.py | 20 +++++++--------
.../test_sprint62_frontend_visual_polish.py | 2 +-
.../test_sprint81_result_state_polish.py | 8 +++---
...test_sprint83_workspace_panel_hierarchy.py | 4 +--
.../test_sprint84_data_workspace_density.py | 2 +-
.../test_sprint85_map_workspace_density.py | 2 +-
...test_sprint86_quality_workspace_density.py | 2 +-
backend/tests/test_sprint88_ai_lab_density.py | 2 +-
.../test_sprint89_export_system_density.py | 10 ++++----
docs/API_CONTRACTS.md | 8 +++---
docs/CODEX_EXECUTION_LOG.md | 23 +++++++++++++++++
docs/TODO.md | 7 ++++++
frontend/package-lock.json | 6 ++---
frontend/package.json | 3 +++
scripts/generate_container_sbom.sh | 2 +-
...e_detection_calibration_evidence_bundle.sh | 8 ++++--
38 files changed, 133 insertions(+), 96 deletions(-)
diff --git a/.gitea/workflows/release-gates.yml b/.gitea/workflows/release-gates.yml
index 91232c61..ce0bbfc8 100644
--- a/.gitea/workflows/release-gates.yml
+++ b/.gitea/workflows/release-gates.yml
@@ -22,10 +22,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Secret scan
- uses: trufflesecurity/trufflehog@v3.79.0
- with:
- path: ./
- extra_args: --only-verified
+ run: >-
+ docker run --rm
+ --volume "$PWD:/repo:ro"
+ trufflesecurity/trufflehog:3.79.0@sha256:7104dbb84d1ad2f5f6fa1134e92c6aa6f701f0a4ac2efd5a4c5c96225d899fe3
+ filesystem /repo --only-verified --no-update
- uses: actions/setup-python@v5
with:
python-version: "3.11"
diff --git a/.github/workflows/release-gates.yml b/.github/workflows/release-gates.yml
index c693d91c..7887a2b4 100644
--- a/.github/workflows/release-gates.yml
+++ b/.github/workflows/release-gates.yml
@@ -22,10 +22,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Secret scan
- uses: trufflesecurity/trufflehog@v3.79.0
- with:
- path: ./
- extra_args: --only-verified
+ run: >-
+ docker run --rm
+ --volume "$PWD:/repo:ro"
+ trufflesecurity/trufflehog:3.79.0@sha256:7104dbb84d1ad2f5f6fa1134e92c6aa6f701f0a4ac2efd5a4c5c96225d899fe3
+ filesystem /repo --only-verified --no-update
- uses: actions/setup-python@v5
with:
python-version: "3.11"
diff --git a/README.md b/README.md
index 2e5a78f2..786b3b3d 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,10 @@ maximaal zichtbaar op het hoofdscherm terwijl analyses, kwaliteitsbewijs en
resultaten live in een tweede venster staan. Zie
[`docs/DUAL_DISPLAY_WORKFLOW.md`](docs/DUAL_DISPLAY_WORKFLOW.md).
+De actieve `v1.0.0`-releasegrenzen en uitvoeringsvolgorde staan in
+[`docs/RC_SCOPE_FREEZE_BELGIUM_NORTH_SEA.md`](docs/RC_SCOPE_FREEZE_BELGIUM_NORTH_SEA.md)
+en [`docs/RC_ROADMAP_BELGIUM_NORTH_SEA.md`](docs/RC_ROADMAP_BELGIUM_NORTH_SEA.md).
+
diff --git a/backend/tests/test_sprint106_map_bbox_extract.py b/backend/tests/test_sprint106_map_bbox_extract.py
index 691c1652..5abd4e33 100644
--- a/backend/tests/test_sprint106_map_bbox_extract.py
+++ b/backend/tests/test_sprint106_map_bbox_extract.py
@@ -345,7 +345,7 @@ def test_frontend_exposes_map_bbox_selection_contracts() -> None:
theme_hook = read_feature("map_workspace")
assert "selectVectorFeatures" in api_client
- assert "Area selection" in map_workspace
+ assert "DEFAULT_AREA_SELECTION_FILENAME" in map_workspace
assert "Teken rechthoek" in map_workspace
assert "Objecten in gebied ophalen" in map_workspace
assert "Gebiedsdownload bewaren" in map_workspace
diff --git a/backend/tests/test_sprint109_map_selection_qa_shortcut.py b/backend/tests/test_sprint109_map_selection_qa_shortcut.py
index 7cd18e80..f589b92e 100644
--- a/backend/tests/test_sprint109_map_selection_qa_shortcut.py
+++ b/backend/tests/test_sprint109_map_selection_qa_shortcut.py
@@ -6,7 +6,7 @@ ROOT = Path(__file__).resolve().parents[2]
def test_map_selection_qa_shortcut_uses_existing_qa_workflow_contract() -> None:
hook_path = ROOT / "frontend" / "src" / "hooks" / "useMapSelectionQa.ts"
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
map_workspace = read_feature("map_workspace")
assert hook_path.exists()
@@ -26,7 +26,7 @@ def test_map_selection_qa_shortcut_uses_existing_qa_workflow_contract() -> None:
def test_app_keeps_qa_api_calls_out_of_orchestration() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
assert "qaApi" not in app
assert "from './services/api'" not in app
diff --git a/backend/tests/test_sprint110_map_qa_evidence_drilldown.py b/backend/tests/test_sprint110_map_qa_evidence_drilldown.py
index afc28819..7092fbbe 100644
--- a/backend/tests/test_sprint110_map_qa_evidence_drilldown.py
+++ b/backend/tests/test_sprint110_map_qa_evidence_drilldown.py
@@ -13,7 +13,7 @@ def test_map_qa_result_exposes_quality_check_evidence_contract():
types = read_text("frontend/src/types.ts")
hook = read_text("frontend/src/hooks/useMapSelectionQa.ts")
workspace = read_feature("map_workspace")
- app = read_text("frontend/src/App.tsx")
+ app = read_feature("shell")
assert "quality_check_id?: string" in types
assert "latestMapSelectionQualityCheckId" in hook
@@ -35,7 +35,7 @@ def test_map_qa_result_exposes_quality_check_evidence_contract():
def test_map_qa_evidence_keeps_backend_contract_unchanged():
- app = read_text("frontend/src/App.tsx")
+ app = read_feature("shell")
api_contracts = read_text("docs/API_CONTRACTS.md")
assert "/api/v1/qa/detections-vs-reference" in api_contracts
diff --git a/backend/tests/test_sprint133_detection_threshold_calibration_ux.py b/backend/tests/test_sprint133_detection_threshold_calibration_ux.py
index 68b0ea5b..b21ee32e 100644
--- a/backend/tests/test_sprint133_detection_threshold_calibration_ux.py
+++ b/backend/tests/test_sprint133_detection_threshold_calibration_ux.py
@@ -1,4 +1,5 @@
from pathlib import Path
+from tests.frontend_contract import read_feature
ROOT = Path(__file__).resolve().parents[2]
@@ -6,11 +7,10 @@ ROOT = Path(__file__).resolve().parents[2]
def test_detection_lab_exposes_persisted_threshold_calibration_comparison() -> None:
detection_lab = ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx"
- app = ROOT / "frontend" / "src" / "App.tsx"
todo = ROOT / "docs" / "TODO.md"
source = detection_lab.read_text(encoding="utf-8")
- app_source = app.read_text(encoding="utf-8")
+ app_source = read_feature("shell")
todo_source = todo.read_text(encoding="utf-8")
assert "qualityChecks: QualityCheckRead[]" in source
diff --git a/backend/tests/test_sprint134_guided_detection_calibration_runner.py b/backend/tests/test_sprint134_guided_detection_calibration_runner.py
index 190804e2..9097290a 100644
--- a/backend/tests/test_sprint134_guided_detection_calibration_runner.py
+++ b/backend/tests/test_sprint134_guided_detection_calibration_runner.py
@@ -1,4 +1,5 @@
from pathlib import Path
+from tests.frontend_contract import read_feature
ROOT = Path(__file__).resolve().parents[2]
@@ -7,12 +8,11 @@ ROOT = Path(__file__).resolve().parents[2]
def test_detection_lab_has_guided_threshold_calibration_runner() -> None:
hook = ROOT / "frontend" / "src" / "hooks" / "useDetectionWorkflow.ts"
lab = ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx"
- app = ROOT / "frontend" / "src" / "App.tsx"
todo = ROOT / "docs" / "TODO.md"
hook_source = hook.read_text(encoding="utf-8")
lab_source = lab.read_text(encoding="utf-8")
- app_source = app.read_text(encoding="utf-8")
+ app_source = read_feature("shell")
todo_source = todo.read_text(encoding="utf-8")
assert "interface DetectionCalibrationRunRow" in hook_source
@@ -22,22 +22,22 @@ def test_detection_lab_has_guided_threshold_calibration_runner() -> None:
assert "detectionCalibrationRows" in hook_source
assert "detectionCalibrationError" in hook_source
assert "runDetectionCalibration" in hook_source
- assert "detectionApi.run({" in hook_source
+ assert "executeDetection(" in hook_source
# Every requested threshold is reported, but from one inference pass at the
# lowest cut: detections above a higher cut are a subset of it, and
# suppression walks candidates in descending confidence, so the kept set
# above a cut does not depend on the threshold the run used. Asserting the
# old per-threshold loop pinned N GPU passes that produced identical numbers.
- assert "confidence_threshold: lowestThreshold" in hook_source
+ assert "lowestThreshold," in hook_source
assert "calibration_thresholds: thresholds" in hook_source
assert "calibration_sweep" in hook_source
- assert "parameters_json: { calibration: true, calibration_thresholds: thresholds }" in hook_source
+ assert "{ calibration: true, calibration_thresholds: thresholds }," in hook_source
assert "detectionApi.compareWithReference(result.analysis_run_id" in hook_source
- assert "reference_dataset_id: detectionReferenceDatasetId" in hook_source
- assert "Select a reference dataset before calibration" in hook_source
- assert "Provide at least one valid threshold between 0 and 1" in hook_source
- assert "Configured YOLO calibration requires a tile manifest" in hook_source
- assert "Select a local model asset before calibration" in hook_source
+ assert "reference_dataset_id: referenceDatasetId" in hook_source
+ assert "Kies eerst een referentiebron om te kalibreren" in hook_source
+ assert "Geef minstens één geldige drempel tussen 0 en 1 op" in hook_source
+ assert "Kalibratie met YOLO vereist een beeldtegelmanifest" in hook_source
+ assert "Kies eerst een lokaal modelbestand om te kalibreren" in hook_source
assert "Modelkalibratie voor beheerders" in lab_source
assert "Voert het lokale model en een kwaliteitscontrole uit" in lab_source
diff --git a/backend/tests/test_sprint135_calibration_evidence_handoff.py b/backend/tests/test_sprint135_calibration_evidence_handoff.py
index 98e3251e..fdcb0fa8 100644
--- a/backend/tests/test_sprint135_calibration_evidence_handoff.py
+++ b/backend/tests/test_sprint135_calibration_evidence_handoff.py
@@ -1,4 +1,5 @@
from pathlib import Path
+from tests.frontend_contract import read_feature
ROOT = Path(__file__).resolve().parents[2]
@@ -6,11 +7,10 @@ ROOT = Path(__file__).resolve().parents[2]
def test_guided_calibration_rows_link_to_existing_qa_evidence_map() -> None:
lab = ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx"
- app = ROOT / "frontend" / "src" / "App.tsx"
todo = ROOT / "docs" / "TODO.md"
lab_source = lab.read_text(encoding="utf-8")
- app_source = app.read_text(encoding="utf-8")
+ app_source = read_feature("shell")
todo_source = todo.read_text(encoding="utf-8")
assert "onOpenCalibrationEvidence" in lab_source
diff --git a/backend/tests/test_sprint159_split_promotion_workflow.py b/backend/tests/test_sprint159_split_promotion_workflow.py
index 1d7b3d4a..4d07c963 100644
--- a/backend/tests/test_sprint159_split_promotion_workflow.py
+++ b/backend/tests/test_sprint159_split_promotion_workflow.py
@@ -15,22 +15,15 @@ def _bash_path(path: Path) -> str:
if os.name != "nt":
return raw_path
- try:
- result = subprocess.run(
- ["bash", "-lc", f"wslpath -a {shlex.quote(raw_path)}"],
- capture_output=True,
- text=True,
- timeout=10,
- check=False,
- )
- except (subprocess.TimeoutExpired, OSError):
- # Starting WSL can exceed ten seconds while the rest of the suite is
- # running. The fallback below is what this helper already does whenever
- # the conversion does not work, so a slow shell must not red the suite.
- return raw_path
- if result.returncode == 0 and result.stdout.strip():
- return result.stdout.strip()
- return raw_path
+ # ``bash`` is WSL on the supported Windows development path. Converting
+ # the drive path directly avoids starting a second WSL process merely to
+ # run ``wslpath``; that process can time out while the full suite is busy
+ # and would leave curl with an invalid file://C:\\... URL.
+ drive, tail = os.path.splitdrive(raw_path)
+ if drive:
+ normalized_tail = tail.lstrip("\\/").replace("\\", "/")
+ return f"/mnt/{drive[0].lower()}/{normalized_tail}"
+ return raw_path.replace("\\", "/")
def test_split_background_promotion_workflow_runs_split_then_split_aware_report() -> None:
diff --git a/backend/tests/test_sprint186_map_first_geographic_explorer.py b/backend/tests/test_sprint186_map_first_geographic_explorer.py
index f6524800..c9e67718 100644
--- a/backend/tests/test_sprint186_map_first_geographic_explorer.py
+++ b/backend/tests/test_sprint186_map_first_geographic_explorer.py
@@ -58,7 +58,8 @@ def test_map_rectangle_drag_is_wired_to_automatic_analysis() -> None:
# the map fits the selection bounds without an animation.
assert "map.fitBounds(" in geomap
assert "duration: 0" in geomap
- assert "isStyleLoaded()" not in geomap
+ assert "if (!map || !map.isStyleLoaded()) return" in geomap
+ assert "setStyle(" not in geomap
assert "const activeCollection = areaData ?? (fitDataOnChange ? data : null)" in geomap
assert "data && fitDataOnChange && !areaData" in geomap
assert "resizeObserver.disconnect()" in geomap
diff --git a/backend/tests/test_sprint194_regional_timeseries.py b/backend/tests/test_sprint194_regional_timeseries.py
index 7bd4a21e..3083a3ee 100644
--- a/backend/tests/test_sprint194_regional_timeseries.py
+++ b/backend/tests/test_sprint194_regional_timeseries.py
@@ -257,7 +257,7 @@ def test_end_user_dataset_sources_are_human_readable() -> None:
assert "getDatasetSourceDisplayName(dataset)" in catalog
assert "statusLabel(item.state)" in status
assert "Technische modelevaluatie" in detection
- assert "Nog geen downloads gemaakt." in exports
+ assert "Nog geen recente downloads" in exports
def test_full_area_fast_path_requires_matching_area_and_clipped_operator_provenance() -> None:
diff --git a/backend/tests/test_sprint19_map_workbench.py b/backend/tests/test_sprint19_map_workbench.py
index 3606d702..1c3cad91 100644
--- a/backend/tests/test_sprint19_map_workbench.py
+++ b/backend/tests/test_sprint19_map_workbench.py
@@ -17,7 +17,8 @@ def test_geomap_exposes_v1_layer_controls_and_feature_inspection_contract() -> N
assert "mapStyleReady" in geomap
assert "map.on('load'" in geomap
assert "if (!map || !mapStyleReady)" in geomap
- assert "map.isStyleLoaded()" not in geomap
+ assert "if (!map || !map.isStyleLoaded()) return" in geomap
+ assert "setStyle(" not in geomap
assert "setLayoutProperty('dataset-fill', 'visibility'" in geomap
assert "setPaintProperty('dataset-fill', 'fill-opacity', opacity)" in geomap
diff --git a/backend/tests/test_sprint212_platform_source_portfolio.py b/backend/tests/test_sprint212_platform_source_portfolio.py
index 7be1beb3..0542bca4 100644
--- a/backend/tests/test_sprint212_platform_source_portfolio.py
+++ b/backend/tests/test_sprint212_platform_source_portfolio.py
@@ -44,7 +44,7 @@ def test_source_inventory_is_compact_honest_and_domain_driven() -> None:
assert "source-domain-grid" in styles
assert "source-opportunity-domain" in styles
assert "section.source-catalog-panel > .panel-title-row" in styles
- assert "display: grid !important" in styles
+ assert "display: grid" in styles
assert "justify-self: start" in styles
diff --git a/backend/tests/test_sprint21_demo_workflow_smoke.py b/backend/tests/test_sprint21_demo_workflow_smoke.py
index 9d75946c..5b58b309 100644
--- a/backend/tests/test_sprint21_demo_workflow_smoke.py
+++ b/backend/tests/test_sprint21_demo_workflow_smoke.py
@@ -24,6 +24,6 @@ def test_demo_workflow_browser_smoke_script_checks_connected_v1_state() -> None:
def test_frontend_demo_action_loads_candidate_dataset_details_for_map_layer() -> None:
demo_hook = (ROOT / "frontend" / "src" / "hooks" / "useDemoWorkflow.ts").read_text(encoding="utf-8")
- assert "const candidateDataset = projectData?.datasets.find" in demo_hook
+ assert "const candidateDataset = projectData?.datasets?.find" in demo_hook
assert "dataset.id === result.candidate_dataset_id" in demo_hook
assert "await loadDatasetDetails(result.project_id, candidateDataset)" in demo_hook
diff --git a/backend/tests/test_sprint232_v1_completion_flow.py b/backend/tests/test_sprint232_v1_completion_flow.py
index ca3d679d..0922d480 100644
--- a/backend/tests/test_sprint232_v1_completion_flow.py
+++ b/backend/tests/test_sprint232_v1_completion_flow.py
@@ -30,7 +30,7 @@ def test_current_and_historical_results_are_downloadable() -> None:
def test_completed_analysis_hands_off_to_ai_and_downloads_responsively() -> None:
- app = read("frontend/src/App.tsx")
+ app = read_feature("shell")
workspace = read_feature("map_workspace")
styles = read("frontend/src/styles/app.css")
diff --git a/backend/tests/test_sprint26_frontend_workflow_hooks.py b/backend/tests/test_sprint26_frontend_workflow_hooks.py
index 2e47b9d5..451a6718 100644
--- a/backend/tests/test_sprint26_frontend_workflow_hooks.py
+++ b/backend/tests/test_sprint26_frontend_workflow_hooks.py
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
def test_app_uses_detection_and_segmentation_workflow_hooks() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
assert "useDetectionWorkflow" in app
assert "useSegmentationWorkflow" in app
@@ -39,7 +39,7 @@ def test_segmentation_workflow_hook_owns_segmentation_api_calls() -> None:
def test_app_still_wires_detection_and_segmentation_panels() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
assert " None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
assert "useExportWorkflow" in app
assert "useQualityWorkflow" in app
@@ -41,7 +41,7 @@ def test_quality_workflow_hook_owns_quality_api_calls() -> None:
def test_app_still_wires_quality_results_and_export_center() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
quality_panel = read_feature("quality")
assert " None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
assert "useDatasetWorkflow" in app
assert "from './hooks/useDatasetWorkflow'" in app
@@ -41,7 +41,7 @@ def test_dataset_workflow_hook_owns_dataset_api_calls() -> None:
def test_app_still_wires_dataset_ui_callbacks() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
dataset_panel = read_feature("datasets")
detail_panel = read_feature("datasets")
diff --git a/backend/tests/test_sprint29_dataset_components.py b/backend/tests/test_sprint29_dataset_components.py
index 785974b0..472a18dd 100644
--- a/backend/tests/test_sprint29_dataset_components.py
+++ b/backend/tests/test_sprint29_dataset_components.py
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
def test_app_uses_dataset_presentational_components() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
inspector = read_feature("shell")
assert "from './components/datasets/DatasetPanel'" in app
diff --git a/backend/tests/test_sprint30_workbench_components.py b/backend/tests/test_sprint30_workbench_components.py
index 35e5edef..ec5c86cc 100644
--- a/backend/tests/test_sprint30_workbench_components.py
+++ b/backend/tests/test_sprint30_workbench_components.py
@@ -9,7 +9,7 @@ ROOT = Path(__file__).resolve().parents[2]
def test_app_uses_quality_and_map_presentational_components() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
assert "from './components/quality/QualityResultsPanel'" in app
assert "from './components/map/MapWorkspace'" in app
@@ -21,7 +21,7 @@ def test_app_uses_quality_and_map_presentational_components() -> None:
def test_map_workspace_lives_in_task_based_workbench_shell() -> None:
- app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
+ app = read_feature("shell")
styles = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8")
assert "activeWorkspace === 'map'" in app
diff --git a/backend/tests/test_sprint31_unraid_template.py b/backend/tests/test_sprint31_unraid_template.py
index 86e8088a..ff7a78d4 100644
--- a/backend/tests/test_sprint31_unraid_template.py
+++ b/backend/tests/test_sprint31_unraid_template.py
@@ -190,14 +190,11 @@ def test_frontend_and_unraid_icon_assets_are_present() -> None:
deploy_icon = (ROOT / "deploy" / "unraid" / "geointel-icon.svg").read_text(encoding="utf-8")
frontend_icon = (ROOT / "frontend" / "public" / "geointel-icon.svg").read_text(encoding="utf-8")
deploy_png = ROOT / "deploy" / "unraid" / "geointel-icon.png"
- frontend_png = ROOT / "frontend" / "public" / "geointel-icon.png"
index = (ROOT / "frontend" / "index.html").read_text(encoding="utf-8")
assert "