193 lines
6.5 KiB
Markdown
193 lines
6.5 KiB
Markdown
# Phase 13.6 — Hardening Closure (FORMAL CLOSURE)
|
|
|
|
**Status:** CLOSED / DEPLOYED / VERIFIED
|
|
**Datum:** 01.09.2026
|
|
**Autor:** Rain Ocampo (Hermes) / Red Queen
|
|
**Freigabe:** Christian List (Owner)
|
|
|
|
---
|
|
|
|
## 1. Scope
|
|
|
|
Phase 13.6 umfasst die produktive Härtung des Historical-Service:
|
|
|
|
- **Korrigierter TOCTOU-Befund** (Dataset-Version)
|
|
- **Dataset-Version-Repair** (repository.py)
|
|
- **TrustGate Defense-in-Depth**
|
|
- **Legacy Entry-Point Hardening**
|
|
- **Schema-Entscheidung** (keine Migration nötig)
|
|
|
|
Phase 13.6 ist bereits erfolgreich produktiv deployed und verifiziert. Diese Mission persistiert ausschließlich die verifizierte Abschlussdokumentation in der autoritativen Git-Historie. **KEINE Trading-/Runtime-Änderung.**
|
|
|
|
---
|
|
|
|
## 2. Korrigierter TOCTOU-Befund
|
|
|
|
**Ursprünglicher Befund (Phase 13.5, Deferred Risk #2):** `get_or_create_dataset_version` ohne UNIQUE auf Hash → potenzielle doppelte Dataset-Version-Metadaten bei parallelen identischen Requests.
|
|
|
|
**Korrigierte Analyse:** `dataset_version_hash` hatte bereits UNIQUE-Schutz. Der tatsächliche Defekt war ein **SELECT→INSERT-Concurrency-Race**, das eine `UniqueViolation` werfen konnte (nicht doppelte Zeilen).
|
|
|
|
---
|
|
|
|
## 3. Dataset-Version-Repair (repository.py)
|
|
|
|
Repair in `app/persistence/repository.py` (Image-SHA `33cca6421a595c68a12bf6b25eb02b47edf868fb27501330e356de2c0c3a7bd6`):
|
|
|
|
- `pg_advisory_xact_lock(dataset_id)` — serialisiert konkurrierende Requests pro Dataset
|
|
- `ON CONFLICT(dataset_version_hash) DO NOTHING RETURNING` — idempotenter Insert
|
|
- kanonischer Re-SELECT nach Konflikt
|
|
- deterministische kanonische ID
|
|
- fail-closed bei ambigem/Fehlerzustand
|
|
|
|
**Concurrency-Validierung:**
|
|
- Baseline Gold x10: 3 OK, 7 UniqueViolation, 1 row
|
|
- Patched x10: 10/10 OK, gleiche kanonische ID, 1 row
|
|
|
|
---
|
|
|
|
## 4. TrustGate Defense-in-Depth
|
|
|
|
- Fehlender TrustGate auf produktionsfähigem Pfad: **FAIL CLOSED**
|
|
- UNKNOWN / UNTRUSTED / CONDITIONAL (Default) / MISSING / EXCEPTION: **BLOCK**
|
|
- Nur TRUSTED (oder CONDITIONAL mit expliziter Policy) persistierbar
|
|
|
|
---
|
|
|
|
## 5. Legacy Entry-Point Hardening
|
|
|
|
- `run_backfill.py`: HARD-FAIL (non-zero exit, kein Provider/Persistence-Continuation)
|
|
- `run_phase11_pilot.py`: HARD-FAIL (non-zero exit, kein Provider/Persistence-Continuation)
|
|
|
|
---
|
|
|
|
## 6. Schema-Entscheidung
|
|
|
|
**SCHEMA MIGRATION = NOT REQUIRED.** Bestehendes `UNIQUE(dataset_version_hash)` bleibt erhalten.
|
|
|
|
---
|
|
|
|
## 7. Production DB Precheck
|
|
|
|
- UNIQUE existiert: **JA**
|
|
- duplicates: **0**
|
|
- NULL anomalies: **0**
|
|
- FK anomalies: **0**
|
|
- dataset_version: **336**
|
|
|
|
---
|
|
|
|
## 8. Candidate Image / Build Provenance
|
|
|
|
| Feld | Wert |
|
|
|---|---|
|
|
| Image ID | `sha256:21598a3597cfd53c4bc22c01cb7f7874259878ecd7608528ccd6327305ea07fc` |
|
|
| Tag | `historical-v2-historical-service:candidate-phase13-6-hardening` |
|
|
| Build Input SHA | `f45e4885…` (nur gekürzt in Evidence verfügbar) |
|
|
| Archive SHA | `92a9982a212e1f7576305aa765f3c0163812a486f0afb64cb1dd58ba5b55f0c5` |
|
|
| Pin | `rq-historical-pin-phase13-6-hardening` |
|
|
| Status | **VERIFIED + ARCHIVED + PINNED = READY** |
|
|
|
|
---
|
|
|
|
## 9. Production Deployment
|
|
|
|
| Feld | Wert |
|
|
|---|---|
|
|
| Source | Phase-13.5 Remediation `sha256:f72b27e72fc6418edde5810090dad62538f2f85903424992691d79cfc69b8884` |
|
|
| Target | Phase-13.6 `sha256:21598a3597cfd53c4bc22c01cb7f7874259878ecd7608528ccd6327305ea07fc` |
|
|
| Real Recreate Count | **1** |
|
|
| Exit Code | **0** |
|
|
| Container (nach) | `d274568ae85173b408531315e7a51aa9fd54b0587931d8c662548736b154313b` |
|
|
| running / RestartCount | `true` / `0` |
|
|
| health / ready | `200` / `200` |
|
|
|
|
---
|
|
|
|
## 10. Target Manifest
|
|
|
|
- **58** Gold/unchanged matches
|
|
- **5** autorisierte Divergenzen:
|
|
1. `run_backfill_year.py` — bestehende Phase-13.5-Autorisierung (Runner `6cca3c55bb559d75be2f58e59c231003902f124a54ada25582970524599f0752`)
|
|
2. `repository.py` — `33cca6421a595c68a12bf6b25eb02b47edf868fb27501330e356de2c0c3a7bd6`
|
|
3. `backfill.py` — `fb93ee1f09b3708eae155b12df1b8a1103ea7c0a4a6aea70c476fd544d58ac0e`
|
|
4. `run_backfill.py` — `79ee38fd51cf3f92550997cab2ffd6700468d4d7b3921ca97bbc7a38d6a8f383`
|
|
5. `run_phase11_pilot.py` — `34e345a951a92eecfa8418ae078e30d9fef24c5ef2043dc0b194b064f84cf551`
|
|
- unauthorized: **0**
|
|
- missing: **0**
|
|
- extra: **0**
|
|
|
|
---
|
|
|
|
## 11. Rollback Control Plane
|
|
|
|
- Historischer Gold-Anker `1f3ba210…` ist unverfügbar (Coolify-GC, kein SHA-verifiziertes docker-save-Archiv).
|
|
- Bewiesen: `1f3ba210…` war ein **stale/wrong-target pre-gate** für den Remediation-Rollback (SOURCE-state/historische Referenz, NICHT Rollback-TARGET-Requirement).
|
|
- **Kein Fake/Retag/Rebuild** von `1f3ba210…` durchgeführt.
|
|
- Primary Rollback zielt/verifiziert jetzt exakt auf den Phase-13.5-Remediation-Target.
|
|
- Direct no-op bleibt **FAIL CLOSED**.
|
|
- Primary Rollback dry-run: **PASS**
|
|
- Secondary Recovery Rollback dry-run: **PASS**
|
|
|
|
---
|
|
|
|
## 12. Production DB Integrity
|
|
|
|
- dataset_version: **336 → 336**
|
|
- duplicates: **0 → 0**
|
|
- NULL anomalies: **0 → 0**
|
|
- FK anomalies: **0**
|
|
- **Keine produktiven DB-Writes durch den Deployment.**
|
|
|
|
---
|
|
|
|
## 13. Mutation Accounting
|
|
|
|
| Mutation | Anzahl |
|
|
|---|---|
|
|
| Wrapper Target-Class Deploy | 1 |
|
|
| Rollback Control-Plane Wrapper Patch | 1 |
|
|
| Production Recreate | 1 |
|
|
| Production DB Write | 0 |
|
|
| Schema | 0 |
|
|
| Backfill | 0 |
|
|
| Provider | 0 |
|
|
| Rollback | 0 |
|
|
| Phase 14 | 0 |
|
|
|
|
---
|
|
|
|
## 14. Security Invariants
|
|
|
|
- TrustGate fail-closed auf produktionsfähigem Pfad: **PASS**
|
|
- Legacy Entry-Points (`run_backfill.py`, `run_phase11_pilot.py`): **HARD-FAIL**
|
|
- Kein Runner/Backfill aktiv
|
|
- Keine produktiven DB-Writes
|
|
|
|
---
|
|
|
|
## 15. Deferred Work (NICHT durch Phase 13.6 autorisiert/gelöst)
|
|
|
|
Phase 13.6 autorisiert oder löst NICHT:
|
|
|
|
- **kein produktiver Historical Backfill** ausgeführt
|
|
- **kein Trusted Historical Provider** ausgewählt
|
|
- **kein Trusted Provider Pilot** ausgeführt
|
|
- **keine Provider/Provenance-Acceptance** abgeschlossen
|
|
- **kein Phase 14**
|
|
- **keine Live-Capital/Trading-Aktivierung**
|
|
|
|
Der nächste große Workstream bleibt separat.
|
|
|
|
---
|
|
|
|
## 16. Final Closure Statement
|
|
|
|
> **PHASE 13.6 CLOSED — DEPLOYED — VERIFIED — DOCUMENTED — FAST-FORWARD PUSHED — REMOTE SOT PERSISTED — RUNTIME UNCHANGED**
|
|
|
|
Phase 13.6 ist formal geschlossen. Die autoritative Closure-Evidence wurde in Red-Queen-/Rain-Ocampo-Ausführungskontext erzeugt und verifiziert:
|
|
|
|
- `/opt/data/rq_phase136_repair/` (Primary Rollback Control-Plane Repair)
|
|
- `/opt/data/rq_phase136_owner_verify/` (Owner Candidate Verification)
|
|
- `/opt/data/rq_phase136_deployment/` (Controlled Deployment)
|
|
|
|
**Git-Baseline vor dieser Closure:** `51c03f7ade49db263f4908b087418ec92979e4e6` (`phase13.5: formally close runner trustgate remediation`).
|