feat: expose per-manufacturer validation metadata dict for consuming applications
## Motivation
SleepLab (joshuamyers-dev/sleeplab) currently maintains a parallel `MANUFACTURER_VALIDATED` dict to track which manufacturers/data surfaces are validated against OSCAR. This duplicates information the parser already knows and risks drifting out of sync with the parser's actual capabilities.
After review feedback on sleeplab#44, the consuming application should import validation metadata from the parser at runtime instead of maintaining its own copy.
## Proposed API
Add a static, runtime-queryable function:
```python
from cpap_parser import get_validation_status
status = get_validation_status()
# Returns dict keyed by manufacturer name:
# {
# "Lowenstein": ManufacturerValidation(
# summary_validated=True,
# spo2_validated=True,
# events_validated=True,
# waveform_validated=False,
# ),
# "ResMed": ManufacturerValidation(
# summary_validated=False,
# spo2_validated=False,
# events_validated=False,
# waveform_validated=False,
# ),
# ...
# }
```
Each entry is a dataclass:
```python
@dataclass
class ManufacturerValidation:
summary_validated: bool # AHI, pressure, leak, usage hours match OSCAR
spo2_validated: bool # SpO2 avg/min/pulse match OSCAR
events_validated: bool # Event type classification + counts match OSCAR
waveform_validated: bool # Waveform/timeseries channel identity confirmed
```
## Design notes
- **`route_enabled` is NOT included.** The decision to route a manufacturer through cpap-parser vs. a native path is a consuming-application concern. SleepLab keeps its own `ROUTE_ENABLED` dict for operational control.
- The dict is static (not auto-detected per-directory) because validation status is a property of the parser code version, not the data being parsed.
- Should be versioned with the parser release and linked to the docs page at https://open-cpap-parser-9efe6c.gitlab.io/device_support/.
## Initial entries
| Manufacturer | summary | spo2 | events | waveform |
|---|---|---|---|---|
| Lowenstein | ✅ | ✅ | ✅ | ❌ (tracks #27) |
| ResMed | ❌ | ❌ | ❌ | ❌ (blocked by #28) |
| All others (DeVilbiss, BMC, F&P, Yuwell, Apex, Respironics) | ❌ | ❌ | ❌ | ❌ |
## Related
- #6 (ResMed validation tracking)
- #10 (Lowenstein validation tracking)
- #27 (Lowenstein channel misidentification)
- #28 (ResMed adapter bugs)
issue