Status: accepted for publication
Prepared: 2026-08-13
Target: v1.7.0
Origin: external upgrade review of 1.4.1 → 1.6.2 against a live
3,586-drawer store (Jarvis, for Lou), 2026-08-11
By the Release Cadence tiebreak — if a user would need to read the changelog to know what changed, it is a MINOR — two changes qualify:
cairntir_home()/models, so the ONNX model downloads once more.cairntir reindex now refuses a store containing drawers wider than the
embedder window, where it previously succeeded and silently truncated them.Everything else is a fix. This is not a patch.
The embedding space is unchanged from 1.5.0: same model, same 512 dimensions,
same embedding_space_id. Only the location of the cached model file
changes. The live store was checked before tagging and reports
state=verified dim=512, so no migration or reindex is part of this upgrade.
test_the_window_covers_the_whole_live_corpusscripts/check_release_tags.py) — cleancairntir-1.7.0.tar.gz, cairntir-1.7.0-py3-none-any.whlRead before tagging, without writing:
db : %LOCALAPPDATA%\cairntir\cairntir.db
model cache : %LOCALAPPDATA%\cairntir\models
drawers : 425 wings: 24
longest drawer: #239 8,924 chars 2,377 tokens
headroom : 3.45x (window 8,192)
over window : 0 drawers
index state : verified dim=512
The rewritten window test measures this store with the real tokenizer rather than comparing two literals. Note that 2,377 tokens matches the constant the old test froze — the literal was accurate for this store, which is precisely why the test stayed green while being false on the reviewer’s 3,586-drawer corpus, where the longest drawer is 6,414 tokens and the true headroom is 1.28x.
Fresh venv, wheel installed from dist/, run from outside the source tree:
cairntir version → cairntir 1.7.0cairntir --help redirected to a file → exit 0, 60 lines, no cp1252 crash
(the Windows encoding regression fixed in 1.2.0 stays fixed)cairntir recipe-list → all three bundled recipes resolved from
site-packages/cairntir/recipes/bundled/: codeglass, decision-replay,
signal-readerTwo fixes were confirmed by the install itself. The model downloaded into the
new anchored cache at %LOCALAPPDATA%\cairntir\models\, proving the cache
relocation, and the directory it created is
models--xenova--jina-embeddings-v2-small-en — direct confirmation of the
provenance finding that the declared jinaai/… identifier resolves to a
third-party re-conversion.
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f to stderr while
printing the correct version to stdout. It did not reproduce across four
subsequent attempts, including one with the update-check cache deleted to
force a cold PyPI check, and it never appears outside the source tree. Cause
unidentified. Recorded rather than explained away; if it recurs, start with
the update-notifier thread, whose exception handling catches OSError,
URLError, JSONDecodeError and TimeoutError but not
UnicodeDecodeError.ModelSource has no revision field, so
the download takes the upstream repository’s HEAD and integrity checking is
size-only. Two machines provisioned a month apart can hold different weights
under the same model name. Closing this needs a fastembed API that does not
exist yet; the exposure is documented on PRODUCTION_MODEL.CLAUDE.md and this changelog.Tag v1.7.0 pushed to trigger trusted publishing. Confirm the GitHub Release,
the PyPI upload, and both provenance attestations before considering the
release done. If a tag push creates no workflow run, check
https://www.githubstatus.com before suspecting the workflow — that was the
cause in 1.4.1, and the escape hatch is
gh workflow run release.yml --ref v1.7.0, which is legitimate because the
publish jobs gate on the ref being a tag.
PyPI’s aggregate /pypi/cairntir/json lags the per-version endpoint by
minutes. Checking only the aggregate immediately after publishing produces a
false “publish failed” verdict. Confirm with /pypi/cairntir/1.7.0/json.