test(suite): declare the interp oracle's platform scope - #65
Merged
LoganAMorrison merged 2 commits intoAug 13, 2026
Conversation
`test/test_core_interp.py` decided whether to compare `hazma._core.interp` against `np.interp` bit-for-bit by *measuring* whether the installed NumPy fused its interpolation step. That is the mechanism Task 4.1 retired in `test_core_positron_muon.py` and the 2026-08-12 rewrite retired in `test_core_boost.py`: a probe tests one contraction mechanism and is blind to every other, so it fails in both directions. This module was resolving the second way -- built for linux/amd64 the probe returned False and all nine cross-implementation claims skipped, leaving the port checked against nothing but its own clamping contract, quirks and error paths on every CI entry but macOS. The module now runs 42 passed / 0 skipped on both. The mode is declared from the platform (`ON_THE_CAPTURING_PLATFORM`, read from the parity corpus manifest so the two scopes cannot drift), and the divergence off it was measured rather than assumed -- built for linux/amd64 (Debian bookworm, glibc 2.36, CPython 3.12.13, NumPy 2.5.1) and compared directly over 1,154,010 abscissae. The port and that build's `np.interp` differ at 311,501 points by up to 4.0e-02 pointwise relative but only 2.2e-16 of the peak, with no non-finite value and no disagreement about which abscissae return exactly zero. Hence `OFF_PLATFORM_BUDGET = 1e-12` scaled to the peak -- two orders *tighter* than the boost module's, because peak scaling collapses the very cancellation population the pointwise reading blows up. `TestFusedArithmetic` no longer discriminates against NumPy. Its reference is `interp_reference`, a full Python transcription of `rust/src/interp.rs` parameterised by its multiply-add, asserted bit-for-bit on every platform -- which makes it the stronger of the two off-platform gates, since peak scaling is blind to a defect confined to a small value. Unfusing the Rust and rebuilding fails 15 tests on macOS and 7 on linux/amd64, where `TestAgainstNumpy` passes the mutant because there `np.interp` *is* the unfused form; under the old module the off-platform count was 0. Two supporting fixes the measurement forced: `rng.uniform(lo, hi, n)` is not platform-independent (NumPy computes `lo + (hi - lo) * u` in C and macOS/arm64 contracts it -- 6,532 of 20,000 draws landed on different doubles), so `spread()` writes it as separate ufunc calls; and the per-table seed moved off `hash(name)`, which is randomised per process. Without both, every count recorded here would be a per-platform anecdote. `rust/src/interp.rs` is comment-only: it carried the now-measurably-wrong claim that an unfused NumPy would differ by <=1.1e-13, "an order inside the 1e-12 budget test/parity/tolerances.py sets". No public value moves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review round 1 on PR #65. The resolved follow-up's §Why and §Entry points cite five line numbers in `test/test_core_interp.py` for symbols the resolution deletes, so they were stale the instant the PR landed rather than "later" -- and `check_doc_citations.py` passes them, because it bounds-checks lines rather than resolving symbols. Pinned to `707b07c`, verified with `git show 707b07c:test/test_core_interp.py`. The Task 3.4 records gave the `np.interp` sweep as 20,204 abscissae per table. The sweep is `20,000 + 3n + 4`, so it is 20,304 for the 100-row eta table and 21,504 for the six 500-row tables; the note's own enumeration of the sweep contradicted its number, so this was wrong when written rather than changed since. Corrected at all three sites, each marked with the date and the old value, per the precedent of c316afc. The companion `1,549` is annotated rather than replaced: it was drawn with a `hash()`-seeded sweep and so was never reproducible, and the deterministic seed gives 1,571. Task 3.4's §Numerical impact, §Files Changed and §Stale-state sweep describe that task's own diff in the present tense, which a reviewer read as a claim about this branch -- "one file, `hazma/_core.pyi`, comment-only" against a branch touching no `hazma/` file. Headed with the task's PR number and date. Both classes were already in the lessons ledger; PR #65 is added to [touched-doc-inherits-its-citations] and [partial-historical-labeling] with the sharper trigger each one missed. Docs only -- no code, no public value moves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
test/test_core_interp.pyscoped its NumPy oracle with a probe, and that probe was resolving the wrong way. Built for linux/amd64 it returnedFalse, so all nine of the module's cross-implementation claims skipped andhazma._core.interpwas checked against nothing but its own clamping contract, quirks and error paths on every CI entry but macOS. Same mechanism Task 4.1 retired intest_core_positron_muon.pyand the 2026-08-12 rewrite retired intest_core_boost.py. The module now runs 42 passed, 0 skipped on both platforms (was24 passed, 9 skippedoff macOS). Resolvesinterp-oracle-scoped-by-an-unsound-probe.md.ON_THE_CAPTURING_PLATFORMis read fromtest/parity/data/manifest.jsonso this module's scope cannot drift from the corpus's. Off it, the tree was built for linux/amd64 (Debian bookworm, glibc 2.36, CPython 3.12.13, NumPy 2.5.1) and compared directly over 1,154,010 abscissae: the port and that build'snp.interpdiffer at 311,501 points by up to 4.0e-02 pointwise relative but only 2.2e-16 of the peak, with no non-finite value on either side (0 of 2,308,020) and no disagreement anywhere about which abscissae return exactly zero. HenceOFF_PLATFORM_BUDGET = 1e-12scaled to the peak — two orders tighter than the boost module's1e-10, not looser as the follow-up guessed, because peak scaling collapses the very cancellation population the pointwise reading blows up.TestFusedArithmeticno longer discriminates against NumPy. Its reference isinterp_reference, a full Python transcription ofrust/src/interp.rs(bisection, clamps, exact-node short circuit, NumPy's two-step NaN rescue) parameterised by its multiply-add, asserted bit-for-bit on every platform. That makes it the stronger of the two off-platform gates, since peak scaling is blind to a defect confined to a value far below the peak. The discrimination is direct, not assumed:np.interpis bit-equal tomul_add=fmaon all seven live tables on macOS/arm64 and bit-equal tomul_add=unfusedon all seven on linux/amd64.TestOffPlatformBudgetguards both the tolerance and the mode dispatch.rng.uniform(lo, hi, n)is not platform-independent — NumPy computeslo + (hi - lo) * uin C and macOS/arm64 contracts that, so 6,532 of 20,000 draws over the eta grid landed on different doubles than the same seed gives on Linux; the newspread()helper writes it as separate ufunc calls. And the per-table seed moved fromhash(name)(randomised per process unlessPYTHONHASHSEEDis set) tozlib.crc32. Without both, every count recorded here would have been a per-platform anecdote rather than a reproducible measurement.rust/src/interp.rsis comment-only (verified:git diff origin/master -- rust/src/interp.rsfiltered to non-//!lines is empty). Its module docs carried the now-measurably-wrong claim that an unfused NumPy "would differ from this function by ≤1.1e-13 — an order inside the 1e-12 budgettest/parity/tolerances.pysets"; the pointwise figure is 5.9e-05 on the live tables, and the corpus is skipped off-platform anyway.No public value moves. The diff is one test module, comment-only Rust edits, and four docs; no public function changed.
Project
projects/cython-to-rust/— not a PLAN task. This resolves thecross-cutting follow-up
interp-oracle-scoped-by-an-unsound-probe.md,which was carved out of the
test_core_boost.pyprobe removal(
1ed4eda), so the branch is ad-hoc (claude/<short-description>) ratherthan
claude/<project-slug>/<task-slug>and there is notask-notes/task-N-<slug>.mdfor it. The follow-up file carries theResolution, Verification and stale-state sweep that a task note would.
The module under change was built by Task 3.4 (
projects/cython-to-rust/task-notes/phase-03/task-3.4-interp-boost.md,shipped as #61); this PR supersedes that task's platform-scoping remedy
and patches the two inbound links plus a sweep-size slip in its records.
It does not reopen Task 3.4, whose status stays
Complete.Test plan
scripts/agents/preflight.sh --paths "test/test_core_interp.py" --md "…"—RESULT: PASS, all eleven rows:pytest test/test_core_interp.py -qon macOS/arm64 →42 passed in 0.94sthe same command inside the linux/amd64 container built from this tree →
42 passed in 2.61scargo test --manifest-path rust/Cargo.toml --no-default-features→80 passedTest validity, stash-proof.
slope.mul_add(x - xp[j], fp[j])inrust/src/interp.rsreplaced withslope * (x - xp[j]) + fp[j], rebuilt withpip install -e ., module re-run on both platforms:15 failed, 27 passed(all sevenTestAgainstNumpytable cases, the random grid, all sevenTestFusedArithmeticcases)7 failed, 35 passed(the sevenTestFusedArithmeticcases only)That second line is the point in both directions: off-platform
TestAgainstNumpypasses the mutant, because therenp.interpis the unfused form — the budget genuinely cannot see this defect, and the fused reference is what catches it. Under the old module the off-platform count would have been 0 failed. Mutation reverted and the tree rebuilt before the gate was run.The 14th skip is
test/parity/test_parity.pyin budget rather than bit-equality mode (hazma._core serves 1 kernel(s)) — Task 4.1's positron-muon swap, present on master before this change and untouched by it.Confirmed on CI, which is where the skips lived. Linux
py3.12,pytest --ignore=test/parity:707b07c(run 31646076820)797 passed, 22 skipped815 passed, 13 skipped−9 skipped, +18 passed — the 9 are exactly the module's previously-voided cross-implementation claims, and the +18 is those 9 plus the 9 net-new tests (33 → 42). All eight checks green, including all five Ubuntu entries
py3.10–py3.14and macOSpy3.14.