@@ -62,6 +62,15 @@ class ProbeResult: |
| 62 | 62 | One-line diagnostic. Surfaces in the terminal report. |
| 63 | 63 | duration_s: |
| 64 | 64 | Wall time to execute. |
| 65 | + ci_95: |
| 66 | + 95% percentile-bootstrap confidence interval on :attr:`raw`. |
| 67 | + Populated by aggregating probes (``delta_kl`` over N prompts, |
| 68 | + ``calibration_drift`` over pack items, etc.) via |
| 69 | + :func:`dlm_sway.core.stats.bootstrap_ci`. ``None`` when the |
| 70 | + probe doesn't aggregate (``adapter_ablation``, |
| 71 | + ``style_fingerprint``), when the sample count is too low to |
| 72 | + bootstrap meaningfully, or when the raw value isn't finite. |
| 73 | + Report surfaces it inline as ``raw [lo–hi]``. |
| 65 | 74 | """ |
| 66 | 75 | |
| 67 | 76 | name: str |
@@ -75,6 +84,7 @@ class ProbeResult: |
| 75 | 84 | evidence: dict[str, Any] = field(default_factory=dict) |
| 76 | 85 | message: str = "" |
| 77 | 86 | duration_s: float = 0.0 |
| 87 | + ci_95: tuple[float, float] | None = None |
| 78 | 88 | |
| 79 | 89 | |
| 80 | 90 | @dataclass(frozen=True, slots=True) |
@@ -181,6 +191,7 @@ def safe_finalize( |
| 181 | 191 | evidence: dict[str, Any] | None = None, |
| 182 | 192 | message: str = "", |
| 183 | 193 | duration_s: float = 0.0, |
| 194 | + ci_95: tuple[float, float] | None = None, |
| 184 | 195 | critical_fields: tuple[str, ...] = ("raw",), |
| 185 | 196 | ) -> ProbeResult: |
| 186 | 197 | """Build a :class:`ProbeResult` with defense against non-finite metrics. |
@@ -252,6 +263,11 @@ def safe_finalize( |
| 252 | 263 | for fname in non_finite: |
| 253 | 264 | numeric_kwargs[fname] = None |
| 254 | 265 | |
| 266 | + # ``ci_95`` is only attached when ``raw`` survived the |
| 267 | + # defensive-null sweep — a CI bracketing a nulled-out point |
| 268 | + # estimate would mislead more than it informs. |
| 269 | + final_ci_95 = ci_95 if numeric_kwargs["raw"] is not None else None |
| 270 | + |
| 255 | 271 | return ProbeResult( |
| 256 | 272 | name=name, |
| 257 | 273 | kind=kind, |
@@ -264,4 +280,5 @@ def safe_finalize( |
| 264 | 280 | evidence=ev, |
| 265 | 281 | message=message, |
| 266 | 282 | duration_s=duration_s, |
| 283 | + ci_95=final_ci_95, |
| 267 | 284 | ) |