You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
W1-2: guard partial_correlation against NaN leak on zero-variance input (#40)
## Summary
Fixes the two `must_fix` items from reviewer feedback on W1-2
(`.claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.md`):
`partial_correlation` still leaked `NaN` on a degenerate `n>=4` input,
and
the degenerate-input test suite never exercised that path.
- **`src/stats/correlation_regression.jl:274` (`partial_correlation`)**
—
the function guarded `n<4` and the final `denom==0` case, but computed
`r_xy = cor(x,y)`, `r_xz = cor(x,z)`, `r_yz = cor(y,z)` directly via
`Statistics.cor()`, which returns `NaN` (not an error) on a
constant/zero-variance vector, and returned that `NaN` straight through
in the `r_xy`/`r_xz`/`r_yz` fields — violating acceptance criterion #1
("No core stat function returns NaN/Inf on degenerate input").
Replaced the three `cor()` calls with a guarded pairwise-correlation
helper using the same `den > 0` pattern `pearson_correlation` already
uses, so a constant `x`, `y`, or `z` now yields `r_xy`/`r_xz`/`r_yz` =>
`nothing` instead of `NaN`, with `r_partial`/`t_stat`/`p_value`
cascading to `nothing` and a `"note"` explaining why.
- **`test/degenerate_input_test.jl`** — the only existing
`partial_correlation` degenerate test used `n=3` (the `n<4` early
return), so the constant-vector/zero-variance case at `n>=4` was never
tested. Added a new test reproducing the reviewer's exact repro
(`partial_correlation(fill(2.0,5), [1,2,3,4,5], [2,1,4,3,5])`) that
asserts `r_xy`, `r_xz`, and `r_partial` are `nothing` and runs the
`assert_finite_and_serialisable` walk over the full returned `Dict`.
Branch was rebuilt on the latest `main` (which had moved one commit
ahead
with the unrelated P0 guardrail work, #37) via a merge + cherry-pick —
no
force-push, no history rewrite of the already-pushed commit.
## Verification
```
flock /tmp/statistikles-julia.lock -c 'cd <repo> && julia --project=. -e "using Pkg; Pkg.test()"'
```
(WSL Debian login shell.) Full suite green, 0 failures:
| Testset | Pass/Total |
|---|---|
| Statistikles Full Test Suite | 424/424 |
| Statistikles E2E Pipeline Tests | 155/155 |
| Statistikles Property-Based Tests | 3800/3800 |
| Reference Validation (ground truth) | 35/35 |
| Degenerate Input Guards | 943/943 |
| Neural-Boundary Guardrail | 80/80 |
Total: 5437/5437 passed.
## Nothing skipped
Both `must_fix` items from the review are addressed; no other changes
were needed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments