mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
refactor(insights): strip release markers from the model-facing prompt
The insights ground-rules carried changelog tokens ("v1.4.16 phase B8", "W4d")
inside the prompt strings the model reads — token waste and inconsistent with
the project voice. Move the rule content to clean numbered rules; the markers
belong in code comments, not shipped prompt prose. Update the test pins to the
cleaned rule headers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
9a07a27001
commit
0193dbc1ee
2 files changed
+25
-24
No files matched your search
@@ -37,7 +37,7 @@ describe("getStrictInsightsSystemPrompt — EN", () => {
|
||||
const prompt = getStrictInsightsSystemPrompt("en");
|
||||
|
||||
it("carries the Apple Health silent-fallback contract (rule 11)", () => {
|
||||
expect(prompt).toMatch(/11\. v1\.4\.23/);
|
||||
expect(prompt).toMatch(/11\. Optional Apple Health metric categories/);
|
||||
expect(prompt).toMatch(/Apple Health metric categories/);
|
||||
expect(prompt).toMatch(/HRV/);
|
||||
expect(prompt).toMatch(/sleep duration/);
|
||||
@@ -49,11 +49,12 @@ describe("getStrictInsightsSystemPrompt — EN", () => {
|
||||
it("does not bake live tenant figures into the new rule", () => {
|
||||
// PII rule: the Apple Health rule frames in terms of metric
|
||||
// categories, never a specific number / email / username. The block
|
||||
// starts at "11. v1.4.23" (renumbered when v1.4.28 dropped the
|
||||
// weekly-report rule) and ends at the GUIDELINE TARGETS heading
|
||||
// that closes the ground-rules section.
|
||||
// starts at "11. Optional Apple Health metric categories" and ends at
|
||||
// the GUIDELINE TARGETS heading that closes the ground-rules section.
|
||||
const ruleAppleHealth =
|
||||
prompt.split("11. v1.4.23")[1]?.split("GUIDELINE TARGETS")[0] ?? "";
|
||||
prompt
|
||||
.split("11. Optional Apple Health metric categories")[1]
|
||||
?.split("GUIDELINE TARGETS")[0] ?? "";
|
||||
expect(ruleAppleHealth.length).toBeGreaterThan(0);
|
||||
expect(ruleAppleHealth).not.toMatch(/@.+\.(com|net|org|de|test)/);
|
||||
// The rule mentions metric category names but no concrete sample
|
||||
@@ -72,7 +73,7 @@ describe("getStrictInsightsSystemPrompt — DE", () => {
|
||||
const prompt = getStrictInsightsSystemPrompt("de");
|
||||
|
||||
it("carries the German silent-fallback wording (rule 11)", () => {
|
||||
expect(prompt).toMatch(/11\. v1\.4\.23/);
|
||||
expect(prompt).toMatch(/11\. Optionale Apple-Health-Metrik-Kategorien/);
|
||||
expect(prompt).toMatch(/Apple-Health-Metrik-Kategorien/);
|
||||
expect(prompt).toMatch(/HRV/);
|
||||
expect(prompt).toMatch(/Schlafdauer/);
|
||||
@@ -100,7 +101,7 @@ describe("getStrictInsightsSystemPrompt — DE", () => {
|
||||
describe("getStrictInsightsSystemPrompt — enum-identifier ban (no enum names in prose, rule 12)", () => {
|
||||
it("EN prompt carries the rule and enumerates the banned identifiers", () => {
|
||||
const prompt = getStrictInsightsSystemPrompt("en");
|
||||
expect(prompt).toMatch(/12\. v1\.4\.25/);
|
||||
expect(prompt).toMatch(/12\. Internal metric identifiers/);
|
||||
expect(prompt).toMatch(/Internal metric identifiers/);
|
||||
// The banned-list is enumerated verbatim so the model has no
|
||||
// ambiguity about which strings are off-limits in prose.
|
||||
@@ -122,7 +123,7 @@ describe("getStrictInsightsSystemPrompt — enum-identifier ban (no enum names i
|
||||
|
||||
it("DE prompt carries the rule with the same banned list", () => {
|
||||
const prompt = getStrictInsightsSystemPrompt("de");
|
||||
expect(prompt).toMatch(/12\. v1\.4\.25/);
|
||||
expect(prompt).toMatch(/12\. Interne Metrik-Identifier/);
|
||||
expect(prompt).toMatch(/Interne Metrik-Identifier/);
|
||||
expect(prompt).toMatch(/"Pressure_Sys"/);
|
||||
expect(prompt).toMatch(/"BLOOD_PRESSURE_SYS"/);
|
||||
|
||||
@@ -133,14 +133,14 @@ gib die obige Verweigerung zurück.`,
|
||||
language. Reference the user's actual data trends — do not paste
|
||||
in placeholder text. The rationale.dataWindow MUST equal the
|
||||
metricSource.timeRange so the UI's mini-chart can pin to it.
|
||||
6. v1.4.16 phase B8 — when the user prompt contains a "SYSTEM
|
||||
6. When the user prompt contains a "SYSTEM
|
||||
CONTEXT — COMPARISON MODE ACTIVE" block, narrate the comparison
|
||||
in the summary's first sentence using the prior-period numbers
|
||||
that block carries. Cite the deltas verbatim — do NOT invent
|
||||
comparison numbers, and do NOT extrapolate beyond the metrics
|
||||
listed. When the block reports "no prior-period data available"
|
||||
for every metric, state that explicitly and skip the narration.
|
||||
7. v1.4.19 — Do NOT open with a compliment about the data quantity
|
||||
7. Do NOT open with a compliment about the data quantity
|
||||
or data quality. The user does not see what fields were sent and
|
||||
reads such openers as filler. Mention data quality ONLY when it
|
||||
materially limits the analysis: n<7 readings in the analyzed
|
||||
@@ -150,7 +150,7 @@ gib die obige Verweigerung zurück.`,
|
||||
patterns include "Your data foundation is strong", "Datengrundlage
|
||||
ist sehr stark", "You have a solid baseline", "Great dataset" and
|
||||
any rephrasing of the same sentiment.
|
||||
8. v1.4.20 — Optional "dailyBriefing" block. When the snapshot
|
||||
8. Optional "dailyBriefing" block. When the snapshot
|
||||
carries enough signal (any of bp / weight / pulse / mood /
|
||||
medications.compliance) emit a top-level "dailyBriefing" object
|
||||
with two fields:
|
||||
@@ -170,7 +170,7 @@ gib die obige Verweigerung zurück.`,
|
||||
When the snapshot has no analysable data, omit "dailyBriefing"
|
||||
or set it to null. Empty paragraph or filler-only findings are
|
||||
rejected by the parser.
|
||||
9. v1.4.20 phase B3 — Optional "trendAnnotations" block. When the
|
||||
9. Optional "trendAnnotations" block. When the
|
||||
snapshot has enough signal for a given metric (bp, weight, or
|
||||
mood), emit a one-sentence annotation that reads directly below
|
||||
the metric's small chart in the Trends row. Each annotation MUST:
|
||||
@@ -185,7 +185,7 @@ gib die obige Verweigerung zurück.`,
|
||||
the entire block (or set null) when no metric qualifies. Trend
|
||||
annotations are SHORT — they sit below charts and compete for
|
||||
attention with the chart itself; one tight sentence is the goal.
|
||||
10. v1.4.20 phase B4 — Optional "storyboardAnnotations" array (max 20).
|
||||
10. Optional "storyboardAnnotations" array (max 20).
|
||||
When the 90-day BP timeline includes notable factual events the
|
||||
user logged, emit annotations that pin to specific dates. Each
|
||||
annotation MUST:
|
||||
@@ -205,7 +205,7 @@ gib die obige Verweigerung zurück.`,
|
||||
Date format: "YYYY-MM-DD". Label cap: 80 chars. Detail cap:
|
||||
400 chars. Hard array cap: 20. Omit the field entirely when the
|
||||
timeline has no notable events.
|
||||
11. v1.4.23 — Optional Apple Health metric categories. When the
|
||||
11. Optional Apple Health metric categories. When the
|
||||
snapshot carries any of HRV, sleep duration, resting HR, step
|
||||
count, active energy, flights climbed, walking/running distance,
|
||||
VO2 max, or body temperature, you may reference those categories
|
||||
@@ -218,7 +218,7 @@ gib die obige Verweigerung zurück.`,
|
||||
the user connect a wearable. The presence or absence of the
|
||||
HealthKit metric block in the snapshot is the only signal you
|
||||
should act on.
|
||||
12. v1.4.25 — Internal metric identifiers stay OUT of your prose.
|
||||
12. Internal metric identifiers stay OUT of your prose.
|
||||
Never write database / enum-style names like "Pressure_Sys",
|
||||
"BLOOD_PRESSURE_SYS", "PULSE_BPM", "MOOD_SCORE",
|
||||
"MEDICATION_COMPLIANCE_PCT", "HEART_RATE_VARIABILITY",
|
||||
@@ -240,7 +240,7 @@ gib die obige Verweigerung zurück.`,
|
||||
contract-level identifiers the parser reads — those stay in
|
||||
the documented enum vocabulary exactly as listed in OUTPUT
|
||||
FORMAT below. The ban applies ONLY to prose.
|
||||
13. v1.4.25 W4d — NEVER prescribe or modify medication doses, even
|
||||
13. NEVER prescribe or modify medication doses, even
|
||||
when the snapshot reveals a named GLP-1 receptor agonist
|
||||
(Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda,
|
||||
Rybelsus). Findings may NOTE the named medication and the
|
||||
@@ -278,14 +278,14 @@ gib die obige Verweigerung zurück.`,
|
||||
Platzhaltertext. rationale.dataWindow MUSS gleich
|
||||
metricSource.timeRange sein, damit die UI das Mini-Chart auf das
|
||||
gleiche Fenster fixieren kann.
|
||||
6. v1.4.16 phase B8 — wenn der User-Prompt einen Block "SYSTEM
|
||||
6. Wenn der User-Prompt einen Block "SYSTEM
|
||||
CONTEXT — VERGLEICHSMODUS AKTIV" enthält, narrative die im Block
|
||||
gelisteten Deltas im ersten Satz der Zusammenfassung. Zitiere die
|
||||
Werte exakt — erfinde KEINE Vergleichszahlen und extrapoliere
|
||||
nicht über die gelisteten Metriken hinaus. Wenn der Block für
|
||||
alle Metriken "no prior-period data available" meldet, sag das
|
||||
explizit und lass die Narration weg.
|
||||
7. v1.4.19 — Beginne NICHT mit einem Kompliment über Datenmenge
|
||||
7. Beginne NICHT mit einem Kompliment über Datenmenge
|
||||
oder Datenqualität. Der Nutzer sieht nicht, welche Felder gesendet
|
||||
wurden, und empfindet solche Eröffnungen als Füllsatz. Erwähne
|
||||
Datenqualität AUSSCHLIEßLICH dann, wenn sie die Analyse
|
||||
@@ -296,7 +296,7 @@ gib die obige Verweigerung zurück.`,
|
||||
Verbotene Eröffnungsmuster sind unter anderem "Datengrundlage ist
|
||||
sehr stark", "Your data foundation is strong", "Du hast eine solide
|
||||
Baseline", "Großartiger Datensatz" und jede sinngemäße Umformulierung.
|
||||
8. v1.4.20 — Optionaler "dailyBriefing"-Block. Wenn der Snapshot
|
||||
8. Optionaler "dailyBriefing"-Block. Wenn der Snapshot
|
||||
genügend Signal trägt (irgendwas aus bp / weight / pulse / mood /
|
||||
medications.compliance), emittiere ein Top-Level-Objekt
|
||||
"dailyBriefing" mit zwei Feldern:
|
||||
@@ -318,7 +318,7 @@ gib die obige Verweigerung zurück.`,
|
||||
Hat der Snapshot keine analysierbaren Daten, lass "dailyBriefing"
|
||||
weg oder setze es auf null. Leerer Paragraph oder Findings ohne
|
||||
Substanz werden vom Parser abgelehnt.
|
||||
9. v1.4.20 phase B3 — Optionaler "trendAnnotations"-Block. Wenn der
|
||||
9. Optionaler "trendAnnotations"-Block. Wenn der
|
||||
Snapshot für eine Metrik (bp, weight oder mood) genügend Signal
|
||||
trägt, emittiere eine einsätzige Annotation, die direkt unter dem
|
||||
kleinen Chart der Metrik in der Trends-Reihe gelesen wird. Jede
|
||||
@@ -336,7 +336,7 @@ gib die obige Verweigerung zurück.`,
|
||||
Metrik qualifiziert. Trend-Annotationen sind KURZ — sie stehen unter
|
||||
Charts und konkurrieren mit dem Chart selbst um Aufmerksamkeit; ein
|
||||
prägnanter Satz ist das Ziel.
|
||||
10. v1.4.20 phase B4 — Optionales "storyboardAnnotations"-Array
|
||||
10. Optionales "storyboardAnnotations"-Array
|
||||
(max 20). Wenn die 90-Tage-BP-Timeline bemerkenswerte vom Nutzer
|
||||
geloggte Ereignisse enthält, emittiere Annotationen, die auf
|
||||
konkrete Daten zeigen. Jede Annotation MUSS:
|
||||
@@ -358,7 +358,7 @@ gib die obige Verweigerung zurück.`,
|
||||
Datumsformat: "YYYY-MM-DD". Label-Cap: 80 Zeichen. Detail-Cap:
|
||||
400 Zeichen. Array-Höchstgrenze: 20. Lass das Feld komplett
|
||||
weg, wenn die Timeline keine bemerkenswerten Ereignisse hat.
|
||||
11. v1.4.23 — Optionale Apple-Health-Metrik-Kategorien. Wenn der
|
||||
11. Optionale Apple-Health-Metrik-Kategorien. Wenn der
|
||||
Snapshot eine der folgenden Kategorien führt — HRV, Schlafdauer,
|
||||
Ruhepuls, Schrittzahl, aktiver Energieumsatz, Stockwerke,
|
||||
Geh-/Laufdistanz, VO2 max oder Körpertemperatur — kannst du diese
|
||||
@@ -371,7 +371,7 @@ gib die obige Verweigerung zurück.`,
|
||||
HealthKit, schlage nicht vor, ein Wearable zu verbinden. Das
|
||||
Vorhandensein oder Fehlen des HealthKit-Metrik-Blocks im Snapshot
|
||||
ist das einzige Signal, auf das du reagieren solltest.
|
||||
12. v1.4.25 — Interne Metrik-Identifier gehören NICHT in deinen
|
||||
12. Interne Metrik-Identifier gehören NICHT in deinen
|
||||
Fließtext. Schreibe niemals Datenbank- bzw. Enum-Namen wie
|
||||
"Pressure_Sys", "BLOOD_PRESSURE_SYS", "PULSE_BPM", "MOOD_SCORE",
|
||||
"MEDICATION_COMPLIANCE_PCT", "HEART_RATE_VARIABILITY",
|
||||
@@ -394,7 +394,7 @@ gib die obige Verweigerung zurück.`,
|
||||
Parser liest — diese bleiben EXAKT in der unten in
|
||||
AUSGABEFORMAT dokumentierten Enum-Schreibweise. Das Verbot
|
||||
gilt AUSSCHLIEßLICH für Fließtext.
|
||||
13. v1.4.25 W4d — Du verschreibst und änderst NIEMALS
|
||||
13. Du verschreibst und änderst NIEMALS
|
||||
Medikamenten-Dosen, auch wenn der Snapshot einen
|
||||
GLP-1-Rezeptoragonisten namentlich benennt (Mounjaro, Ozempic,
|
||||
Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). Befunde dürfen
|
||||
|
||||
Reference in new issue
Block a user