# Sprint 7C-D – Inventar Lebensmittel-Mapping und subjektiver Stress

Stand: 2026-08-16, verbindliche Basis `af91e14c21e25d2a4245757ab435c49240830113`.

## Preflight

- Lokaler `HEAD` und frisch geladener `origin/main` entsprechen der Basis; Arbeitsbaum war sauber.
- Sprint 7C-C ist genau ein Commit auf `b7dbc1ae89b340bc6297900c91de4c18663fa586`; die neun geänderten Runtime-Dateien sind bytegleich mit Git.
- Die private V5-Runtime nennt exakt den Basis-Commit; V5-Artefakt vor Sprint: `560e94b5cc4e916c14ca30e2a6755e8d332c40a6f4d77395c4831634049ca8a3`.
- `health-dashboard.service` und der aktivierte Action-Worker-Pfad sind aktiv; seit Tagesbeginn lagen keine Unit-Fehler vor.
- SQLite `integrity_check=ok`, Foreign-Key-Prüfung leer.
- V4 und V5 liefern privat HTTP 200. Der V4-Hash ist unverändert `798d11f191b402c556ec9233f50f5622d7f849022ff301cb4336ef2556e5f3a8`.
- Vergleichskatalog und Beobachtungsplan-Vorlagen liefern HTTP 200; der Vergleichsvertrag ist `health.explorer_comparison.v1`.
- Produktiver Ausgangsbestand: 305 Ernährungseinträge, 227 technisch zugeordnet – nicht bestätigt, 78 offen.
- Es bestehen keine produktiven Beobachtungspläne oder Ergebnisstände.

## Bestehender Mapping-Vertrag

### Kanonische Daten und Katalog

- `nutrition_items`: unveränderte importierte Ernährungseinträge und Quellmetadaten.
- `nutrition_histamine_scores`: angewendete Zuordnung pro Ernährungseintrag; `canonical_food`, `sighi_score`, technisches `confidence` und Begründung.
- `histamine_food_rules`: lokaler versionierter Lebensmittelkatalog mit Score 0–3, Kategorie, Tags, technischer Confidence und Quelle.
- `histamine_food_aliases`: exakte bekannte Aliase zu kanonischen Lebensmitteln.
- `nutrition_review_queue`: bestehende Queue-Aggregation mit `open`, `mapped`, `ignored`.
- `nutrition_mapping_action_log`: idempotenter Aktionsbeleg mit Aktionshash, Entscheidung, Quelle, Confidence und Definition.
- `nutrition_mapping_provenance`: betroffener Tag und Zuordnungsprovenienz pro Aktion.
- `nutrition_composite_product_review`: getrennte Zutatenprüfung für zusammengesetzte Produkte.

Die produktiven Tabellen sind bereits vorhanden. Sprint 7C-D legt keine Tabelle und keine Migration an.

### Bestehende Review- und Aktionssemantik

Bisherige Entscheidungen:

- `assign`: Nutzerzuordnung anwenden;
- `composite`: zusammengesetztes Produkt ohne Histaminklassifikation zur Zutatenprüfung markieren;
- `ignore`: ohne Zuordnung schließen.

Sprint 7C-D erweitert denselben Aktionsvertrag migrationsfrei um `defer`, `not_assignable`, `irrelevant`, `conflict` und `reopen`. Diese Zustände werden im vorhandenen Action-Log belegt; sie erzeugen keine parallele Klassifikationstabelle.

Bisherige Queuezustände sind gröber als die gewünschte Benutzeroberfläche. Verständliche Reviewzustände werden deshalb deterministisch aus bestehendem Queuezustand, tatsächlich angewendeter Zuordnung, Konfliktprüfung und letztem bestehenden Action-Log abgeleitet. Confidence bleibt ein eigenes technisches Feld und erzeugt niemals automatisch „bestätigt“.

### Identität und Normalisierung

Der alte Worker normalisiert Umlaute und entfernt Interpunktion. Dadurch kann er ähnlich geschriebene, aber nicht sicher identische Bezeichnungen nicht getrennt bearbeiten. Sprint 7C-D bestätigt deshalb ausschließlich die engere, in der Vorschau sichtbare Exaktgruppe. Eine Kollision der alten aggressiven Normalform wird weiterhin fail-closed als Konflikt angezeigt, aber niemals automatisch zusammengeführt.

Die produktive Bestandsaufnahme zeigt:

- 90 unveränderte Rohbezeichnungsgruppen insgesamt, davon 33 offen;
- 88 sicher normalisierte Exaktgruppen insgesamt, davon 56 technisch zugeordnet – nicht bestätigt und 32 offen;
- die 32 offenen Exaktgruppen enthalten zusammen 78 Einträge;
- 10 offene Gruppen mit 36 Einträgen fehlen im alten Queue-Snapshot;
- im aktuellen Produktivbestand liegt keine Kollision zwischen zwei sicher getrennten Exaktgruppen vor; der Kollisionsvertrag bleibt für künftige Einträge aktiv.
- Keine der 32 offenen Exaktgruppen besitzt aktuell eine nach dem bestehenden Katalogvertrag sicher validierbare Empfehlung. Die UI zeigt deshalb keine künstliche Ähnlichkeitszuordnung; „Anders zuordnen“ bietet ausschließlich Einträge des vorhandenen lokalen Katalogs an und übernimmt deren Kategorie.

Sprint 7C-D verwendet für die Gruppenansicht eine engere Identität: Unicode-NFC, Groß-/Kleinschreibung und wiederholte Leerzeichen werden vereinheitlicht; Interpunktion bleibt identitätsrelevant. Ähnliche Bezeichnungen bleiben getrennt. Ein separater Kollisionscheck gegen die alte aggressive Normalform markiert unsichere Überschneidungen als Konflikt.

### Bestehende Sicherheit

- Private Browser-Session, exakter Origin und Einmal-CSRF.
- Atomare private Action-Inbox mit deterministischer Identität aus dem kanonischen Payload.
- Worker revalidiert Payload, Queue-/Gruppenidentität und bestehende Klassifikationen.
- Eine SQLite-Transaktion umfasst Gruppenänderung, Tagesneuberechnung, Provenienz und Action-Log.
- Replay mit gleichem Aktionshash ist idempotent; abweichender Payload unter derselben Identität ist ein Konflikt.
- Bestehende abweichende Klassifikationen und mehrdeutige Normalisierung brechen fail-closed ab.
- Dashboard-HTTP-Prozess schreibt nicht direkt in SQLite.

Sprint 7C-D ergänzt einen Digest über die exakte, sortierte Zielmenge. Preview und Confirm tragen denselben Digest, dieselbe Anzahl Einträge und dieselbe Anzahl Tage. Jede Änderung zwischen Preview und Worker führt zum sicheren Konflikt vor der ersten Mutation.

### Bestehende UI und Tests

Die bestehende Ernährungsansicht besitzt bereits den Unterbereich „Zuordnungen“, Suche, URL-/History-Restore, Desktop-Master/Detail, echten mobilen Drill-down, 44-Pixel-Ziele, technische Details im Accordion sowie eine einzige Heute-Aufgabe. Sprint 7C-D ergänzt fünf verständliche Filter, gruppierte Beispiele, eine Preview mit Zielmengen-Digest und die vorhandene sichere Queue. Python-Tests prüfen Transaktion, Idempotenz, Zielmengen-Drift, Rollback ohne Teilbestätigung, Zustandswechsel, Trusted-Rule-Provenienz, CSRF/Formshape, Tagesneuberechnung und unveränderte Rohdaten. Sieben fokussierte Playwright-Szenarien prüfen Desktop, Tablet, 390 Pixel, 200-Prozent-Text, Suche, Filter, Fokus, Preview, sichere Vormerkung, die begrenzte Heute-Aufgabe sowie deterministisch begrenzte und unbegrenzte Beispiel-/Tageslisten mit exakten Anzeige-/Gesamtzahlen.

## Subjektiver Stress – Vertragsprüfung

Im Startstand existieren mehrere nicht gleichwertige Stresspfade:

1. `personal_observation_checkins.stress` mit den Textwerten `low`, `moderate`, `high`, `unknown`, ausschließlich innerhalb eines konkreten Beobachtungsplans.
2. Allgemeine beziehungsweise Capture-Ereignisse der Kategorie `stress` mit optionaler technischer Intensität 0–3.
3. Legacy-Explorer-Ereignis `event.stress`, kein eigenständiger subjektiver täglicher Messwert.

Für die geforderte Integration in den allgemeinen Symptom-Check-in ist kein bereits eindeutiger, globaler und migrationsfreier Vertrag belegt:

- Die kategoriale Plan-Skala und die numerische Ereignisskala sind nicht identisch.
- Für numerisch `0` ist im Stressvertrag nicht ausdrücklich belegt, dass es „keine Anspannung“ bedeutet.
- `unknown` und fehlender Eintrag sind nicht über alle Pfade als eine gemeinsame tägliche Reihe definiert.
- Es existiert noch kein globaler Stress-Metrik-Identifier mit eindeutiger Quelle, Renderer- und Beobachtungsplan-Verfügbarkeit.

Das verlinkte Weiterentwicklungskonzept wurde über die autorisierte private Drive-Quelle geprüft. Es fordert verständliche Missingness und verbietet neue künstliche Scores, enthält aber keine Stressskala, keine Definition von numerisch `0` und keine Zuordnung zwischen den beiden vorhandenen Verträgen. Auch diese Quelle löst den Konflikt daher nicht auf.

Daher wird im Sprint keine neue Stresssemantik erfunden, kein bestehender Wert umgedeutet und keine Stressreihe aus HRV, Puls, Schlaf oder Atemfrequenz berechnet. Der Mapping-Teil wird fortgesetzt.

Minimaler Entscheidungsvorschlag für einen Folgesprint: eine der beiden bestehenden Semantiken ausdrücklich als globalen Selbsteinschätzungsvertrag festlegen. Falls numerisch 0–3 gewählt wird, müssen die Bedeutung aller vier Werte, insbesondere `0`, Missingness, Tagesmehrfachwerte und Korrektursemantik vor Implementierung verbindlich dokumentiert werden. Falls `low/moderate/high` gewählt wird, darf kein künstlicher numerischer Abstand für Diagramme oder Vergleiche angenommen werden.
