ScanResult.degraded and degraded_layers are declared at sdk/src/unplug/api/types.py:51-58 and documented as reporting configured layers that were unavailable. Neither is written anywhere in the SDK.
Reproduction, core install with no ml extra:
guard=Guard(model="tiny")
guard.ml_degraded# Truer=guard.scan("some text")
r.degraded# Falser.degraded_layers# []The Guard knows it is degraded and keeps it in the private _ml_degraded flag at guard.py:166. The result, which is what callers actually inspect, says everything is fine.
Related and part of the same decision: other optional scanners fail closed here. Guard(scanners=["yara"]) and Guard(scanners=["pii"]) raise ConfigError from _validate_optional_scanners at guard.py:751-770, while the ML path degrades silently.
unplug-server already implements the intended semantics in services/scan_result.py (mark_degraded), so the SDK should match it rather than invent a second answer.
Comment here if you want this one. It needs a design conversation first, so expect questions before code.
ScanResult.degradedanddegraded_layersare declared atsdk/src/unplug/api/types.py:51-58and documented as reporting configured layers that were unavailable. Neither is written anywhere in the SDK.Reproduction, core install with no
mlextra:The Guard knows it is degraded and keeps it in the private
_ml_degradedflag atguard.py:166. The result, which is what callers actually inspect, says everything is fine.Related and part of the same decision: other optional scanners fail closed here.
Guard(scanners=["yara"])andGuard(scanners=["pii"])raiseConfigErrorfrom_validate_optional_scannersatguard.py:751-770, while the ML path degrades silently.unplug-serveralready implements the intended semantics inservices/scan_result.py(mark_degraded), so the SDK should match it rather than invent a second answer.Comment here if you want this one. It needs a design conversation first, so expect questions before code.