v1.108.284 — A documented setting the storage layer never read
A documented setting the storage layer never read
CODE_INDEX_PATH is described in the env table as "Index storage location", and config.py, process_registry.py, install_pack.py, receipt.py and two server.py sites all read it. IndexStore, SQLiteIndexStore and process_locks._lock_dir hardcoded ~/.code-index and ignored it — so anyone who set the variable got their config from one directory and their indexes and locks from another.
Nothing errored, which is why it survived: an index written to the wrong root is a successful write.
⚠ If you set CODE_INDEX_PATH, read this
Your indexes are not migrated. From this release the variable is honoured, so the next index goes where it points. Anything previously written to ~/.code-index stays there.
Two remedies, both one step:
- point
CODE_INDEX_PATHat~/.code-indexto keep the old location, or - re-index at the new one.
Installs that never set the variable are unaffected — the fallback is unchanged.
CODE_INDEX_PATH= (empty) is treated as unset rather than as ., so a bare export can't scatter indexes into whatever directory the server started in.
How it was found
Isolating the test suite. Any test calling index_folder() without an explicit storage_path was writing the developer's real store — tolerable serially, and not under pytest-xdist, where four workers share one store and its indexwrite and watcher process-lock scopes.
The obvious fix was tried first and failed usefully: pinning storage_path= on the twelve unpinned call sites produced eight failures, because the tests wrote to the pinned store and read back through a loader still on the default. No single knob moved both — and that was the bug. Every test edit was reverted; the fix is three source lines.
What was deliberately left alone
token_tracker's six sites were routed the same way and then reverted. test_v1_108_188.py::test_no_base_path_still_uses_the_default sets CODE_INDEX_PATH to the named store and asserts a no-argument call lands in the default — which this change makes self-contradictory, since the variable then is the default. A test written to pin default-versus-named could no longer express the distinction. Telemetry routing is what v1.108.188 and v1.108.280 pinned deliberately, and it is not the flake, so _savings.json and session_stats.json still resolve to home.
Stated limit
This does not claim the flake is fixed. test_probe_runs_when_identity_true failed once on a Linux CI leg, passed on a re-run of the identical tree, and survived all fourteen bisect pairings. Measured on a full run, the real store now gains nothing and no _watcher_*.signal appears — the contention mechanism it pointed at is removed. That is a different and weaker statement, and it is the one the evidence supports.
Verification
7,894 passed / 17 skipped / 0 failed, with the exit code captured before any pipe. The 3.13 CI-environment reproduce returns the identical totals and skip split. uv run ruff check src/ clean. All 9 CI matrix jobs green on the released SHA before anything was published. Reconciled by same-tree collect: 7,911 with the new test file, 7,902 without — exactly its 9.
Full detail: CHANGELOG.md