Skip to content

Commit 5e9644d

Browse files
committed
Clarify planning activation edge cases
1 parent 36d9647 commit 5e9644d

4 files changed

Lines changed: 66 additions & 14 deletions

File tree

docs/plan/planning/open/plan-domain-migration-optimization-run-can-execute.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ Migration der Ausführungsentscheidung auf `CanExecute`.
215215
percent-encodiertem ISO-Zeitstempelwert wird persistiert, geparst,
216216
innerhalb des `kv1`-Parsers decodiert und bytegleich zum ursprünglichen
217217
fachlichen Wert verglichen.
218+
- Source-Guard-Vorsorgetest ergänzen: eine timestamp-basierte
219+
`series_version` mit Doppelpunkt (z. B. `2026-05-24T12:00:00Z-v3`) wird
220+
als hypothetischer `kv1`-Wert percent-encoded, roundtrippt und decodiert
221+
bytegleich. Das bleibt auch dann Pflicht, wenn aktuelle Preis-/Forecast-
222+
Slices `series_version` noch nicht im `TerminationDetail` persistieren.
218223
- API-Kompatibilität:
219224
- Producer-Vertrag: `can_execute` ist nach der Migration ein required Feld in
220225
Optimierungs-Run-Responses.

docs/plan/planning/open/plan-ler-fcr-reserve-robustness.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ Deterministische Berechnung (verbindlich):
320320
- optionale Pflichtanteile je Produkt und Richtung:
321321
- `alpha_afrr_up_t`, `alpha_afrr_down_t`
322322
- `alpha_mfrr_up_t`, `alpha_mfrr_down_t`
323-
- Default: `1.0`, wenn das Produkt gebucht ist, sonst `0.0` bei nicht gebuchtem Produkt.
323+
- Default: `1.0`, wenn das Produkt nach den obigen Produkt-Aktivitätsregeln
324+
produktiv aktiv ist, sonst `0.0`.
324325
- Vor der Rechnung ist hart zu validieren:
325326
- Alle Reserve- und Alphafelder pro Zeitschritt sind endlich und nicht negativ.
326327
- `fcr_*`, `afrr_*`, `mfrr_*` und die optionalen `required_*`-Felder sind `>= 0`.
@@ -370,6 +371,14 @@ Deterministische Berechnung (verbindlich):
370371
- Für die Worst-Case-Hülle ist die zu reservierende FCR-Energie auf
371372
`min(Δt, fcr_remaining_envelope_t/60)` h zu skalieren.
372373
- Mit der Tracking-Logik wird bei kleinen `Δt` die volle Mindestdauer konservativ über Folgeintervalle berücksichtigt.
374+
- Beispiel: Bei `Δt=1/60 h`, `t_min_fcr=30 min` und `fcr_up_kw_t=1 MW`
375+
ist `fcr_remaining_envelope_t` zwar pro Schritt statisch `30 min`, der
376+
FCR-Term aber `min(1/60, 30/60) * 1000 kW = 16,67 kWh` je Schritt.
377+
Über 30 fortgeschriebene SOC-Schritte akkumuliert dies zu `500 kWh`,
378+
also genau 30 Minuten FCR-Energie. Es wird nicht pro Schritt erneut
379+
30-Minuten-Energie abgezogen; die statische Größe erzwingt nur, dass
380+
jeder Entscheidungszeitpunkt als neuer Worst-Case-Startpunkt bewertet
381+
wird.
373382
- Hilfsgröße:
374383
- `self_discharge_loss_kwh_t` ist deterministisch zu berechnen:
375384
- bei `self_discharge_mode=absolute_kwh_per_hour`:
@@ -445,10 +454,17 @@ Restore- und Gate-Entscheidungslogik (verbindlich):
445454
Die folgenden `restore_shortfall_*`-Größen gehören zur unabhängigen
446455
Worst-Case-Hülle je Richtung; sie sind keine konkrete Fahrplanaktion und
447456
dürfen nicht als gleichzeitiges Laden/Entladen interpretiert werden.
457+
- Effektiver Restore-Bedarf:
458+
- `required_restore_up_kwh_t = coalesce(required_up_kwh_t, worst_up_kwh_t)`
459+
- `required_restore_down_kwh_t = coalesce(required_down_kwh_t, worst_down_kwh_t)`
460+
- Operatorseitig gesetzte `required_*`-Werte dürfen größer sein als die
461+
Worst-Case-Hülle; wenn gesetzt, sind sie bewusst der größere
462+
Restore-Planungs- und Gate-Bedarf. So entstehen keine divergierenden
463+
Gate- und Plan-Energien.
448464
- Up-Verstoß-Defizit:
449-
`restore_shortfall_up_kwh = max(0, worst_up_kwh_t - (soc_plan_up_t - soc_min_eff_kwh) * eta_discharge)`
465+
`restore_shortfall_up_kwh = max(0, required_restore_up_kwh_t - (soc_plan_up_t - soc_min_eff_kwh) * eta_discharge)`
450466
- Down-Verstoß-Defizit:
451-
`restore_shortfall_down_kwh = max(0, worst_down_kwh_t - (soc_max_eff_kwh - soc_plan_down_t) / eta_charge)`
467+
`restore_shortfall_down_kwh = max(0, required_restore_down_kwh_t - (soc_max_eff_kwh - soc_plan_down_t) / eta_charge)`
452468
- Verfügbare Wiederherstellungsleistung je Schritt:
453469
- Effektive Restore-Kapazität je Richtung berechnet sich per Coalesce:
454470
per-step Envelope-Override > Policy-Skalar > technischer Default.
@@ -581,8 +597,9 @@ Pflichtregeln:
581597
vorschlagen:
582598

583599
- Zuerst wird je Zeitfenster berechnet, ob eine Wiederherstellung je Richtung nötig ist:
584-
- `required_restore_up_kwh_t = coalesce(required_up_kwh_t, worst_up_kwh_t)`
585-
- `required_restore_down_kwh_t = coalesce(required_down_kwh_t, worst_down_kwh_t)`
600+
- `required_restore_up_kwh_t` und `required_restore_down_kwh_t` sind die
601+
bereits in der Gate-Entscheidungslogik verwendeten effektiven
602+
Restore-Bedarfe.
586603
- `scheduled_restore_up_kwh_t = max(0, required_restore_up_kwh_t - available_up_kwh_t)`
587604
- `scheduled_restore_down_kwh_t = max(0, required_restore_down_kwh_t - available_down_kwh_t)`
588605
- Vor der Berechnung gilt hart:

docs/plan/planning/open/plan-market-colocation-model.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,23 @@ Mögliche Domain-/Application-Erweiterungen:
286286

287287
- `LocalOriginState`
288288
- virtuelle Zwischenbilanz für herkunftsgebundene Energie (kWh)
289+
- `e_local_0` als Initialzustand der Herkunftsbilanz; Default `0`.
290+
Erforderlich, sobald `OriginConstraint` aktiv ist.
289291
- `e_local_t` je Zeitschritt
290292
- `eta_charge` (optional, default `1.0`)
291293
- `eta_discharge` (optional, default `1.0`)
292294
- Begrenzung via `local_origin_capacity_kwh`
293295
- Für `GreenStorageRestricted` muss `local_origin_capacity_kwh > 0` gelten.
294296
`local_origin_capacity_kwh=0` ist keine nutzbare Herkunftsbilanz und führt zu
295297
`CONFIG_INCONSISTENT` mit `format=kv1;reason=GREEN_STORAGE_ORIGIN_CAPACITY_ZERO`.
298+
- Für `ClassicalCoLocation`/`HybridWithGridImport` mit aktivem
299+
`OriginConstraint` gilt ebenfalls `local_origin_capacity_kwh > 0`; sonst
300+
ist die aktivierte Herkunftsbilanz inkonsistent
301+
(`CONFIG_INCONSISTENT`, `format=kv1;reason=ORIGIN_CAPACITY_ZERO`).
302+
Ohne aktiven `OriginConstraint` darf das Feld fehlen; `0` bedeutet nicht
303+
"unbounded", sondern "keine nutzbare Herkunftsbilanz".
304+
- Validierung: `0 <= e_local_0 <= local_origin_capacity_kwh`, wenn
305+
`OriginConstraint` aktiv ist.
296306
- Validierung (nur wenn von `1.0` abweichend): `eta_min <= eta_charge <= 1`
297307
und `eta_min <= eta_discharge <= 1`; `eta_min` ist die gemeinsame
298308
Assetmodell-Invariante aus dem Robustheitspfad
@@ -468,10 +478,12 @@ Rollback-/Backout-Verhalten:
468478
`unclear`/`incompatible` nicht freizuschalten.
469479
- Für Ausnahmeszenarien kann ein Release-Block oder eine kontrollierte Suspendierung gelten:
470480
- Release-Block: Freigabe bis Daten bereinigt sind.
471-
- Notfallmodus: optionaler Operator-Override nur für nicht-aktive Sites im Rahmen einer
472-
dokumentierten Wartungsfreigabe.
473-
- Nicht-aktive Sites sind im Notfallmodus mit `can_dispatch=false` explizit zu markieren;
474-
aktive Sites bleiben weiterhin hart blockiert.
481+
- Notfallmodus: optionaler Operator-Override nur für Sites, deren
482+
Aktivitätsbewertung aus dem aktuellen Request-Kontext nicht aktiv ist, im
483+
Rahmen einer dokumentierten Wartungsfreigabe.
484+
- Im Notfallmodus dürfen Sites, deren Aktivitätsbewertung nicht aktiv ist, mit
485+
`can_dispatch=false` modelliert werden; die Aktivitätsbewertung bleibt
486+
request-basiert. Aktive Sites bleiben weiterhin hart blockiert.
475487
- Keine stillschweigende „Best-Effort“-Auto-Ableitung in produktivem Requestbetrieb.
476488

477489
### GreenStorageRestricted-Regeln (MVP)
@@ -486,7 +498,8 @@ Rollback-/Backout-Verhalten:
486498
- `0 <= e_local_t <= local_origin_capacity_kwh`
487499
- `local_origin_capacity_kwh > 0`; `0` ist `CONFIG_INCONSISTENT` mit
488500
`format=kv1;reason=GREEN_STORAGE_ORIGIN_CAPACITY_ZERO`.
489-
- `e_local_0` ist konfigurierbar (meist 0).
501+
- `e_local_0` kommt aus `LocalOriginState` und muss in der konfigurierten
502+
Kapazität liegen.
490503
- Harte Koppelregeln:
491504
- `p_grid_import_t == 0` (für beide Site-Konventionen) – vollständiges Netzbezugsverbot.
492505
- `-b_t <= (g_t - c_t)` (Laden nur solange lokaler Überschuss vorliegt)
@@ -502,6 +515,7 @@ Fehlerklassifikation für `GreenStorageRestricted`:
502515
| Produktiv-Precheck | Produktiver Routine-Run ohne `green_storage_validation_mode=true` | `CONFIG_INVALID` | `GREEN_STORAGE_RESTRICTED_PRODUCTIVE_BLOCKED` |
503516
| Dispatch-Gate | `green_storage_validation_mode=true` ohne produktive Compliance-/Förderfreigabe | `CONFIG_INCONSISTENT` | `GREEN_STORAGE_RESTRICTED_VALIDATION_ONLY` |
504517
| Input-/Pre-Solver-Validierung | Fehlender oder nicht auditierbarer Herkunftsnachweis | `CONFIG_INCONSISTENT` | `GREEN_STORAGE_ORIGIN_PROOF_MISSING` |
518+
| Input-/Pre-Solver-Validierung | Aktivierter weicher Herkunftsnachweis ohne nutzbare Herkunftskapazität | `CONFIG_INCONSISTENT` | `ORIGIN_CAPACITY_ZERO` |
505519
| Input-/Pre-Solver-Validierung | Request fordert Netzladung oder modelliert Netzbezug als zulässige Ladequelle | `CONFIG_INCONSISTENT` | `GREEN_STORAGE_GRID_CHARGE_BLOCKED` |
506520
| Solver-Ergebnis | Harte Constraints (`p_grid_import_t == 0`, lokale Quelle, `e_local_t`) machen den angefragten Fahrplan mathematisch unerfüllbar | `MODEL_INFEASIBLE` | `GREEN_STORAGE_MODEL_INFEASIBLE` |
507521

@@ -603,6 +617,9 @@ Bestandsrouten nicht brechen:
603617
`local_origin_capacity_kwh`-Randfall (`0`, Minimalreserve) werden explizit geprüft;
604618
`local_origin_capacity_kwh=0` blockiert mit `CONFIG_INCONSISTENT` und
605619
`format=kv1;reason=GREEN_STORAGE_ORIGIN_CAPACITY_ZERO`.
620+
- Weicher `OriginConstraint` in `ClassicalCoLocation`/`HybridWithGridImport`
621+
mit `local_origin_capacity_kwh=0` blockiert mit `CONFIG_INCONSISTENT` und
622+
`format=kv1;reason=ORIGIN_CAPACITY_ZERO`.
606623
- `GreenStorageRestricted`: Lauf wird mit `CONFIG_INCONSISTENT` und
607624
`GREEN_STORAGE_GRID_CHARGE_BLOCKED` geblockt, wenn eine Netzladung
608625
(`p_grid_import_t > 0`) versucht wird.

docs/plan/planning/open/plan-price-forecast-adapters.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,12 @@ Einheitliche Adaptervertraege für Preis- und Forecastdaten:
227227
eigenen Flag-Wert, falls dieser später explizit eingeführt wird.
228228
3. **Cutover freigeben**: Neue Family wird produktiv als `primary` markiert und auf mindestens `SOURCE_OK` oder ausdrücklich zugelassene `SOURCE_DEGRADED` gesetzt.
229229
4. **Produktiver Umschaltpunkt**: Alte Family in produktiven Runs auf `SOURCE_REJECTED`/`CanExecute=false` halten; alte Werte sind nur noch Replay/Diagnose sichtbar.
230-
5. **Rollback-Fenster**: Rückkehr auf alte Family nur mit explizitem Release-Block möglich; Rollback ist nur dann erlaubt, wenn die neue Family in einem vollständigen Beobachtungsfenster keine vollständige akzeptierbare Lastserie (ohne harte Fallback) geliefert hat. Die Runbook-Marker `release_block` und `controlled_switchover` werden im Aktivierungs-Runbook definiert, inklusive Ablageort, Berechtigung und Löschregel.
230+
5. **Rollback-Fenster**: Rückkehr auf alte Family nur mit explizitem
231+
Release-Block möglich. Rollback ist nur zulässig, wenn die neue Family
232+
im Beobachtungsfenster die Lastserie nicht ohne harten Fallback
233+
akzeptierbar liefern konnte. Die Runbook-Marker `release_block` und
234+
`controlled_switchover` werden im Aktivierungs-Runbook definiert,
235+
inklusive Ablageort, Berechtigung und Löschregel.
231236
6. **Abschluss**: Alter Family-Schlüssel wird auf `ARCHIVED` gesetzt; neue Family läuft ohne Alias-Wechsel weiter.
232237
- Für einen stabilen Tie-Break werden bei gleicher Klasse numerisch zuerst
233238
`series_version` (wie definiert), danach nur bei unterschiedlichen, gültigen
@@ -333,6 +338,11 @@ Kanonische Ableitungsregeln (deterministisch):
333338
- Bei vorhandenem kompatiblem Fallback folgt die Fallback-Evaluierung.
334339
- Bei erfolgreichem Fallback: `series_status=SOURCE_FALLBACK_USED` oder
335340
`SOURCE_DEGRADED` je nach Backfill/Qualitätsminderung.
341+
Präzedenz bei kombinierten Ereignissen ist verbindlich:
342+
Qualitätsminderung schlägt Fallback. Wenn Fallback und Backfill bzw. andere
343+
Degradation zugleich auftreten, ist `series_status=SOURCE_DEGRADED` und
344+
`status_flags` enthält mindestens `SOURCE_FALLBACK_USED` und den
345+
Degradationsflag, z. B. `SOURCE_BACKFILL`.
336346
- Bei fehlendem kompatiblen Fallback: harte Abweisung außer im `degraded_ok`-Modus
337347
für `SOURCE_STALE` (-> `SOURCE_DEGRADED`).
338348
- `source_eval_status=SOURCE_TRANSITIONAL_INPUT`:
@@ -430,9 +440,12 @@ Empfohlene Integrationskonvention (API/Operator):
430440
genau 1. Diese Rundungsregel ist bewusst konservativ und ersetzt
431441
horizon-spezifische Magic Numbers.
432442
Operative Folge: Bei typischen 24-h-/15-min-Horizonten greift Backfill wegen
433-
dieser Mindestabdeckung praktisch nicht; Backfill ist erst bei längeren
434-
Horizonten oder explizit konfigurierter niedrigerer Mindestabdeckung im
435-
`quality_mode=degraded_ok` wirksam.
443+
dieser Mindestabdeckung praktisch nicht. Das ist im Default gewollt:
444+
Backfill ist nur bei längeren Horizonten oder explizit konfigurierter
445+
niedrigerer Mindestabdeckung im `quality_mode=degraded_ok` aktiv. Tests für
446+
`SOURCE_BACKFILL` müssen deshalb entweder einen längeren Horizon oder eine
447+
explizit abgesenkte `min_coverage_ratio` verwenden; ein typischer
448+
24-h-/15-min-Defaulttest erwartet keinen Backfill.
436449
- Die konsolidierte konsumierbare Serie muss nach Backfill keine offenen Lücken mehr enthalten.
437450
- Lückenregime:
438451
- Rohdaten mit Lücken vor Backfill sind nur zulässig, solange

0 commit comments

Comments
 (0)