Skip to content

Releases: prometheion/nerve-protocol

Nerve 0.0.6

Choose a tag to compare

@github-actions github-actions released this 22 Oct 20:24
39e9f2a

The desktop app

  • nerve-node-desktop is 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 is nerve-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. See docs/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 the nerve:// 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 against SHA256SUMS, 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-node is taken over: the service runs the desktop app's program, so there is one program to update. On Linux /usr/local/bin/nerve-node becomes a link to it, so the terminal command keeps working (--version through it says nerve-node-desktop), and uninstall removes the link. On Windows the old nerve-node.exe is removed, as the app has no console; for a terminal, download nerve-node-x86_64-windows.exe from the release. A plain nerve-node uninstall after 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 pkexec or polkit agent, no desktop portal for the file dialogs, no update-desktop-database; without OpenGL it draws in software. docs/user/desktop.md lists what each desktop needs.
  • The release has nerve-node-desktop-x86_64-linux and nerve-node-desktop-x86_64-windows.exe, with their checksums in SHA256SUMS.
  • The NOTICE file 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 guard adds 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 is nerve-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, kill or mask nerve-node, service nerve-node stop or restart, and pkill or killall on nerve-node on Linux, and sc stop, config or delete, net stop, Stop-Service, Restart-Service, Set-Service, Remove-Service, Stop-Process -Name and taskkill /im nerve-node.exe (or nerve-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, and sudo counts at a command's start only, so a quoted mention such as git 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 after then, do, else, {, !, time or nohup counts 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, \r and \n, and config add and 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, \r and \n written out (rule ls, the app's rule lists), and rule rm and rule edit take it so.

Folder mode as an account of its own (#142)

  • On the node installed as a service on Linux, folder mode commands, and allowlist mode commands unless mode set allowlist --as-owner, run as nerve-run, an account install makes with a home of its own (/var/lib/nerve-run), no login and no other groups; uninstall removes it. In 0.0.5 the commands of every mode ran as one account that install took or setup chose (machine.user). nerve-run is 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. user mode runs as the owner, the account that ran install. There is no other account to choose: setup --create-user, setup's question for the account and machine.user on 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 by uninstall (which also takes them off what nerve-run made there, and gives what it made to the o...
Read more

Nerve 0.0.6 (pre-release pre3-v0.0.6)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 20 Oct 11:49

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)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 20 Oct 07:50

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)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 19 Oct 22:16

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

Choose a tag to compare

@github-actions github-actions released this 18 Oct 21:59
7649fc9

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 forbidden and 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 in docs/user/action-checker.md.
  • The blocklist is on by default. It catches an agent's mistakes (rm -rf ~, mkfs, dd to a disk, a force-push to main, 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 the checker/ 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 the checker/ 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

Choose a tag to compare

@github-actions github-actions released this 16 Oct 12:31
2321b99

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] of node.toml; exec.run takes memory_mb, cpu_percent and processes up to that most. A command past its memory is killed, and its result (killed: "memory") and the audit log say why. nerve-node status shows 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. After update, run sudo nerve-node install once more to write it; until then commands run without these limits. A node you start yourself has them under systemd-run --user --scope -p Delegate=yes nerve-node run.
  • A 0.0.3 node refuses a node.toml that sets [limits.command]. Before you go back to 0.0.3, remove it with nerve-node config unset limits.command.

Backup, restore and moving

  • nerve-node backup <file> and nerve-node restore <file>, and the same for nerve-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 of nerve-center's subcommands now; a harness still starts it without one.

The center as a service

  • On Linux with systemd, sudo nerve-center install installs 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, which install writes once with a new harness token, so the web UI asks for a login from the start. update replaces the program with the latest release, checked against SHA256SUMS, or with --from <file>, and puts the old one back when the new one does not start. uninstall removes the service, the user and the program; --purge also the folders (#123).
  • The released node's install and uninstall no 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 with provider: <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 folder mode an action that names no path, which is what a provider adds, runs only where the owner set it on.
  • 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.toml that holds providers. Before you go back to 0.0.3, remove it with nerve-node config unset providers.

Run-time limit for commands

  • Every command has a time limit now. A call without timeout_ms gets limits.default_timeout_secs (10 minutes), and a timeout_ms above limits.max_timeout_secs (1 hour) is cut to it. A command past its limit is killed and the call fails with timeout, as before; the message says which limit it was. Before, a command without timeout_ms ran until it ended or its session did. The agent sees both numbers in the description of exec_run and in its timeout_ms parameter, and machines with other limits are separate tools. Only the owner sets them, for example nerve-node config set limits.max_timeout_secs 86400 for jobs that run a day; a center cannot, also with the settings grant (#120).
  • A 0.0.3 node refuses a node.toml that holds either key. Before you go back to 0.0.3, remove them with nerve-node config unset limits.default_timeout_secs and limits.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-key sends 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 feature rotate (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.toml that holds public_key or key_rotations under 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.toml that holds pin_rotations or old_pin under a pairing. A rotation of the center's key writes both (old_pin for up to 7 days; the running node drops it once that time is over), and so does setting a center's pin by hand with config set center.<name>.pin, which writes pin_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 with nerve-node config unset center.<name>.pin_rotations and nerve-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

Choose a tag to compare

@github-actions github-actions released this 14 Oct 15:54
80b9786

Upgrading from 0.0.2

  • A 0.0.2 nerve-node CLI talking to a 0.0.3 node on Linux is refused for everything except status, because it sends no control-socket token (#83). update of 0.0.2 still works, as it asks only status. After it, run the CLI from the 0.0.3 program too.
  • A 0.0.2 node refuses a node.toml that holds places under a pairing's policy, which 0.0.3 writes with folder add (#88). Before you go back to 0.0.2, remove the key with nerve-node config unset center.<name>.policy.places for 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.md also lists what the AppContainer does not stop (#86).
  • PowerShell cd, chdir, sl and pushd work with whole paths in the container, not only inside the Work: drive (#85).
  • folder add, folder set and folder rm reach 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 set and folder rm name 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 panic and unlock no 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 add refuses the fs:... and exec:... forms, and rule rm removes 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).
  • install and setup warn 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).
  • uninstall removes a node's profiles even when its state folder is already gone (#55, #84).

CI

  • Pull requests run cargo fmt, clippy and 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

Choose a tag to compare

@github-actions github-actions released this 13 Oct 14:25
8e25cdc
  • Install the node as a service with install, update and uninstall, on Linux (systemd) and on Windows. The service runs as its own nerve user; 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-user makes 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_root is 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

Choose a tag to compare

@github-actions github-actions released this 13 Oct 07:54
bccd3f5
  • 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-node runs on a machine and offers files (fs) and commands (exec) to the center, with a headless CLI to manage it.
  • nerve-center runs 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)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 12 Oct 20:40
4227214

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).