From bf4534b80f6ffb747fd894167ba3c11f7b10a41a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 14 Jun 2026 14:29:54 +0000 Subject: [PATCH 1/3] Fix macOS wheel build: set MACOSX_DEPLOYMENT_TARGET=10.14 cibuildwheel defaults the x86_64 macOS deployment target to 10.9, but nanobind's C++17 runtime uses aligned new/delete which requires macOS 10.13+. Every macOS wheel job failed to compile nanobind (nb_type.cpp: 'aligned deallocation function ... only available on macOS 10.13 or newer'). Pin the deployment target to 10.14 for the macOS builds. --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 41eb3cc9..0cb07840 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,6 +125,9 @@ test-command = 'python -c "import nns, nns._nnscore as c; print(c.lpm(2.0, 0.0, [tool.cibuildwheel.macos] archs = ["x86_64", "arm64"] +# nanobind's C++17 runtime uses aligned new/delete, which requires macOS 10.13+. +# cibuildwheel otherwise defaults x86_64 to 10.9 and the build fails to compile. +environment = { MACOSX_DEPLOYMENT_TARGET = "10.14" } [tool.cibuildwheel.windows] archs = ["AMD64"] From 89442bdd64a950bab2556b34fd09db37278a37f6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 14 Jun 2026 14:50:46 +0000 Subject: [PATCH 2/3] Fix Linux wheel test: build on manylinux_2_28 cibuildwheel's default Linux image is manylinux2014 (glibc 2.17), but numpy/scipy only publish manylinux_2_27/_2_28 wheels. In the glibc 2.17 test container those wheels are incompatible, so pip falls back to compiling scipy from source, which needs OpenBLAS/Fortran that aren't present, and the wheel smoke-test fails. Our runtime deps already require glibc >= 2.27, so manylinux2014 wheels were never installable anyway. Build and test the x86_64 Linux wheels on manylinux_2_28 to match the dependencies' wheel floor. musllinux_1_2 (the cibuildwheel default) is pinned explicitly; it already has matching numpy/scipy wheels. --- pyproject.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0cb07840..588f2e88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,6 +120,12 @@ mypy_path = ["tests"] build = "cp311-* cp312-* cp313-*" skip = ["pp*", "*_i686", "*-win32", "*-musllinux_i686"] build-frontend = "build" +# Build/test on glibc 2.28: numpy/scipy only publish manylinux_2_27/_2_28 wheels, +# so the default manylinux2014 (glibc 2.17) test image cannot install them and +# falls back to compiling scipy from source (no OpenBLAS) and fails. musllinux_1_2 +# (the cibuildwheel default) already has matching numpy/scipy wheels. +manylinux-x86_64-image = "manylinux_2_28" +musllinux-x86_64-image = "musllinux_1_2" # Smoke-test every built wheel: the native extension imports and computes. test-command = 'python -c "import nns, nns._nnscore as c; print(c.lpm(2.0, 0.0, [-2.0, -1.0, 0.5, 3.0]))"' From 71916a6a5fa01ca6c9dd2548970bb5abdfc90fa2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 14 Jun 2026 15:12:03 +0000 Subject: [PATCH 3/3] Record release provenance: resolve r_commit and core_commit Resolve the two placeholder SHAs in sync/nns_source.json by matching the vendored bytes to upstream history: - r_commit 905b8bbd: the OVVO-Financial/NNS commit that introduced the exact vendored tools/NNS_13.0.tar.gz blob (parent carried a different tarball). Version 13.0 / Date 2026-06-10, Packaged 2026-06-11 03:14 UTC. - core_commit 7f93df9d: the OVVO-Financial/NNS-core commit that authored the exact vendored extern/NNS-core include/src/CMakeLists objects (its parent had different include/src). A later commit carries the identical core forward unchanged. The release provenance gate now passes for a real tagged release. test_unknown_provenance_fails_real_release previously ran the gate against the committed manifest and relied on it carrying placeholder provenance. Point it at a fixture manifest so it tests the unknown-provenance failure behavior without depending on the real manifest being unfilled. --- sync/nns_source.json | 4 ++-- tests/tools/test_release_provenance.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sync/nns_source.json b/sync/nns_source.json index a592d4fb..92867f1c 100644 --- a/sync/nns_source.json +++ b/sync/nns_source.json @@ -1,10 +1,10 @@ { "r_repo": "OVVO-Financial/NNS", - "r_commit": "unknown", + "r_commit": "905b8bbd42b3236bf88aba7f18df7a9a378dbd7b", "r_version": "13.0", "r_src_tree_hash": "654e411bd4e8caabfd57a1a4190eb1d97411e059", "core_repo": "OVVO-Financial/NNS-core", - "core_commit": "unknown", + "core_commit": "7f93df9dff8762df870c1fbba6e03c0469be6e69", "python_repo": "OVVO-Financial/NNS-python", "python_commit": null, "vendored_core_path": "extern/NNS-core", diff --git a/tests/tools/test_release_provenance.py b/tests/tools/test_release_provenance.py index 4cc39e2b..f32a0ae1 100644 --- a/tests/tools/test_release_provenance.py +++ b/tests/tools/test_release_provenance.py @@ -43,8 +43,10 @@ def test_allow_unknown_passes_with_placeholder_provenance() -> None: assert result.returncode == 0, result.stdout + result.stderr -def test_unknown_provenance_fails_real_release() -> None: - result = _run([]) +def test_unknown_provenance_fails_real_release(tmp_path: Path) -> None: + manifest = tmp_path / "manifest.json" + _write_manifest(manifest) # default r_commit/core_commit are "unknown" + result = _run(["--manifest", str(manifest)]) assert result.returncode != 0 assert "provenance" in (result.stdout + result.stderr).lower()