Skip to content

v5.3.0-beta.2

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 22 Sep 14:40
· 661 commits to main since this release
576d333

This release covers changes since v5.3.0-beta.1. For everything in the 5.3 line since the last stable release, read the beta.1 notes as well.

Security

  • SSH private keys no longer reach the logs. A private key passed to add_ssh_key or update_ssh_key was written verbatim to the core operations log and to the MCP audit log. Both redactors now apply an operation- and tool-scoped field policy, so the key is removed for those operations without hiding the same field name where it carries no secret (for example an environment variable's name). (#2741)
  • A rejected cookie or mTLS session is now a decision, not a raw error. A server.getUser override that rejected a cookie session escaped the authentication middleware as a stringified error. Those branches now behave like the Authorization branch: a failed principal resolution becomes a negotiated 401, or a deferred credential rejection the route owner settles, and a component can tell a rejected credential apart from an internal fault. (#2717, fixes #2703)

Replication and clustering

  • An out-of-order write below the audit-retention floor no longer stalls replication. Such a write entered the reconciliation walk, and the walk's head lookup fanned out across every per-origin transaction log. On a 16-node cluster this left two replication legs with zero commits for over 24 hours, with one HTTP worker per receiver pinned at 100% CPU and progress of roughly one record every few minutes. Below the floor a write now contributes only its commutative operations. (#2684)
  • A record key beginning with / no longer hangs the subscription broadcaster. notifyFromTransactionData walked / to / forever, pegging every HTTP worker that held a subscription on that table at 100% CPU with nothing in the log. The walk now stops when the computed parent equals the current key, and a subscriber on the root key is still notified once. The bug was present in 5.1.x and 5.2.x as well. (#2689)
  • An exhausted cluster lock wait reports what a home actually answered. A contended lock() with a short wait returned 423 or 503 LOCK_UNAVAILABLE at random, which matters because 423 means "held, retry" while 503 means cluster lock coordination is broken. A wait's terminal status is now taken from the last reply a home completed, bound to the route and generation that produced it; a deadline this node imposed on its own probe never classifies the wait. The loop also stops before issuing a probe that cannot complete within the remaining budget. (#2685)

Storage and recovery

  • The restoring marker is now published atomically. beginRestore() opened the marker with openSync(path, 'w'), truncating it before the database name was written, and scanBlockedRestores() skips a marker whose first line is empty. A crash inside that window left a half-purged database that loaded as healthy on the next boot. The marker is now written temp file, fsync, rename, parent fsync, and an intact marker is reused rather than rewritten. (#2644)
  • Blob paths stay stable for aliased databases. A shared physical store kept being restamped by later logical aliases, so blob-root resolution moved across reconciles. The identity assigned first in initStores() now wins. Compatibility note: a deployment with file-backed blobs stored under an alias that previously happened to load last will now resolve to the first-assigned identity; no persisted identity or blob migration ships with this change. (#2683)
  • rocksdb-js updated to 2.10.0. (#2720)

Analytics

  • Aggregation resumes from the last raw record it rolled up. The resume marker was stamped with the cycle's own end-of-run Date.now(), so every raw report that arrived between the end of the rolled-up window and the end of the cycle was skipped permanently: the remainder of a backlog left by a late tick, and anything a worker reported while the cycle ran. get_analytics under-counted by whatever fell in that gap and the samples never came back. The resume point is now a cursor that moves only to a record a cycle actually read, and stays put when a cycle reads nothing. (#2692)

Vector search

  • Native HNSW planes use about half the layer-0 memory. The layer-0 neighbour array reserved 128 u32 slots per node, derived from values nativePlane pins, so no index declaration could change it — while a live 7.7M-node plane carries a mean layer-0 degree of 29. The new per-index nativePlaneLayer0Cap option defaults to 64, which holds recall@10 within about 0.5 points of cap 128 at every ef ≥ 128 measured at 1M and 4M vectors, at the same latency. (#2701)
  • @harperfast/hnsw updated to 0.4.0, which brings a 32x cut in visited-set memory, kernel-level prefetch of non-resident slots, and a parallel batch build not yet consumed here. The on-disk plane format is unchanged, so existing installations need no reindex. (#2722)

Full-text search (groundwork, not yet reachable)

  • A native full-text derived-index backend converts committed record changes into @harperfast/fulltext mutation batches and publishes the Harper replay cursor with the Tantivy commit. Harper records and audit logs stay authoritative; the Tantivy files are rebuildable derived state. This is the backend slice only — schema activation, reader attachment, Table.search, REST exposure and status reporting are follow-up work, so nothing about it is reachable by an application yet. (#2569, part of #2510)

Also in this release

logger.closeLogFile now stays bound to the current file after a path reassignment, a latent hazard on public API surface whose only callers today are test fixtures (#2724); CI now requires a planning receipt on changes to core-shared storage paths (#2594) and the derived-index runtime is back under that policy (#2745); DESIGN.md is partitioned into per-directory design notes indexed from the root (#2728); test stabilisation for the analytics aggregation cycle (#2699), HNSW distance inversions (#2702) and unit-test database teardown (#2720); dependency updates for alasql 4.19.1 (#2698) and mocha 12 (#2700); and a refresh of the AI review prompt pin (#2610).

Full changelog: v5.3.0-beta.1...v5.3.0-beta.2