Define and enforce the 1.x compatibility contract - #29
Merged
Conversation
tvanreenen
marked this pull request as ready for review
August 24, 2026 15:36
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.
Overview
NumPy Vector Store is close enough to 1.0 that users need to know which parts of the library they can safely build against, and maintainers need release checks that enforce those promises. This PR defines the intended 1.x compatibility contract and adds the repository-owned safeguards needed to publish that contract with confidence during the 0.7 adoption cycle.
This remains a hardening change. It does not add a new feature family, remove an API, change search results, or introduce a new archive format.
What changes
VectorStore,VectorHit, and__version__as the supported top-level package exports and tests that declaration.VectorHitcomparison behavior, deprecation rules, Python and NumPy support, performance expectations, and format-version-1 archive guarantees.MITlicense expression, explicit license-file inclusion, theTyping :: Typedclassifier, and Beta maturity for the 0.7 adoption cycle.OSErrorsubclass and checking exact POSIX permission preservation only where the filesystem can represent those bits.Why this helps
Before this change, the package documentation described behavior in several places but did not draw one clear line between supported API and implementation detail. That makes normal maintenance riskier: users may reasonably depend on a submodule path, private helper, exact error message, or incidental
VectorHitbehavior without knowing that it was never intended as a stable interface.The new policy makes the small supported surface easy to find and explains what stability will mean after 1.0. It also protects the persistence promise users care about: every 1.x release will continue to read and write valid format-version-1 archives, while pickle-backed metadata remains explicitly limited to trusted files with compatible application types available.
The publication checks address a different but related risk. A release can pass ordinary tests and still be mislabeled if the GitHub tag, source version, or built metadata is stale. Comparing the values inside the actual wheel and source distribution stops that class of mistake before trusted publishing starts.
User impact
Existing valid applications do not need to change. The constructor, search methods, result values, row ownership, persistence lifecycle, Python and NumPy requirements, and archive format remain unchanged.
Users gain a documented top-level import contract, a concrete 1.x compatibility policy, clearer installation and optional-row examples, correctly declared typing and licensing metadata, cross-platform test evidence, and stronger assurance that the version downloaded from PyPI matches the release they selected.
Code importing from
numpy_vector_store.vector_store, subclassingVectorStore, or depending on private state continues to work where it works today, but the compatibility document now makes clear that those are not supported extension points. No runtime warning or forced migration is introduced.Implementation details
The release verifier uses only the Python standard library. It parses the literal
__version__assignment from the source file, readsVersionfrom the wheel's.dist-info/METADATA, readsVersionfrom the source distribution'sPKG-INFO, and optionally compares thev<version>GitHub release tag. TestPyPI keeps the same artifact checks without requiring a release tag because that workflow is manually dispatched.The Windows job intentionally runs the full suite instead of selecting persistence tests by name. The project is small enough that this remains inexpensive, and the broader run also catches platform-specific path, temporary-file, NumPy, and filesystem behavior without adding wall-clock performance thresholds.
Remote actions use immutable commits because tags and branches can move. The adjacent release comments preserve the human-readable versions so future dependency updates remain straightforward.
Documentation and ancillary changes
COMPATIBILITY.mdand links it from the README and roadmap.pipinstallation command alongside the existing uv example.get()examples to handle its documented optional return before unpacking.Verification
uv lock --checkuv run --locked ruff check .uv run --locked ruff format --check .uv run --locked mypy src/ benchmarks/ tools/v0.6.0, the current source version on this pre-release branch.twine check; both include the MIT license, and the wheel includespy.typed.Release and migration notes
This PR deliberately leaves
__version__at 0.6.0. The separate 0.7.0 release-preparation PR will update the version, write the final changelog entry, mark the milestone complete, and validate clean installation before tagging.No data migration is required. The archive schema remains format version 1, and this change adds no runtime dependency.
The PyPI job retains its existing least-privilege OIDC permissions. This PR does not add a named GitHub deployment environment because that name must be coordinated with the external PyPI Trusted Publisher configuration; adding one unilaterally could block publication rather than protect it.