docs: RELEASES.md entry for 8.3.1 (full-removal deletes + family-scoped gate)

This commit is contained in:
David Snelling 2026-07-14 10:12:00 -07:00
parent 366f9a91f5
commit c0c68ac6a6

View file

@ -10,10 +10,47 @@ Full auto-generated changelog: `CHANGELOG.md` · Releases: https://github.com/so
---
## v8.3.1 — 2026-07-14 (full-removal deletes + family-scoped migration gate)
Two production-reported fixes in the write/index spine, plus an operator repair path. No API changes;
all behavior changes make previously-wrong states honest.
- **Deleting an entity now removes it completely — no more "ghost" leftovers on disk.** A canonical
noun delete removed the metadata (content) leg but left the entity's `vectors.json` and its `<id>/`
directory behind. Consequences observed in a production deployment: deleted rows were
indistinguishable on disk from damage scars, enumerated counts inflated monotonically with every
delete (the leftovers were counted forever), and locator-style reads hit unreadable ghost rows.
`remove()`/`removeMany()`/`deleteNoun`/`deleteVerb` now remove **both legs and the entity
container**, with a full two-leg before-image rollback inside the transaction. The generation log
still holds the delete's before-image, so `asOf()` time-travel reconstructs deleted entities exactly
as before — this is live-HEAD hygiene, not a history change. This also fixes **duplicate `readdir`
entries for re-created VFS paths** at the root: with no ghost state, a delete always unposts its
index rows, so a delete→recreate cycle lists the path exactly once (regression-tested across
repeated cycles).
- **`repairIndex()` prunes ghost/scar directories left by earlier versions.** Stores that deleted
entities under ≤8.3.0 may hold orphaned entity directories (a vector-only leg, or an empty dir).
`brain.repairIndex()` now sweeps them: it removes only containers with **no metadata content leg**
(never a directory that still holds content), logs every removal, and recomputes type/subtype
counts afterward so totals stop counting ghosts.
- **Reads no longer hang behind an unrelated index migration (family-scoped gate).** During a native
provider's one-time background migration, *every* read — including plain `get()`, VFS
`readdir`/`readFile`, and metadata-only `find({ where })` — blocked on the whole-brain migration
lock until timeout, even when the migrating index was irrelevant to the read. The gate is now
scoped to the index families a read actually consults: canonical reads (`get`, `batchGet`, VFS
content) never wait; a `find` waits only on the families its query shape needs (vector for
semantic, metadata for `where`/type, graph for `connected`); graph traversals wait only on the
graph family. Writes and unclassified operations keep the conservative whole-brain wait. A read
that *does* need the migrating family still blocks (bounded by `migrationWaitTimeoutMs`) and
surfaces the retryable `MigrationInProgressError` — never a partial result.
No breaking API change. Each fix ships with regression tests.
## v8.3.0 — 2026-07-13 (faster index heals + the cross-layer integrity contract)
Three additive changes. The first is an immediate, standalone performance win; the other two are the
brainy side of the write/index-spine integrity contract (ADR-004), inert until a native accelerator
brainy side of the write/index-spine integrity contract, inert until a native accelerator
that implements the matching hooks is present — so this release changes nothing for a JS-only brain
beyond the speedup.