probes: route every happy-path return through safe_finalize
- SHA
0f66b7036b3f8c26b867fed0c534e9e00291ce30- Parents
-
074a7d2 - Tree
04a7d75
0f66b70
0f66b7036b3f8c26b867fed0c534e9e00291ce30074a7d2
04a7d75src/dlm_sway/probes/adapter_ablation.pymodified@@ -30,7 +30,7 @@ from typing import Literal | ||
| 30 | 30 | import numpy as np |
| 31 | 31 | from pydantic import Field |
| 32 | 32 | |
| 33 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 33 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 34 | 34 | from dlm_sway.core.scoring import ScalableDifferentialBackend |
| 35 | 35 | from dlm_sway.probes._divergence import Divergence, divergence |
| 36 | 36 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
@@ -111,7 +111,7 @@ class AdapterAblationProbe(Probe): | ||
| 111 | 111 | sat_score = 1.0 if ok_sat else 0.3 |
| 112 | 112 | score = 0.4 * lin_score + 0.3 * sat_score + 0.3 * over_score |
| 113 | 113 | |
| 114 | - return ProbeResult( | |
| 114 | + return safe_finalize( | |
| 115 | 115 | name=spec.name, |
| 116 | 116 | kind=spec.kind, |
| 117 | 117 | verdict=verdict, |
src/dlm_sway/probes/adapter_revert.pymodified@@ -22,7 +22,7 @@ from typing import Any, Literal | ||
| 22 | 22 | from pydantic import BaseModel, ConfigDict, Field |
| 23 | 23 | |
| 24 | 24 | from dlm_sway.core.errors import BackendNotAvailableError |
| 25 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 25 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 26 | 26 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 27 | 27 | |
| 28 | 28 | |
@@ -130,7 +130,7 @@ class AdapterRevertProbe(Probe): | ||
| 130 | 130 | score = max(0.0, 1.0 - rate / max(spec.assert_revert_rate_lt, 1e-6)) |
| 131 | 131 | score = float(np.clip(score, 0.0, 1.0)) |
| 132 | 132 | |
| 133 | - return ProbeResult( | |
| 133 | + return safe_finalize( | |
| 134 | 134 | name=spec.name, |
| 135 | 135 | kind=spec.kind, |
| 136 | 136 | verdict=verdict, |
src/dlm_sway/probes/calibration_drift.pymodified@@ -23,7 +23,7 @@ from typing import Literal | ||
| 23 | 23 | |
| 24 | 24 | from pydantic import Field |
| 25 | 25 | |
| 26 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 26 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 27 | 27 | from dlm_sway.probes._calibration_pack import BUILT_IN_PACK |
| 28 | 28 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 29 | 29 | |
@@ -107,7 +107,7 @@ class CalibrationDriftProbe(Probe): | ||
| 107 | 107 | drift_component = max(0.0, min(1.0, (mean_delta + 1.0) / 1.5)) |
| 108 | 108 | score = 0.6 * regress_component + 0.4 * drift_component |
| 109 | 109 | |
| 110 | - return ProbeResult( | |
| 110 | + return safe_finalize( | |
| 111 | 111 | name=spec.name, |
| 112 | 112 | kind=spec.kind, |
| 113 | 113 | verdict=verdict, |
src/dlm_sway/probes/delta_kl.pymodified@@ -20,7 +20,7 @@ from typing import Literal | ||
| 20 | 20 | |
| 21 | 21 | from pydantic import Field |
| 22 | 22 | |
| 23 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 23 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 24 | 24 | from dlm_sway.probes._divergence import Divergence, divergence, js_ln2 |
| 25 | 25 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 26 | 26 | from dlm_sway.probes.null_adapter import get_null_stats |
@@ -97,7 +97,7 @@ class DeltaKLProbe(Probe): | ||
| 97 | 97 | bound = js_ln2() if spec.divergence == "js" else 1.0 |
| 98 | 98 | score = min(1.0, raw_mean / bound) if bound > 0.0 else 0.0 |
| 99 | 99 | |
| 100 | - return ProbeResult( | |
| 100 | + return safe_finalize( | |
| 101 | 101 | name=spec.name, |
| 102 | 102 | kind=spec.kind, |
| 103 | 103 | verdict=verdict, |
src/dlm_sway/probes/leakage.pymodified@@ -21,7 +21,7 @@ from typing import Literal | ||
| 21 | 21 | |
| 22 | 22 | from pydantic import Field |
| 23 | 23 | |
| 24 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 24 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 25 | 25 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 26 | 26 | |
| 27 | 27 | PerturbationKind = Literal["typo", "case_flip", "drop_punct"] |
@@ -130,7 +130,7 @@ class LeakageSusceptibilityProbe(Probe): | ||
| 130 | 130 | fragility_bonus = min(1.0, max(0.0, mean_fragility / max(spec.min_fragility, 1e-6))) |
| 131 | 131 | score = 0.7 * recall_score + 0.3 * fragility_bonus |
| 132 | 132 | |
| 133 | - return ProbeResult( | |
| 133 | + return safe_finalize( | |
| 134 | 134 | name=spec.name, |
| 135 | 135 | kind=spec.kind, |
| 136 | 136 | verdict=verdict, |
src/dlm_sway/probes/paraphrase_invariance.pymodified@@ -28,7 +28,7 @@ from typing import Literal | ||
| 28 | 28 | |
| 29 | 29 | from pydantic import BaseModel, ConfigDict, Field |
| 30 | 30 | |
| 31 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 31 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 32 | 32 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 33 | 33 | |
| 34 | 34 | Intent = Literal["generalize", "memorize", "both"] |
@@ -102,7 +102,7 @@ class ParaphraseInvarianceProbe(Probe): | ||
| 102 | 102 | |
| 103 | 103 | verdict, score, msg = _decide(spec, mean_verb, mean_par, ratio) |
| 104 | 104 | |
| 105 | - return ProbeResult( | |
| 105 | + return safe_finalize( | |
| 106 | 106 | name=spec.name, |
| 107 | 107 | kind=spec.kind, |
| 108 | 108 | verdict=verdict, |
src/dlm_sway/probes/preference_flip.pymodified@@ -22,7 +22,7 @@ from typing import Literal | ||
| 22 | 22 | |
| 23 | 23 | from pydantic import BaseModel, ConfigDict, Field |
| 24 | 24 | |
| 25 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 25 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 26 | 26 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 27 | 27 | |
| 28 | 28 | |
@@ -83,7 +83,7 @@ class PreferenceFlipProbe(Probe): | ||
| 83 | 83 | (ft - base) for base, ft in zip(base_margins, ft_margins, strict=True) |
| 84 | 84 | ) |
| 85 | 85 | verdict = Verdict.WARN |
| 86 | - return ProbeResult( | |
| 86 | + return safe_finalize( | |
| 87 | 87 | name=spec.name, |
| 88 | 88 | kind=spec.kind, |
| 89 | 89 | verdict=verdict, |
@@ -106,7 +106,7 @@ class PreferenceFlipProbe(Probe): | ||
| 106 | 106 | flip_rate = len(flipped_idx) / len(base_wrong_idx) |
| 107 | 107 | verdict = Verdict.PASS if flip_rate >= spec.assert_flip_rate_gte else Verdict.FAIL |
| 108 | 108 | score = min(1.0, flip_rate / max(spec.assert_flip_rate_gte, 1e-6)) |
| 109 | - return ProbeResult( | |
| 109 | + return safe_finalize( | |
| 110 | 110 | name=spec.name, |
| 111 | 111 | kind=spec.kind, |
| 112 | 112 | verdict=verdict, |
src/dlm_sway/probes/prompt_collapse.pymodified@@ -20,7 +20,7 @@ from typing import Literal | ||
| 20 | 20 | import numpy as np |
| 21 | 21 | from pydantic import Field |
| 22 | 22 | |
| 23 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 23 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 24 | 24 | from dlm_sway.probes._divergence import Divergence, divergence |
| 25 | 25 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 26 | 26 | |
@@ -98,7 +98,7 @@ class PromptCollapseProbe(Probe): | ||
| 98 | 98 | if half_life is not None |
| 99 | 99 | else "could not fit exponential decay (too flat or non-monotonic)" |
| 100 | 100 | ) |
| 101 | - return ProbeResult( | |
| 101 | + return safe_finalize( | |
| 102 | 102 | name=spec.name, |
| 103 | 103 | kind=spec.kind, |
| 104 | 104 | verdict=verdict, |
src/dlm_sway/probes/section_internalization.pymodified@@ -30,7 +30,7 @@ from typing import Literal | ||
| 30 | 30 | |
| 31 | 31 | from pydantic import Field |
| 32 | 32 | |
| 33 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 33 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 34 | 34 | from dlm_sway.core.scoring import ScoringBackend |
| 35 | 35 | from dlm_sway.core.sections import Section, SectionKind |
| 36 | 36 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
@@ -124,7 +124,7 @@ class SectionInternalizationProbe(Probe): | ||
| 124 | 124 | passing_frac = passing / len(eligible) |
| 125 | 125 | verdict = Verdict.PASS if passing_frac >= spec.assert_passing_section_frac else Verdict.FAIL |
| 126 | 126 | score = passing_frac |
| 127 | - return ProbeResult( | |
| 127 | + return safe_finalize( | |
| 128 | 128 | name=spec.name, |
| 129 | 129 | kind=spec.kind, |
| 130 | 130 | verdict=verdict, |
src/dlm_sway/probes/style_fingerprint.pymodified@@ -27,7 +27,7 @@ import numpy as np | ||
| 27 | 27 | from numpy.typing import NDArray |
| 28 | 28 | from pydantic import Field |
| 29 | 29 | |
| 30 | -from dlm_sway.core.result import ProbeResult, Verdict | |
| 30 | +from dlm_sway.core.result import ProbeResult, Verdict, safe_finalize | |
| 31 | 31 | from dlm_sway.probes.base import Probe, ProbeSpec, RunContext |
| 32 | 32 | |
| 33 | 33 | _SENTENCE_SPLIT = re.compile(r"(?<=[.!?])\s+") |
@@ -145,7 +145,7 @@ class StyleFingerprintProbe(Probe): | ||
| 145 | 145 | verdict = Verdict.PASS if shift >= spec.assert_shift_gte else Verdict.FAIL |
| 146 | 146 | score = float(np.clip((shift + 1.0) / 2.0, 0.0, 1.0)) |
| 147 | 147 | |
| 148 | - return ProbeResult( | |
| 148 | + return safe_finalize( | |
| 149 | 149 | name=spec.name, |
| 150 | 150 | kind=spec.kind, |
| 151 | 151 | verdict=verdict, |