Repository navigation
Releases: prometheion/nerve-protocol
Release list
Nerve 0.0.6
The desktop app
nerve-node-desktopis the node with a window, for Linux x86_64 (GNOME or KDE Plasma, Wayland or X11; glibc 2.35 or newer) and Windows x86_64 (#10). It is one program: started with arguments it isnerve-node, started without any it opens the window. The window runs the CLI for every action, so it has the CLI's checks and audit records. Seedocs/user/desktop.md.- Its pages: overview (the node's state, panic and unlock, and the service's start, stop and restart); centers with pairing (also from a
nerve://link), pause, resume and key rotation; relay; permissions (mode, folders, rules, capability switches, sudo); audit; log; settings (config, proxy, backup and restore); help; and the About dialog. A first-run setup names the node and pairs its first center. Light and dark follow the system, or the choice saved in the app. - The audit page has allow, allow as wildcard, deny and deny as wildcard on each entry, which write the same rule as
nerve-node rule add --action(#23). - The downloaded file installs itself: the program, the node as a service under its own user (as
nerve-node install), the menu or Start menu entry with its icon, and thenerve://handler, after the system's question for the rights (pkexec, UAC). Started again, it offers to open, update or uninstall Nerve. Settings update it (from the latest release, checked againstSHA256SUMS, or a file) and uninstall it, keeping or deleting the node's data. On Windows it is in Apps & features, whose Uninstall opens the app's uninstall. - A node installed with
nerve-nodeis taken over: the service runs the desktop app's program, so there is one program to update. On Linux/usr/local/bin/nerve-nodebecomes a link to it, so the terminal command keeps working (--versionthrough it saysnerve-node-desktop), and uninstall removes the link. On Windows the oldnerve-node.exeis removed, as the app has no console; for a terminal, downloadnerve-node-x86_64-windows.exefrom the release. A plainnerve-node uninstallafter the takeover removes the app too. - A change the running service takes only when it starts again (on Windows every change but a folder's, a pairing too) makes the app restart the service, two seconds after the last one or as the app closes, and say so. A restore stops the service and starts it again.
- On Windows a standard user can install and use the app with an administrator's name and password in the UAC prompt; the commands still run as that user.
- On Linux the app says what the desktop lacks instead of failing silently: no display, no
pkexecor polkit agent, no desktop portal for the file dialogs, noupdate-desktop-database; without OpenGL it draws in software.docs/user/desktop.mdlists what each desktop needs. - The release has
nerve-node-desktop-x86_64-linuxandnerve-node-desktop-x86_64-windows.exe, with their checksums inSHA256SUMS. - The
NOTICEfile holds the licence of the Lucide icons, which the app and the center's web UI use. The app is built with Slint under its Royalty-free license 2.0. - Rights once, like an installed program: the user who installs becomes the node's owner, and opens the app, changes settings, pairs, edits rules and starts, stops and restarts the service without a question. The administrator's password is asked only for update, uninstall, sudo on and the
machine.*settings that pick an account or program (also a restore that would change them), each time for that action. - The look: colour with a meaning (the node's state, the page's icon, the open page), text that reads well in light and dark (WCAG AA), short texts. A busy button shows a spinner in place of its icon and keeps its size. Light and dark are chosen at the foot of the sidebar, and a change comes in one step, with no light frame between two dark ones. Keys: Ctrl+1 … Ctrl+8 for the pages, Ctrl+R and F5 read the page again, Esc and Enter in dialogs, Tab through every control. A click on the open page's tab reads nothing again.
- Settings has tabs (General, Keys, Network, Limits, Backup, App, Advanced), with a control for each setting an owner changes, the limits per command too; Any setting is under Advanced. Network keeps the proxy: the relay has a page of its own.
- The Relay page has both sides of a relay: this node through one, from one pasted link, and this machine as one, with its nodes, their links, centers, limits and tunnels now. Pairing checks the link first (the center answers, its pin, the code still valid) and offers Pair only when it can work. The first-run steps have Back.
- Permissions puts the rules that count in the center's mode first (in allowlist mode the deny rules as its exceptions), keeps the sudo list with sudo, and lets every rule be edited in place. It says who runs the commands, offers Run them as you in allowlist mode, lists
nerve-run's built-in folders, and shows a folder grant that failed. A one-line warning says when commands run without their limits. - A list longer than some eight rows (rules, folders, capabilities, a relay's nodes and tunnels, the Overview's centers) scrolls in a box of its own with a scroll bar in sight. Help has the keys and the command reference, by topic or A to Z and filtered, each command opening on its arguments, an example and the place in the app; each part, topic and command opens and closes on its own. Clear on Audit and Log asks first. Audit filters by decision (allowed, refused, settings changes), center, action and words in the target and reason, combined and counted, newest or oldest first.
- The window has the app's icon in GNOME's dash, KDE's task manager and the Windows taskbar. With System, the app is dark when GNOME (also Zorin OS, by its GTK theme) or KDE is. The downloaded file opened while the app is open brings the window up and offers its update.
- Animations of 100 to 200 ms: pages and settings tabs fade in, dialogs rise in and their veil lifts as they close, the note in the corner comes and goes, Help's sections slide open, the open page's mark grows, buttons and switches change smoothly. None delays a click or a key. They are off, and the loading dots and spinners still, when the desktop asks for less motion: GNOME's Reduce Animation, KDE's animation speed Instant, Windows' Animation effects off, or the desktop portal's
reduced-motion(#136).
The guard against changing the node (#143)
- A new pairing starts with deny rules, the guard, that keep its commands off the node itself: a command that runs the node's programs (not one that only names them, like
cargo build -p nerve-node), one that names its socket or its config and state folders, and a write into those folders.rule guardadds them to a pairing that lacks them, a pairing made before 0.0.6 included, and the desktop app offers that on Permissions. They catch an agent's mistake, not a name built at run time; the real protection isnerve-run, the separate account for commands on Linux. - The guard also refuses a command that stops, restarts, disables or kills the node's service or process by its name:
systemctl stop,restart,disable,killormask nerve-node,service nerve-node stoporrestart, andpkillorkillallonnerve-nodeon Linux, andsc stop,configordelete,net stop,Stop-Service,Restart-Service,Set-Service,Remove-Service,Stop-Process -Nameandtaskkill /im nerve-node.exe(ornerve-node-desktop.exe) on Windows. The Windows commands match in any case, a line break after a command or a name ends it like a space, andsudocounts at a command's start only, so a quoted mention such asgit commit -m "run sudo systemctl stop nerve-node"runs. Reading stays allowed (systemctl status,journalctl -u nerve-node,pgrep,sc query,Get-Service nerve-node). A command afterthen,do,else,{,!,timeornohupcounts as one that starts a line, and an indent of up to 16 characters is read. A refusal's reason and the settings log write the rule's tabs and line breaks as\t,\rand\n, andconfig addand the app refuse the listed text of such a rule as a new rule. The rules that name the node's programs, sockets and folders end a name at a tab or line break too, and see a command after one. A rule with a tab or line break is listed with\t,\rand\nwritten out (rule ls, the app's rule lists), andrule rmandrule edittake it so.
Folder mode as an account of its own (#142)
- On the node installed as a service on Linux,
foldermode commands, andallowlistmode commands unlessmode set allowlist --as-owner, run asnerve-run, an accountinstallmakes with a home of its own (/var/lib/nerve-run), no login and no other groups;uninstallremoves it. In 0.0.5 the commands of every mode ran as one account thatinstalltook orsetupchose (machine.user).nerve-runis not the owner: the owner socket refuses it, and the owner's session programs (service manager, session bus, tmux) take no requests from it, on every kernel.usermode runs as the owner, the account that raninstall. There is no other account to choose:setup --create-user, setup's question for the account andmachine.useron Linux (it stays for Windows) are gone. - The folders you give a pairing become POSIX ACL entries for
nerve-run(the folder and everything below it, default entries so that what it makes stays yours, a pass-through entry on your closed folders above it), taken off again when the grant goes and byuninstall(which also takes them off whatnerve-runmade there, and gives what it made to the o...
Nerve 0.0.6 (pre-release pre3-v0.0.6)
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, and the desktop app nerve-node-desktop for Linux x86_64 (glibc 2.35 or newer) and Windows x86_64, built from ebcb116. SHA256SUMS lists their checksums. They are not signed; nerve-node update and the desktop app's update check the one they download against SHA256SUMS (docs/user/service.md, docs/user/desktop.md).
Nerve 0.0.6 (pre-release pre2-v0.0.6)
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, and the desktop app nerve-node-desktop for Linux x86_64 (glibc 2.35 or newer) and Windows x86_64, built from 04e6e50. SHA256SUMS lists their checksums. They are not signed; nerve-node update and the desktop app's update check the one they download against SHA256SUMS (docs/user/service.md, docs/user/desktop.md).
Nerve 0.0.6 (pre-release pre1-v0.0.6)
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, and the desktop app nerve-node-desktop for Linux x86_64 (glibc 2.35 or newer) and Windows x86_64, built from ea8cb7e. SHA256SUMS lists their checksums. They are not signed; nerve-node update and the desktop app's update check the one they download against SHA256SUMS (docs/user/service.md, docs/user/desktop.md).
Nerve 0.0.5
The action checker
- The center checks each call before the machine gets it, and can refuse it (#17). In this order: a blocklist of dangerous commands and paths, the allow rules saved in the center, an optional decision model, then the machine's own policy as before. A block anywhere wins: a center allow rule only skips the model, never a blocklist entry or the machine's rules. The refusal comes back to the agent as
forbiddenand says what refused it and where the owner changes that. Set it up on the new Action checker page of the web UI; the details are indocs/user/action-checker.md. - The blocklist is on by default. It catches an agent's mistakes (
rm -rf ~,mkfs,ddto a disk, a force-push tomain, their Windows equivalents), not command lines written to get past it; against those the machine's own policy counts. A download piped into a shell (curl … | sh,irm … | iex) is refused by default too, also a tool's official install one-liner. Entries can be added, removed, switched off and reset to the defaults. The built-in entries come with the program, so a later release's changes to them reach the center; what you switched off or removed stays. - Block entries and allow rules are for every machine or one, an entry for every machine can be switched off for one, and each machine sets the blocklist and the model to follow the center, on or off.
- The decision model is off by default. It is a System One endpoint (
/v1/systemone, with an optional bearer token), or a local model the center installs with one click: a pinned llama.cpp build and LiquidAI d1-3B (LFM Open License v1.0, the default) or Kev-4B (Apache-2.0), each checked against its pinned SHA-256 and run on loopback, on the CPU or the GPU (Vulkan). A model that cannot be reached or answer in time refuses the call (fail closed) unless the owner switches that to allow-and-log. - Taint marks a session once a call of it returned content, so the model can be given only the calls of such sessions. Every decision of the checker is on the Audit page and in the center's log.
- The center now keeps
checker-model.token(the endpoint's token) and thechecker/folder (the local build and model, 1.7 or 3.0 GB) in its state folder. Neither is in a backup: after a restore on another machine, enter the token again and install the local model again; until then a model that is on refuses the calls it sees. - A center that ran 0.0.4 starts with the blocklist on and its default entries, so a call that 0.0.4 passed to the machine may now be refused. Switch the blocklist, or one entry, off on the Action checker page, for every machine or under Per machine. Nodes need no update: the checker runs on the center only.
- A 0.0.4 center reads a 0.0.5
state.json, but leaves the checker's settings out the next time it writes the state (after a call or a change), so they are gone. Before you go back to 0.0.4, note your own entries, allow rules and model settings: 0.0.5 starts from the defaults again. Delete thechecker/folder in the state folder to free its space; 0.0.4 does not use it or the token.
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, built from 7649fc9. SHA256SUMS lists their checksums. They are not signed; nerve-node update checks the one it downloads against SHA256SUMS (docs/user/service.md).
Nerve 0.0.4
Limits per command
- On Linux every command runs in a cgroup of its own, held to its memory, CPU and processes. The owner sets the defaults and the most a call may ask for in
[limits.command]ofnode.toml;exec.runtakesmemory_mb,cpu_percentandprocessesup to that most. A command past its memory is killed, and its result (killed: "memory") and the audit log say why.nerve-node statusshows the limits and whether the node holds them (#119). - When a command ends, everything in its cgroup ends too, also a process it moved out of its process group.
- The installed unit gets
Delegate=cpu memory pids. Afterupdate, runsudo nerve-node installonce more to write it; until then commands run without these limits. A node you start yourself has them undersystemd-run --user --scope -p Delegate=yes nerve-node run. - A 0.0.3 node refuses a
node.tomlthat sets[limits.command]. Before you go back to 0.0.3, remove it withnerve-node config unset limits.command.
Backup, restore and moving
nerve-node backup <file>andnerve-node restore <file>, and the same fornerve-center, write the config and keys (the center's certificate, key and state) to one file that a passphrase protects (PBKDF2-HMAC-SHA256 and ChaCha20-Poly1305, at least 12 characters), and put them back on the same machine or another, so a node or a center can be moved without pairing again (#122).- Keys in the system keyring, and a proxy's header values, go into a backup only with
--include-keyring. A restore never goes under a running node or center, refuses a backup of another node or center unless you add--replace, keeps every pin as saved, except a newer one here from a key rotation (or set by hand since), which stays, and a center's old pin whose time ended here, which does not come back, and sets the sudo switch off. These are two ofnerve-center's subcommands now; a harness still starts it without one.
The center as a service
- On Linux with systemd,
sudo nerve-center installinstalls the center as a service that starts with the machine, under a user of its own (nerve-center) with its own state folder (/var/lib/nerve-center), with MCP over HTTP and no privilege. Its settings are in/etc/nerve-center/center.env, whichinstallwrites once with a new harness token, so the web UI asks for a login from the start.updatereplaces the program with the latest release, checked againstSHA256SUMS, or with--from <file>, and puts the old one back when the new one does not start.uninstallremoves the service, the user and the program;--purgealso the folders (#123). - The released node's
installanduninstallno longer fail on the control socket, or on a link, in its state folder: the static Linux programs opened such an entry instead of only giving it to the node's user.
Capability providers
- A program on the machine that the owner names in
providers.allowed, such as a desktop app, can attach to the node's control socket and add capabilities of its own. The node lists them to every center withprovider: <name>, decides and audits every call to them by that center's policy, forwards only the allowed ones, and drops them when the program exits. Linux only for now; the conformance suite has a provider part (#16). - In
foldermode an action that names no path, which is what a provider adds, runs only where the owner set iton. - A center with the settings grant can no longer allow, or turn on, a capability or an action the node does not offer now: it may sense once a provider offers it, so only the owner does that.
- A 0.0.3 node refuses a
node.tomlthat holdsproviders. Before you go back to 0.0.3, remove it withnerve-node config unset providers.
Run-time limit for commands
- Every command has a time limit now. A call without
timeout_msgetslimits.default_timeout_secs(10 minutes), and atimeout_msabovelimits.max_timeout_secs(1 hour) is cut to it. A command past its limit is killed and the call fails withtimeout, as before; the message says which limit it was. Before, a command withouttimeout_msran until it ended or its session did. The agent sees both numbers in the description ofexec_runand in itstimeout_msparameter, and machines with other limits are separate tools. Only the owner sets them, for examplenerve-node config set limits.max_timeout_secs 86400for jobs that run a day; a center cannot, also with the settings grant (#120). - A 0.0.3 node refuses a
node.tomlthat holds either key. Before you go back to 0.0.3, remove them withnerve-node config unset limits.default_timeout_secsandlimits.max_timeout_secs. A file in which you set neither reads on 0.0.3, as the defaults are not written.
Key rotation
- A machine's key for a center, and the center's own TLS key, can be replaced without pairing again (#121).
nerve-node center rotate-keysends the machine's new key to the center over the link, signed with the old one; in the center's web UI, Settings, Rotate key makes a new center key that the linked machines learn, signed with the old one. The old key stays valid for 7 days, or until its owner ends that (--end-grace, Serve the new key now). The machine keeps its id. Each rotation is in the node's audit log and the center's log. - The protocol gets additive features (
hello.features,welcome.features, spec §1.1) and the featurerotate(spec §4.10). A node or center older than 0.0.4 keeps working with a newer one, but cannot rotate; a node older than 0.0.4 has to pair again after its center's key was rotated. - A 0.0.3 node refuses a
node.tomlthat holdspublic_keyorkey_rotationsunder a pairing, which a rotation of the machine's key writes, and cannot use the rotated key anyway: such a pairing has to be paired again on 0.0.3. - A 0.0.3 node refuses a
node.tomlthat holdspin_rotationsorold_pinunder a pairing. A rotation of the center's key writes both (old_pinfor up to 7 days; the running node drops it once that time is over), and so does setting a center's pin by hand withconfig set center.<name>.pin, which writespin_rotations. Such a pairing works on 0.0.3 with the new pin once the center serves its new key (after its 7 days, or Serve the new key now); until then 0.0.3 cannot link with it. So go back only after that, and before you do, remove them withnerve-node config unset center.<name>.pin_rotationsandnerve-node config unset center.<name>.old_pin.
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, built from 2321b99. SHA256SUMS lists their checksums. They are not signed; nerve-node update checks the one it downloads against SHA256SUMS (docs/user/service.md).
Nerve 0.0.3
Upgrading from 0.0.2
- A 0.0.2
nerve-nodeCLI talking to a 0.0.3 node on Linux is refused for everything exceptstatus, because it sends no control-socket token (#83).updateof 0.0.2 still works, as it asks onlystatus. After it, run the CLI from the 0.0.3 program too. - A 0.0.2 node refuses a
node.tomlthat holdsplacesunder a pairing'spolicy, which 0.0.3 writes withfolder add(#88). Before you go back to 0.0.2, remove the key withnerve-node config unset center.<name>.policy.placesfor each pairing.
Folder mode on Windows
- Commands in folder mode now run in an AppContainer of their own, so a command only reaches the folders you gave it, on a node you run yourself; the installed Windows service still runs no command in folder mode (#39, #45).
docs/user/modes.mdalso lists what the AppContainer does not stop (#86). - PowerShell
cd,chdir,slandpushdwork with whole paths in the container, not only inside theWork:drive (#85). folder add,folder setandfolder rmreach a running node at once, through a control pipe that a command cannot use (#53, #93).- A large folder is walked only where the grant changes, so applying the same grant again is much faster (#54, #95).
- The keyring refusal text for folder mode names the AppContainer and the Credential Manager, not Landlock (#91, #102).
Folder mode on Linux
- A folder a command replaced by a link is no longer followed (#74, #80).
- On Windows and Linux, a recorded folder stays at the place it was added, so a junction or link made later does not move it (#77, #88).
folder setandfolder rmname the stored folder when the node cannot look into the path you typed (#98, #103).
Control socket and config
- A sandboxed command can no longer read the node config over the control socket; the socket answers only requests that carry the owner's token, and refuses every request that comes from below a command the node runs (#70, #83).
- A busy control socket is no longer taken for a stopped node, and
panicandunlockno longer report a change the node did not get (#69, #79). - The keys lock is free again right after it is released, even when a command was forked in the meantime (#73, #79).
rule addrefuses thefs:...andexec:...forms, andrule rmremoves entries that older runs made by mistake (#78, #79).machine.secret_storage = "keyring"keeps the node's own keys in the system keyring, opt-in (#46, #47).
Sudo and install
- On Windows, sudo runs the command account with its elevated token (#60, #75).
installandsetupwarn when the account that runs the commands can become root without a password (#97, #104).- The installed Windows node writes start, stop and failures to the Event Log (#65, #71).
- On the installed Windows node, a proxy with header values or a URL password is refused, because the node cannot read them (#68, #81).
uninstallremoves a node's profiles even when its state folder is already gone (#55, #84).
CI
- Pull requests run
cargo fmt,clippyand the tests on Linux and on Windows (#58, #100). - The keyring places test runs on Unix only, and the Windows test build works again (#96, #101).
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, built from 80b9786. SHA256SUMS lists their checksums. They are not signed; nerve-node update checks the one it downloads against SHA256SUMS (docs/user/service.md).
Nerve 0.0.2
- Install the node as a service with
install,updateanduninstall, on Linux (systemd) and on Windows. The service runs as its ownnerveuser; config, keys and state are kept out of the commands' reach. - Commands run as the account that installed the node, or as one you choose in
setup.setup --create-usermakes a new account with its own home folder. - User mode, folder mode and sudo run their commands as that account. Folder mode on Linux is limited to the folders you gave.
- A node started as root, or as administrator on Windows, is refused unless
machine.allow_rootis set, and warns when it runs. - Download and install in two steps:
sudo ./nerve-node-x86_64-linux install.
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, built from 8e25cdc. SHA256SUMS lists their checksums. They are not signed; nerve-node update checks the one it downloads against SHA256SUMS (docs/user/service.md).
Nerve 0.0.1
- Pair a node with a center using a one-time code; the node pins the center's certificate and the two talk over a signed link.
nerve-noderuns on a machine and offers files (fs) and commands (exec) to the center, with a headless CLI to manage it.nerve-centerruns as an MCP server for an agent harness and offers every paired node's capabilities as MCP tools.- Policy modes per center: default deny, allowlist (the default), folder and user. Folder and user give full access in their area; allowlist allows only what a rule names.
- Allow and deny rules with wildcards for every action, and protected paths that stay closed in every mode.
- Folder access is set per folder as read, write and execute, in any combination.
- Commands run with sudo only if the owner turns sudo on for the node. The password is kept in memory and never logged.
- The node keeps a local audit log of every decision, and can be locked with panic and unlock.
- A web UI for the center shows nodes, the audit log (with one-click rules), statistics and help, and lets you disable a node.
- The web UI has a Log page for the center's own log (written to
log.jsonl), with levels, filters and download. - Statistics can be shown per machine, picked from a searchable list; the default is overall.
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, built from bccd3f5. SHA256SUMS lists their checksums. They are not signed: Nerve has no update channel yet (docs/dev/releasing.md).
Nerve 0.0.1 (pre-release pre1-v0.0.1)
Static Linux binaries (x86_64, aarch64) and Windows x86_64 programs of nerve-center and nerve-node, built from 4227214. SHA256SUMS lists their checksums. They are not signed: Nerve has no update channel yet (docs/dev/releasing.md).