diff --git a/docs/clinical-scoring-refactor-summary.md b/docs/clinical-scoring-refactor-summary.md new file mode 100644 index 0000000..57d3175 --- /dev/null +++ b/docs/clinical-scoring-refactor-summary.md @@ -0,0 +1,281 @@ +# VigilCare Clinical — Roadmap Summary for Clinical Review + +This document summarizes all planned changes to VigilCare's clinical monitoring system across two major initiatives: a **clinical scoring refactor** (based on your feedback) and a **climate resilience** architecture for ward-level reliability during network outages. + +--- + +# Part 1 — Clinical Scoring Refactor (Phases 25–29) + +Based on your feedback, we're aligning the system with modern sepsis guidelines (Sepsis-3) and adding more granular consciousness assessment. + +## What's Changing + +### 1. Replacing SIRS with Full SOFA for Sepsis Detection + +**Current system:** Uses SIRS criteria (temperature, heart rate, respiratory rate, WBC count — 2 of 4 met = sepsis warning). As you noted, this is too non-specific — a patient with a mild cold or post-exercise can trigger it. + +**New system:** Full SOFA score across six organ systems, each scored 0–4 (total 0–24): + +| Organ System | What We Measure | Score 0 (Normal) | Score 4 (Severe) | +|---|---|---|---| +| **Respiratory** | PaO2/FiO2 ratio (or SpO2/FiO2 if no ABG) | ≥ 400 | < 100 with ventilation | +| **Coagulation** | Platelet count | ≥ 150 k/µL | < 20 k/µL | +| **Liver** | Bilirubin | < 1.2 mg/dL | > 12 mg/dL | +| **Cardiovascular** | MAP + vasopressor requirement | MAP ≥ 70, no pressors | High-dose pressors | +| **Neurological** | Glasgow Coma Scale | GCS 15 | GCS < 6 | +| **Renal** | Creatinine / urine output | Cr < 1.2 mg/dL | Cr > 5.0 or UO < 200 mL/day | + +**Sepsis definition:** A rise of ≥ 2 points from the patient's baseline SOFA score in the presence of suspected infection triggers a sepsis alert and activates the hour-1 treatment bundle (blood cultures, lactate, antibiotics, IV fluids). + +**Handling lab gaps:** Lab values (platelets, bilirubin, creatinine, PaO2) aren't continuously available. The system carries forward the most recent value for up to 24 hours, and flags when data is getting stale (> 12 hours old) so clinicians know the score may be based on older labs. When no arterial blood gas is available (common on general wards), the system uses the SpO2/FiO2 ratio as a proxy for the respiratory component. + +--- + +### 2. Adding Glasgow Coma Scale + +**Current system:** Uses AVPU (Alert / Voice / Pain / Unresponsive) — a 4-level scale that loses significant clinical detail. + +**New system:** Full GCS with three separately entered components: + +| Component | Scale | Labels | +|---|---|---| +| **Eye Response (E)** | 1–4 | No opening → Spontaneous | +| **Verbal Response (V)** | 1–5 | None → Oriented | +| **Motor Response (M)** | 1–6 | None → Obeys commands | +| **Total** | 3–15 | Computed from E + V + M | + +**Why three separate inputs:** A GCS of 9 from E2/V3/M4 tells a different clinical story than E3/V2/M4. The component breakdown is more informative for tracking which aspect of consciousness is changing. + +**GCS feeds into three systems:** +- **SOFA** — neurological organ score (GCS 15 = 0, GCS 13–14 = 1, GCS 10–12 = 2, GCS 6–9 = 3, GCS < 6 = 4) +- **NEWS2** — consciousness parameter (GCS 15 = score 0, any GCS < 15 = score 3) +- **Standalone alerts** — GCS ≤ 8 triggers a critical alert; GCS 9–12 triggers a warning + +The system still accepts AVPU for backward compatibility, but GCS is the preferred input going forward. + +--- + +### 3. Keeping qSOFA as a Bedside Screening Tool + +**Current system:** qSOFA ≥ 2 fires as a critical sepsis alert and triggers the treatment bundle — same weight as SIRS. + +**New system:** qSOFA ≥ 2 creates a **screening recommendation** (warning level, not critical) that says: *"qSOFA screen positive — recommend ordering SOFA labs (PaO2/FiO2, platelets, bilirubin, creatinine) to evaluate for organ dysfunction."* + +qSOFA no longer triggers the sepsis bundle directly. Only a confirmed SOFA delta ≥ 2 does. + +**The clinical workflow becomes:** + +``` +Bedside screening (qSOFA ≥ 2) + ↓ +"Order SOFA labs" recommendation + ↓ +Labs return → SOFA score computed + ↓ +SOFA delta ≥ 2 from baseline → Sepsis confirmed → Hour-1 bundle activated +``` + +This matches the Sepsis-3 two-tier approach: quick bedside screen → lab-confirmed organ dysfunction. + +--- + +### 4. Separating Deterioration Detection from Sepsis + +The system has two independent deterioration engines that remain unchanged: + +- **NEWS2** (National Early Warning Score 2) — 7-parameter composite score for general patient deterioration. Score ≥ 7 = emergency, score 5–6 = warning. This is the broad safety net. +- **Trend detection** — velocity-based alerting that catches rapid changes even when values are still in the normal range (e.g., heart rate rising from 72 to 95 in 30 minutes). + +These are now cleanly separated from the sepsis engine. A patient can deteriorate without being septic (and vice versa). + +--- + +## What Stays the Same + +- **Critical threshold alerts** — single-value breaches (e.g., potassium > 6.5 mEq/L) still fire immediately within the observation recording transaction. These are the fastest safety net. +- **Sepsis bundle** — same four elements (blood cultures, serum lactate, antibiotics, IV fluids) with the same one-hour compliance deadline. Only the trigger changes (SOFA instead of SIRS). +- **Alert acknowledgment and escalation** — same workflow. Unacknowledged critical alerts escalate after 5 minutes. +- **NEWS2 scoring** — same 7 parameters, same risk levels. Only change: consciousness input prefers GCS over AVPU. + +--- + +## New Data the System Will Need + +These are the new observations the system will accept (in addition to the 12 it already tracks): + +| Observation | Unit | Typical Source | How Often | +|---|---|---|---| +| GCS Eye Response | 1–4 | Nurse assessment | Every 1–4 hours (neuro checks) | +| GCS Verbal Response | 1–5 | Nurse assessment | Every 1–4 hours | +| GCS Motor Response | 1–6 | Nurse assessment | Every 1–4 hours | +| PaO2 | mmHg | ABG lab result | Every 4–12 hours (ICU) | +| FiO2 | % | Ventilator / manual | With each O2 change | +| Platelet Count | k/µL | CBC lab result | Every 6–24 hours | +| Total Bilirubin | mg/dL | CMP/hepatic panel | Every 12–24 hours | +| Serum Creatinine | mg/dL | BMP/CMP lab result | Every 6–24 hours | +| Urine Output | mL/h | Nursing I&O | Every 1–4 hours | + +The cardiovascular SOFA component also reads vasopressor data from the medication administration record (drug name and dose for dopamine, dobutamine, epinephrine, norepinephrine). + +--- + +## Implementation Order + +| Phase | What Gets Built | Clinical Capability Added | +|---|---|---| +| **25** | GCS scoring engine | 3-component consciousness assessment; feeds NEWS2 + qSOFA | +| **26** | Full SOFA scoring engine | 6-organ-system scoring with baseline tracking and delta detection | +| **27** | Sepsis engine refactor | SIRS removed; qSOFA becomes screening; bundle triggered by SOFA | +| **28** | Dashboard updates | GCS entry form, SOFA display panel, updated alert labels | +| **29** | Scenario validation | Realistic patient scenarios testing the full pathway end-to-end | + +After these five phases, the system moves on to climate resilience (phases 20–24). + +--- + +# Part 2 — Climate Resilience: Ward Gateway Architecture (Phases 20–24) + +This initiative addresses a real-world hospital problem: **what happens to patient monitoring when the network goes down?** + +Currently, the entire system runs on a central server. If the connection between a ward and the server room is disrupted — construction, a storm, a router failure — the ward loses all clinical alerting. Nurses would have no automated safety net until connectivity is restored. + +## The Problem + +In a typical hospital deployment, bedside monitors and nurse workstations on the ward send data over the hospital network to a central server that runs all the scoring and alerting. This works well under normal conditions, but the network path from an ICU ward to the server room is a single point of failure. If that link goes down: + +- Critical lab values (e.g., potassium 6.8 mEq/L) generate **no alerts** +- Nurses have no automated warning system +- All observations recorded during the outage are **lost** until someone notices + +## The Solution: A Local Ward Server + +We place a small server on each ward (in the nurse station or equipment room) that can run independently when the central server is unreachable. + +**When the network is healthy (normal operation):** + +``` +Bedside Monitor → Ward Server → Central Server + ↓ + Full scoring (SOFA, NEWS2, trend analysis) + Sepsis bundle tracking + Analytics and reporting +``` + +The ward server passes everything through to central. It's essentially transparent. + +**When the network is down (degraded mode):** + +``` +Bedside Monitor → Ward Server (runs locally) + ↓ + Critical threshold alerts (potassium, glucose, etc.) + Warning threshold alerts + Local paging to charge nurse + All data buffered for later sync +``` + +The ward server handles the most time-sensitive safety checks on its own. A nurse entering a potassium of 6.8 will still get an immediate critical alert, even if the central server is completely unreachable. + +**When the network comes back:** + +``` +Ward Server → Central Server + ↓ + Buffered observations replayed + SOFA/NEWS2/trend catch up with correct timestamps + Alerts reconciled (no duplicate pages) + Audit trail complete — no gaps +``` + +All the data recorded during the outage syncs to central. The scoring engines (SOFA, NEWS2, trend) process the backlog with the original timestamps so the clinical timeline is accurate. + +## What Runs Locally vs. What Waits for Central + +| Capability | Runs on Ward Server? | Why | +|---|---|---| +| **Critical threshold alerts** (e.g., K+ > 6.5) | Yes | Life-safety — cannot wait for network | +| **Warning threshold alerts** (e.g., HR 105) | Yes | Important clinical awareness | +| **Nurse paging + escalation** | Yes (local) | Must work during outage | +| **Observation recording** | Yes (buffered) | No data loss | +| **Alert acknowledge / resolve** | Yes (local) | Nurses must be able to act | +| SOFA scoring | No — central only | Requires lab pipeline and multi-organ state | +| NEWS2 composite scoring | No — central only | Complex multi-parameter; catches up after sync | +| Trend / velocity detection | No — central only | Needs history window that spans outages | +| Sepsis bundle tracking | No — central only | Depends on SOFA and order management | +| Analytics and reporting | No — central only | Not time-critical | + +**The trade-off is intentional:** composite scores (SOFA, NEWS2) lag during an outage, but single-value critical breaches — the most immediately dangerous situations — still fire locally. A potassium of 6.8 doesn't need a composite score to be dangerous. + +## What the Dashboard Shows During an Outage + +When the ward dashboard is connected to the local ward server instead of central: + +- An **amber banner** appears: *"Central sync paused — ward operating in local mode. Alerts and documentation on this ward remain active."* +- Vital signs, critical/warning alerts, and acknowledge/resolve actions all work normally +- SOFA score, NEWS2 history, and sepsis bundle panels show *"Central connection required"* +- Once connectivity returns, the banner clears and full scoring catches up + +## Operations Visibility + +Hospital IT staff get a fleet management view showing: + +| Gateway | Department | Status | Buffer | Last Sync | +|---|---|---|---|---| +| GW-ICU-3B | ICU | ONLINE | 0 | 2 min ago | +| GW-ICU-1A | ICU | DEGRADED | 847 | 45 min ago | +| GW-GM-8B | Gen Med | OFFLINE | 1,240 | 3 hrs ago | + +This lets IT know which wards are operating in degraded mode and how much data is waiting to sync. + +## Implementation Order + +| Phase | What Gets Built | Clinical Capability Added | +|---|---|---| +| **20** | Site & gateway registry | Central server knows about each ward server; secure communication | +| **21** | Ward gateway service | Local observation recording, critical alerts, nurse paging during outage | +| **22** | Sync batch engine | Buffered data replays to central when network returns; no duplicates | +| **23** | Operations visibility | IT dashboard for fleet health; degraded mode banner for clinicians | +| **24** | Resilience verification | Chaos testing — intentionally break the network to prove it works | + +## What the Hospital Needs to Provide + +The ward gateway architecture requires: + +- **A small server on each ward** (can be a mini PC or rack-mount) with UPS battery backup +- **Local network infrastructure** — the ward LAN must work independently of the uplink to the server room +- **Clinical policy** for local-only mode — who is responsible for escalation when composite scores are unavailable + +The system handles everything else: automatic failover, data buffering, reconciliation, and audit trail preservation. + +--- + +# Overall Implementation Timeline + +| Order | Phases | Initiative | Summary | +|---|---|---|---| +| **First** | 25–29 | Clinical scoring refactor | SOFA replaces SIRS, GCS added, qSOFA becomes screening | +| **Second** | 20–24 | Climate resilience | Ward gateway keeps critical alerting alive during outages | + +--- + +## Questions for Your Review + +### Clinical Scoring (Phases 25–29) + +1. **SOFA baseline timing:** We establish the baseline SOFA when at least 4 of 6 organ systems have lab data. Does this threshold make clinical sense, or should we require all 6? + +2. **Lab staleness window:** We carry forward lab values for up to 24 hours before considering them expired. Is 24 hours reasonable for ICU patients? Should it differ for ward patients? + +3. **SpO2/FiO2 fallback:** When no ABG is available, we use SpO2/FiO2 as a proxy for the respiratory SOFA component. Are you comfortable with this approximation for ward-level monitoring? + +4. **GCS alert thresholds:** We alert at GCS ≤ 8 (critical) and GCS 9–12 (warning). Do these cutoffs match your clinical expectations? + +5. **qSOFA screening level:** We changed qSOFA from CRITICAL to WARNING severity. Should a positive qSOFA screen still page the physician, or just appear on the dashboard for the next review? + +### Climate Resilience (Phases 20–24) + +6. **Local-only scoring scope:** During a network outage, the ward server runs critical and warning threshold alerts only (e.g., potassium > 6.5, heart rate > 150). Composite scores (SOFA, NEWS2) wait for central to catch up after reconnection. Is this acceptable, or are there specific composite alerts you'd want running locally? + +7. **Degraded mode clinical policy:** When the ward is in local-only mode, composite scores are unavailable. Should the system display a specific clinical guidance message (e.g., "Increase manual assessment frequency") or just indicate that scoring is offline? + +8. **Sync reconciliation:** When buffered data syncs back to central, the scoring engines replay everything with the original timestamps. Is there clinical value in flagging these "retroactively computed" scores differently from real-time ones? diff --git a/docs/ext-climate-resilience-roadmap.md b/docs/ext-climate-resilience-roadmap.md new file mode 100644 index 0000000..dbdd845 --- /dev/null +++ b/docs/ext-climate-resilience-roadmap.md @@ -0,0 +1,210 @@ +# VigilCare Clinical — Climate Resilience Extension Roadmap + +**Internal document | Phases 20–24 | June 2026** + +**Prerequisites:** Phases 1–19 complete — full clinical CDSS pipeline, ward dashboard, simulator, and clinician feedback mode. + +**Reference implementation:** POS System API Phase 10 ([phase-10-plan.md](../PosAPI/phase-10-plan.md)) — offline batch upload, async processor, two-layer idempotency, partial conflict model. + +--- + +## Problem Statement + +Hospital clinical monitoring assumes reliable connectivity between the ward, the hospital datacenter, and any cloud-hosted central services. Climate and infrastructure shocks break that assumption: + +| Scenario | What fails | Clinical risk | +|---|---|---| +| Ward WiFi outage | Central API unreachable from bedside | Alerts never reach the ward dashboard | +| Hospital uplink loss (typhoon, fiber cut) | Central VigilCare unreachable for hours | Same — cloud-dependent alerting stops | +| Regional cloud outage | Central stack down | Population analytics lost; ward safety at risk if ward depends on cloud | +| Power blip (UPS handoff) | Gateway host restart | Buffered events lost if not persisted locally | +| Post-disaster partial recovery | Intermittent connectivity | Duplicate alerts or lost audit trail on sloppy sync | + +VigilCare Phases 1–19 run as a **central** clinical backend. Observations ingest to PostgreSQL, fan out through Kafka, and drive alerting, scoring, and archival. That architecture is correct when the network is healthy. It is not sufficient when the ward must operate alone for typhoon-length outages. + +**Climate resilience** means: **Tier 1 patient safety runs at the ward even when central is unreachable; Tier 3 analytics and archival catch up idempotently when connectivity returns.** + +This extension does not change the clinical domain (hospital wards, sepsis bundles, NEWS2). It adds a **ward-first deployment model**. + +--- + +## Design Principle — Three Tiers + +| Tier | Responsibility | Runs where | Must work offline? | +|---|---|---|---| +| **Tier 1 — Safety** | Critical + warning threshold alerts, ack/resolve, local paging, ward dashboard reads | `VigilCare.WardGateway` | **Yes** | +| **Tier 2 — Reconciliation** | Buffered event upload, idempotent apply, conflict reporting | Gateway → central sync API | On reconnect | +| **Tier 3 — Analytics** | NEWS2, SIRS, qSOFA, trend, sepsis bundle, Elasticsearch, Parquet | Central `VigilCareClinicalAPI` | No — replays after sync | + +**Invariant (carry into every phase plan):** Append-only observations, synchronous critical / asynchronous warning split, idempotency keys, DLQ escalation — same rules as Phases 1–19. The gateway is not a different clinical system; it is a **degraded-mode replica** of the hot path. + +--- + +## Target Architecture + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ Ward (UPS-backed server) — VigilCare.WardGateway │ +│ ┌──────────────┐ ┌─────────────────┐ ┌──────────────────────────┐ │ +│ │ Local ingest │→ │ Critical+warning│→ │ Local RabbitMQ paging │ │ +│ │ + idempotency│ │ eval (Tier 1) │ │ + DLQ escalation │ │ +│ └──────────────┘ └─────────────────┘ └──────────────────────────┘ │ +│ │ │ │ │ +│ └────────────────────┴──────────────────────┘ │ +│ │ │ +│ ┌─────────▼─────────┐ │ +│ │ Local PostgreSQL │ │ +│ │ + sync buffer │ │ +│ └─────────┬─────────┘ │ +└──────────────────────────────┼──────────────────────────────────────────┘ + │ POST /sync/batches (when link up) +┌──────────────────────────────▼──────────────────────────────────────────┐ +│ Central — VigilCareClinicalAPI │ +│ ClinicalSyncBatchProcessor → ObservationService → outbox → Kafka │ +│ → NEWS2 / SIRS / qSOFA / trend / ES / Parquet (Tier 3 replay) │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Phase Map + +| Phase | Name | Deliverable | +|---|---|---| +| **20** | Site & Gateway Registry | `ClinicalSite`, `WardGateway`, API key auth, `VigilCare.ClinicalContracts` sync DTOs | +| **21** | Ward Gateway Service | New `VigilCare.WardGateway` project — local ingest, Tier 1 eval, buffer, local paging | +| **22** | Clinical Sync Batch Engine | Central batch upload + `ClinicalSyncBatchProcessor` (POS Phase 10 adapted) | +| **23** | Degraded Operations Visibility | Ops fleet APIs, dashboard ops view, Grafana panels, partition demo script | +| **24** | Climate Resilience Verification | Outage scenario, 6 chaos experiments, interview Q&A, verify script | + +### Dependency graph + +``` +Phase 20 (registry + contracts) + ├── Phase 21 (ward gateway service) + └── Phase 22 (central sync engine) + ├── Phase 23 (ops visibility) + └── Phase 24 (verification) +``` + +Implementation order: **20 → 21 → 22 → 23 → 24**. Phase plans for 21 and 22 can be drafted in parallel once Phase 20 defines the sync contract. + +--- + +## Sync Payload Contract (summary) + +Shared types live in **`VigilCare.ClinicalContracts`** (class library referenced by central API and WardGateway). Full field definitions in [phase-20-plan.md](phase-20-plan.md) Step 6. + +```json +{ + "batchReference": "550e8400-e29b-41d4-a716-446655440000", + "gatewayId": "...", + "siteId": "...", + "capturedAtUtc": "2026-06-20T14:30:00Z", + "observations": [ + { + "clientRef": "...", + "idempotencyKey": "device-retry-key-001", + "encounterId": "...", + "observationCode": "HEART_RATE", + "value": 118, + "recordedAt": "2026-06-20T14:28:00Z", + "source": "bedside_monitor" + } + ], + "alertEvents": [ + { + "clientAlertId": "...", + "encounterId": "...", + "alertType": "CRITICAL_HEART_RATE", + "severity": "CRITICAL", + "details": "...", + "generatedAt": "2026-06-20T14:28:01Z" + } + ], + "alertAcknowledgments": [ + { + "clientRef": "...", + "clientAlertId": "...", + "clinicianId": "RN-Smith", + "acknowledgedAt": "2026-06-20T14:29:00Z", + "note": "At bedside" + } + ] +} +``` + +**Replay order inside batch processor:** observations → alert events → acknowledgments → resolve events. Ack before alert in the same batch → `ClinicalSyncConflict` with reason `ALERT_NOT_YET_SYNCED`. + +**Idempotency layers (mirror POS):** + +1. Batch level — unique index on `batch_reference`; re-upload returns existing batch. +2. Item level — observation `idempotency_key`; alert `client_alert_id`; silent skip on duplicate. + +--- + +## What Is Explicitly Out of Scope + +Defer to [vigilcare-clinical-roadmap.md](vigilcare-clinical-roadmap.md): + +- FHIR read endpoints, real notification channels (SMS/Twilio), department-specific threshold configuration +- Full local NEWS2 / SIRS / qSOFA / trend / sepsis bundle on the gateway (central Kafka replay after sync instead) +- HIPAA / TFDA certification language +- Home / infant monitoring domain pivots + +--- + +## Interview Talking Points + +**"How is this different from just running VigilCare in the hospital datacenter?"** + +Datacenter deployment still fails when the **ward-to-datacenter link** fails — common during typhoons, construction, or router failures. The gateway colocates Tier 1 safety with the ward LAN. Central adds cross-ward analytics when available. + +**"Why not run everything locally and skip central?"** + +NEWS2 composite scoring, SIRS window state, sepsis bundle compliance, Elasticsearch population views, and Parquet regulatory archival require the full Kafka multi-consumer pipeline. Duplicating that on every ward gateway is operationally expensive. The split is: **safety local, intelligence central**. + +**"How do you prevent duplicate critical pages after reconnect?"** + +Observation and alert idempotency keys survive the sync boundary. The batch processor silently skips items already applied. Alert events use `client_alert_id` — if central already has the alert from a partial sync, no second RabbitMQ page fires. + +**"What happens if a nurse acknowledges an alert locally but central never receives it?"** + +The acknowledgment is buffered. On sync, it applies to the matching alert by `client_alert_id`. If central never receives it (gateway lost before sync), the reconciliation job (Phase 7) still flags unacknowledged critical alerts on central — but during outage, **local** escalation (DLQ) is authoritative. Ops dashboard (Phase 23) shows buffer depth so IT knows reconciliation is pending. + +**"How does this relate to POS offline sync?"** + +Same pattern: edge node buffers writes, uploads batch with `batchReference`, central applies idempotently with partial conflicts, async processor via outbox + RabbitMQ. POS conflicts are inventory; clinical conflicts are ordering dependencies (ack before alert) or duplicate device retries. + +--- + +## Document Index + +| Document | Purpose | +|---|---| +| [phase-20-plan.md](phase-20-plan.md) | Site/gateway registry + shared contracts | +| [phase-21-plan.md](phase-21-plan.md) | Ward gateway service | +| [phase-22-plan.md](phase-22-plan.md) | Central sync batch engine | +| [phase-23-plan.md](phase-23-plan.md) | Ops visibility + dashboard | +| [phase-24-plan.md](phase-24-plan.md) | Verification suite | +| [resilience-learning-plan.md](../../resilience-learning-plan.md) | Chaos experiment methodology | + +--- + +*After Phase 24, the portfolio claim becomes: "Clinical monitoring that continues during ward isolation and reconciles honestly when the link returns — with measured failure-mode evidence."* + +--- + +## Verification Checklist (Phase 24) + +Documentation complete when: + +- [ ] Phase plans 20–24 written ([phase-20-plan.md](phase-20-plan.md) … [phase-24-plan.md](phase-24-plan.md)) +- [ ] [ward-outage-reconnect-01.json](scenarios/ward-outage-reconnect-01.json) scenario present +- [ ] [resilience/README.md](resilience/README.md) experiment index populated +- [ ] Six chaos experiments documented with baseline/broken/fixed artifacts +- [ ] Interview questions #29–32 in [interview-questions.md](interview-questions.md) +- [ ] `scripts/verify-phase-24.ps1` passes + +Implementation complete when all phase exit gates in plans 20–24 pass and integration tests green. +