Skip to content

v7.82.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 13:49
· 1901 commits to main since this release
f61d897

Pairs with engine-service-v0.1.160 (REQUIRED_ENGINE_VERSION unchanged). RDR-228 follow-through: a one-command installer (install.sh, install.ps1), install pages around two routes, measured install sizes, and Desktop told to quit and reopen after setup. The conexus skill listing shrinks: ten commands hidden from the model, six wrapper skills retired into agents and rules, the review and planning procedure carried in the agents, and bd prime printed by the session-start hook when the beads plugin is off. Fixes: the streaming PDF index race, Windows first-session hook timeouts, and the MinerU semaphore leak.

Added

  • web/install.sh and web/install.ps1 install the CLI, the plugin and, on request, the service in one command (RDR-228 Phase 3, nexus-sv2wx.26; published at hellblazer.github.io/nexus/install.sh and install.ps1). The script installs uv when it is missing, runs uv tool run --python 3.12 --from conexus@latest nx self install --bootstrap when no CLI resolves (and says it is skipping the build when one does), adds the plugin when claude is on the PATH, then sets up the service. With no flag it asks one question on the terminal, before any download; with no terminal and no flag it builds the CLI only and says so. --local, --cloud and --cli-only choose the service; --autostart and --no-autostart choose the login unit. The autostart default (nexus-omlpd): with --local and neither flag the script asks "Start the service at login? [y/N]" when a terminal is attached and passes nx init --no-autostart when none is; it never passes --yes by default. All of install.sh is inside one function called on its last line, so a cut-short download runs nothing. Tests: tests/test_install_sh.py, tests/test_install_ps1.py.

Changed

  • The four-choice question gives the measured sizes on disk (nexus-gxzfq). The table in the setup question, the setup tool's description, the no-service notice, /conexus:setup and the install pages said Local takes 2.4 GB on disk and Cloud or CLI only 1.6 GB; the 1.6 GB was a 2026-10-12 uv tool install environment, not the generation layout. Measured from nothing with conexus 7.81.0, the install itself took 2.4 GB (Local, macOS), 2.1 and 2.7 GB on Linux and 2.3 and 3.1 GB on Windows, so the table now says about 2.4 to 3.1 GB for Local and 2.1 to 2.3 GB for Cloud or CLI only. The download figures are unchanged. The pages' per-system paragraph shrinks to one sentence.
  • Six wrapper skills are retired into agents and rules: code-review, debugging, development, test-validation, query and using-nx-skills (nexus-dg7i6.6). A 30-day census of 509 transcripts found zero model loads of any of them beside 2,517 agent dispatches, and an eval with every premise made true loaded four of them 0 of 3 times: the model does the work inline or dispatches the agent that the rules name (T2 nexus/skill-routing-never-load-analysis-2026-10-17). What a caller still needs moved into the orchestration skill: the acceptance bar ("Ship when X") and triage, the first-pass and confirmation-pass reviewer briefs, the five-question implementer brief, the debugger escalation guard, the model choices, the routing menu for the remaining skills, the nx_answer cost rule, the working rules (sequential thinking, tiers, T2 ttl), Common Mistakes and Red Flags; AGENTS.md carries the three-sentence hot rule. SessionStart now names the destination for each situation (the debugger agent, code-review-expert and substantive-critic, nx_answer, a few skills) and points at orchestration instead of at a skill it would have to load first, in 1,135 bytes where it was 1,140. /debug, /review-code, /test-validate and /implement still work for the user and now dispatch their agent directly. /conexus:query is gone; ask the question in plain words and the model calls nx_answer. Registry, docs, site pages and the nx hook preflight degraded text follow. The conexus eval cases that grade loading of these skills (p01, p02, p05, p09, p10) are left for nexus-dg7i6.7, which rewrites them to grade outcomes. The plugin files wait in the pending-release ledger's deferred section with the wheel-side change.
  • The review, critic, developer and planner agents carry the skill procedure the model never loaded (nexus-dg7i6.3). In 30 days the model invoked the code-review, debugging and development skills zero times and dispatched their agents hundreds of times (T2 nexus/skill-routing-census-baseline-2026-10-16), so procedure held only in a skill never reached the work. code-review-expert now reports everything on a first review, counts ship_blockers against the relay's "Ship when X" bar, and answers a confirmation-pass relay with CONFIRMED-CLOSED or NOT-CLOSED lines and no new findings; substantive-critic gets the same confirmation-pass rule; developer hands back the first live run of any check, gate, census or lint it adds; strategic-planner's continuation-state example carries ttl=14. The debugging, test-validation and strategic-planning skills held nothing else the agents lack (the Serena navigation advice reaches every subagent through the SubagentStart hook). The skills' skills: preload was not used: it would inject the caller-side relay and model-selection text into every dispatch.
  • Ten conexus commands are hidden from the model's skill listing, and the model is routed to the skill each one wraps (nexus-dg7i6.2). debug, review-code, test-validate, create-plan, implement, research, analyze-code, plan-audit, rdr-list and nx-preflight carry disable-model-invocation: true: their descriptions (524 bytes) leave the model's context and the /slash forms stay for the user. Agents load relevant skills less as the listing grows, and an entry that does not apply suppresses loading; these commands wrapped a same-topic skill and had no model-initiated invocation in 30 days. using-nx-skills and the skills and agent that named a hidden command now name the skill (debugging, code-review, test-validation, strategic-planning, development, research-synthesis, codebase-analysis, plan-validation) or, for the RDR list, nx rdr preamble rdr-list; the degraded-mode text of nx-hook preflight follows. conexus/commands/rdr-audit.md now says to follow the rdr-audit-checklist skill. tests/test_plugin_structure.py::TestModelHiddenCommands pins the hidden set and that no model-facing text names a hidden command, and the listing byte budget no longer counts hidden entries. The plugin files wait in the pending-release ledger's deferred section with the wheel-side change.
  • The session-start hook prints bd prime itself when the beads plugin is not enabled (nexus-dg7i6.4). In a repo with .beads/, nx-hook session-context runs bd prime and adds its output (the repo's .beads/PRIME.md and beads' own memories) unless the beads Claude Code plugin is enabled and installed for the project, in which case the plugin's own hook prints it. Enablement follows Claude Code's enabledPlugins precedence: the project's settings.local.json, then its settings.json, then the user's. This lets a project drop the plugin's 28 skill-listing entries (T3 1.11.758: agents load relevant skills less as the listing grows) without losing PRIME. The conexus agents and skills now name bd <verb> where they named the plugin's /beads:<verb> commands.
  • The install pages describe two routes: one command, or uv plus the plugin plus one question (RDR-228 Phase 4, nexus-sv2wx.30). The site's install page, README.md, docs/getting-started.md, docs/desktop-deployment.md and docs/windows-install.md give the installer address (install.sh, install.ps1) with its flags, the four choices with their sizes, the Desktop route ("Set up Nexus", since Desktop offers plugin skills and not commands) and the Desktop upgrade (remove the marketplace and add it again). The manual commands move to an "Install by hand" section.
  • The install pages take the P4.R critique (RDR-228 Phase 4, nexus-sv2wx.31). The sizes paragraph now gives the measured install sizes (about 2.1 GB Cloud or CLI only and 2.7 GB Local on Linux, 2.3 and 3.1 GB on Windows) and says the uv cache shares files with the install: from nothing on Linux, du counted the cache and the install together at 2.4 GB against 4.4 GB added up separately. After /plugin install the pages say to run /reload-plugins or start a new session, tell a Desktop reader who added Hellblazer/nexus earlier to remove it and add it again, assert only what was seen about /conexus:setup in Desktop (macOS, 2.42304.0), warn Linux readers with a uv older than 0.9.19, and say that pressing Enter, or having no terminal, installs the CLI only. The stale Windows 7.72.1 size block is replaced. Changing the size table itself waits for a client release (nexus-gxzfq).

Fixed

  • After setup in Claude Desktop, the guidance says to quit the app and open it again, not to start a new conversation (nexus-93xx0). Desktop starts a plugin's server once, when the app starts, keeps it for every new conversation and has no Reconnect command, so after setup finished a new conversation still talked to the stand-in and the model said it could not reach Nexus (measured on macOS with Desktop and conexus 7.81.0: the real server, 46 tools, came up only after the app was quit and reopened). The stand-in's instructions, its setup and setup_status answers and the setup_status description, the finished setup record's next step, and the install pages now give Claude Code's step (/mcp or a new session) and Desktop's (quit the app fully and open it again). Tests: tests/hooks/test_nx_standin.py::test_every_reconnect_instruction_names_the_desktop_restart, tests/hooks/test_nx_setup.py::test_a_finished_run_names_the_desktop_restart_as_its_next_step.

  • A streaming PDF index no longer finishes its write before the last chunks arrive, and one record's unexpected error no longer stops nx dt index (nexus-gjxkb). The uploader read the chunk buffer and only then checked whether the chunker was done, so chunks the chunker wrote between the two were missed: the writer sent its last request (with the sweep) against a manifest missing its tail, and the next poll handed the late chunks to the finished writer, which raised ValueError: MultiBatchDocumentWriter: already finished. The uploader now looks at the chunker before reading, takes chunks only as a contiguous run from the next position (a chunk not yet visible is waited for, never skipped), and finishes the writer only when the buffer holds every chunk the chunker made. In nx dt index, an exception that is not a NexusError fails that record, is listed under Failures with its traceback in the dt_index_unexpected_error log event, and the command exits non-zero after the rest of the batch has run. A record that fails with RuntimeError or ImportError (the cases that catch always survived) now also leaves the run exiting non-zero after the batch, instead of 0. The uploader no longer waits forever for a chunk that never becomes readable: with the chunker finished and no progress, it logs uploader_waiting_for_a_chunk after 30 polls (60 s), and after 150 polls (5 minutes) raises UploadStalledError, a per-record error, so that one document fails and the batch goes on; it also raises UploaderInvariantError, naming the document and chunk positions, if rows ever reach a writer that has already finished. Tests: tests/test_gjxkb_uploader_landing_race.py, tests/test_commands_dt.py::TestAnUnexpectedExceptionFailsOneRecordNotTheBatch.

  • The first Claude Code session on Windows no longer has its conexus SessionStart hooks cancelled at their timeouts (nexus-3ya9d). Every hook command is uv tool run --directory ${CLAUDE_PLUGIN_ROOT} ... python <script>, so even nx_setup_notice.py and version_lockstep_hook.py, which run no nx code, wait for uv before their first line runs. On a first session uv may have to fetch a Python 3.12 (uv keeps managed interpreters outside UV_CACHE_DIR, which is why a seeded cache did not help) and build the tool environment, and all nine hook processes wait on the same uv locks. Measured on macOS with empty uv directories and seven hooks started together: 0.1 to 0.2 s with a Python present, 2.3 s for every hook when uv fetches one, 0.1 s warm. Windows is slower (a warm session measured 3.1 to 5.5 s per hook against the 5 s limit). Each SessionStart entry's timeout is now its own work budget plus a 30 s cold-start allowance (setup notice and lockstep 5 to 35 s; preflight, session-start, session-context and rdr 10 to 40 s; upgrade-auto and self-gc 30 to 60 s; mcp-connect-wait 20 to 50 s). A warm hook returns when it is done, so healthy sessions are unchanged. The fix is inert until the plugin release that carries hooks.json (conexus/PENDING_RELEASE.md). Test: tests/test_session_start_cold_start_allowance.py.

  • A CLI-only install by web/install.sh or web/install.ps1 no longer leaves Claude Code asking about a service at every session (RDR-228 Phase 4, nexus-sv2wx.31, P4.R critique S2). The session-start hook goes quiet only when the plugin's setup record says CLI only was chosen, and the scripts wrote no record, so a user who pressed Enter at the question, or ran with no terminal, was told at each session start that no service is set up. The scripts now write the same setup/status.json the plugin's setup tool writes for cli-only (state done, mode cli-only), under NEXUS_CONFIG_DIR, else NX_CONFIG_DIR, else ~/.config/nexus, and remove a "not now" marker as the plugin does. A live setup run keeps its record, and a record that cannot be written is a note, not a failure. --local and --cloud write nothing. The tests read the record with the plugin's own status_view and run the real hook against it.

  • The installer scripts build the CLI the way the plugin's setup does, and --local means local (nexus-sv2wx.27 review, nexus-sv2wx.28). On Linux web/install.sh (and web/install.ps1 under PowerShell 7 there) runs the build with UV_TORCH_BACKEND=${NX_TORCH_BACKEND:-cpu}, so the throwaway environment no longer downloads CUDA torch, 14 nvidia-* packages and triton, about 4.5 GB; a uv too old to know the variable ignores it. The build asks for conexus@latest, because a bare --from conexus reuses the environment uv cached on an earlier run, which can predate --bootstrap. nx self install --bootstrap now writes the version-lockstep marker (nexus.lockstep_marker, one place for the CLI's reads and writes), so the first Claude session after the installer no longer announces an upgrade and dispatches one. --local runs nx init with NX_LOCAL=1 on that one call, so a configured service_url cannot send it to the managed arm while the script says it set up the local service, and with --no-beads-prime, as the plugin's setup does. --cloud with no terminal and no NX_SERVICE_URL and NX_SERVICE_TOKEN (or NX_MINT_TOKEN) in the environment stops before downloading anything. install.sh removes its temporary uv-installer file when interrupted, finds uv in UV_INSTALL_DIR, names the right directory when the build leaves no nx, and says (by name, never the value) when NX_INSTALL_UV_URL replaces uv's installer, refusing anything but https: and file:. A push that touches only web/install.sh or web/install.ps1 now runs the pytest matrix: CI's docs-only predicate treated all of web/ as static pages.

  • A detached process no longer starts in the directory that launched it, nx mineru status no longer calls a server healthy that cannot do work, and no nexus kill path leaks POSIX semaphores (nexus-x3m8e). A MinerU server started from a session worktree that was later deleted answered every task with FileNotFoundError while /health said 200 and nx mineru status said "healthy". The failing call, from the server's own traceback: importing torchvision.ops pulls in torch._dynamo.config, whose module body runs os.path.join(os.getcwd(), "torch_compile_debug"). Python's import system is not the cause (it guards getcwd for the empty sys.path entry); the class is any getcwd/abspath/Path.cwd call in a daemon or its libraries. Reproduced on a real mineru-api: a server started in a launch directory that was then deleted answers a one-page PDF with a 409 naming that line and nx mineru status reports UNHEALTHY (exit 1); the same server started through the new spawn from a deleted launch directory runs in / and parses the page (200, 7.9 s).

    • Stable cwd. Every detached process starts in the filesystem root (nexus.util.stable_cwd, re-exported by service_registry; stdlib-only so the hooks share it): the storage supervisor, the aspect worker, the Windows autostart launcher, the MinerU server, the per-page MinerU worker, the deferred taxonomy labelling, the upgrade hook's child, and both session-end launchers (POSIX double-fork grandchild, Windows child). The supervisor's --foreground entry, the aspect worker and each grandchild also chdir themselves, so a daemon launched by launchd or an older client detaches too. A relative NEXUS_CONFIG_DIR is pinned absolute first, in the child's env or in os.environ; the helper creates no directory. A child that reads the per-repo .nexus.yml (the labelling run, the upgrade child, the session-end cleanup) is handed the old directory as NEXUS_REPO_ROOT, which load_config reads where it used to read the cwd, and load_config no longer raises from a deleted cwd. tests/test_detached_spawn_cwd_lint.py fails on any new detaching Popen or setsid daemon that keeps its caller's directory.
    • Kill paths. The semaphore leak that exhausted macOS's 10,000 (kern.posix.sem.max) and made mp.Lock() fail machine-wide was nexus's own SIGKILL of whole process groups, which killed the multiprocessing resource tracker before it could unlink the pool's named semaphores. The rule now lives in the shared primitive: safe_killpg, safe_killpg_group and kill_tree (and kill_child_and_descendants through them) signal every member of the group except the tracker, rescan until none is left, and count a group with only its tracker left as stopped; nx mineru stop, the extractor's restart and the per-page worker kill all use them, with no sparing pass of their own, and tests/test_process_group_killpg_lint.py fails on any other killpg in src/nexus. Measured with a real spawn-context pool and a probe by semaphore name, 4 trials per door: a raw group SIGKILL left 20 of 20 semaphores behind, safe_killpg_group, safe_killpg, kill_tree and kill_child_and_descendants left 0 of 20 each, and 0 of 100 remained after cleanup. The orphan-tracker sweep (nx doctor remedy) no longer SIGKILLs a tracker, which ignores SIGTERM by design: it kills the workers, waits, and reports a tracker that is still there.
    • Honest status. nx mineru status prints UNHEALTHY and exits 1 when the server's working directory is gone (compared by device and inode, so a path deleted and recreated reads gone on macOS), when its interpreter, executable or output directory no longer exists, when no POSIX semaphore can be created (the remedy names /dev/shm on Linux, kern.posix.sem.max on macOS), or when at least 3 recent tasks failed and at least 90% of the finished ones did. nx doctor --check-resources and the MinerU check share one semaphore probe. The extractor replaces a registered server whose working directory is gone before it sends a task, and restarts it once when a task fails with FileNotFoundError only if the failing URL is the registered server and its working directory is gone or the error names a path it owns (a missing PDF restarts nothing); the replacement checks that the pid is still a mineru-api before signalling its group, as nx mineru stop does, and the 120 s cooldown is a timestamp file next to mineru.pid, shared by every process on the machine. An ENOSPC from the server is reported as a machine fault (MineruMachineResourceError, not a RuntimeError, so the page-bisect ladder does not retry it) only after a probe on the box fails to create a semaphore; a full disk also says ENOSPC.