1.7.2 / Rust crate 0.3.2 — 2026-05-18
ADR-001 phase-2 release. Three enforcement mechanisms now live, plus the sub-linear contrastive primitive that completes roadmap item #6's phase-2 plan.
Added
-
find_anomalous_rows_in_subset(baseline, current, candidates, k)insrc/contrastive.rs. Drops the phase-1O(n log k)full scan toO(|candidates| log k)by limiting the scan to a caller-supplied candidate set. Combined with the existingSublinearNeumannSolver's single-entry primitive (O(log n)per query), the total contrastive top-k cost becomesO(|candidates| · log n)— true sub-linear in n when |candidates| ≪ n. RuView / Cognitum / Ruflo callers compute the candidate set from a sparse RHS delta's reachable rows, then invoke this function on the top-k boundary check. -
CI
complexity-baseline-guardjob (.github/workflows/ci.yml) +scripts/extract_complexity_classes.sh+ frozen.github/complexity-baseline.txt. Diffs the liveComplexityimpls against a checked-in snapshot on every PR; a silent class downgrade fails the build the same way safe-path regressions do. UsesLC_ALL=Cso the sort is byte-stable across hosts.
Improved
- Phase-2 enforcement matrix now complete for ADR-001:
- Server-side budget rejection (v1.7.1): MCP refuses over-budget solver invocations at dispatch time.
- Type-level baseline guard (this release): CI refuses
Complexityimpls that silently degrade. - Sub-linear contrastive primitive (this release):
find_anomalous_rows_in_subsetlets callers pay only for the rows they care about.
Tests
- 5 new unit tests in
src/contrastive.rspinning the new function's contract (out-of-set anomalies stay ignored, OOB indices silently skipped, full-set candidates equals phase-1 output, k limit, empty-candidates → empty result). - Total: 165 lib pass (160 → +5), 11 doc pass, 7 CI gates on every PR (test×2 OS, fmt+clippy, safe-path, bench-smoke, joules smoke, complexity-baseline-guard).