Repository navigation
Reject non-one-based t in munge_data - #624
ChrisRackauckas-Claude wants to merge 1 commit into
Conversation
`munge_data` only checked `length(t)`, so a `t` with non-one-based indexing (e.g. an OffsetArray) passes through silently: subsequent 1-based indexing into `t` elsewhere in the package reads the wrong elements, giving a wrong value instead of an error. Other interpolation types already throw for this case; ConstantInterpolation does not. Add `Base.require_one_based_indexing(t)` to all three `munge_data` methods (vector, matrix, N-d `u`). Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude <noreply@anthropic.com> Agent-Harness: Claude Code Agent-Model: claude-sonnet-5 Agent-Session: https://claude.ai/code/session_01LPHREnnonfLg1VcE1EJovv
Independent review (Devin CLI 3000.11.3, model fusion-claude-opus-5-5-high-sidekick-swe-2-medium): CHANGES, risk low. Full reviewVERDICT: CHANGES The code change is correct. On master I reproduced the silent wrong value, the fix turns it into an Blocking findings
Non-blocking findings
What I ran
What I did not verify
🤖 Posted by an AI agent — harness: Devin CLI 3000.11.3 (review), Claude Code 2.1.285 (posting) · model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium |
What changed and why
Every interpolation type's constructor funnels
u, tthroughmunge_data, which only validateslength(t)(and, for vectoru,sortedness). It never checks that
thas one-based indexing. AnOffsetArraytis therefore accepted silently, and subsequent 1-basedindexing into
telsewhere in the package (knot lookups,get_idx,etc.) reads the wrong elements — a wrong value rather than an error.
Most interpolation types happen to throw anyway (via some other
incidental bounds check), but
ConstantInterpolationdoes not.This PR adds
Base.require_one_based_indexing(t)to all threemunge_datamethods (vector, matrix, N-du) ininterpolation_utils.jl,matching the existing use of
require_one_based_indexingelsewhere in thepackage (
_cumulative_integral).Failing before / passing after
Before (unmodified
master, commitb98db80):ConstantInterpolation(sin.(1:10), OffsetArray(1:10, 0:9))(2.5)silentlyreturns
0.8415on master (the value att=1), where0.9093(the valueat
t=2) is correct — no error, no warning.New test
"munge_data rejects offset t"intest/interpolation_tests.jlchecks
munge_datadirectly (vector, matrix, N-d) andConstantInterpolationend-to-end, asserting all four throw
ArgumentErrorfor an offsett.This test fails (wrong value, no error) against unmodified master and
passes with the fix.
What was not verified
offset
tbeyondConstantInterpolation(the one the audit foundsilently wrong); other types already throw before this change for
unrelated reasons, and this change makes that uniform and explicit.
Core/QAgroups were run on Julia 1.12 and 1.10 (lts);prewas notrun.
Anything a reviewer should push back on
None beyond the usual: this duplicates the vector-
urequire_one_based_indexing(t)call across three methods rather than factoring it into a shared helper;
given each method's small size this seemed clearer than adding another
layer of indirection, but a reviewer might prefer otherwise.
Please ignore until reviewed by @ChrisRackauckas.
Risk assessment
munge_datamethods ininterpolation_utils.jl, used by every interpolation type'sconstructor. Only rejects input (non-one-based
t) that was alreadysilently wrong or (for most types) already erroring; no change to
accepted (one-based) input. No public API signature change.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LPHREnnonfLg1VcE1EJovv
Breaking change
Breaking:
ConstantInterpolation(u, OffsetArray(t, 1))and directmunge_datacalls with non-one-based time axes now throwArgumentError; the current release accepts them. This is a public behavior change and needs a major bump (Project.toml is still 10.1.3), or Chris's explicit call that it ships as a bug fix. The one-based time-axis precondition should also be documented. Flagged by the independent review (codex-cli gpt-6.1-sol).🤖 Posted by an AI agent — harness: Claude Code 2.1.301 · model: claude-opus-5-5
Conversation: https://claude.ai/code/session_01VZjwf7Ux9YtTzwHGHMqnsq
Risk assessment (independent review, Codex gpt-6.1-sol, head 83cb259)
git diff origin/HEAD...HEAD; there is no linked issue. Archived origin/HEAD (898d88e) and HEAD into scratch, then created separate scratch environments withPkg.developand OffsetArrays. All Julia commands used Julia 1.12.4, the requested JULIA_DEPOT_PATH, JULIA_NUM_THREADS=4, TMPDIR under scratch, andtimeout 3600, sequentially. Commands from scratch:julia --project=env_base regression.jl→ 4 failures/4 assertions (three missing exceptions and one BoundsError instead of ArgumentError);julia --project=env_head head-tests.jl→ new assertions 4/4 pass, data-preparation controls 24/24 pass, interpolation controls 8/8 pass;julia --project=env_base controls.jl→ the same 24/24 and 8/8 controls pass. Logs: scratch/regression-base.log, scratch/head-tests.log, scratch/controls-base.log. Probes reproduce the negative-offset wrong value (0.8414709848078965 instead of sin(2)=0.9092974268256817) and the valid missing-data regression described below.git diff --check origin/HEAD...HEADpassed;git status --porcelainstayed empty. GitHub read-only metadata reports no failing checks; there was consequently no failing CI check requiring a default-branch comparison. Read the Extensions job log: Mooncake 769/769, sparse tracer 660/660, Zygote 29470/29470, overall passed. G1 pass: independent left-sample and analytic linear references checked; no numerical formula changes. G2 pass for affected AD integration through the existing Extensions CI; no GPU/Reactant/MPI paths changed. G3 not applicable: no shared-state/cache/threading changes. No existing assertions are skipped or weakened, no new public names are added, and the added dependency is test-only OffsetArrays with an inspected MIT license; the implementation uses public Base.require_one_based_indexing.🤖 Posted by an AI agent — harness: Codex CLI 0.162.1 · model: gpt-6.1-sol
Conversation: local headless review run (no public session URL); transcript kept by the fleet master.