Replace #132: pack fixtures, fix CI, remove hash pinning
Replaces #132. It carries the same fixed-income workflow work as #132, rebuilt on main so that 5.9 GB of JSON fixtures never enter Git history. It also fixes the problems that kept #132's CI red, and removes the hash pinning that made every edit to the repository need a matching hash refresh.
What was wrong with #132
- 5.9 GB of fixtures in Git. #132 committed 631 regression corpora of 1 MB or more. Seven of them (979 MB) were in Git LFS; the rest (5.2 GB) were plain blobs. Every CI checkout pulled all of it, and LFS bandwidth was spent on every job.
- Test and Bounded Rust Assurance ran out of runner disk. About 70
include_str!sites embedded 60–180 MB corpora into hundreds of test and example binaries, on top of the checkout. Both jobs died withNo space left on device. Most of the 935 assurance steps never ran. - Excel Add-in (Windows) had two latent failures.
- The library parity input
curve.fit.datedcame fromexp_m1. MSVC's libm returns a result one ulp away from glibc's, so the emitted request no longer matchedcases.json. - The parity steps passed
--binary target/excel/examples/X.exeto Pythonsubprocess. WindowsCreateProcessrejects forward-slash relative paths. The job never got this far before.
- The library parity input
- The release would have failed to publish.
convex-analyticsnow depends on the newconvex-ratesandconvex-creditcrates, butrelease.ymlstill published only core, math, curves, bonds and analytics. - Every edit needed hash bookkeeping. The assurance tooling pinned the SHA-256 of nearly every protected file in four places (
numeric-evidence.json,inventory.json,library-inventory.json, the comparison catalog) and required achange-reviews.jsonrow with fresh hashes for each change. Any fix, even a clippy one, failed CI until those were refreshed.
Commits
- Bring over the #132 workflow tree without its large fixtures. #132's final tree (
feb8e889), unchanged except that the 631 large fixtures are left out. - Pack the large fixtures and fix the CI and release failures.
- Each fixture of 1 MB or more is committed as
<name>.json.xz: 14.2 MB in total, down from 5.91 GB. Git LFS is no longer used. python3 tools/fixtures.py materializewrites the JSON beside each archive (about 80 s); the written files are Git-ignored.packrefreshes an archive after a deliberate regeneration.- The 67
include_str!sites that pointed at packed corpora, in 56 test and contract files, now callpacked::text(...)fromtests/fixtures/packed.rs. Each file is read once per process. Nothing else in those files changes; I verified this token by token. extended.rsuses the two quote literals already incases.jsoninstead of recomputing them withexp_m1. The Excel job passes Windows-style binary paths.- Test, Bounded Rust Assurance, Excel and Java materialize fixtures instead of fetching LFS. The two Linux heavy jobs free unused preinstalled toolchains and build with
CARGO_PROFILE_DEV_DEBUG=0: with line tables only, the workspace test build passed 32 GB before running a single test. convex-ratesandconvex-creditare published beforeconvex-analytics.docs/TEST-DATA.mdandREADME.mddescribematerializeinstead ofgit lfs pull.
- Each fixture of 1 MB or more is committed as
- Remove hash pinning and change-review records from assurance.
- Deletes
tools/assurance/change-reviews.json,numeric-evidence.jsonandtools/source_pins.py, and the checks that read them. - Drops
sha256from theinventory.jsonrows and from the comparison catalog and pack references.library-inventory.jsonlistsinspected_sourcesas paths; its observation anchors are still checked against the current files. - Removes
tests/fixtures/packed.json. The archives are the source of truth, and xz's CRC64 rejects a corrupt one.materializeandcheckalso requiretests/fixtures/.gitignoreto match the archives. - Kept:
- The structural checks: forbidden dependencies, lints, lifecycle purity, required CI steps, inventory paths and exception expiry.
- The solver-default check (
DEFAULT_TOLERANCE1e-10,DEFAULT_MAX_ITERATIONS100) and the required comparator and reference files. - The
--basechecks that reject wider tolerances and removed cases, measures or library coverage. - The hashes recorded inside fixture data and capture manifests, and the QuantLib wheel download checksum.
- Deletes
- Fix the offline comparison and Excel jobs found on the first full CI run.
- Offline Quantitative Comparison now materializes the packed fixtures. It also frees runner disk and drops debuginfo, like the other jobs that hold the unpacked corpora.
- The Excel tests checked
CX.LIBRARY.RANGEoutput by rejoining it withLibraryCells.Join, which applies the 2 MiB request bound. Fourteen P&L responses are larger; the native response bound is 16 MiB. The tests now rejoin output with a test helper,ResponseCells.Join, that checks cell sizes only. The request-side round trips are unchanged. LibraryCells.ValidateInputletEncoderFallbackExceptionescape for an unpaired surrogate. It now throws the plainArgumentExceptionits test expects.
- Check the optional graph hedge controls within libm drift. Bounded Rust Assurance failed at step 600 of 945, which #132's CI never reached.
- The optional graph hedge reference, qualification and calibrated generators call the platform libm (
expm1,erfc,exp). Their regenerated floats differ in the last digits on Linux and on Windows, and both differ from Codex's committed controls, so their byte-exact checks can pass only on the machine that wrote them. - Regenerating would cascade: the controls' bytes, and the reference script's own bytes, are recorded as source reads in other fixtures.
- So the generators and controls are unchanged, and the three CI steps (same names) now run
tests/scripts/optional_graph_hedge_controls.py. It regenerates the same six files, requires structure, text (including source reads) and integers to match exactly, and allows floats 1e-11 absolute, or 1e-13 relative above magnitude 100. The largest drift is 1.4e-12 on Linux and 2.8e-12 on Windows; the tightest consumer tolerance in the controls is 1e-10 (cash). - The generators' own check modes stay byte-exact, so they still pass only on the platform that wrote the controls.
- The optional graph hedge reference, qualification and calibrated generators call the platform libm (
No financial code, fixture value, expected result, tolerance or solver default changes. The only assertion changes are the Excel output round trips in commit 4 and the three optional-graph-hedge control checks in commit 5. #132's CI never reached dotnet test, so this PR is the first run of those tests.
Verification
Linux (Ubuntu under WSL 2):
-
The full workspace suite (
cargo test --locked --all-features --workspace --no-fail-fast -- --test-threads=1,CARGO_PROFILE_DEV_DEBUG=0) gave 3,351 passed, 0 failed, 78 ignored. It ran before the clippy fixes inpacked.rsand the contract files' module lines. After those fixes, I re-rancargo fmt --check,cargo clippy --locked --workspace --all-targets --all-features -- -D warnings(0 warnings) and the fixture-reading tests (monotone_contracts,child_maturity,concurrent_claims,custody_lineage,date_rolls). -
A regeneration probe found that 344 generator outputs reproduce the fixture bytes exactly.
-
At the final head:
tools/fixtures.py checkandreconciliation/comparison.py checkpassed.tools/assurance/check.pypassed both with and without--base acc357b8.- The unit tests passed: assurance 37, library 64, comparison 26 and swap QuantLib 18.
-
Commit 5: the new checker passes on Linux and Windows. It rejects a 1e-10 change to a price, an edited source-read hash, a changed tolerance, a dropped case and a float turned into an integer.
check.pywith and without--base, the assurance tests andtools/library/check.pypassed. The other 154 Python steps after step 600 that need no build pass on Linux. The 51 Python steps that need a built binary and the 134 cargo steps after it were first run in CI. -
Commit 4: in a fresh clone with no materialized fixtures, the full Offline Quantitative Comparison job passed: 392 retained QuantLib rows, 973 swap values, 35,820 CDS values and the credit calibration.
check.pyand the assurance tests passed again with the new workflow. -
CI on
b111510e(run 39447079562): every job passed, including all 946 steps of Bounded Rust Assurance, Excel Add-in (Windows) withdotnet test, Test, Offline Quantitative Comparison, and the Java and QuantLib workflows.
Windows:
- The Excel job's
library_workflowparity (110 cases) and the five parity steps after it passed. - The Excel test project builds, and the managed
RawJsonChunks…test passes.
Not verified here
- The full Excel job (36 release builds plus
dotnet test) was replayed locally only through its first six parity steps. CI is its first full run, including the 14 P&L P/Invoke tests fixed in commit 4. - This PR does not review #132's 203k lines of Rust and 39k lines of Python in depth. That work was produced and self-attested by Codex. CodeRabbit skipped #132 because it has too many files.
- With byte pins gone, changes to fixtures and comparators rely on pull-request review. The
--basechecks still block wider tolerances and removed coverage. - As in #132, no library, model, platform or production certification is claimed.
🤖 Generated with Claude Code