Repository navigation
v7.82.0
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.shandweb/install.ps1install 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 installsuvwhen it is missing, runsuv tool run --python 3.12 --from conexus@latest nx self install --bootstrapwhen no CLI resolves (and says it is skipping the build when one does), adds the plugin whenclaudeis on thePATH, 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,--cloudand--cli-onlychoose the service;--autostartand--no-autostartchoose the login unit. The autostart default (nexus-omlpd): with--localand neither flag the script asks "Start the service at login? [y/N]" when a terminal is attached and passesnx init --no-autostartwhen none is; it never passes--yesby default. All ofinstall.shis 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
setuptool's description, the no-service notice,/conexus:setupand 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-12uv tool installenvironment, 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,queryandusing-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 (T2nexus/skill-routing-never-load-analysis-2026-10-17). What a caller still needs moved into theorchestrationskill: 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, thenx_answercost rule, the working rules (sequential thinking, tiers, T2 ttl), Common Mistakes and Red Flags;AGENTS.mdcarries the three-sentence hot rule. SessionStart now names the destination for each situation (thedebuggeragent,code-review-expertandsubstantive-critic,nx_answer, a few skills) and points atorchestrationinstead of at a skill it would have to load first, in 1,135 bytes where it was 1,140./debug,/review-code,/test-validateand/implementstill work for the user and now dispatch their agent directly./conexus:queryis gone; ask the question in plain words and the model callsnx_answer. Registry, docs, site pages and thenx hook preflightdegraded 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,debugginganddevelopmentskills zero times and dispatched their agents hundreds of times (T2nexus/skill-routing-census-baseline-2026-10-16), so procedure held only in a skill never reached the work.code-review-expertnow reports everything on a first review, countsship_blockersagainst the relay's "Ship when X" bar, and answers a confirmation-pass relay withCONFIRMED-CLOSEDorNOT-CLOSEDlines and no new findings;substantive-criticgets the same confirmation-pass rule;developerhands back the first live run of any check, gate, census or lint it adds;strategic-planner's continuation-state example carriesttl=14. Thedebugging,test-validationandstrategic-planningskills 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-listandnx-preflightcarrydisable-model-invocation: true: their descriptions (524 bytes) leave the model's context and the/slashforms 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-skillsand 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 ofnx-hook preflightfollows.conexus/commands/rdr-audit.mdnow says to follow therdr-audit-checklistskill.tests/test_plugin_structure.py::TestModelHiddenCommandspins 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 primeitself when the beads plugin is not enabled (nexus-dg7i6.4). In a repo with.beads/,nx-hook session-contextrunsbd primeand adds its output (the repo's.beads/PRIME.mdand 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'senabledPluginsprecedence: the project'ssettings.local.json, then itssettings.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 namebd <verb>where they named the plugin's/beads:<verb>commands. - The install pages describe two routes: one command, or
uvplus 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.mdanddocs/windows-install.mdgive 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
uvcache shares files with the install: from nothing on Linux,ducounted the cache and the install together at 2.4 GB against 4.4 GB added up separately. After/plugin installthe pages say to run/reload-pluginsor start a new session, tell a Desktop reader who addedHellblazer/nexusearlier to remove it and add it again, assert only what was seen about/conexus:setupin Desktop (macOS, 2.42304.0), warn Linux readers with auvolder 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
setupandsetup_statusanswers and thesetup_statusdescription, the finished setup record's next step, and the install pages now give Claude Code's step (/mcpor 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 raisedValueError: 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. Innx dt index, an exception that is not aNexusErrorfails that record, is listed under Failures with its traceback in thedt_index_unexpected_errorlog event, and the command exits non-zero after the rest of the batch has run. A record that fails withRuntimeErrororImportError(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 logsuploader_waiting_for_a_chunkafter 30 polls (60 s), and after 150 polls (5 minutes) raisesUploadStalledError, a per-record error, so that one document fails and the batch goes on; it also raisesUploaderInvariantError, 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
SessionStarthooks cancelled at their timeouts (nexus-3ya9d). Every hook command isuv tool run --directory ${CLAUDE_PLUGIN_ROOT} ... python <script>, so evennx_setup_notice.pyandversion_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 outsideUV_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). EachSessionStartentry'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 carrieshooks.json(conexus/PENDING_RELEASE.md). Test:tests/test_session_start_cold_start_allowance.py. -
A CLI-only install by
web/install.shorweb/install.ps1no 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 samesetup/status.jsonthe plugin'ssetuptool writes forcli-only(statedone, modecli-only), underNEXUS_CONFIG_DIR, elseNX_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.--localand--cloudwrite nothing. The tests read the record with the plugin's ownstatus_viewand run the real hook against it. -
The installer scripts build the CLI the way the plugin's setup does, and
--localmeans local (nexus-sv2wx.27 review, nexus-sv2wx.28). On Linuxweb/install.sh(andweb/install.ps1under PowerShell 7 there) runs the build withUV_TORCH_BACKEND=${NX_TORCH_BACKEND:-cpu}, so the throwaway environment no longer downloads CUDA torch, 14nvidia-*packages and triton, about 4.5 GB; a uv too old to know the variable ignores it. The build asks forconexus@latest, because a bare--from conexusreuses the environment uv cached on an earlier run, which can predate--bootstrap.nx self install --bootstrapnow 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.--localrunsnx initwithNX_LOCAL=1on that one call, so a configuredservice_urlcannot 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.--cloudwith no terminal and noNX_SERVICE_URLandNX_SERVICE_TOKEN(orNX_MINT_TOKEN) in the environment stops before downloading anything.install.shremoves its temporary uv-installer file when interrupted, finds uv inUV_INSTALL_DIR, names the right directory when the build leaves nonx, and says (by name, never the value) whenNX_INSTALL_UV_URLreplaces uv's installer, refusing anything buthttps:andfile:. A push that touches onlyweb/install.shorweb/install.ps1now runs the pytest matrix: CI's docs-only predicate treated all ofweb/as static pages. -
A detached process no longer starts in the directory that launched it,
nx mineru statusno 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 withFileNotFoundErrorwhile/healthsaid 200 andnx mineru statussaid "healthy". The failing call, from the server's own traceback: importingtorchvision.opspulls intorch._dynamo.config, whose module body runsos.path.join(os.getcwd(), "torch_compile_debug"). Python's import system is not the cause (it guardsgetcwdfor the emptysys.pathentry); the class is anygetcwd/abspath/Path.cwdcall in a daemon or its libraries. Reproduced on a realmineru-api: a server started in a launch directory that was then deleted answers a one-page PDF with a 409 naming that line andnx mineru statusreportsUNHEALTHY(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 byservice_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--foregroundentry, the aspect worker and each grandchild alsochdirthemselves, so a daemon launched by launchd or an older client detaches too. A relativeNEXUS_CONFIG_DIRis pinned absolute first, in the child'senvor inos.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 asNEXUS_REPO_ROOT, whichload_configreads where it used to read the cwd, andload_configno longer raises from a deleted cwd.tests/test_detached_spawn_cwd_lint.pyfails on any new detachingPopenorsetsiddaemon that keeps its caller's directory. - Kill paths. The semaphore leak that exhausted macOS's 10,000 (
kern.posix.sem.max) and mademp.Lock()fail machine-wide was nexus's ownSIGKILLof whole process groups, which killed themultiprocessingresource tracker before it could unlink the pool's named semaphores. The rule now lives in the shared primitive:safe_killpg,safe_killpg_groupandkill_tree(andkill_child_and_descendantsthrough 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, andtests/test_process_group_killpg_lint.pyfails on any otherkillpginsrc/nexus. Measured with a real spawn-context pool and a probe by semaphore name, 4 trials per door: a raw groupSIGKILLleft 20 of 20 semaphores behind,safe_killpg_group,safe_killpg,kill_treeandkill_child_and_descendantsleft 0 of 20 each, and 0 of 100 remained after cleanup. The orphan-tracker sweep (nx doctorremedy) no longerSIGKILLs a tracker, which ignoresSIGTERMby design: it kills the workers, waits, and reports a tracker that is still there. - Honest status.
nx mineru statusprintsUNHEALTHYand 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/shmon Linux,kern.posix.sem.maxon macOS), or when at least 3 recent tasks failed and at least 90% of the finished ones did.nx doctor --check-resourcesand 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 withFileNotFoundErroronly 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 amineru-apibefore signalling its group, asnx mineru stopdoes, and the 120 s cooldown is a timestamp file next tomineru.pid, shared by every process on the machine. AnENOSPCfrom the server is reported as a machine fault (MineruMachineResourceError, not aRuntimeError, 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 saysENOSPC.
- Stable cwd. Every detached process starts in the filesystem root (