Trust, safety, and the person at the other end
DeskVNC is built around one safety property, and the rest of the design is what that property needs to stay true at machine speed. A person at the remote computer can take control back at any moment, and the agent on the worker side hears about it through the same channel it sent the click through. Nothing else has to be configured and no separate approval flow sits between the person and the machine. The answer is structural rather than aspirational because the architecture uses the same primitive the keyboard focus uses. This page walks the property, the layers that defend it, the error codes an agent handles, the Boundary module, the trust chain for credentials, and the gates the promotion programme runs on every deploy.
The core safety property
The safety property is one sentence and one mechanism. A person at the remote computer can take control back at any moment, and the agent on the worker side hears about it through the same channel. The mechanism is a per machine lease the person can revoke by focusing the window or pressing a key. The lease is an entry in a table owned by the same code that owns the input queue. When a person reaches the keyboard, the input event reaches the same loop the agent's tools reach, and the lease on that machine is invalidated in the same update that delivers the keystroke to the window. The agent gets the news on its next call, as a structured error, not as an exception or a hang.
The lease model
Every machine is its own limb with its own lease. That single sentence is what the README means when it says ten machines are ten independent loops. Each saved host has its own row in the lease table, each open session has its own input queue, and each protocol stream stands on its own. The MCP server inside DeskVNC holds them all in one process, but they are isolated in the way the agent's plan needs them to be.
That shape is the isolation an operator wants when an agent goes wrong on one machine but the other nine still need to be driven. A misfired loop on the build box does not lock the operator out of the jump host. A hung lease on the database server does not put an exclusive hold on the QA box. The boundaries sit where the operator's eyes and hands already are. Take control on machine A and the lease for A is invalidated, the agent loses only A. Leases on machines B and J, where the agent is still doing useful work, are untouched.
The generation fence
The generation fence is the half of the safety story that catches a click computed against a stale frame before the click reaches the wire. Every dvv_screen call returns a monotonic integer called the generation, tied to the screen the call returned. Every input tool call then requires the agent to include that generation in its arguments. The server checks, before the click leaves the binary, that the generation matches the current screen for that machine.
If the screen has since resized, the click is refused rather than landing in the wrong place, and the refusal reports GEOMETRY_CHANGED with nothing delivered. The agent reads the screen again, picks up the new geometry, and clicks against that one instead. The shape of the retry is the same as the first click, with one field updated. The error is data, the data drives the next call, and the next call is the same loop.
The typing fence
The typing fence is the matching property for keys and text. Typing and key calls are refused until the screen has been read, in pixels, since it last changed significantly. The rule is structural: a click computed against an old picture is one failure mode, and keystrokes fired into a window whose contents have moved on is another. Both are caught before the wire.
The refusal is SCREEN_CHANGED, and only a call that returns pixels clears the fence. Asking for damage rectangles does not clear it, because a damage crop describes what changed rather than proving the agent has seen the current state. dvv_status reads no pixels, needs no lease, and does not clear the typing fence either. The typing fence is the wall between an agent that has looked and an agent that has only asked.
The four real error codes
DeskVNC returns a small, closed set of refusal codes, and every designated interaction is built against them. Four codes exist, and four are listed below. Anything outside this set in an agent's branch logic is invented, and the verify facts gate that scans every published asset will fail the deploy on it.
| Code | What it means | One line recovery |
|---|---|---|
LIMB_GONE |
The connection to the machine has dropped or the lease was cleared. | List limbs with dvv_limbs, reopen the machine with dvv_open, and start the loop again. |
GEOMETRY_CHANGED |
The screen resized since the coordinate was computed. | Call dvv_screen again, pick up the new geometry, and retry the click. |
SCREEN_CHANGED |
Something window sized repainted since the last pixel read. | Call dvv_screen for pixels, then retry the typing or key call. |
LEASE_REVOKED |
A person took control back, which is the intended behaviour. | Read lease.human_took_over from dvv_status; if true, stop and report. |
Earlier drafts of this page also listed two codes that look plausible and do not exist in the source. An earlier agent invented them and they had to be removed from published pages. The verify facts gate fails the build on either, so an honest agent does not branch on invented names.
Boundary and the attended support safety property
The Boundary module is the second surface the safety property lives on. Boundary is DeskVNC's attended support mode, designed for the case where the two people are not on the same network and the person at the remote computer has not saved a machine yet. Download DeskVNC Support from the release page and send it to the person who needs help. They press Get a code (or Create invitation when no code service is configured), approve the connection, and the worker side joins from Boundary support inside DeskVNC.
The safety property carries over intact. Boundary tries a direct encrypted path first and falls back to its relay when the networks do not allow a direct path; the recipient still approves the session, and can revoke control or end it at any time. No account is required. The full walk through, including the code service handoff with four digit groups like 1234 5678 9012, is in the Boundary attended support page, and the deeper design note is in the Boundary module deep dive.
The trust chain for secrets
Credentials live in the operating system keychain on each platform the client runs on. On macOS that is Keychain Services, on Windows it is Credential Manager, and on Linux it is Secret Service. The DeskVNC viewer writes and reads the same kind of entry the system password dialog would write, so a saved host's password is gated by the same authentication the user already uses to unlock the machine. Nothing in the binary holds a plaintext password longer than the call that uses it.
For headless machines, where no interactive keychain is available, DeskVNC keeps an encrypted file fallback that holds the credential on disk under a key derived from a passphrase the operator sets up at install time. The fallback is a feature for unattended deployments rather than a workaround, and the operator chooses it when the host is a server, a build agent, or a worker without a logged in user. The encrypted file is read by the same code path the keychain is read by, so an agent sees one credential surface regardless of where the secret lives.
How the safety property is verified
The safety property is enforced by the binary, and it is also enforced by the gates the promotion programme runs on every publish. Three gates matter for the trust story this page is making.
- Verify facts gate.
scripts/verify-facts.shfetches the live manifest, the live skill file, and the live README, then diffs every published asset against them. Invented tool identifiers, error codes that do not exist, and latency or throughput figures the README does not publish fail the deploy. - Compliance gate.
scripts/compliance-check.shscans every published file for em dashes and en dashes, for negative framing, for fabricated proof points, for placeholders and dead anchors, for external resource dependencies, and for HTML well formedness and JSON validity. - URL verification on every deploy. After a deploy, the live URLs on the Cloudflare Pages site are fetched and checked for the content that was supposed to land, so a publish that quietly failed a step cannot sit on a live URL.
Together those three gates are the load bearing layer below the property in the binary. The binary enforces the property at runtime, the gates enforce the claim at publish time, and an agent reading the published page is reading a claim the gates have already checked against the source.
Why this is the load bearing feature
The lease, the generation fence, the typing fence, the four closed error codes, the Boundary attended path, and the keychain backed credential store are the same property expressed in five places, and the property is what makes the rest of the architecture possible. Without it, an agent on the worker side is a script the operator hopes behaves right. With it, the agent is a tool the operator can stop with the same keyboard the operator already has. The page that summarises the lease in prose is the loop that does not blink. The Boundary page is the Boundary attended support handshake, and the deeper design note is the Boundary module deep dive. The verifier that checks every published page against the manifest is deepaash/deskvnc-resources, and the project itself is at github.com/psmux/DeskVNC.