Skip to content

v7.74.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 06:10
· 2083 commits to main since this release
e1dd763

Pairs with engine-service-v0.1.151 (tagged 2026-10-07 on da58bf1; REQUIRED_ENGINE_VERSION moves from 0.1.150 to 0.1.151): the HNSW search floor below, no changesets and no wire-ledger entries. The engine deployed to the cloud and passed its gates (recall 12/12 at ef 600, cloud client-path gate 10/10) before this client tag. This release also carries the RDR-224 native Windows batch: the uninstall that removes what it installed, the smaller downloads, hooks and MCP servers that run without Node or a project .venv, and the Windows test fixes; the native-Windows CI test set passed under a non-elevated account (1481 passed, 0 failed).

Added

  • A local install downloads less: about 120 MB less engine and 238 MB less model. The model saving is live in this release (model.onnx.xz is on the model release); the engine saving arrives with the first engine tag built with these changes, which v0.1.151 is not. Each Linux and macOS engine also ships as nexus-service-<arch>.txz (a 163 MB mac-arm64 engine measured 41 MB with the release's xz settings), and nx init takes the archive when the pinned release carries it and the single file when it does not, so this client installs the currently pinned engine unchanged. Both gates (sha256 and the Sigstore signature) run on the archive, the one member is placed by one rename, and the receipt records the archive and binary digests. The bge-768 model is fetched as model.onnx.xz (about 198 MB against 436) when the model release carries it, decompressed in a stream and checked against the same pinned sha256 before it is moved into place; a release without it serves the raw file as before. The PostgreSQL bundles drop the headers, static and import libraries, PGXS and pkg-config files that only building against PostgreSQL needs (mac-arm64: 39.6 to 29.1 MB installed, 6.0 to 4.8 MB downloaded).

Changed

  • The engine's default HNSW search floor rises from 200 to 600 (nexus-3wh8d.31). RDR-225 gives each (model, tenant) leaf its own HNSW graph, and the cloud gate then missed one true neighbor at ef 200 on one of its twelve queries (recall@10 0.90). A live sweep on the production leaves restored 12/12 at ef 400 with latency flat up to 1000, so 600 keeps headroom over the measured point. It pairs with engine-service-v0.1.151, which this release pins for local installs; the managed cloud sets its own floor through NX_HNSW_EF_SEARCH.
  • An install downloads OpenCV once, and the Claude Desktop extension no longer installs fastembed (2026-10-07 install-download audit). MinerU requires opencv-python and albumentations (MinerU's formula model) requires opencv-python-headless; both write site-packages/cv2/, so every install downloaded OpenCV twice and which cv2 won depended on install order. An override now drops opencv-python in all three override homes (pyproject.toml, the overrides.txt every nx self install generation build uses on POSIX and Windows, and the .mcpb's own pyproject.toml), so headless is the one cv2. Measured with uv pip compile conexus==7.72.1 per platform, the generation build's wheels drop from 463 to 414 MB on macOS arm64, 471 to 397 MB on Linux x86-64 (CPU torch not counted), 402 to 352 MB on Linux arm64 and 627 to 583 MB on Windows x64. Installed, cv2/ shrinks from 280 to 159 MB on Linux x86-64 and from 181 to 90 MB on Linux arm64, where opencv-python adds Qt libraries; on macOS and Windows the two builds ship the same files. The .mcpb depends on bare conexus instead of conexus[local], the same distribution the plugin's nx-mcp runs from: the engine embeds every T3 write and search and collection names follow the service's bge-768 token, so fastembed only made the extension's plan cache use a different embedder than the plugin and fetch its own bge copy on first use. A bare uv tool install conexus (step 1 of the install page) still installs both OpenCV builds and PyAV, because no dependency declaration can remove a transitive requirement; the nx self install that follows builds without them. A venv that had both OpenCV builds loses cv2 entirely on the next plain uv sync (uv deletes the shared cv2/ files with opencv-python), so a dev checkout needs one uv sync --reinstall-package opencv-python-headless; the .mcpb bootstrap does that reinstall itself when its venv still carries opencv-python.

Fixed

  • The MCP server no longer tells a local service install that search runs at 384 dimensions. Its startup notice, written into the server instructions every plugin and Desktop session sees, reported "you selected bge-768 but the [local] extra is not installed — search is silently running at 384-dim" on every install made by nx init without the [local] extra. On such an install the engine embeds T3 with bge-768; the Python embedder serves only T1 and the plan cache. nx doctor already suppressed the advisory when pg_credentials exists, and the MCP notice now applies the same test.
  • On a Windows machine without the VC++ redistributable, the client's PDF extraction and local embedding load (nexus-lqjll, RDR-224). onnxruntime, pymupdf, torch and fasttext link the system msvcp140.dll and msvcp140_1.dll and failed to import on a clean Windows 11 install. The engine and PostgreSQL bundle already ship those DLLs app-local, so on Windows without a system runtime import nexus adds the installed engine directory and the bundle's bin to the DLL search path. Measured on the clean guest: all four imported afterwards. A cloud-mode Windows install has neither directory, so nx init (its managed and cloud branches) and the SessionStart nx upgrade --auto now download the signed PostgreSQL bundle for the pinned engine tag through the existing sha256 and sigstore checks and copy only msvcp140.dll and msvcp140_1.dll into <config>/vcrt, which joins the search path (PostgreSQL is not provisioned). nx doctor gains a Windows-only row, "VC++ runtime for the client's extension modules": it fails, naming nx init and Microsoft's redistributable, when neither System32 nor an app-local directory has both DLLs, and is absent on macOS and Linux. POSIX is unchanged.
  • The aspect-worker daemon backs off its reclaim sweep while the service is down (nexus-g5rz5). nx daemon service stop leaves the daemon running on every platform, by RDR-224's recorded decision (the worker belongs to the store path, not to the service). With the stack stopped, every reclaim sweep failed and the wait stayed at the 30 s base, about 2,880 failed attempts a day. A failed sweep now doubles the wait up to the stale window, as an empty sweep does, and a reclaim resets it to the base. The Phase 5 gate keeps reporting the surviving worker as an observation and cites the decision.
  • The Claude Desktop extension no longer runs a Python interpreter from a .venv above its own directory (nexus-92gxf). Desktop starts the bundle with the manifest's mcp_config, which was uv run --no-project --directory ${__dirname} src/bootstrap.py. uv run searches that directory and every parent for a .venv, so a ~/.venv, or a C:\.venv that any local Windows user may create, ran the bootstrap. The launcher is now uv tool run --directory ${__dirname} --no-config --quiet --python >=3.12 python src/bootstrap.py, the form the plugin hooks use: a tool environment is built from a managed or PATH interpreter, never a .venv. A second path reached the server itself: the bootstrap's uv sync and uv run treat the bundle as a project, and uv adopted an ancestor pyproject.toml whose [tool.uv.workspace] members matched the bundle as the workspace root, so the server ran in that ancestor's .venv. mcpb/pyproject.toml now declares the bundle its own workspace root (members = []). Measured on a Windows 11 guest (uv 0.12.23) by launching each bundle's manifest command over MCP stdio (initialize, 44 tools, store_put, search): the old bundle ran a planted %USERPROFILE%\.venv, and with that removed a planted C:\.venv; the new bundle ran neither, and a planted C:\pyproject.toml workspace with C:\.venv ran the server only when the bundle lacked its own workspace table. tests/test_mcpb_launcher_venv.py runs the manifest command against real planted venvs with both controls.
  • Two installs started in the same second on Ubuntu 26.04 no longer build into one generation directory (nexus-bo01z). The mkdir there (uutils coreutils 0.8.0) reports a lost create race as success, so install_generation.sh let both racers claim the same gen-<stamp> tree. The claim is now the exclusive creation of the build marker inside the new directory; a racer that loses it takes the next suffix. The service build lease (scripts/lib/build-lease.sh) had the same defect and the same fix, by an exclusive pid write.
  • nx uninstall --yes removes the directories the autostart install created, and its summary reports the stop correctly (nexus-f9bgu, RDR-224). On a clean Windows 11 guest, 7.72.1 left an empty %LOCALAPPDATA%\nexus\autostart, and printed "daemon stop not confirmed" with no nexus process running. Removing the autostart unit now also removes that directory and %LOCALAPPDATA%\nexus when they are empty. A nexus directory that holds anything else stays, and the summary names its contents. With --remove-data, the unit's nexus-service.log goes too, and on Linux so does an empty ~/.local/state/nexus. ~/Library/LaunchAgents, ~/Library/Logs and ~/.config/systemd/user hold other programs' files and are never removed. The "not confirmed" line came from the retired T2 daemon: no install made since its retirement, and no Windows install, has a T2 unit, and the summary read "no unit" as "stop unconfirmed" on every platform. It now prints "no T2 daemon (nothing to stop)". "service stack stopped" now means the survivor probe found no fresh service lease and nothing on the Postgres port after the stop. It no longer depends on the stop command's exit code, which is non-zero when nothing was running. --remove-data also removes the model cache, ~/.cache/nexus (%USERPROFILE%\.cache\nexus on Windows): the service's ONNX models, about 500 MB, and MinerU's fallback output. Earlier releases left it, and the install docs told users to delete it by hand. It goes only after the stop is confirmed, because on Windows the engine holds the model files open. A model root set with NX_ONNX_MODEL_DIR outside that directory is the user's and is kept and named. The preview lists the cache. The path comes from one function, nexus_cache_root(), which the model root and the MinerU fallback now derive from. Uninstall also stops the background workers the service stop leaves running (nexus-7xzc1), after the stop and before anything is removed. On a Windows guest, 7.73.0 left the aspect worker that nx store put had started: it held its crash log open, so .config\nexus and .cache\nexus could not be removed (WinError 32) and part of the generation stayed locked until the user ended the process by hand. Uninstall now stops every aspect worker its lease names, a detached nx taxonomy label run (its spawner now records the pid in deferred_labeling.pid), and the MinerU server when mineru.pid shows nexus started it. Each pid is signalled only while its live command line is still that worker, and MCP servers, which belong to Claude sessions, are never stopped. The lease stop is a new shared primitive, service_registry.stop_tier_holders, with a conformance property for every leased tier. On Windows, uninstall also removes the <tools>\current\bin entry that nx self install put on the user PATH, keeping every other entry, unexpanded %VAR% entries included, and the value's registry type, and broadcasts the change. On macOS and Linux nx self install edits no PATH and no shell rc file, so there is nothing to revert.
  • nx doctor's MCP entry-point rows probe what the plugin launches after nx self install (nexus-7xzc1, RDR-224). On Windows current\bin is a junction into the running generation, so the rows skipped it as "this process's own venv" and probed uv's legacy .local\bin launcher, which stays until the reap. A generation is the installed artifact, so the first PATH hit is probed.

Security

  • The local PostgreSQL cluster now demands a password (scram-sha-256) instead of trusting every local account (nexus-ja4pq). The bundled cluster listens on 127.0.0.1 only, but it was created initdb --auth=trust, so any OS account on the same box could open a superuser session on its port with no password. Windows made that sharper, since the superuser's role name derives from a SID that other accounts can read. A new cluster is created with --auth=scram-sha-256 and a superuser password handed to initdb through a private temp file (never a command line), recorded as PG_SUPERUSER_PASS in the owner-only pg_credentials. The engine already carried nexus_admin and nexus_svc passwords, so it needs no change; PG_SUPERUSER_PASS is not passed to it. An existing cluster is converted on the next service start (the provision fast path that already runs before every start): it sets the passwords, rewrites every trust line in pg_hba.conf to scram-sha-256, reloads, then confirms that a password-less connection is refused and that each role signs in with its recorded password. If any step fails it restores the original pg_hba.conf, leaves the cluster on trust and logs pg_auth_migration_failed, so a failure never locks anyone out. The conversion is idempotent. nx doctor gains a "Local PostgreSQL authentication" row that fails while any pg_hba.conf line is still trust. Role passwords no longer pass through psql -c on a command line. A cluster that already enforces passwords but has lost PG_SUPERUSER_PASS is refused with the single-user recovery steps; nx never loosens pg_hba.conf to recover.