numpy-vector-store 0.6.0__tar.gz → 0.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. numpy_vector_store-0.7.1/.github/actionlint.yaml +4 -0
  2. numpy_vector_store-0.7.1/.github/workflows/checks.yml +233 -0
  3. numpy_vector_store-0.7.1/.github/workflows/publish-pypi.yml +43 -0
  4. numpy_vector_store-0.7.1/.github/workflows/publish-testpypi.yml +40 -0
  5. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/.gitignore +2 -0
  6. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/CHANGELOG.md +201 -2
  7. numpy_vector_store-0.7.1/COMPATIBILITY.md +145 -0
  8. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/MIGRATION.md +10 -5
  9. numpy_vector_store-0.7.1/PKG-INFO +284 -0
  10. numpy_vector_store-0.7.1/README.md +260 -0
  11. numpy_vector_store-0.7.1/RELEASING.md +108 -0
  12. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/ROADMAP.md +105 -6
  13. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/pyproject.toml +23 -8
  14. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/src/numpy_vector_store/__init__.py +2 -2
  15. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/src/numpy_vector_store/vector_store.py +19 -9
  16. numpy_vector_store-0.7.1/tests/test_package.py +34 -0
  17. numpy_vector_store-0.7.1/tests/test_release_version.py +111 -0
  18. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/tests/test_vector_store.py +265 -1
  19. numpy_vector_store-0.7.1/tools/verify_installed_distribution.py +67 -0
  20. numpy_vector_store-0.7.1/tools/verify_release_version.py +169 -0
  21. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/uv.lock +77 -40
  22. numpy_vector_store-0.6.0/.github/workflows/checks.yml +0 -114
  23. numpy_vector_store-0.6.0/.github/workflows/publish-pypi.yml +0 -40
  24. numpy_vector_store-0.6.0/.github/workflows/publish-testpypi.yml +0 -40
  25. numpy_vector_store-0.6.0/PKG-INFO +0 -512
  26. numpy_vector_store-0.6.0/README.md +0 -489
  27. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/.github/FUNDING.yml +0 -0
  28. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/LICENSE +0 -0
  29. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/benchmarks/README.md +0 -0
  30. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/benchmarks/__init__.py +0 -0
  31. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/benchmarks/benchmark.py +0 -0
  32. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/justfile +0 -0
  33. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/src/numpy_vector_store/py.typed +0 -0
  34. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/tests/__init__.py +0 -0
  35. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/tests/fixtures/README.md +0 -0
  36. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/tests/fixtures/vector-store-0.4.0-format-v1.npz +0 -0
  37. {numpy_vector_store-0.6.0 → numpy_vector_store-0.7.1}/tests/test_benchmark.py +0 -0
@@ -0,0 +1,4 @@
1
+ # Blacksmith uses ephemeral runners registered through GitHub's self-hosted API.
2
+ self-hosted-runner:
3
+ labels:
4
+ - blacksmith-4vcpu-ubuntu-2404
@@ -0,0 +1,233 @@
1
+ name: Checks
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ release-tag:
7
+ description: Optional v-prefixed tag that must match the distributions
8
+ required: false
9
+ type: string
10
+ default: ""
11
+ outputs:
12
+ distributions-artifact-id:
13
+ description: Artifact ID for the verified wheel and source distribution
14
+ value: ${{ jobs.distributions.outputs.artifact-id }}
15
+ pull_request:
16
+ push:
17
+ branches:
18
+ - main
19
+ workflow_dispatch:
20
+
21
+ concurrency:
22
+ group: checks-${{ github.workflow }}-${{ github.ref }}
23
+ cancel-in-progress: true
24
+
25
+ permissions:
26
+ contents: read
27
+
28
+ jobs:
29
+ quality:
30
+ name: Lint, format, and type-check
31
+ runs-on: blacksmith-4vcpu-ubuntu-2404
32
+ timeout-minutes: 10
33
+
34
+ steps:
35
+ - name: Check out repository
36
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
37
+ with:
38
+ persist-credentials: false
39
+
40
+ - name: Set up Python
41
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
42
+ with:
43
+ python-version: "3.13"
44
+
45
+ - name: Set up uv
46
+ uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
47
+ with:
48
+ version: "0.13.7"
49
+ python-version: "3.13"
50
+ enable-cache: true
51
+
52
+ - name: Install project dependencies
53
+ run: uv sync --locked --group dev
54
+
55
+ - name: Run Ruff lint checks
56
+ run: uv run --locked ruff check .
57
+
58
+ - name: Check Ruff formatting
59
+ run: uv run --locked ruff format --check .
60
+
61
+ - name: Run mypy
62
+ run: uv run --locked mypy src/ benchmarks/ tools/
63
+
64
+ tests:
65
+ name: Test Python ${{ matrix.python-version }}
66
+ runs-on: blacksmith-4vcpu-ubuntu-2404
67
+ timeout-minutes: 15
68
+ strategy:
69
+ fail-fast: false
70
+ matrix:
71
+ python-version:
72
+ - "3.11"
73
+ - "3.12"
74
+ - "3.13"
75
+ - "3.14"
76
+
77
+ steps:
78
+ - name: Check out repository
79
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
80
+ with:
81
+ persist-credentials: false
82
+
83
+ - name: Set up Python
84
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
85
+ with:
86
+ python-version: ${{ matrix.python-version }}
87
+
88
+ - name: Set up uv
89
+ uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
90
+ with:
91
+ version: "0.13.7"
92
+ python-version: ${{ matrix.python-version }}
93
+ enable-cache: true
94
+
95
+ - name: Install project dependencies
96
+ run: uv sync --locked --group dev
97
+
98
+ - name: Run tests
99
+ run: uv run --locked pytest
100
+
101
+ windows:
102
+ name: Test Windows on Python 3.13
103
+ runs-on: windows-latest
104
+ timeout-minutes: 15
105
+
106
+ steps:
107
+ - name: Check out repository
108
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
109
+ with:
110
+ persist-credentials: false
111
+
112
+ - name: Set up Python
113
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
114
+ with:
115
+ python-version: "3.13"
116
+
117
+ - name: Set up uv
118
+ uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
119
+ with:
120
+ version: "0.13.7"
121
+ python-version: "3.13"
122
+ enable-cache: true
123
+
124
+ - name: Install project dependencies
125
+ run: uv sync --locked --group dev
126
+
127
+ - name: Run tests
128
+ run: uv run --locked pytest
129
+
130
+ minimum-numpy:
131
+ name: Test minimum NumPy on Python 3.11
132
+ runs-on: blacksmith-4vcpu-ubuntu-2404
133
+ timeout-minutes: 15
134
+
135
+ steps:
136
+ - name: Check out repository
137
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
138
+ with:
139
+ persist-credentials: false
140
+
141
+ - name: Set up Python
142
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
143
+ with:
144
+ python-version: "3.11"
145
+
146
+ - name: Set up uv
147
+ uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
148
+ with:
149
+ version: "0.13.7"
150
+ python-version: "3.11"
151
+ enable-cache: true
152
+
153
+ - name: Run tests with the minimum NumPy version
154
+ run: >-
155
+ uv run
156
+ --isolated
157
+ --no-project
158
+ --python 3.11
159
+ --with-editable .
160
+ --with numpy==1.23.2
161
+ --with pytest==8.4.2
162
+ python -m pytest
163
+
164
+ distributions:
165
+ name: Build and test distributions
166
+ runs-on: blacksmith-4vcpu-ubuntu-2404
167
+ timeout-minutes: 15
168
+ outputs:
169
+ artifact-id: ${{ steps.upload.outputs.artifact-id }}
170
+
171
+ steps:
172
+ - name: Check out repository
173
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
174
+ with:
175
+ persist-credentials: false
176
+
177
+ - name: Set up Python
178
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
179
+ with:
180
+ python-version: "3.11"
181
+
182
+ - name: Set up uv
183
+ uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
184
+ with:
185
+ version: "0.13.7"
186
+ python-version: "3.11"
187
+ enable-cache: true
188
+
189
+ - name: Build wheel and source distribution
190
+ run: uv build --out-dir dist
191
+
192
+ - name: Verify release versions
193
+ env:
194
+ RELEASE_TAG: ${{ inputs.release-tag }}
195
+ run: |
196
+ if [[ -n "$RELEASE_TAG" ]]; then
197
+ uv run --locked python tools/verify_release_version.py --tag "$RELEASE_TAG"
198
+ else
199
+ uv run --locked python tools/verify_release_version.py
200
+ fi
201
+
202
+ - name: Check distribution metadata
203
+ run: uvx --from twine==7.0.0 twine check --strict dist/*
204
+
205
+ - name: Test installed wheel
206
+ run: >-
207
+ uv run
208
+ --isolated
209
+ --no-project
210
+ --python 3.11
211
+ --with ./dist/*.whl
212
+ python tools/verify_installed_distribution.py
213
+
214
+ - name: Test installed source distribution
215
+ run: >-
216
+ uv run
217
+ --isolated
218
+ --no-project
219
+ --python 3.11
220
+ --with ./dist/*.tar.gz
221
+ python tools/verify_installed_distribution.py
222
+
223
+ - name: Upload verified distributions
224
+ id: upload
225
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
226
+ with:
227
+ name: python-package-distributions-${{ github.run_id }}-${{ github.run_attempt }}
228
+ path: |
229
+ dist/*.whl
230
+ dist/*.tar.gz
231
+ if-no-files-found: error
232
+ retention-days: 7
233
+ compression-level: 0
@@ -0,0 +1,43 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - published
7
+
8
+ concurrency:
9
+ group: publish-pypi
10
+ cancel-in-progress: false
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ validate:
17
+ name: Validate release
18
+ uses: ./.github/workflows/checks.yml
19
+ with:
20
+ release-tag: ${{ github.event.release.tag_name }}
21
+
22
+ publish-pypi:
23
+ name: Publish to PyPI
24
+ needs: validate
25
+ runs-on: ubuntu-latest
26
+ timeout-minutes: 10
27
+ environment:
28
+ name: pypi
29
+ url: https://pypi.org/p/numpy-vector-store
30
+ permissions:
31
+ id-token: write
32
+
33
+ steps:
34
+ - name: Download verified distributions
35
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
36
+ with:
37
+ artifact-ids: ${{ needs.validate.outputs.distributions-artifact-id }}
38
+ path: dist
39
+
40
+ - name: Publish package distributions to PyPI
41
+ uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # release/v1
42
+ with:
43
+ packages-dir: dist/
@@ -0,0 +1,40 @@
1
+ name: Publish to TestPyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ concurrency:
7
+ group: publish-testpypi
8
+ cancel-in-progress: false
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ validate:
15
+ name: Validate release candidate
16
+ uses: ./.github/workflows/checks.yml
17
+
18
+ publish-testpypi:
19
+ name: Publish to TestPyPI
20
+ needs: validate
21
+ runs-on: ubuntu-latest
22
+ timeout-minutes: 10
23
+ environment:
24
+ name: testpypi
25
+ url: https://test.pypi.org/p/numpy-vector-store
26
+ permissions:
27
+ id-token: write
28
+
29
+ steps:
30
+ - name: Download verified distributions
31
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
32
+ with:
33
+ artifact-ids: ${{ needs.validate.outputs.distributions-artifact-id }}
34
+ path: dist
35
+
36
+ - name: Publish package distributions to TestPyPI
37
+ uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # release/v1
38
+ with:
39
+ packages-dir: dist/
40
+ repository-url: https://test.pypi.org/legacy/
@@ -153,6 +153,8 @@ venv.bak/
153
153
 
154
154
  # mkdocs documentation
155
155
  /site
156
+ /.venv-docs/
157
+ /.cache/zensical/
156
158
 
157
159
  # mypy
158
160
  .mypy_cache/
@@ -1,10 +1,207 @@
1
+ <!-- --8<-- [start:introduction] -->
2
+
1
3
  # Changelog
2
4
 
3
5
  This changelog records user-visible changes to NumPy Vector Store. Earlier
4
6
  release notes remain available on the
5
- [GitHub releases page](https://github.com/tvanreenen/numpy-vector-store/releases).
7
+ [GitHub releases page](https://github.com/tvr-works/numpy-vector-store/releases).
8
+
9
+ <!-- --8<-- [end:introduction] -->
10
+
11
+ ## 0.7.1 - 2026-11-13
12
+
13
+ This patch release corrects two search edge cases without changing the public
14
+ API, runtime requirements, or archive format. It also includes the documentation,
15
+ package-presentation, and release-workflow improvements merged since 0.7.0.
16
+
17
+ Most applications can upgrade without code changes or data migration. The
18
+ observable corrections are that very small normalized Euclidean distances no
19
+ longer collapse to zero, and valid row filters containing different integer
20
+ types are accepted.
21
+
22
+ ### Search correctness
23
+
24
+ - Accumulate normalized Euclidean squared differences in `float64` before
25
+ taking their square root. Previously, a small difference could be represented
26
+ in `float32` while its square was too small to represent, making a nonzero
27
+ distance appear to be zero.
28
+ - Preserve nearest-row ordering, `top_k` selection, and zero-distance threshold
29
+ filtering for these cases, both with and without `within_rows`. Vector
30
+ storage remains `float32`; raw Euclidean, cosine, and dot-product calculation
31
+ paths are unchanged.
32
+ - Accept mixed Python and NumPy integer row filters such as
33
+ `[0, np.uint64(1)]`. NumPy can infer a floating-point array for mixed signed
34
+ and unsigned integers; validation now retains the original values when that
35
+ conversion would erase their integer types.
36
+ - Keep bulk validation for ordinary integer lists, tuples, and ranges, and
37
+ preserve the native NumPy integer-array fast path. Custom integer-index
38
+ objects continue to use the existing per-element validation fallback.
39
+ - Continue rejecting booleans, floating-point indexes, malformed shapes,
40
+ duplicate rows, and out-of-range indexes. Validation remains independent of
41
+ whether the store is empty.
42
+
43
+ ### Documentation and package presentation
44
+
45
+ - Add the searchable [documentation website](https://vectors.tvr.works/) with
46
+ getting-started, search/filtering, persistence, ownership, deployment,
47
+ performance, API-reference, and compatibility guidance.
48
+ - Clarify the README's small-to-medium, in-process search positioning. Explain
49
+ deployment with an archive shipped alongside application code, where each
50
+ worker or replica loads its own in-memory store without a separate vector
51
+ database or shared-write coordination.
52
+ - Update package project links to the existing repository's new
53
+ `tvr-works/numpy-vector-store` location and add the documentation URL.
54
+ Distribution and import names remain `numpy-vector-store` and
55
+ `numpy_vector_store`.
56
+ - Keep documentation source, generated output, build tools, and the independent
57
+ docs environment out of the source distribution. Wheels remain package-only;
58
+ documentation tools add no runtime dependency.
59
+ - Build the public reference and executable guide examples against an exact,
60
+ verified published wheel in a separate locked environment. Development
61
+ changes and release preparation no longer replace the released API reference.
62
+ Prepared changelog entries stay out of the public site until its edition is
63
+ advanced after publication.
64
+
65
+ ### Release validation and publishing
66
+
67
+ - Build distributions once in the validation workflow, check their versions and
68
+ metadata, and smoke-test clean wheel and source-distribution installations.
69
+ The publishing job downloads that verified artifact by its immutable ID
70
+ rather than rebuilding it with publishing credentials available.
71
+ - Pin the Hatchling build backend and publishing/validation tool revisions.
72
+ Retain the supported Python matrix, Windows coverage, and minimum-NumPy check.
73
+ - Configure environment-bound Trusted Publishers for the organization-owned
74
+ repository and document post-upload provenance and installation checks.
75
+ Production cutover is confirmed only after an authorized upload passes those
76
+ checks; the new configuration is not treated as verified merely because it
77
+ is present.
78
+ - Add independent documentation CI that checks the built site and runs rendered
79
+ examples. Pages publication requires successful docs CI for the exact source
80
+ commit, and branch previews are marked not to be indexed.
81
+
82
+ ### Upgrade notes
83
+
84
+ - Continue supporting Python 3.11 through 3.14 and NumPy 1.23.2 or newer.
85
+ - Keep the existing methods, arguments, result types, and input-error categories.
86
+ - Continue reading and writing trusted format-version-1 archives without
87
+ conversion. Opaque metadata still uses pickle-backed object arrays; do not
88
+ open untrusted archives.
89
+ - No new feature family, API removal, runtime dependency, or archive migration
90
+ is introduced. These are corrections within the existing 0.7 contract, not
91
+ the separate 1.0 stability declaration.
92
+
93
+ <!-- --8<-- [start:published] -->
6
94
 
7
- ## 0.6.0 - 2026-08-21
95
+ ## 0.7.0 - 2026-08-24
96
+
97
+ This release closes the remaining public contract gaps found during the 1.0
98
+ readiness audit. It rejects two forms of lossy NumPy coercion, makes a bound
99
+ archive path stable for the lifetime of its store, and publishes the API and
100
+ compatibility policy intended for 1.x. It also adds release checks that enforce
101
+ the package version and distribution metadata before publication.
102
+
103
+ Valid, documented 0.6 usage continues to work. Version 0.7 does not add a new
104
+ feature family, remove a documented API, change search ranking, add a runtime
105
+ dependency, or change archive format version 1.
106
+
107
+ ### Public API and 1.x compatibility policy
108
+
109
+ The supported package-level imports are now explicit:
110
+
111
+ ```python
112
+ from numpy_vector_store import VectorHit, VectorStore, __version__
113
+ ```
114
+
115
+ - Add a [public API and compatibility policy](COMPATIBILITY.md) that names the
116
+ supported `VectorStore` methods and properties, `VectorHit` fields, return
117
+ types, ownership behavior, exception classes, and persistence guarantees.
118
+ - Distinguish the supported top-level interface from private helpers, submodule
119
+ layout, subclass hooks, exact error wording, allocation details, and internal
120
+ algorithms.
121
+ - Define the 1.x semantic-versioning, deprecation, removal, Python and NumPy
122
+ support, and archive-compatibility policies before those promises become
123
+ long-term commitments in 1.0.
124
+ - Keep `VectorHit` as an immutable result record whose equality and hashability
125
+ follow its three values. Opaque metadata retains its own comparison and
126
+ hashing behavior; a hit containing a dictionary remains unhashable.
127
+
128
+ The API itself remains centered on `VectorStore`, `VectorHit`, three explicit
129
+ metric methods, typed opaque metadata, and the create/open/save/reload
130
+ persistence lifecycle.
131
+
132
+ ### Lossless numeric input handling
133
+
134
+ - Reject Python row-selector sequences containing a Python or NumPy Boolean,
135
+ including mixed values such as `[0, True]`, before NumPy can coerce the
136
+ Boolean to row zero or one.
137
+ - Preserve the vectorized validation path for native NumPy integer selectors,
138
+ along with the existing shape, uniqueness, and bounds rules.
139
+ - Reject complex vector batches passed to `add()` and complex queries passed to
140
+ every metric method before conversion to `float32` can discard their
141
+ imaginary components. This includes complex dtypes whose current values have
142
+ a zero imaginary part.
143
+ - Apply complex-query validation before empty-store and empty-filter shortcuts,
144
+ so the accepted query contract does not depend on current store state.
145
+
146
+ These inputs were accepted only through implicit NumPy conversion. Calls that
147
+ deliberately used Boolean row indexes or complex vectors now raise `TypeError`;
148
+ real-valued integer and floating-point inputs keep their existing behavior.
149
+
150
+ ### Stable archive bindings
151
+
152
+ - Anchor a relative path to the current working directory when `save(path)` or
153
+ `VectorStore.open(path)` first binds it.
154
+ - Return that anchored absolute path from `file_path` and keep later `save()` and
155
+ `reload()` calls pointed at the same archive if the process changes working
156
+ directory.
157
+ - Preserve extensionless `.npz` resolution and lexical path behavior. Anchoring
158
+ does not resolve `..` components or dereference symlinks, so ordinary
159
+ filesystem replacement semantics remain intact.
160
+ - Keep Save As transactional: a new binding becomes visible only after the new
161
+ archive has been written successfully.
162
+
163
+ Format version 1 is unchanged, and no archive conversion is required. Code that
164
+ compares `file_path` with a relative path should compare against its anchored
165
+ absolute form. Code that intentionally changed directories to redirect a later
166
+ pathless save should pass the new destination explicitly to `save(path)`.
167
+
168
+ ### Distribution and release safeguards
169
+
170
+ - Publish the MIT license as an SPDX expression and include `LICENSE` in both
171
+ the wheel and source distribution.
172
+ - Declare the existing `py.typed` marker through the `Typing :: Typed`
173
+ classifier and identify 0.7 as the project's beta adoption cycle before 1.0.
174
+ - Verify that the source `__version__`, GitHub release tag, wheel metadata, and
175
+ source-distribution metadata agree before publishing to PyPI. The verifier
176
+ also requires exactly one wheel and one source distribution so stale build
177
+ output cannot be uploaded accidentally.
178
+ - Pin remote GitHub Actions to immutable commits while retaining readable
179
+ release comments beside each pin.
180
+ - Run the complete test suite on Windows with Python 3.13 in addition to the
181
+ supported Python 3.11 through 3.14 matrix on Linux and the Python 3.11 minimum
182
+ NumPy check.
183
+ - Add regression coverage for unexpected archive fields, nonpositive persisted
184
+ dimensions, malformed persisted array shapes, and platform-specific
185
+ filesystem exception and permission behavior.
186
+
187
+ The release verifier and benchmark tools remain outside the runtime wheel and
188
+ add no package dependency.
189
+
190
+ ### Runtime compatibility and upgrade notes
191
+
192
+ - Continue supporting Python 3.11 through 3.14 and NumPy 1.23.2 or newer.
193
+ - Continue reading and writing self-describing format-version-1 archives,
194
+ including archives created by the published 0.4 package.
195
+ - Continue treating persistence as a trusted-file feature because opaque
196
+ metadata uses pickle-backed NumPy object arrays.
197
+ - Require no data migration when upgrading from 0.6.
198
+
199
+ Most applications can upgrade without code changes. Review only code that used
200
+ Boolean row selectors, supplied complex vectors or queries, compared a bound
201
+ `file_path` with a relative path, or relied on a later working-directory change
202
+ to redirect a bound store.
203
+
204
+ ## 0.6.0 - 2026-08-22
8
205
 
9
206
  This release makes the existing API's input and failure contracts predictable
10
207
  before 1.0. It closes cases where the same invalid call could behave
@@ -431,3 +628,5 @@ intentionally break valid existing usage or change the `.npz` archive format.
431
628
  - Environments using NumPy 1.20 must upgrade to NumPy 1.21.3 or newer.
432
629
  - Inputs that previously produced `nan`, `inf`, or unreliable rankings now
433
630
  raise `ValueError` instead.
631
+
632
+ <!-- --8<-- [end:published] -->
@@ -0,0 +1,145 @@
1
+ # Public API and compatibility policy
2
+
3
+ NumPy Vector Store 0.7 publishes the contract intended for 1.0 so applications
4
+ can evaluate it before the project makes a long-term stability commitment. The
5
+ package remains pre-1.0 until the 0.7 API has completed a normal release cycle.
6
+
7
+ This policy separates the small supported interface from implementation details
8
+ that may continue to improve during 1.x.
9
+
10
+ ## Supported public API
11
+
12
+ Import supported names from the top-level package:
13
+
14
+ ```python
15
+ from numpy_vector_store import VectorHit, VectorStore, __version__
16
+ ```
17
+
18
+ These are the package-level public names declared by `numpy_vector_store.__all__`:
19
+
20
+ - `VectorStore`, including its constructor, `len(store)`, and the documented
21
+ methods and properties below.
22
+ - `VectorHit`, including its read-only `index`, `value`, and `metadata` fields.
23
+ - `__version__`, the installed package version as a string.
24
+
25
+ The supported `VectorStore` surface is:
26
+
27
+ | Area | Public interface |
28
+ |---|---|
29
+ | Create | `VectorStore(dimensions, *, normalize=True)` |
30
+ | Inspect configuration | `dimensions`, `normalize`, `file_path` |
31
+ | Inspect rows | `vectors`, `metadata`, `len(store)` |
32
+ | Change rows | `add(vectors, metadata)`, `clear()` |
33
+ | Retrieve one row | `get(index)` |
34
+ | Search | `cosine_search(...)`, `dot_search(...)`, `euclidean_search(...)` |
35
+ | Persist | `VectorStore.open(path)`, `save(path)`, `save()`, `reload()` |
36
+
37
+ The public contract includes documented signatures, accepted input categories,
38
+ return types, public type annotations, state and ownership behavior, search
39
+ ordering, and exception classes. The `VectorStore` generic parameter describes
40
+ its metadata payload type and flows through row retrieval and search results.
41
+ The contract also includes the documented `float32` vector representation and
42
+ format-version-1 archive schema. Exact exception messages are explanatory text,
43
+ not identifiers for application logic.
44
+
45
+ Importing from `numpy_vector_store.vector_store` may work, but the submodule
46
+ layout is an implementation detail. Applications should use top-level imports.
47
+ Names beginning with a single underscore, private object state, spare-capacity
48
+ layout, and internal calculation steps are not public API.
49
+
50
+ `VectorStore` is not designed as a subclass extension framework. Subclassing is
51
+ not prohibited, but overriding methods or depending on private helpers and state
52
+ is outside the compatibility promise. Prefer composition when application code
53
+ needs behavior around a store.
54
+
55
+ ## `VectorHit` and opaque metadata
56
+
57
+ `VectorHit` is an immutable result record. Its fields cannot be reassigned, but
58
+ the `metadata` value remains the same opaque application object held by the
59
+ store. A mutable metadata payload can still be changed through that object.
60
+
61
+ Equality and hashability follow the values stored in the three fields. There is
62
+ no package-specific metadata comparison or hashing policy. In particular:
63
+
64
+ - A hit containing a dictionary or another unhashable payload is unhashable.
65
+ - A metadata type with non-Boolean equality, such as a NumPy array, can make
66
+ whole-hit equality return a non-Boolean value or raise when converted to a
67
+ truth value.
68
+ - A metadata type with application-defined equality keeps those semantics.
69
+
70
+ Use `hit.index` or an immutable application identifier inside `hit.metadata`
71
+ when code needs a stable key. Do not assume every possible metadata payload
72
+ makes the complete `VectorHit` suitable for a set, dictionary key, or Boolean
73
+ equality assertion.
74
+
75
+ ## Semantic versioning after 1.0
76
+
77
+ Starting with 1.0, release numbers follow
78
+ [Semantic Versioning 2.0.0](https://semver.org/) and communicate changes to the
79
+ documented public API:
80
+
81
+ - Patch releases contain backward-compatible defect fixes, documentation
82
+ corrections, and internal improvements. A patch may correct behavior that
83
+ contradicts the documented contract, and the release notes will identify the
84
+ affected case.
85
+ - Minor releases add backward-compatible functionality and may deprecate public
86
+ API. They do not remove or incompatibly change documented public API.
87
+ - Major releases may remove deprecated API or make other incompatible public
88
+ contract changes.
89
+
90
+ A public API deprecation will appear in the documentation and changelog and
91
+ will emit a warning where a runtime warning is practical. Removal waits for a
92
+ later major release and will have at least one minor release of prior
93
+ deprecation.
94
+
95
+ Exact error wording, object representations, private names, submodule layout,
96
+ internal algorithms, allocation strategy, benchmark timings, and undocumented
97
+ side effects may change in any release. Changes to these details must still
98
+ preserve the documented results and ownership rules.
99
+
100
+ ## Archive compatibility
101
+
102
+ Archive format versions are independent of package versions. Format version 1
103
+ is the stable persistence contract for 1.x:
104
+
105
+ - Every 1.x release will continue reading and writing valid format-version-1
106
+ archives.
107
+ - A mandatory replacement for format version 1 requires a major package
108
+ release and a documented migration path.
109
+ - A new archive format may appear during 1.x only as an explicit opt-in while
110
+ format-version-1 read and write support remains available.
111
+ - An older reader is not expected to understand an arbitrary newer archive
112
+ format. Compatibility is a newer-reader promise, not a future-format promise
113
+ for already published code.
114
+
115
+ Unversioned archives containing only `vectors` and `metadata` remain outside
116
+ this contract because they do not record dimensions or normalization semantics.
117
+
118
+ Format compatibility does not make every Python metadata object portable.
119
+ Opaque metadata uses pickle-backed NumPy object arrays and may depend on the
120
+ same application classes, import paths, and compatible dependencies being
121
+ available when it is opened. Archives must come from a trusted source. The
122
+ library does not treat untrusted pickle data as safe input.
123
+
124
+ ## Python and NumPy support
125
+
126
+ The Python versions listed in package metadata are tested in CI. The declared
127
+ minimum NumPy version is tested with the oldest supported Python version.
128
+
129
+ Support for a Python or NumPy version may be removed in a minor release after
130
+ its relevant upstream support window or ecosystem compatibility makes continued
131
+ testing impractical. Such a change will be made in package metadata and called
132
+ out in the changelog and release notes. Dropping a runtime version does not
133
+ remove callable API from applications running on a supported interpreter.
134
+
135
+ ## Performance expectations
136
+
137
+ Search results, metric definitions, threshold behavior, deterministic tie
138
+ ordering, and filtered-row semantics are public behavior. The implementation
139
+ may change how it produces those results.
140
+
141
+ Published benchmark measurements are reference evidence, not latency or memory
142
+ guarantees. Hardware, NumPy, BLAS, process load, vector shape, and metadata all
143
+ affect observed performance. Structural regressions such as repeated full-store
144
+ copies during ordinary ingestion or unnecessary unfiltered search copies remain
145
+ covered by tests rather than fixed wall-clock promises.