Skip to content

numpy 2.5.3 + manifold3d 3.5.3 (supersedes #516, #517) — the floors had to move in both files - #547

Merged
ibuilder merged 3 commits into
mainfrom
claude/codebase-audit-roadmap-45656d
Sep 13, 2026
Merged

ibuilder merged 3 commits into
mainfrom
claude/codebase-audit-roadmap-45656d

Conversation

@ibuilder

@ibuilder ibuilder commented Sep 13, 2026 •

Copy link
Copy Markdown
Owner

What & why

Raises numpy to >=2.5.3 and manifold3d to >=3.5.3, and moves the lock to match. Supersedes #516 and #517, dependabot's PRs for these same two floors, both of which fail the API test gate and could never have passed alone.

Why neither dependabot PR could work

The reason is written in the file they were editing. services/api/requirements.in carries it on the numpy line itself:

numpy>=2.5.2 # floor raised WITH services/data/requirements.txt: pip-compile reads
# only this file, so a floor raised only there cannot move the lock

Dependabot edits services/data/requirements.txt. pip-compile never reads it. So the lock kept pinning numpy==2.5.2 / manifold3d==3.5.2, while test_lock_satisfies_requirements — which deliberately reads both requirements files, because the API image runs the data service's code while installing only the API's lock — kept failing on the mismatch.

That is structural, not incidental. No rebase, recreate or re-run could have fixed either PR; the floor had to move in both files at once.

What moved

Exactly two pins. Nothing added, nothing removed.

manifold3d  3.5.2 -> 3.5.3
numpy       2.5.2 -> 2.5.3

Predicted from a measurement before the change was made, then confirmed by CI: lockfile.yml's Verify step has passed on the committed bytes (run 34766807906), which is byte-identity against a fresh compile in python:3.12-slim.

Both versions were checked to exist on PyPI with cp312 manylinux wheels before relying on them.

A note on where the lock came from, because it reverses the previous PR

#546 took its lock bytes by transcribing CI's Verify diff, because a local resolve had produced an unrecognisable 34-package answer. This PR compiles locally. The reversal is deliberate and rests on the correction landed in #546: pip-compile treats an existing output file as constraints and moves only what the inputs force, while a fresh output path preserves nothing and re-resolves the world. Compiled in place, against the real lock, the local tool is the same tool CI runs — and Verify confirms it on a lock with hundreds of hash lines, not just alembic's two.

The clock said it before the diff did. The fresh-path compile took over forty minutes; the in-place compile took thirty-nine seconds, because it only fetched what actually moved. Two runs of "the same" command differing sixty-fold in cost were never the same command.

Transcription was not available here regardless: Verify prints head -60 of its diff, which alembic's two hashes fit inside and manifold3d's dozens of wheel hashes do not, and the artifact with the full file sits behind an egress block in this environment. Both routes end at the same gate, which is what makes either one safe.

Checklist (mirrors CONTRIBUTING.md)

  • Backend: no Python source changed; test_lock_satisfies_requirements, test_declared_imports and test_desktop_paths pass locally
  • Backend: affected test_*.py pass
  • Web: untouched by this change
  • No import cycles introduced (no source change)
  • CHANGELOG.md entry added (newest at top)
  • Version bump — not a release PR
  • No secrets, no competitor names in shipped docs

🤖 Generated with Claude Code

https://claude.ai/code/session_01Tt2XKB83wwNt2nrMbK6eEA


Generated by Claude Code

Summary by CodeRabbit

  • Documentation

    • Added changelog details covering recent maintenance updates, lock-file verification, CI comparisons, and known limitations in reproducing CI output.
  • Maintenance

    • Updated supported package versions for the API and data services to ensure compatibility with the latest approved releases.

…517)

Dependabot raised these floors only in services/data/requirements.txt, and both PRs
fail the API test gate for a reason the tree already documents. services/api/
requirements.in carries the explanation on the numpy line itself: "floor raised WITH
services/data/requirements.txt: pip-compile reads only this file, so a floor raised only
there cannot move the lock."

So the failure is structural rather than incidental. test_lock_satisfies_requirements
reads BOTH requirements files and checks them against requirements.lock -- deliberately,
because the API image RUNS the data service's code while installing only the API's lock,
and a floor raised in the data requirements is otherwise a claim nothing enforces. With
the lock still pinning numpy==2.5.2 and manifold3d==3.5.2, a floor of 2.5.3/3.5.3 is
unsatisfied and the gate fails. Neither PR could ever have gone green alone.

Both floors move here, so pip-compile sees a constraint the existing pins no longer
satisfy, and the lock follows.

MEASURED, NOT ASSUMED: compiling with both floors raised moves EXACTLY TWO pins --
manifold3d 3.5.2 -> 3.5.3 and numpy 2.5.2 -> 2.5.3 -- and nothing else. Both versions
exist on PyPI with cp312 manylinux wheels, checked directly rather than inferred.

This commit deliberately leaves the lock stale, as the alembic bump did: the recompile
belongs in python:3.12-slim, which lockfile.yml provides, and pushing this fires it on
the requirements.in path. Its Verify step is red on this commit alone and prints the
diff the next commit transcribes. That is the documented bootstrap path, not a failure
to chase.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tt2XKB83wwNt2nrMbK6eEA
…orrection said to

Exactly two pins move: numpy 2.5.2 -> 2.5.3 and manifold3d 3.5.2 -> 3.5.3. Zero packages
added, zero removed, nothing else touched -- which is what was predicted before the
floors were raised, from a measurement rather than a hope.

THIS USED THE LOCAL COMPILER, and that is a deliberate reversal of how the alembic lock
in the previous PR was produced. There the lock bytes were transcribed out of CI's Verify
diff, because a local resolve had produced a wildly different answer and could not be
trusted. The cause turned out to be the invocation: pip-compile treats an EXISTING output
file as constraints and moves only what the inputs force, while those runs wrote to fresh
scratch paths where nothing was preserved. Compiled in place, against the real lock, the
local tool is the same tool CI runs.

The runtime says the same thing more loudly than the diff does. The fresh-path compile
took over forty minutes, because it re-resolved and re-hashed the entire graph; this one
took THIRTY-NINE SECONDS, because an in-place compile only has to fetch what actually
changed. A forty-minute run and a forty-second run were never doing the same work, and
that was visible from the start for anyone who thought to look at the clock.

Transcribing from CI was also not available here even if wanted: alembic had two hashes
and fit in the Verify step's `head -60`, while manifold3d alone carries dozens of wheel
hashes, so the printed diff is truncated well before the content ends. The artifact that
holds the full file sits on a host this environment's egress policy blocks. So the choice
was a correctly-invoked local compile or nothing -- and CI's Verify step will confirm
byte-identity either way, which is the property that makes either route safe.

Verified: test_lock_satisfies_requirements (the gate that reads BOTH requirements files
and is the reason #516 and #517 could never pass alone), test_declared_imports and
test_desktop_paths all pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tt2XKB83wwNt2nrMbK6eEA
…e the diff did

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tt2XKB83wwNt2nrMbK6eEA
@coderabbitai

coderabbitai Bot commented Sep 13, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 19b8a07e-8163-4275-b61c-959060e4b434

📥 Commits

Reviewing files that changed from the base of the PR and between 1bd706a and 9ef9ed9.

⛔ Files ignored due to path filters (1)
  • services/api/requirements.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • CHANGELOG.md
  • services/api/requirements.in
  • services/data/requirements.txt

Included review availability: Your plan provides up to 2 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The dependency floors for NumPy and manifold3d were raised in the API and data requirements files. The changelog records the lock recompilation and verification details.

Changes

Dependency update

Layer / File(s) Summary
Raise dependency floors
services/api/requirements.in, services/data/requirements.txt
NumPy now requires at least 2.5.3, and manifold3d now requires at least 3.5.3 in both dependency files.
Record recompilation verification
CHANGELOG.md
The changelog documents the corrected requirements, two-pin recompilation, local and CI lock verification, compile-time differences, and CI output limitations.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Other

Suggested reviewers: claude

Merge Risk: ⚪ Minimal · up to 9ef9e

The dependency floors and lockfile updates are aligned and verified, with no actionable merge-blocking risk identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the two dependency floor changes and explains that both requirements files needed updates. It is somewhat long, but it remains specific and relevant.
Description check ✅ Passed The description includes the required What & why section, explains the dependency and lockfile changes, documents the superseded PRs, and provides a completed checklist with appropriate exceptions for…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/codebase-audit-roadmap-45656d

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ibuilder
ibuilder marked this pull request as ready for review September 13, 2026 16:17
@strix-security

Copy link
Copy Markdown

Strix is installed on this repository, but we couldn't run this PR security review because this workspace's trial has ended. Add a card to resume code reviews here.

So far, Strix has reviewed 28 pull requests, surfaced 3 security issues (1 critical/high) and blocked 2 risky merges across this workspace.

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants