@@ -95,2 +95,12 @@
     monkeypatch.setattr(worker, "DASHBOARD_V5_FILE", None)
+    connection = sqlite3.connect(fixture_db)
+    try:
+        connection.execute(
+            """INSERT INTO nutrition_daily_summary_v2
+               (datum,kcal,protein_g,carb_g,fat_g,item_count,histamine_score,histamine_max,histamine_unknown_count,histamine_label,nutrient_json)
+               VALUES('2026-06-13',123,4,5,6,1,2,2,0,'classified','{}')"""
+        )
+        connection.commit()
+    finally:
+        connection.close()
     payload = {
@@ -128,2 +138,4 @@
         assert connection.execute("SELECT COUNT(*) FROM nutrition_mapping_provenance WHERE affected_day='2026-06-14'").fetchone()[0] == 1
+        unaffected = connection.execute("SELECT kcal,histamine_score FROM nutrition_daily_summary_v2 WHERE datum='2026-06-13'").fetchone()
+        assert dict(unaffected) == {"kcal": 123.0, "histamine_score": 2.0}
         provenance = connection.execute("SELECT decision,alias,confidence,mapping_method,source_label,source_version,note,ingredient_review_required,personal_tolerance,definition_version FROM nutrition_mapping_provenance").fetchone()
@@ -146,2 +158,24 @@

+def test_worker_schema_bootstrap_is_idempotent_and_preserves_raw_items(fixture_db: Path) -> None:
+    import health_dashboard_action_worker as worker
+
+    connection = sqlite3.connect(fixture_db)
+    connection.row_factory = sqlite3.Row
+    try:
+        before = connection.execute(
+            "SELECT COUNT(*),SUM(raw_item_json IS NOT NULL),SUM(raw_product_json IS NOT NULL) FROM nutrition_items"
+        ).fetchone()
+        worker.ensure_nutrition_mapping_schema(connection)
+        worker.ensure_nutrition_mapping_schema(connection)
+        after = connection.execute(
+            "SELECT COUNT(*),SUM(raw_item_json IS NOT NULL),SUM(raw_product_json IS NOT NULL) FROM nutrition_items"
+        ).fetchone()
+        assert tuple(before) == tuple(after)
+        columns = {row["name"] for row in connection.execute("PRAGMA table_info(nutrition_mapping_provenance)")}
+        assert {"decision", "alias", "mapping_method", "source_label", "source_version", "definition_version"} <= columns
+        assert connection.execute("PRAGMA integrity_check").fetchone()[0] == "ok"
+    finally:
+        connection.close()
+
+
 def test_composite_and_ignore_do_not_alter_mappings(fixture_db: Path, monkeypatch: pytest.MonkeyPatch) -> None:


Output:
Exit code: 0
Wall time: 0.1 seconds
Output:
Success. Updated the following files:
M tests/test_dashboard_v5_sprint6g_nutrition.py


The migration/bootstrap test is in place and checks repeat application, integrity, and raw nutrition item preservation. I’m rerunning Sprint 6G focused tests after that addition.


Output:
Chunk ID: be11d9
Wall time: 10.4965 seconds
Process exited with code 0
Original token count: 25
Output:
......                                                                   [100%]
6 passed in 10.30s


Sprint 6G focused tests pass with the added bootstrap gate. I’m doing quick static checks for the modified JavaScript/Python and then I’ll inspect the final diff for any accidental V4 or production-facing changes.


python -m py_compile scripts/health/health_dashboard_action_worker.py scripts/health/health_dashboard_server.py scripts/health/dashboard_v5/read_api.py scripts/health/dashboard_v5/data_provider.py scripts/health/dashboard_v5/contracts.py scripts/health/dashboard_v5/render.py tests/fixtures/dashboard_v5_fixture.py


git diff -- scripts/health/health_dashboard_v4.py


Output:
Chunk ID: 560f82
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


Output:
Chunk ID: 263ca4
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


Output:
Chunk ID: ee5db7
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 194
Output:
 database/schema.sql                                |  57 ++-
 .../health-assets/dashboard-v5-api-explorer.js     |   2 +-
 .../health/assets/health-assets/dashboard-v5.css   |  15 +-
 .../health/assets/health-assets/dashboard-v5.js    | 248 +++++++++++--
 scripts/health/dashboard_v5/contracts.py           |  17 +-
 scripts/health/dashboard_v5/data_provider.py       |  18 +-
 scripts/health/dashboard_v5/read_api.py            | 292 ++++++++++++++-
 scripts/health/dashboard_v5/render.py              |  14 +-
 scripts/health/health_dashboard_action_worker.py   | 409 ++++++++++++++++++++-
 scripts/health/health_dashboard_server.py          | 115 +++++-
 tests/fixtures/dashboard_v5_fixture.py             |  28 +-
 11 files changed, 1130 insertions(+), 85 deletions(-)


Output:
Chunk ID: 1dbf52
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


rg -n "def dispatch_api|nutrition/day|API_PATHS" scripts/health/dashboard_v5/read_api.py


Output:
Chunk ID: 917ffc
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 93
Output:
98:API_PATHS = frozenset(
106:        "/api/v1/nutrition/days",
2523:def dispatch_api(database: Path, path: str, query: str) -> dict[str, Any]:
2536:        path not in API_PATHS
2540:        and not re.fullmatch(r"/api/v1/nutrition/day/\d{4}-\d{2}-\d{2}", path)
2628:        if path == "/api/v1/nutrition/days":
2630:        if path.startswith("/api/v1/nutrition/day/"):


Static checks are clean, and there is no diff in `health_dashboard_v4.py`. I’m checking the dispatch and serialization edges now, then I’ll run one final focused command set.


sed -n '2500,2650p' scripts/health/dashboard_v5/read_api.py


Output:
Chunk ID: acdb84
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1568
Output:
                    "symptoms": False,
                    "appointments": False,
                    "documents": bool(document_page.get("truncated")),
                }[name],
            }
            for name, section_payload in {
                "overview": overview,
                "labs": labs,
                "medications": sum(
                    len(medications.get(kind, []))
                    for kind in ("planned", "administered", "missed", "corrected")
                ),
                "symptoms": symptoms,
                "appointments": appointments,
                "documents": documents,
            }.items()
            if name in selected
        },
        "medical_statement": "Dokumentierte Daten ohne Diagnose-, Kausalitäts- oder Therapieaussage.",
    }
    return payload

def dispatch_api(database: Path, path: str, query: str) -> dict[str, Any]:
    document_route = re.fullmatch(
        r"/api/v1/documents/(api-document-[a-f0-9]{24})(?:/(matches))?", path
    )
    allowed_record = {
        "/api/v1/record-summary",
        "/api/v1/record-labs",
        "/api/v1/medications",
        "/api/v1/appointments",
        "/api/v1/documents",
        "/api/v1/doctor-report",
    }
    if (
        path not in API_PATHS
        and path not in allowed_record
        and not document_route
        and not re.fullmatch(r"/api/v1/day/\d{4}-\d{2}-\d{2}", path)
        and not re.fullmatch(r"/api/v1/nutrition/day/\d{4}-\d{2}-\d{2}", path)
    ):
        raise APIError(404, "endpoint_not_found")
    connection = connect_read_only(database)
    try:
        if path == "/api/v1/record-summary":
            parse_query(query, set())
            return _record_summary(connection)
        if path == "/api/v1/record-labs":
            return _record_labs(connection, parse_query(query, {"q", "from", "to"}))
        if path == "/api/v1/medications":
            return _record_medications(connection, parse_query(query, {"from", "to"}))
        if path == "/api/v1/appointments":
            return _record_appointments(
                connection, parse_query(query, {"from", "to", "order", "institution"})
            )
        if path == "/api/v1/documents":
            return _record_document_rows(
                connection,
                parse_query(
                    query,
                    {
                        "from",
                        "to",
                        "category",
                        "institution",
                        "type",
                        "review_status",
                        "sort",
                        "q",
                        "cursor",
                        "limit",
                    },
                ),
            )
        if document_route:
            opaque, suffix = document_route.groups()
            if suffix == "matches":
                return _record_document_matches(
                    connection, opaque, parse_query(query, {"q"})
                )
            return _record_document_detail(
                connection,
                opaque,
                parse_query(query, {"cursor", "limit"}),
            )
        if path == "/api/v1/doctor-report":
            return _doctor_report(
                connection, parse_query(query, {"from", "to", "sections"})
            )
        if path == "/api/v1/metric-catalog":
            params = parse_query(query, {"q"})
            query_text = params.get("q", "")
            metrics = (
                catalog_search(connection, query_text)
                if query_text
                else public_catalog(connection)
            )
            inventory = inventory_sources(connection)
            return {
                "version": 2,
                "timezone": TZ_NAME,
                "today": local_today().isoformat(),
                "groups": {"metrics": metrics},
                "inventory": {
                    "apple_observed_identifiers": len(inventory["apple_health"]),
                    "apple_released_identifiers": sum(
                        item["status"] == "released"
                        for item in inventory["apple_health"]
                    ),
                    "canonical_verified_laboratory_parameters": len(
                        inventory["laboratory"]
                    ),
                    "observed_vital_sign_parameters": len(inventory["vital_signs"]),
                },
            }
        if path == "/api/v1/series":
            params = parse_query(query, {"metric", "from", "to", "resolution"})
            if not params.get("metric"):
                raise APIError(400, "metric_required")
            return _series(connection, params)
        if path.startswith("/api/v1/day/"):
            if query:
                raise APIError(400, "unknown_parameter")
            requested_day = parse_iso_day(path.rsplit("/", 1)[-1])
            if requested_day > local_today() + timedelta(days=MAX_FUTURE_DAYS):
                raise APIError(422, "future_date_not_allowed")
            return _day(connection, requested_day)
        if path == "/api/v1/nutrition/days":
            return _nutrition_days(connection, parse_query(query, {"from", "to"}))
        if path.startswith("/api/v1/nutrition/day/"):
            if query:
                raise APIError(400, "unknown_parameter")
            requested_day = parse_iso_day(path.rsplit("/", 1)[-1])
            if requested_day > local_today():
                raise APIError(422, "future_date_not_allowed")
            return _nutrition_day_detail(connection, requested_day)
        if path == "/api/v1/nutrition/mapping-queue":
            return _nutrition_mapping_queue(connection, parse_query(query, {"status"}))
        if path == "/api/v1/calendar":
            params = parse_query(query, {"from", "to"})
            return _calendar(connection, params)
        if path == "/api/v1/events":
            params = parse_query(query, {"from", "to", "types"})
            return _events(connection, params)
        if path == "/api/v1/labs":
            parse_query(query, set())
            rows = _verified_lab_rows(connection)
            if len(rows) > MAX_LAB_ROWS:
                raise APIError(422, "row_limit_exceeded")
            return {


One remaining privacy issue from the frozen review applies outside nutrition too: lab read rows used an internal numeric ID in an opaque-looking string. I’m replacing that with a hash-derived opaque ID so read APIs do not expose internal numeric identifiers.


Output:
Chunk ID: 77bf2e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 345
Output:
scripts/health/dashboard_v5/read_api.py:139:def api_document_id(
scripts/health/dashboard_v5/read_api.py:233:    include_raw_json: bool = False,
scripts/health/dashboard_v5/read_api.py:235:    if include_raw_json:
scripts/health/dashboard_v5/read_api.py:237:                        file_name,file_hash,raw_json
scripts/health/dashboard_v5/read_api.py:311:        connection, "blood_pressure", start, end, include_raw_json=True
scripts/health/dashboard_v5/read_api.py:320:            payload = json.loads(str(row["raw_json"] or ""))
scripts/health/dashboard_v5/read_api.py:543:            "id": f"lab-observation-{int(row['id'])}",
scripts/health/dashboard_v5/read_api.py:571:                    "id": api_document_id(
scripts/health/dashboard_v5/read_api.py:923:                "id": api_document_id(row["id"], document_day, category, institution),
scripts/health/dashboard_v5/read_api.py:946:            "id": row["id"],
scripts/health/dashboard_v5/read_api.py:1162:                "id": api_document_id(row["id"], requested, category, institution),
scripts/health/dashboard_v5/read_api.py:1954:                "id": api_document_id(row["id"], document_day, category, institution),
scripts/health/dashboard_v5/read_api.py:1990:            {"b": binding, "k": cursor_key, "id": int(last_row["id"])}
scripts/health/dashboard_v5/read_api.py:2029:            and api_document_id(


Output:
Chunk ID: 3fd863
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 684
Output:
tests/test_dashboard_v5_sprint6c_api_contracts.py:53:                    source_version,device,file_name,file_hash,record_hash,raw_json,imported_at)
tests/test_health_dashboard_v5.py:237:        "date": "2026-01-04", "name": "/home/person/private.pdf", "dose": "40 mg", "status": "planned"
tests/test_dashboard_v5_sprint6b_api.py:38:    "raw_json", "file_name", "file_hash", "record_hash", "quelle",
tests/test_dashboard_v5_sprint6b_api.py:108:                source_version,device,file_name,file_hash,record_hash,raw_json,imported_at)
tests/test_dashboard_v5_sprint6b_api.py:119:                "synthetic-lab.pdf", "/tmp/private/synthetic-lab.pdf", "pdf", "eingearbeitet",
tests/test_dashboard_v5_sprint6b_api.py:121:                "https://drive.invalid/private", "/tmp/private/original.pdf",
tests/test_dashboard_v5_sprint6b_api.py:150:            ((ANCHOR - timedelta(days=2)).isoformat(), "malformed", "prefix /home/agent/private", None, None, "fixture", None),
tests/test_dashboard_v5_sprint6b_api.py:157:                    "prefix:/home/agent/private.db",
tests/test_dashboard_v5_sprint6b_api.py:159:                    "x|/tmp/private/report.pdf",
tests/test_dashboard_v5_sprint6b_api.py:189:        assert "/tmp/private" not in value
tests/test_dashboard_v5_sprint6b_api.py:190:        assert "/home/agent" not in value
tests/test_dashboard_v5_sprint6b_api.py:350:        ("/api/v1/series", "metric=apple.steps&from=2026-01-01&to=2026-01-02&resolution=day&column=raw_json"),
tests/test_dashboard_v5_sprint6b_api.py:352:        ("/api/v1/labs", "path=/tmp/private"),
tests/test_dashboard_v5_sprint6b_api.py:412:            "INSERT INTO apple_health_records(metric,value,unit,raw_json) VALUES(?,?,?,?)",
tests/test_dashboard_v5_sprint6b_api.py:427:            """INSERT INTO apple_health_records(metric,value,unit,raw_json,start_date)
tests/test_dashboard_v5_sprint6b_api.py:462:            """INSERT INTO apple_health_records(metric,value,unit,raw_json,start_date)
tests/test_dashboard_v5_sprint6g_nutrition.py:82:    assert not any(forbidden in serialized for forbidden in ("raw_json", "source_product_id", "http://", "https://", "/home/", "/tmp/", ".hermes"))
tests/test_dashboard_v5_sprint6g_nutrition.py:86:    assert "source_product_id" not in json.dumps(queue)
tests/test_dashboard_v5_sprint6g_nutrition.py:166:            "SELECT COUNT(*),SUM(raw_item_json IS NOT NULL),SUM(raw_product_json IS NOT NULL) FROM nutrition_items"
tests/test_dashboard_v5_sprint6g_nutrition.py:171:            "SELECT COUNT(*),SUM(raw_item_json IS NOT NULL),SUM(raw_product_json IS NOT NULL) FROM nutrition_items"
tests/test_dashboard_v5_sprint6g_nutrition.py:215:    monkeypatch.setenv("HEALTH_DASHBOARD_FILE", "/tmp/synthetic-v4.html")


Input:
*** Begin Patch
*** Update File: scripts/health/dashboard_v5/read_api.py
@@
 def api_document_id(
@@
     return f"api-document-{hashlib.sha256(b'health-api-document-v1:' + material).hexdigest()[:24]}"
+
+
+def api_observation_id(prefix: str, raw_id: Any, *parts: Any) -> str:
+    material = json.dumps(
+        [int(raw_id), *parts],
+        ensure_ascii=False,
+        separators=(",", ":"),
+    ).encode("utf-8")
+    return f"{prefix}-{hashlib.sha256(b'health-api-observation-v1:' + material).hexdigest()[:24]}"
@@
-            "id": f"lab-observation-{int(row['id'])}",
+            "id": api_observation_id("lab-observation", row["id"], parameter, unit, day),
*** End Patch


Success. Updated the following files:
M scripts/health/dashboard_v5/read_api.py

@@ -149,2 +149,11 @@

+def api_observation_id(prefix: str, raw_id: Any, *parts: Any) -> str:
+    material = json.dumps(
+        [int(raw_id), *parts],
+        ensure_ascii=False,
+        separators=(",", ":"),
+    ).encode("utf-8")
+    return f"{prefix}-{hashlib.sha256(b'health-api-observation-v1:' + material).hexdigest()[:24]}"
+
+
 def connect_read_only(database: Path) -> sqlite3.Connection:
@@ -542,3 +551,3 @@
         item: dict[str, Any] = {
-            "id": f"lab-observation-{int(row['id'])}",
+            "id": api_observation_id("lab-observation", row["id"], parameter, unit, day),
             "metric_id": LAB_CATALOG_SPECS[parameter].metric_id,


Output:
Exit code: 0
Wall time: 0.1 seconds
Output:
Success. Updated the following files:
M scripts/health/dashboard_v5/read_api.py


The lab observation ID is now hash-derived from stable observation fields rather than the raw numeric primary key. I’m rerunning the focused Python checks that cover API contracts and nutrition.


pytest -q tests/test_dashboard_v5_sprint6g_nutrition.py && PYTHONPATH=. pytest -q tests/test_health_dashboard_v5.py tests/test_dashboard_v5_sprint6b_api.py tests/test_dashboard_v5_sprint6c_api_contracts.py -k 'not http_api_requires_private_bearer_token_and_never_caches and not http_api_is_fail_closed_without_explicit_database_and_token_paths and not server_exposes_v5_preview_and_exact_asset_allowlist'


Output:
Chunk ID: 91c907
Wall time: 30.0012 seconds
Process running with session ID 37596
Original token count: 31
Output:
......                                                                   [100%]
6 passed in 10.57s
........................


The combined focused run is still going; Sprint 6G passed again and the selected V5/API tests are progressing. I’m waiting for the final status.


Output:
Chunk ID: 42806c
Wall time: 15.9777 seconds
Process exited with code 0
Original token count: 23
Output:
...........                                      [100%]
35 passed, 3 deselected in 38.89s


The focused API/V5 tests pass with the socket-dependent tests deselected. I’m doing one last grep over the modified Sprint 6G surfaces for forbidden wording/fields and a final compile check.


rg -n "Ampel|safe|traffic_light|suggested_traffic_light|mapping_scope|green|yellow|orange|red" scripts/health/dashboard_v5 scripts/health/health_dashboard_action_worker.py scripts/health/health_dashboard_server.py scripts/health/assets/health-assets/dashboard-v5.js tests/test_dashboard_v5_sprint6g_nutrition.py docs/adr/0003-dietary-inflammation-model.md -S


Output:
Chunk ID: bd5e46
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


Output:
Chunk ID: 027f32
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


Output:
Chunk ID: 66f65b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 7646
Output:
docs/adr/0003-dietary-inflammation-model.md:30:- required DII parameters are not covered with a complete, licensed, versioned reference table.
docs/adr/0003-dietary-inflammation-model.md:32:The Dietary Inflammatory Index methodology required for a real DII implementation is the peer-reviewed Shivappa et al. 2014 method: nutrient/food-parameter intake is standardized against a global comparative database, converted to centered percentiles, multiplied by literature-derived inflammatory effect scores, and summed across available parameters. That methodology requires stable parameter names, units, global means/standard deviations, effect scores, coverage thresholds, and versioning. Those inputs are not available in this project state.
docs/adr/0003-dietary-inflammation-model.md:44:The dashboard does not compute a dietary inflammation index when required inputs are insufficient. Unknown or unmapped foods make the histamine component incomplete rather than zero. Composite products require ingredient review before a definitive mapping is applied.
docs/adr/0003-dietary-inflammation-model.md:46:Personal tolerance labels remain separate from shared food mapping definitions.
tests/test_dashboard_v5_sprint6g_nutrition.py:69:    assert "traffic_light" not in json.dumps(days)
tests/test_dashboard_v5_sprint6g_nutrition.py:119:        "ingredient_review_required": False,
tests/test_dashboard_v5_sprint6g_nutrition.py:141:        provenance = connection.execute("SELECT decision,alias,confidence,mapping_method,source_label,source_version,note,ingredient_review_required,personal_tolerance,definition_version FROM nutrition_mapping_provenance").fetchone()
tests/test_dashboard_v5_sprint6g_nutrition.py:150:            "ingredient_review_required": 0,
tests/test_dashboard_v5_sprint6g_nutrition.py:198:        "ingredient_review_required": True,
tests/test_dashboard_v5_sprint6g_nutrition.py:203:    worker.apply_mapping_action({**base, "decision": "ignore", "ingredient_review_required": False}, "c" * 32)
tests/test_dashboard_v5_sprint6g_nutrition.py:208:        assert connection.execute("SELECT status FROM nutrition_composite_product_review").fetchone()[0] == "needs_ingredient_review"
tests/test_dashboard_v5_sprint6g_nutrition.py:233:        "ingredient_review_required": ["false"],
scripts/health/assets/health-assets/dashboard-v5.js:23:      credentials: "same-origin",
scripts/health/assets/health-assets/dashboard-v5.js:33:    const response = await fetch(path, { credentials: "same-origin" });
scripts/health/assets/health-assets/dashboard-v5.js:55:    const raw = item.date || item.datetime || item.timestamp || item.measured_at || item.recorded_at;
scripts/health/assets/health-assets/dashboard-v5.js:83:    const value = path.split(".").reduce((current, key) => {
scripts/health/assets/health-assets/dashboard-v5.js:139:        animation: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? false : undefined,
scripts/health/assets/health-assets/dashboard-v5.js:202:        ? values.reduce((total, item) => total + item, 0)
scripts/health/assets/health-assets/dashboard-v5.js:203:        : values.reduce((total, item) => total + item, 0) / values.length;
scripts/health/assets/health-assets/dashboard-v5.js:300:    if (!target || target.dataset.renderedPeriod === activePeriod) return;
scripts/health/assets/health-assets/dashboard-v5.js:337:    target.dataset.renderedPeriod = activePeriod;
scripts/health/assets/health-assets/dashboard-v5.js:352:      .concat(bundle.medication?.last_administered?.date || [])
scripts/health/assets/health-assets/dashboard-v5.js:400:    const last = medication.last_administered;
scripts/health/assets/health-assets/dashboard-v5.js:475:        [["sighi_reference", "SIGHi-Referenz"], ["ingredient_label", "Zutatenliste"], ["manual_review", "manuelle Prüfung"], ["local_alias", "lokaler Alias"]].forEach(([value, label]) => {
scripts/health/assets/health-assets/dashboard-v5.js:484:        const reviewRequired = node("input");
scripts/health/assets/health-assets/dashboard-v5.js:485:        reviewRequired.type = "hidden";
scripts/health/assets/health-assets/dashboard-v5.js:486:        reviewRequired.name = "ingredient_review_required";
scripts/health/assets/health-assets/dashboard-v5.js:487:        reviewRequired.value = "false";
scripts/health/assets/health-assets/dashboard-v5.js:491:          reviewRequired.value = composite ? "true" : "false";
scripts/health/assets/health-assets/dashboard-v5.js:508:        form.append(reviewRequired);
scripts/health/assets/health-assets/dashboard-v5.js:645:      row.status === "computed" && (correlationIds.has(row.id.predictor) || correlationIds.has(row.id.target))
scripts/health/assets/health-assets/dashboard-v5.js:659:    rows.slice(0, 30).forEach((row) => target.append(node("div", "v5-card v5-card--quiet", `${row.id.predictor} → ${row.id.target}; Prädiktor an Tag d, Ziel an Tag d + ${row.dimensions.lag_days}; Phase ${row.dimensions.medication_phase}: n=${row.sample.observed_pairs}, Coverage ${formatValue(row.sample.target_coverage)}, ρ=${formatValue(row.statistics.rho)}, q=${formatValue(row.statistics.q_value)}. Explorativ, keine Kausalität.`)));
scripts/health/assets/health-assets/dashboard-v5.js:744:    canvas.dataset.completePointCount = String([...rowsByMetric.values()].reduce((count, rows) => count + rows.filter((point) => typeof point.value === "number" && Number.isFinite(point.value)).length, 0));
scripts/health/assets/health-assets/dashboard-v5.js:787:    const config = { type: "line", data: { labels: days.map((day) => formatValue(day, "date")), datasets }, options: { responsive: true, maintainAspectRatio: false, animation: useExplorerCadence || window.matchMedia("(prefers-reduced-motion: reduce)").matches ? false : undefined, interaction: { intersect: false, mode: "index" }, plugins: { legend: { position: "bottom", labels: { font: { size: 14 } } } }, scales: { x: { grid: { display: false }, ticks: { maxTicksLimit: 7, font: { size: 13 } } }, y: { ticks: { maxTicksLimit: 6, font: { size: 13 } } } } } };
scripts/health/assets/health-assets/dashboard-v5.js:853:          const cell = node("div", "explorer-result-cell", `${correlationLabel(row.id.predictor)} an Tag d → ${correlationLabel(row.id.target)} an Tag d + ${row.dimensions.lag_days} · ${phaseLabels[row.dimensions.medication_phase] || "Phase unbekannt"} · ρ ${formatValue(rho)} · q ${formatValue(row.statistics.q_value)} · n ${row.sample.observed_pairs}`);
scripts/health/assets/health-assets/dashboard-v5.js:875:          rows.forEach((row) => section.append(node("div", "explorer-result-cell", `${correlationLabel(row.id.predictor)} → ${correlationLabel(row.id.target)} · d zu d + ${row.dimensions.lag_days} · ρ ${formatValue(row.statistics.rho)} · q ${formatValue(row.statistics.q_value)} · n ${row.sample.observed_pairs} · Coverage ${formatValue(row.sample.target_coverage)}`)));
scripts/health/assets/health-assets/dashboard-v5.js:987:    const observed = Object.values(bundle.series || {}).reduce((count, rows) => count + rows.length, 0);
scripts/health/assets/health-assets/dashboard-v5.js:1177:        qa('#metric-cards').forEach(node => { delete node.dataset.renderedPeriod; });
scripts/health/health_dashboard_action_worker.py:55:MAPPING_METHODS = frozenset({"sighi_reference", "ingredient_label", "manual_review", "local_alias"})
scripts/health/health_dashboard_action_worker.py:112:    required = {
scripts/health/health_dashboard_action_worker.py:125:        "ingredient_review_required",
scripts/health/health_dashboard_action_worker.py:128:    if not required <= set(payload) <= required | optional:
scripts/health/health_dashboard_action_worker.py:142:    ingredient_review = payload["ingredient_review_required"]
scripts/health/health_dashboard_action_worker.py:158:        raise ValueError("required mapping documentation missing")
scripts/health/health_dashboard_action_worker.py:161:    if type(ingredient_review) is not bool:
scripts/health/health_dashboard_action_worker.py:162:        raise ValueError("invalid ingredient review flag")
scripts/health/health_dashboard_action_worker.py:166:        if not canonical or score == "unknown" or ingredient_review:
scripts/health/health_dashboard_action_worker.py:167:            raise ValueError("assign requires canonical score without ingredient review")
scripts/health/health_dashboard_action_worker.py:169:        if score != "unknown" or not ingredient_review:
scripts/health/health_dashboard_action_worker.py:170:            raise ValueError("composite must stay unclassified for ingredient review")
scripts/health/health_dashboard_action_worker.py:172:        if score != "unknown" or canonical or ingredient_review:
scripts/health/health_dashboard_action_worker.py:187:        "ingredient_review_required": ingredient_review,
scripts/health/health_dashboard_action_worker.py:246:        raise RuntimeError("HEALTH_DASHBOARD_DB is required")
scripts/health/health_dashboard_action_worker.py:337:            ingredient_review_required INTEGER,
scripts/health/health_dashboard_action_worker.py:355:            ingredient_review_required INTEGER,
scripts/health/health_dashboard_action_worker.py:365:            status TEXT NOT NULL DEFAULT 'needs_ingredient_review',
scripts/health/health_dashboard_action_worker.py:374:            "note": "TEXT", "ingredient_review_required": "INTEGER", "personal_tolerance": "TEXT",
scripts/health/health_dashboard_action_worker.py:380:            "ingredient_review_required": "INTEGER", "personal_tolerance": "TEXT",
scripts/health/health_dashboard_action_worker.py:456:        raise RuntimeError("HEALTH_DASHBOARD_DB is required")
scripts/health/health_dashboard_action_worker.py:487:                       VALUES(?,?, 'needs_ingredient_review', CURRENT_TIMESTAMP)""",
scripts/health/health_dashboard_action_worker.py:494:                           (item_id,canonical_food,sighi_score,traffic_light,tags,confidence,reason,scored_at)
scripts/health/health_dashboard_action_worker.py:500:                connection.execute("UPDATE nutrition_review_queue SET status='ignored',updated_at=CURRENT_TIMESTAMP WHERE normalized_name=?", (normalized,))
scripts/health/health_dashboard_action_worker.py:507:                        mapping_method,source_label,source_version,note,ingredient_review_required,
scripts/health/health_dashboard_action_worker.py:513:                        payload["source_version"], payload["note"], int(payload["ingredient_review_required"]),
scripts/health/health_dashboard_action_worker.py:520:                    mapping_method,source_label,source_version,note,ingredient_review_required,
scripts/health/health_dashboard_action_worker.py:527:                    int(payload["ingredient_review_required"]), payload.get("personal_tolerance"),
scripts/health/health_dashboard_action_worker.py:581:        print("HEALTH_DASHBOARD_DB is required", file=sys.stderr)
scripts/health/health_dashboard_server.py:28:from dashboard_v5.document_originals import configured_original_roots, probe_original
scripts/health/health_dashboard_server.py:139:MAPPING_METHODS = {"sighi_reference", "ingredient_label", "manual_review", "local_alias"}
scripts/health/health_dashboard_server.py:155:ORIGINAL_ROOTS = configured_original_roots()
scripts/health/health_dashboard_server.py:171:        raise OSError("read-only API authentication is not configured")
scripts/health/health_dashboard_server.py:204:        expired = [key for key, expiry in _browser_sessions.items() if expiry <= now]
scripts/health/health_dashboard_server.py:205:        for key in expired:
scripts/health/health_dashboard_server.py:207:        session_id = secrets.token_urlsafe(32)
scripts/health/health_dashboard_server.py:333:def safe_report_path(name: str) -> Path | None:
scripts/health/health_dashboard_server.py:390:    token = secrets.token_urlsafe(24)
scripts/health/health_dashboard_server.py:392:        expired = [
scripts/health/health_dashboard_server.py:397:        for existing in expired:
scripts/health/health_dashboard_server.py:415:    token = secrets.token_urlsafe(18)
scripts/health/health_dashboard_server.py:418:        expired = [
scripts/health/health_dashboard_server.py:423:        for key in expired:
scripts/health/health_dashboard_server.py:446:    nonce = secrets.token_urlsafe(18)
scripts/health/health_dashboard_server.py:490:    required = {"csrf_token", "date", "notes", *SYMPTOM_FIELDS}
scripts/health/health_dashboard_server.py:491:    allowed = required | {"return_to"}
scripts/health/health_dashboard_server.py:493:    if keys not in {frozenset(required), frozenset(allowed)}:
scripts/health/health_dashboard_server.py:505:    required = {
scripts/health/health_dashboard_server.py:517:        "ingredient_review_required",
scripts/health/health_dashboard_server.py:520:    allowed = required | {"personal_tolerance"}
scripts/health/health_dashboard_server.py:521:    if not required <= set(form) <= allowed or any(len(values) != 1 for values in form.values()):
scripts/health/health_dashboard_server.py:536:    review = form["ingredient_review_required"][0]
scripts/health/health_dashboard_server.py:544:        raise ValueError("mapping documentation required")
scripts/health/health_dashboard_server.py:547:    ingredient_review_required = review == "true"
scripts/health/health_dashboard_server.py:548:    if decision == "assign" and (score == "unknown" or not canonical_food or ingredient_review_required):
scripts/health/health_dashboard_server.py:550:    if decision == "composite" and (score != "unknown" or not ingredient_review_required):
scripts/health/health_dashboard_server.py:552:    if decision == "ignore" and (score != "unknown" or canonical_food or ingredient_review_required):
scripts/health/health_dashboard_server.py:567:        "ingredient_review_required": ingredient_review_required,
scripts/health/health_dashboard_server.py:753:            receipt = quote(issue_queue_receipt(), safe="")
scripts/health/health_dashboard_server.py:830:            report = safe_report_path(path.rsplit("/", 1)[-1])
scripts/health/health_dashboard_server.py:911:            self._send_api_error(401, "authentication_required", send_body)
scripts/health/dashboard_v5/data_provider.py:30:    "administered", "verabreicht",
scripts/health/dashboard_v5/data_provider.py:135:        return {"last_administered": None, "next_planned": None}, []
scripts/health/dashboard_v5/data_provider.py:142:        and (administered_day := parse_day(row["datum"])) is not None
scripts/health/dashboard_v5/data_provider.py:143:        and administered_day <= today
scripts/health/dashboard_v5/data_provider.py:185:        "last_administered": public_medication(last, parse_day(last["datum"]) if last else None, planned=False),
scripts/health/dashboard_v5/data_provider.py:193:            events.append({"date": day, "type": "medication_administered", "label": label})
scripts/health/dashboard_v5/data_provider.py:249:                and row["histamine_label"] in {"classified", "green", "yellow", "orange", "red"}
scripts/health/dashboard_v5/data_provider.py:281:        "lag_direction": "predictor_d_to_target_d_plus_lag",
scripts/health/dashboard_v5/data_provider.py:290:        """SELECT predictor,target,lag_days,medication_phase,n,eligible_target_days,
scripts/health/dashboard_v5/data_provider.py:294:           ORDER BY predictor,target,lag_days,medication_phase LIMIT 1000"""
scripts/health/dashboard_v5/data_provider.py:302:                predictor=str(row["predictor"]), target=str(row["target"]),
scripts/health/dashboard_v5/data_provider.py:315:            "id": {"predictor": result.predictor, "target": result.target},
scripts/health/dashboard_v5/document_originals.py:1:"""Fail-closed document-original availability shared by V5 metadata and streaming."""
scripts/health/dashboard_v5/document_originals.py:32:def configured_original_roots() -> tuple[Path, ...]:
scripts/health/dashboard_v5/document_originals.py:81:    allowed_roots = roots or configured_original_roots()
scripts/health/dashboard_v5/contracts.py:51:        raise ValueError(f"unsafe whitespace at {path}")
scripts/health/dashboard_v5/contracts.py:53:        raise ValueError(f"unsafe text at {path}")
scripts/health/dashboard_v5/contracts.py:182:        if event_day > today or event["type"] != "medication_administered":
scripts/health/dashboard_v5/contracts.py:187:    medication = _exact(bundle["medication"], {"last_administered", "next_planned"}, "medication")
scripts/health/dashboard_v5/contracts.py:189:        ("last_administered", {"date", "name", "dose"}),
scripts/health/dashboard_v5/contracts.py:197:        if (field == "last_administered" and medication_day > today) or (field == "next_planned" and medication_day <= today):
scripts/health/dashboard_v5/contracts.py:242:        if row["histamine_status"] not in {"classified", "green", "yellow", "orange", "red", "unknown"}:
scripts/health/dashboard_v5/contracts.py:293:        "lag_direction": "predictor_d_to_target_d_plus_lag",
scripts/health/dashboard_v5/contracts.py:302:        identity = _exact(row["id"], {"predictor", "target"}, f"{path}.id")
scripts/health/dashboard_v5/contracts.py:306:        if identity["predictor"] not in engine.ALLOWED_PREDICTORS or identity["target"] not in engine.ALLOWED_TARGETS:
scripts/health/dashboard_v5/contracts.py:312:        order = (identity["predictor"], identity["target"], dims["lag_days"], dims["medication_phase"])
scripts/health/dashboard_v5/contracts.py:314:            raise ValueError("correlation results are not uniquely and deterministically ordered")
scripts/health/dashboard_v5/contracts.py:347:def safe_json(bundle: dict[str, Any]) -> str:
scripts/health/dashboard_v5/read_api.py:70:    {"medication_administered", "symptom_day", "health_event", "health_period"}
scripts/health/dashboard_v5/read_api.py:122:def safe_metadata_text(
scripts/health/dashboard_v5/read_api.py:215:    params: dict[str, str], *, required: bool = False
scripts/health/dashboard_v5/read_api.py:221:    if required and not raw_start:
scripts/health/dashboard_v5/read_api.py:222:        raise APIError(400, "range_required")
scripts/health/dashboard_v5/read_api.py:353:            "quality": "paired_observation",
scripts/health/dashboard_v5/read_api.py:443:               AND histamine_label IN ('classified','green','yellow','orange','red')"""
scripts/health/dashboard_v5/read_api.py:575:            category = safe_metadata_text(row["kategorie"], 80, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:576:            institution = safe_metadata_text(row["institution"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:798:    start, end = parse_range(params, required=True)
scripts/health/dashboard_v5/read_api.py:808:    if "medication_administered" in selected and table_exists(
scripts/health/dashboard_v5/read_api.py:811:        administered_values = tuple(sorted(ADMINISTERED))
scripts/health/dashboard_v5/read_api.py:812:        if len(administered_values) != 6:
scripts/health/dashboard_v5/read_api.py:823:                    *administered_values,
scripts/health/dashboard_v5/read_api.py:831:            label = safe_metadata_text(row["medication_name"], 120)
scripts/health/dashboard_v5/read_api.py:835:                    {"date": day, "type": "medication_administered", "label": label}
scripts/health/dashboard_v5/read_api.py:856:            category = safe_metadata_text(row["category"], 80, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:857:            parameter = safe_metadata_text(row["parameter"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:880:            event_type = safe_metadata_text(row["event_type"], 80)
scripts/health/dashboard_v5/read_api.py:881:            label = safe_metadata_text(row["label"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:912:def _safe_documents(
scripts/health/dashboard_v5/read_api.py:922:        category = safe_metadata_text(row["kategorie"], 80, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:923:        institution = safe_metadata_text(row["institution"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:999:        groups["documents"] = _safe_documents(connection, clean)
scripts/health/dashboard_v5/read_api.py:1009:def _safe_day_text(
scripts/health/dashboard_v5/read_api.py:1012:    return safe_metadata_text(value, maximum, allow_empty=allow_empty)
scripts/health/dashboard_v5/read_api.py:1032:            note = _safe_day_text(row["notizen"], 300)
scripts/health/dashboard_v5/read_api.py:1054:    result = {"planned": [], "administered": [], "missed": [], "corrected": []}
scripts/health/dashboard_v5/read_api.py:1069:        name = _safe_day_text(row["medication_name"], 120, allow_empty=False)
scripts/health/dashboard_v5/read_api.py:1070:        dose = _safe_day_text(row["dose"], 40)
scripts/health/dashboard_v5/read_api.py:1071:        route = _safe_day_text(row["route"], 40)
scripts/health/dashboard_v5/read_api.py:1072:        note = _safe_day_text(row["notes"], 300)
scripts/health/dashboard_v5/read_api.py:1073:        source = _safe_day_text(row["source"], 80)
scripts/health/dashboard_v5/read_api.py:1086:            result["administered"].append(item)
scripts/health/dashboard_v5/read_api.py:1109:                "category": _safe_day_text(row["category"], 80),
scripts/health/dashboard_v5/read_api.py:1110:                "label": _safe_day_text(row["parameter"], 120),
scripts/health/dashboard_v5/read_api.py:1111:                "value": _safe_day_text(row["value"], 80),
scripts/health/dashboard_v5/read_api.py:1112:                "unit": _safe_day_text(row["unit"], 40),
scripts/health/dashboard_v5/read_api.py:1113:                "source": _safe_day_text(row["source"], 80),
scripts/health/dashboard_v5/read_api.py:1114:                "note": _safe_day_text(row["notes"], 300),
scripts/health/dashboard_v5/read_api.py:1127:            event_type = _safe_day_text(row["event_type"], 80, allow_empty=False)
scripts/health/dashboard_v5/read_api.py:1128:            label = _safe_day_text(row["label"], 120)
scripts/health/dashboard_v5/read_api.py:1129:            source = _safe_day_text(row["source"], 80)
scripts/health/dashboard_v5/read_api.py:1130:            note = _safe_day_text(row["notes"], 300)
scripts/health/dashboard_v5/read_api.py:1165:        category = _safe_day_text(row["kategorie"], 80)
scripts/health/dashboard_v5/read_api.py:1166:        institution = _safe_day_text(row["institution"], 120)
scripts/health/dashboard_v5/read_api.py:1188:        practitioner = _safe_day_text(row["arzt"], 120)
scripts/health/dashboard_v5/read_api.py:1189:        institution = _safe_day_text(row["klinik"], 120)
scripts/health/dashboard_v5/read_api.py:1190:        reason = _safe_day_text(row["grund"], 160)
scripts/health/dashboard_v5/read_api.py:1191:        note = _safe_day_text(row["notizen"], 300)
scripts/health/dashboard_v5/read_api.py:1247:        and row["histamine_label"] in {"classified", "green", "yellow", "orange", "red"}
scripts/health/dashboard_v5/read_api.py:1383:                    "score": _public_number(meal["histamine_score"]) if meal["histamine_label"] in {"green", "yellow", "orange", "red"} else None,
scripts/health/dashboard_v5/read_api.py:1384:                    "status": "complete" if meal["histamine_label"] in {"classified", "green", "yellow", "orange", "red"} else "incomplete",
scripts/health/dashboard_v5/read_api.py:1396:                      h.canonical_food,h.sighi_score,h.traffic_light,h.confidence
scripts/health/dashboard_v5/read_api.py:1403:            name = safe_metadata_text(item["name"], 120, allow_empty=False)
scripts/health/dashboard_v5/read_api.py:1404:            brand = safe_metadata_text(item["brand"], 80, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:1405:            canonical = safe_metadata_text(item["canonical_food"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:1474:        example = safe_metadata_text(row["example_name"], 160, allow_empty=False)
scripts/health/dashboard_v5/read_api.py:1475:        suggested = safe_metadata_text(row["suggested_canonical_food"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:1476:        reason = safe_metadata_text(row["reason"], 160, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:1492:            "allowed_mapping_methods": ["sighi_reference", "ingredient_label", "manual_review", "local_alias"],
scripts/health/dashboard_v5/read_api.py:1593:        raise APIError(400, "range_required")
scripts/health/dashboard_v5/read_api.py:1780:    return "record-cursor-" + base64.urlsafe_b64encode(raw + signature).decode(
scripts/health/dashboard_v5/read_api.py:1790:        packed = base64.urlsafe_b64decode(encoded + "=" * (-len(encoded) % 4))
scripts/health/dashboard_v5/read_api.py:1838:            clean = safe_metadata_text(raw, maximum, allow_empty=False)
scripts/health/dashboard_v5/read_api.py:1942:        category = safe_metadata_text(row["kategorie"], 80, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:1943:        institution = safe_metadata_text(row["institution"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:1978:                "processing_quality": safe_metadata_text(
scripts/health/dashboard_v5/read_api.py:2033:        category = safe_metadata_text(row["kategorie"], 80, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:2034:        institution = safe_metadata_text(row["institution"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:2051:    category = safe_metadata_text(row["kategorie"], 80, allow_empty=True) or ""
scripts/health/dashboard_v5/read_api.py:2052:    institution = safe_metadata_text(row["institution"], 120, allow_empty=True) or ""
scripts/health/dashboard_v5/read_api.py:2146:        "administered": [],
scripts/health/dashboard_v5/read_api.py:2154:        "administered": tuple(sorted(ADMINISTERED)),
scripts/health/dashboard_v5/read_api.py:2190:            name = safe_metadata_text(row["medication_name"], 120)
scripts/health/dashboard_v5/read_api.py:2199:                    "dose": safe_metadata_text(row["dose"], 40, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2200:                    "route": safe_metadata_text(row["route"], 40, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2201:                    "note": safe_metadata_text(row["notes"], 300, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2202:                    "source": safe_metadata_text(row["source"], 80, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2219:        safe_metadata_text(params["institution"], 120)
scripts/health/dashboard_v5/read_api.py:2247:        institution = safe_metadata_text(row["klinik"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:2255:        practitioner = safe_metadata_text(row["arzt"], 120, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:2256:        reason = safe_metadata_text(row["grund"], 160, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:2257:        note = safe_metadata_text(row["notizen"], 300, allow_empty=True)
scripts/health/dashboard_v5/read_api.py:2291:    if query and (len(query) > 80 or safe_metadata_text(query, 80) is None):
scripts/health/dashboard_v5/read_api.py:2371:        name = safe_metadata_text(row["medication_name"], 120)
scripts/health/dashboard_v5/read_api.py:2379:                    "dose": safe_metadata_text(row["dose"], 40, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2380:                    "route": safe_metadata_text(row["route"], 40, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2381:                    "note": safe_metadata_text(row["notes"], 300, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2382:                    "source": safe_metadata_text(row["source"], 80, allow_empty=True),
scripts/health/dashboard_v5/read_api.py:2414:        "latest_administered": medications["administered"][:3],
scripts/health/dashboard_v5/read_api.py:2430:    start, end = parse_range(params, required=True)
scripts/health/dashboard_v5/read_api.py:2451:        else {"planned": [], "administered": [], "missed": [], "corrected": []}
scripts/health/dashboard_v5/read_api.py:2519:                    for kind in ("planned", "administered", "missed", "corrected")
scripts/health/dashboard_v5/read_api.py:2628:                raise APIError(400, "metric_required")
scripts/health/dashboard_v5/document_chunks.py:1:"""Shared deterministic reviewed-document chunk contract for FTS and read APIs."""
scripts/health/dashboard_v5/render.py:7:from dashboard_v5.contracts import safe_json
scripts/health/dashboard_v5/render.py:20:    payload = safe_json(bundle)
scripts/health/dashboard_v5/render.py:34:        f"<label><span>{label}</span><select name='{key}' required><option value=''>–</option>"
scripts/health/dashboard_v5/metric_catalog_v2.py:150:    _metric("panel.blood_pressure", "Blutdruck", ("Blutdruck", "BD", "RR"), "vital_signs", "apple_health", "mmHg", "panel", 0, "panel", "intermittent", "blood_pressure_panel", {}, "paired_panel", ("systolisch", "diastolisch"), "explorer", False, (), "blood_pressure", "apple_health_blood_pressure_panel_v1"),
scripts/health/dashboard_v5/metric_catalog_v2.py:151:    _metric("apple.blood_pressure.systolic", "Blutdruck systolisch", ("systolisch",), "vital_signs", "apple_health", "mmHg", "number", 0, "last", "intermittent", "blood_pressure", _baseline(30), "paired_panel", ("blutdruck", "bd", "rr"), "explorer", False, (), "blood_pressure", "apple_health_blood_pressure_panel_v1", "panel.blood_pressure"),
scripts/health/dashboard_v5/metric_catalog_v2.py:152:    _metric("apple.blood_pressure.diastolic", "Blutdruck diastolisch", ("diastolisch",), "vital_signs", "apple_health", "mmHg", "number", 0, "last", "intermittent", "blood_pressure", _baseline(30), "paired_panel", ("blutdruck", "bd", "rr"), "explorer", False, (), "blood_pressure", "apple_health_blood_pressure_panel_v1", "panel.blood_pressure"),
scripts/health/dashboard_v5/metric_catalog_v2.py:335:                 AND histamine_label IN ('green','yellow','orange','red')
scripts/health/dashboard_v5/apple_identifier_report.py:1:"""Generate a safe machine-readable inventory of observed Apple Health identifiers."""
scripts/health/dashboard_v5/apple_identifier_report.py:87:    parser.add_argument("--db", required=True, type=Path)
scripts/health/dashboard_v5/apple_identifier_report.py:88:    parser.add_argument("--output", required=True, type=Path)


Output:
Chunk ID: 39d3ae
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 183
Output:
 M database/schema.sql
 M scripts/health/assets/health-assets/dashboard-v5-api-explorer.js
 M scripts/health/assets/health-assets/dashboard-v5.css
 M scripts/health/assets/health-assets/dashboard-v5.js
 M scripts/health/dashboard_v5/contracts.py
 M scripts/health/dashboard_v5/data_provider.py
 M scripts/health/dashboard_v5/read_api.py
 M scripts/health/dashboard_v5/render.py
 M scripts/health/health_dashboard_action_worker.py
 M scripts/health/health_dashboard_server.py
 M tests/fixtures/dashboard_v5_fixture.py
?? docs/adr/0003-dietary-inflammation-model.md
?? scripts/health/assets/health-assets/dashboard-v5-echarts.js
?? tests/browser/dashboard_v5_sprint6g_echarts.spec.js
?? tests/test_dashboard_v5_sprint6g_nutrition.py


The final grep found one neutral display bug: meal-level score visibility still checked only legacy color labels. I’m patching that and the catalog availability SQL to recognize the new `classified` summary label.


Input:
*** Begin Patch
*** Update File: scripts/health/dashboard_v5/read_api.py
@@
-                    "score": _public_number(meal["histamine_score"]) if meal["histamine_label"] in {"green", "yellow", "orange", "red"} else None,
+                    "score": _public_number(meal["histamine_score"]) if meal["histamine_label"] in {"classified", "green", "yellow", "orange", "red"} else None,
*** End Patch


@@ -1382,3 +1382,3 @@
                 "histamine": {
-                    "score": _public_number(meal["histamine_score"]) if meal["histamine_label"] in {"green", "yellow", "orange", "red"} else None,
+                    "score": _public_number(meal["histamine_score"]) if meal["histamine_label"] in {"classified", "green", "yellow", "orange", "red"} else None,
                     "status": "complete" if meal["histamine_label"] in {"classified", "green", "yellow", "orange", "red"} else "incomplete",


Output:
Exit code: 0
Wall time: 0.1 seconds
Output:
Success. Updated the following files:
M scripts/health/dashboard_v5/read_api.py


Input:
*** Begin Patch
*** Update File: scripts/health/dashboard_v5/metric_catalog_v2.py
@@
-                 AND histamine_label IN ('green','yellow','orange','red')
+                 AND histamine_label IN ('classified','green','yellow','orange','red')
*** End Patch


Success. Updated the following files:
M scripts/health/dashboard_v5/metric_catalog_v2.py

@@ -334,3 +334,3 @@
                  AND histamine_score IS NOT NULL
-                 AND histamine_label IN ('green','yellow','orange','red')
+                 AND histamine_label IN ('classified','green','yellow','orange','red')
                  AND datum<=? LIMIT ?""",


Output:
Exit code: 0
Wall time: 0.1 seconds
Output:
Success. Updated the following files:
M scripts/health/dashboard_v5/metric_catalog_v2.py


That last compatibility patch is in. I’m rerunning the focused nutrition tests and static compilation one more time after touching the catalog helper.


python -m py_compile scripts/health/health_dashboard_action_worker.py scripts/health/health_dashboard_server.py scripts/health/dashboard_v5/read_api.py scripts/health/dashboard_v5/data_provider.py scripts/health/dashboard_v5/contracts.py scripts/health/dashboard_v5/render.py scripts/health/dashboard_v5/metric_catalog_v2.py tests/fixtures/dashboard_v5_fixture.py


Output:
Chunk ID: 9d176c
Wall time: 10.7307 seconds
Process exited with code 0
Original token count: 25
Output:
......                                                                   [100%]
6 passed in 10.53s


Output:
Chunk ID: 79244f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


Output:
Chunk ID: dd0f1d
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


Focused nutrition and static checks are clean. Since I touched metric catalog availability, I’m rerunning the selected non-socket V5/API tests once more.


PYTHONPATH=. pytest -q tests/test_health_dashboard_v5.py tests/test_dashboard_v5_sprint6b_api.py tests/test_dashboard_v5_sprint6c_api_contracts.py -k 'not http_api_requires_private_bearer_token_and_never_caches and not http_api_is_fail_closed_without_explicit_database_and_token_paths and not server_exposes_v5_preview_and_exact_asset_allowlist'


Output:
Chunk ID: 52897f
Wall time: 30.0013 seconds
Process running with session ID 38772
Original token count: 8
Output:
..............................


The selected V5/API run is still active and remains green so far. I’m waiting for the final test summary before closing out.


Output:
Chunk ID: fab62a
Wall time: 1.8900 seconds
Process exited with code 0
Original token count: 21
Output:
.....                                      [100%]
35 passed, 3 deselected in 38.35s


The selected V5/API tests pass. I’m collecting the final status and diff summary now, then I’ll report exactly what changed and what was verified.


git diff -- scripts/health/health_dashboard_action_worker.py scripts/health/health_dashboard_server.py scripts/health/dashboard_v5/read_api.py scripts/health/dashboard_v5/data_provider.py scripts/health/dashboard_v5/contracts.py scripts/health/dashboard_v5/metric_catalog_v2.py tests/test_dashboard_v5_sprint6g_nutrition.py docs/adr/0003-dietary-inflammation-model.md | sed -n '1,260p'


Output:
Chunk ID: acff57
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 196
Output:
 M database/schema.sql
 M scripts/health/assets/health-assets/dashboard-v5-api-explorer.js
 M scripts/health/assets/health-assets/dashboard-v5.css
 M scripts/health/assets/health-assets/dashboard-v5.js
 M scripts/health/dashboard_v5/contracts.py
 M scripts/health/dashboard_v5/data_provider.py
 M scripts/health/dashboard_v5/metric_catalog_v2.py
 M scripts/health/dashboard_v5/read_api.py
 M scripts/health/dashboard_v5/render.py
 M scripts/health/health_dashboard_action_worker.py
 M scripts/health/health_dashboard_server.py
 M tests/fixtures/dashboard_v5_fixture.py
?? docs/adr/0003-dietary-inflammation-model.md
?? scripts/health/assets/health-assets/dashboard-v5-echarts.js
?? tests/browser/dashboard_v5_sprint6g_echarts.spec.js
?? tests/test_dashboard_v5_sprint6g_nutrition.py


Output:
Chunk ID: 8f1acf
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 209
Output:
 database/schema.sql                                |  57 ++-
 .../health-assets/dashboard-v5-api-explorer.js     |   2 +-
 .../health/assets/health-assets/dashboard-v5.css   |  15 +-
 .../health/assets/health-assets/dashboard-v5.js    | 248 +++++++++++--
 scripts/health/dashboard_v5/contracts.py           |  17 +-
 scripts/health/dashboard_v5/data_provider.py       |  18 +-
 scripts/health/dashboard_v5/metric_catalog_v2.py   |   2 +-
 scripts/health/dashboard_v5/read_api.py            | 303 ++++++++++++++-
 scripts/health/dashboard_v5/render.py              |  14 +-
 scripts/health/health_dashboard_action_worker.py   | 409 ++++++++++++++++++++-
 scripts/health/health_dashboard_server.py          | 115 +++++-
 tests/fixtures/dashboard_v5_fixture.py             |  28 +-
 12 files changed, 1141 insertions(+), 87 deletions(-)


Output:
Chunk ID: d416c5
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 3326
Output:
diff --git a/scripts/health/dashboard_v5/contracts.py b/scripts/health/dashboard_v5/contracts.py
index 97cb689..853e812 100644
--- a/scripts/health/dashboard_v5/contracts.py
+++ b/scripts/health/dashboard_v5/contracts.py
@@ -239,7 +239,7 @@ def validate_bundle(bundle: dict[str, Any]) -> None:
         for field in ("item_count", "unknown_items"):
             if row[field] is not None and (type(row[field]) is not int or row[field] < 0):
                 raise ValueError(f"invalid count at {path}.{field}")
-        if row["histamine_status"] not in {"green", "yellow", "orange", "red", "unknown"}:
+        if row["histamine_status"] not in {"classified", "green", "yellow", "orange", "red", "unknown"}:
             raise ValueError(f"invalid histamine status at {path}")
         if row["quality"] not in {"complete", "incomplete"}:
             raise ValueError(f"invalid nutrition quality at {path}")
@@ -251,11 +251,24 @@ def validate_bundle(bundle: dict[str, Any]) -> None:
     review_rows = _bounded_list(nutrition["mapping_review"], "nutrition.mapping_review", MAX_REVIEW_ITEMS)
     for index, entry in enumerate(review_rows):
         path = f"nutrition.mapping_review[{index}]"
-        row = _exact(entry, {"name", "occurrences", "reason"}, path)
+        allowed = {
+            "name", "occurrences", "reason", "queue_key", "suggested_canonical_food",
+            "suggested_score",
+        }
+        if not isinstance(entry, dict) or not {"name", "occurrences", "reason"} <= set(entry) <= allowed:
+            raise ValueError(f"invalid fields at {path}")
+        row = entry
         _bounded_text(row["name"], f"{path}.name", 160)
         _bounded_text(row["reason"], f"{path}.reason", 120)
         if type(row["occurrences"]) is not int or row["occurrences"] < 0:
             raise ValueError(f"invalid occurrences at {path}")
+        if "queue_key" in row:
+            if not isinstance(row["queue_key"], str) or not re.fullmatch(r"[a-z0-9_]{0,80}", row["queue_key"]):
+                raise ValueError(f"invalid queue key at {path}")
+        if "suggested_canonical_food" in row:
+            _bounded_text(row["suggested_canonical_food"], f"{path}.suggested_canonical_food", 120, allow_empty=True)
+        if "suggested_score" in row and row["suggested_score"] not in {0, 1, 2, 3, "unknown"}:
+            raise ValueError(f"invalid suggested score at {path}")

     tasks = _bounded_list(bundle["tasks"], "tasks", min(MAX_TASKS, 3))
     for index, entry in enumerate(tasks):
diff --git a/scripts/health/dashboard_v5/data_provider.py b/scripts/health/dashboard_v5/data_provider.py
index 40f3017..9c910d1 100644
--- a/scripts/health/dashboard_v5/data_provider.py
+++ b/scripts/health/dashboard_v5/data_provider.py
@@ -246,21 +246,31 @@ def nutrition_data(connection: sqlite3.Connection) -> dict[str, Any]:
                 day is not None and row["item_count"] is not None and int(row["item_count"]) > 0
                 and row["histamine_unknown_count"] is not None and int(row["histamine_unknown_count"]) == 0
                 and row["histamine_score"] is not None
-                and row["histamine_label"] in {"green", "yellow", "orange", "red"}
+                and row["histamine_label"] in {"classified", "green", "yellow", "orange", "red"}
             )
             if day:
                 daily.append({
                     "date": day, "kcal": row["kcal"], "item_count": row["item_count"],
                     "histamine_score": row["histamine_score"] if complete else None,
-                    "histamine_status": str(row["histamine_label"]) if complete else "unknown",
+                    "histamine_status": "classified" if complete else "unknown",
                     "unknown_items": row["histamine_unknown_count"], "quality": "complete" if complete else "incomplete",
                 })
     review = []
     if table_exists(connection, "nutrition_review_queue"):
-        for row in connection.execute("SELECT example_name,occurrence_count FROM nutrition_review_queue WHERE status='open' ORDER BY occurrence_count DESC,last_seen DESC LIMIT 25"):
+        for row in connection.execute("SELECT normalized_name,example_name,occurrence_count,suggested_canonical_food,suggested_score FROM nutrition_review_queue WHERE status='open' ORDER BY occurrence_count DESC,last_seen DESC LIMIT 25"):
             name = public_text(row["example_name"], 160)
             if name:
-                review.append({"name": name, "occurrences": int(row["occurrence_count"] or 0), "reason": "Zuordnung fehlt"})
+                queue_key = slug(row["normalized_name"])
+                suggested = public_text(row["suggested_canonical_food"], 120, allow_empty=True)
+                score = row["suggested_score"] if row["suggested_score"] in (0, 1, 2, 3) else None
+                review.append({
+                    "queue_key": queue_key,
+                    "name": name,
+                    "occurrences": int(row["occurrence_count"] or 0),
+                    "reason": "Zuordnung fehlt",
+                    "suggested_canonical_food": suggested or "",
+                    "suggested_score": score if score is not None else "unknown",
+                })
     return {"daily": list(reversed(daily)), "mapping_review": review, "mapping_open_count": len(review)}

diff --git a/scripts/health/dashboard_v5/metric_catalog_v2.py b/scripts/health/dashboard_v5/metric_catalog_v2.py
index bccb575..7854aa2 100644
--- a/scripts/health/dashboard_v5/metric_catalog_v2.py
+++ b/scripts/health/dashboard_v5/metric_catalog_v2.py
@@ -332,7 +332,7 @@ def _availability(connection: sqlite3.Connection, metric: MetricV2) -> dict[str,
             """SELECT datum,histamine_score FROM nutrition_daily_summary_v2
                WHERE item_count>0 AND histamine_unknown_count=0
                  AND histamine_score IS NOT NULL
-                 AND histamine_label IN ('green','yellow','orange','red')
+                 AND histamine_label IN ('classified','green','yellow','orange','red')
                  AND datum<=? LIMIT ?""",
             (today.isoformat(), MAX_BLOOD_PRESSURE_SOURCE_ROWS + 1),
         ))
diff --git a/scripts/health/dashboard_v5/read_api.py b/scripts/health/dashboard_v5/read_api.py
index a17191e..9a5e721 100644
--- a/scripts/health/dashboard_v5/read_api.py
+++ b/scripts/health/dashboard_v5/read_api.py
@@ -59,6 +59,9 @@ MAX_EVENT_ROWS = 1000
 MAX_LAB_ROWS = 100
 MAX_SEARCH_ROWS_PER_GROUP = 20
 MAX_CALENDAR_DAYS = 62
+MAX_NUTRITION_DAYS = 180
+MAX_NUTRITION_ITEMS = 200
+MAX_NUTRITION_QUEUE = 50
 MAX_FUTURE_DAYS = 366
 MAX_QUERY_BYTES = 512
 QUERY_TIMEOUT_SECONDS = 1.0
@@ -66,6 +69,24 @@ ALLOWED_RESOLUTIONS = frozenset({"day", "week"})
 ALLOWED_EVENT_TYPES = frozenset(
     {"medication_administered", "symptom_day", "health_event", "health_period"}
 )
+NUTRIENT_ALLOWLIST = {
+    "energy.energy": ("Energie", "kcal"),
+    "nutrient.protein": ("Protein", "g"),
+    "nutrient.carb": ("Kohlenhydrate", "g"),
+    "nutrient.fat": ("Fett", "g"),
+    "nutrient.fiber": ("Ballaststoffe", "g"),
+    "nutrient.sugar": ("Zucker", "g"),
+    "nutrient.saturated_fat": ("Gesättigte Fettsäuren", "g"),
+    "nutrient.salt": ("Salz", "g"),
+    "nutrient.sodium": ("Natrium", "mg"),
+}
+MEAL_LABELS = {
+    "breakfast": "Frühstück",
+    "lunch": "Mittagessen",
+    "dinner": "Abendessen",
+    "snack": "Snack",
+    "unassigned": "Nicht zugeordnet",
+}
 FORBIDDEN_METADATA_TEXT = re.compile(
     r"(?:/home/|/tmp/|/Users/|/(?:var|etc|usr|opt|srv|root|run|mnt|media|private)/|"
     r"~/|file:|https?://|[A-Za-z]:[\\/]|"
@@ -82,6 +103,8 @@ API_PATHS = frozenset(
         "/api/v1/labs",
         "/api/v1/calendar",
         "/api/v1/search",
+        "/api/v1/nutrition/days",
+        "/api/v1/nutrition/mapping-queue",
     }
 )
 EXPECTED_ANALYTICS_UNITS = APPLE_ANALYTICS_UNITS
@@ -124,6 +147,15 @@ def api_document_id(
     return f"api-document-{hashlib.sha256(b'health-api-document-v1:' + material).hexdigest()[:24]}"

+def api_observation_id(prefix: str, raw_id: Any, *parts: Any) -> str:
+    material = json.dumps(
+        [int(raw_id), *parts],
+        ensure_ascii=False,
+        separators=(",", ":"),
+    ).encode("utf-8")
+    return f"{prefix}-{hashlib.sha256(b'health-api-observation-v1:' + material).hexdigest()[:24]}"
+
+
 def connect_read_only(database: Path) -> sqlite3.Connection:
     connection = sqlite3.connect(f"{database.resolve().as_uri()}?mode=ro", uri=True)
     connection.row_factory = sqlite3.Row
@@ -408,7 +440,7 @@ def _nutrition_points(
     sql = """SELECT datum,histamine_score,item_count,histamine_unknown_count,histamine_label
              FROM nutrition_daily_summary_v2 WHERE item_count>0
                AND histamine_unknown_count=0 AND histamine_score IS NOT NULL
-               AND histamine_label IN ('green','yellow','orange','red')"""
+               AND histamine_label IN ('classified','green','yellow','orange','red')"""
     parameters: list[Any] = []
     if start:
         sql += " AND datum>=?"
@@ -517,7 +549,7 @@ def _verified_lab_rows(
             else None
         )
         item: dict[str, Any] = {
-            "id": f"lab-observation-{int(row['id'])}",
+            "id": api_observation_id("lab-observation", row["id"], parameter, unit, day),
             "metric_id": LAB_CATALOG_SPECS[parameter].metric_id,
             "parameter": parameter,
             "value": value,
@@ -1207,6 +1239,261 @@ def _day_nutrition(connection: sqlite3.Connection, requested: str) -> dict[str,
     }

+def _nutrition_complete(row: sqlite3.Row) -> bool:
+    return (
+        int(row["item_count"] or 0) > 0
+        and int(row["histamine_unknown_count"] or 0) == 0
+        and row["histamine_score"] is not None
+        and row["histamine_label"] in {"classified", "green", "yellow", "orange", "red"}
+    )
+
+
+def _public_number(value: Any) -> int | float | None:
+    try:
+        numeric = float(value)
+    except (TypeError, ValueError):
+        return None
+    if not math.isfinite(numeric):
+        return None
+    rounded = round(numeric, 3)
+    return int(rounded) if rounded.is_integer() else rounded
+
+
+def _nutrition_days(connection: sqlite3.Connection, params: dict[str, str]) -> dict[str, Any]:
+    start, end = parse_range(params)
+    if not table_exists(connection, "nutrition_daily_summary_v2"):
+        return {"version": 1, "timezone": TZ_NAME, "definition": _histamine_definition(), "days": []}
+    sql = """SELECT datum,kcal,protein_g,carb_g,fat_g,item_count,histamine_score,
+                    histamine_max,histamine_unknown_count,histamine_label
+             FROM nutrition_daily_summary_v2 WHERE datum<=?"""
+    values: list[Any] = [local_today().isoformat()]
+    if start:
+        sql += " AND datum>=?"
+        values.append(start.isoformat())
+    if end:
+        sql += " AND datum<=?"
+        values.append(end.isoformat())
+    sql += " ORDER BY datum DESC LIMIT ?"
+    values.append(MAX_NUTRITION_DAYS + 1)
+    rows = list(connection.execute(sql, values))
+    if len(rows) > MAX_NUTRITION_DAYS:
+        raise APIError(422, "row_limit_exceeded")
+    days = []
+    for row in reversed(rows):
+        day = parse_day(row["datum"])
+        if not day:
+            continue
+        complete = _nutrition_complete(row)
+        days.append({
+            "date": day,
+            "macros": {
+                "kcal": _public_number(row["kcal"]),
+                "protein_g": _public_number(row["protein_g"]),
+                "carb_g": _public_number(row["carb_g"]),
+                "fat_g": _public_number(row["fat_g"]),
+            },
+            "item_count": int(row["item_count"] or 0),
+            "histamine": {
+                "score": _public_number(row["histamine_score"]) if complete else None,
+                "max_score": int(row["histamine_max"] or 0) if complete else None,
+                "mapping_coverage": round((int(row["item_count"] or 0) - int(row["histamine_unknown_count"] or 0)) / int(row["item_count"] or 1), 3) if int(row["item_count"] or 0) else 0,
+                "unknown_items": int(row["histamine_unknown_count"] or 0),
+                "status": "complete" if complete else "incomplete",
+                "definition_version": _histamine_definition()["version"],
+            },
+        })
+    return {"version": 1, "timezone": TZ_NAME, "definition": _histamine_definition(), "days": days}
+
+
+def _histamine_definition() -> dict[str, Any]:
+    return {
+        "id": "sighi_mapping_load_v1",
+        "version": "sighi_mapping_load_v2",
+        "components": ["mapped_item_score_sum", "mapped_item_score_max", "mapping_coverage", "unknown_item_count"],
+        "coverage_semantics": "unknown_or_unmapped_items_make_day_incomplete",
+        "insufficient_inputs": "no_index",
+        "score_scale": "SIGHi 0-3 or unknown per mapped item",
+        "complete_rule": "complete only when every documented nutrition item has a mapping",
+    }
+
+
+def _nutrition_day_detail(connection: sqlite3.Connection, requested: date) -> dict[str, Any]:
+    day = requested.isoformat()
+    if not table_exists(connection, "nutrition_daily_summary_v2"):
+        return {"version": 1, "date": day, "timezone": TZ_NAME, "status": "supported_no_data"}


Implemented the Sprint 6G-A repair in the current uncommitted worktree. No commit/push/deploy, no production access.

Key fixes:
- Replaced mapping action contract with explicit `decision` (`assign|composite|ignore`), alias, canonical food, SIGHi `0-3|unknown`, confidence, mapping method allowlist, source label/version, bounded note, ingredient-review flag, and optional neutral personal tolerance documentation.
- Removed traffic-light semantics from new public nutrition/mapping APIs and UI wording; no `safe` personal tolerance label in the new contract.
- Worker is now idempotent/transactional, audits provenance/version fields, maps all items matching normalized product slug, preserves composite as unclassified, and makes ignore not alter mappings.
- Recompute preserves missing macros as unknown, rebuilds allowlisted nutrient JSON from `nutrition_item_nutrients`, omits unknown-unit micronutrients, and only recomputes affected days.
- Read APIs avoid raw/source/internal numeric exposure; lab observation IDs are now opaque hashes.
- Mapping POST uses the bounded exact form shape with same-origin one-time CSRF.
- V5 worker regeneration preserves `--health-record-6e`, `--explorer-6c`, and `--calendar-day-6d`.
- UI mapping workspace is functional; nutrition day groups cover breakfast/lunch/dinner/snack/unassigned.
- ADR 0003 now includes DII methodology constraints, coverage/unit findings, licensing/reference limitation, versioning requirements, and the required conclusion: `Entzündungsindex derzeit nicht belastbar berechenbar`.
- V4 file was not modified.

Verification run:
- `pytest -q tests/test_dashboard_v5_sprint6g_nutrition.py` -> 6 passed
- `PYTHONPATH=. pytest -q tests/test_health_dashboard_v5.py tests/test_dashboard_v5_sprint6b_api.py tests/test_dashboard_v5_sprint6c_api_contracts.py -k 'not http_api_requires_private_bearer_token_and_never_caches and not http_api_is_fail_closed_without_explicit_database_and_token_paths and not server_exposes_v5_preview_and_exact_asset_allowlist'` -> 35 passed, 3 deselected
- `python -m py_compile ...` on modified Python modules -> passed
- `node --check scripts/health/assets/health-assets/dashboard-v5.js` -> passed

The three deselected tests require opening local sockets; the full run hit sandbox `PermissionError: [Errno 1] Operation not permitted` there.