Repository navigation
The center's Capabilities tab, and capabilities a center adds (#152, B8) - #182
Merged
Merged
Conversation
The cap ls overview with each unit's effect, source and switch for one center, and the programs allowed as providers. The switches leave Permissions and the provider allow list leaves Settings > Advanced; the page opens with Ctrl+9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A dialog checks each field as the node and the center do while the owner types; the save runs cap add or cap edit with the schema on stdin, and what the node refuses stays in the dialog with its reason. Removing one asks first. Windows and a node run by hand say why they offer none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The dialog checks a capability's time limit against the node's own limits.max_timeout_secs, read with the page, not the default 3600. - A unit with no switch of its own shows its capability's (from the `centers` of `cap ls`), marked "like its capability". - A save's answer goes to the dialog that sent it; a refusal after the dialog closed is a toast, and a second save cannot run alongside. - Add and Save are always offered; a click shows the empty fields. - Tests for the stale `cap ls` answer, the raised limit, the inherited switch, the answers of saves and the empty save. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dialog checks a time limit against the default once the node's limit is unset, its Arguments and Result boxes scroll, and an empty name or command stays an error after the first save. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The scrolling text box panned on a drag and selected nothing. The wheel and the cursor follow still scroll it. Also move the time-limit test above the doc comment of the dialog's save test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pick and an unpairing of the shown center are tested now, and the "In use" pill says "Usable now", as the node only says the center may use the unit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Also test the Programs row's Choose... button. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A press on a line cut off at the bottom brings it into view, and how many lines fit depends on the platform's font; on Windows the old start scrolled the box by two pixels. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A center adds, edits and removes capabilities in its own entry of the pairing (settings.cap-add, cap-edit, cap-rm). They are offered to that center alone as center-added, run as nerve-run, count as execute unless they sense or actuate, wait for the owner's on where they do, and are audited as the center's change. The owner's capabilities and programs come first; the owner removes one with cap rm --center, and an off of one stays until the owner changes it. Windows and a node run by hand take none and say why. The conformance node part checks both cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A page of its own with a machine picker: each unit a machine offers the agent with its effect and where it comes from, the ones the center left out with the reason, and, on a machine that gave the center the settings grant, the capabilities this center added, with a form to add and edit them and Remove. The center checks the form with the node's own rules while it is typed and before it sends it; the node checks it again and its refusal shows in the form. A machine without the grant is shown read only. The form's checks move from the desktop app to nerve-policy, so the app, the center and the node share them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The line of a capability a center added that senses or actuates said it counted as execute; it waits for the owner's on instead. The hint under the form's row of effects stands on its own line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A center removes its own capability also once the owner declares the same name; an edit of a sensing one that changes its effect or command waits for the owner's on again; the form says an unknown effect or platform; a summary, a command element and a center's capabilities together have a bound; the Capabilities tab tells the center's own units by capability and takes a node's odd answer as data; a test of the tab for a node that takes none; docs for the pause, the log lines, the desktop app and protocol 7.4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its params decide what fills the command and its timeout how long it runs, so the owner's on was given for those too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d say why one is not offered The center fetches the node's description before it answers a cap-add, cap-edit or cap-rm, so the page drawn after it is not the one from before. A capability the center added that the node neither offers nor leaves out is marked not offered, with what turns it on. The descriptor section of the protocol names the providers config and center-added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t offered Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A center that added a capability could turn on or allow that capability as a whole, and that switch or rule then also covered a sensing action of a program the owner allowed that came later under the same name. Now: - a center turns on or allows only its own action, by its name; the capability as a whole stays the owner's while nothing else offers it; - while a center keeps one of its own under a name a program offers, the program's capability is not offered to that center either; - removing what a center added (by the center or with cap rm --center) drops that center's on and allow rules for that action; an off stays. cap ls says of a center's sensing capability that only the owner turns it on, not that it waits. The Capabilities tab names the action's key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Also say that an off of a center's capability lasts past removing and adding it again, and that a removal takes its on and allow rules along. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts name A center's own sensing or actuating entries count for what only the owner turns on in settings.set, so a switch or rule for their name set while a program or the owner's node.toml offered it without sensing cannot cover them later. A removal keeps the switches and rules where the owner declares that very name, and an add refused under a program's capability no longer tells the center to remove an entry it does not have. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A program's events, state and streams no longer reach a center that keeps its own under that capability; cap ls --center lists only that center's added ones; an owner's sensing capability under a center's name waits for the owner's on; the Capabilities tab leaves out an entry whose schema the node would not keep; tests for these and for the grant taken back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The owner's `on` for the owner's capability no longer turns on a center's own sensing one of that name once the owner's goes: `cap rm`, `config.write` and `config accept` switch it off and `cap rm` says so. While a program keeps the center's own out, the owner's write that turns it on is refused, and `config accept` switches it off. - A center's time limit is checked when it adds or edits one, so the owner may lower `limits.max_timeout_secs` later. - The Capabilities tab keeps its picker while a machine loads, says why one did not load, and reads the machines again after a 404. - Docs: the size limits of a summary and a command element, also in node.toml; a test of a center's capability that takes a path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A removal of a center's last capability under a name drops the owner's on and allow rules for that name as a whole too, unless the owner declares it; tests for the owner's other writes keeping its on; a superseded load of the Capabilities tab ends quietly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts own While a center keeps an entry of its own under a program's capability, it is offered neither, so an on or allow rule the owner sets then for that capability as a whole, or for the center's action of that name, was meant for the program's, and would go unseen with the center's own when it is removed. config.write refuses it and says to remove the center's first; config accept switches it off and reports it as held. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ConfigCapability::line, which cap ls and the audit use for a command, left DEL, the C1 controls, the line separators and the format characters (such as direction marks) as they are, and did not quote an element with a format character. A center's command could then read as something else in cap ls. They are now written as \u escapes in quotes, which read back to the same words. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owner turns on a center's capability that senses or acts for what it runs, but the page showed only the center's own summary. A row of a center's capability now shows its command, from cap ls's added, as the owner's rows do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A center adds none under an on or allow rule set for what else offers that name; config accept tells each kind of held switch apart; a center's 64 entries are said in its own words; the desktop shows a center's whole command, wrapped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ties Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… daemon Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e row Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
config accept names a center's own sensing action once, with the note that fits it, where the file sets an allow rule for it; a center's add refused for a switch set for something else says the center may take it away itself; protocol 7.4.2 and the web UI's page name that refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
config unset, config set, a config command without a running node and a hand edit that config accept takes dropped a center's own capability but kept its on and allow rules for it, which then turned on what a program offers under that name later. Each of them now drops them as cap rm --center does; config accept names what it dropped. The center's test also reads the log lines of a change, a removal and a refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd with the node stopped cap rm --center finds no entry once the hand edit took it out, so the advice now says to use cap rm before, take the switches out in the same edit, or switch them off and remove the rule afterwards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The node part sends one wrong sudo password and expects it refused. The test ran it against the machine's own sudo, which a CI runner has without a password, so the wrong one worked. The node now uses a fake sudo that wants a password nobody gives, as the conformance e2e and the relay test do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Piggidragon
changed the base branch from
feature/desktop-capabilities
to
main
November 2, 2026 08:36
Piggidragon
added a commit
that referenced
this pull request
Nov 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step B8 of #152, stacked on #181 (B7). Part of #152.
A center with the settings grant can now add, change and remove capabilities of its own on a node, and the center's web UI gets a Capabilities tab to see and manage them (owner decisions Q22, Q24).
The node
settings.cap-add,settings.cap-editandsettings.cap-rm.[[center.capability]]). No other center ever sees them, inlist, incap lsrows or in the settings.commitascenter <name>.settingsstays unreachable throughexecute.nerve-run; there is no account field (B5).execute, whatever effect is declared.cap set … on --center. A center's ownonis refused.offorhiddenof a center's capability stays until the owner changes it.nerve-run.cap lsshows who added each capability ("added by center X, counted as execute", or "waits for your cap set on" for sensing).cap rm NAME --center Cremoves one;settings.get capabilitieslists a center's own.config::form), so the app, the center and the node check a capability with the same code.The center's web UI
node.toml, this center, program X), and the ones left out with their reason.GET /api/caps,POST /api/caps/check,POST /api/caps/saveandPOST /api/caps/remove. Each change is in the center's log.Docs
Tests
tests/center_caps.rs):tests/caps.rs), an in-process center and node:listandexecutethrough MCP, withsettings.cap-addunreachable throughexecute;ui.rscovers the API and app.js sources.Real machines
who.am(id, read) andcam.look(sense).node.tomlalready has was refused by the node, shown in the form.execute who.amran asuid=…(nerve-run).cam.lookwas not offered. The center'sonwas refused ("only the owner can turn on what senses or actuates"). After the owner'scap set cam.look on --center lxcit ran.who.amoff (the center'sonwas then refused) and removed it withcap rm --center.cap lscalled a center's sensing capability "counted as execute".uninstall --purgeleft nothing.Review and checks
cargo fmt --check, clippy andcargo xwin clippy: clean.cargo test --workspace: 1740 passed, 0 failed.Known limits
cap rm --center. Its switches work there.🤖 Generated with Claude Code