Files
desktop/BLOCKERS.md
T
pastilhasandClaude Opus 5 b91d4df21d desktop, extracted from the platform
x11vnc against display :0 — the session the owner is actually logged into, not a second one Officer
installs. sidecar/, api/, web/ and the host setup script, moved out of src/ whole.

Dormant when it moved: the websocket was commented out in server.tsx and the router in hono.ts since
2026-08-13, and no officer-vnc process was running on any machine. Nothing regressed and nothing was
restored — this took switched-off code out of the platform.

The point of the move is what the platform stopped knowing. Its sidecar/protocol.ts carried a VNC
section — vnc:start, vnc:ensure-password, vnc:stop, four reply variants, VncStartParams,
VncSessionInfo — and sidecar-registry.ts carried startVnc, ensureVncPassword, stopVnc and
isVncConnected. That is the platform speaking a plugin's vocabulary, which CLAUDE.md names as a rule
and this was the clearest breach of. All of it is in sidecar/protocol.ts here now.

The permission made a round trip worth recording. It was kind: 'execution' — "runs as the server owner
and cannot be shared" — and a plugin permission has no kind, deliberately, because a permission nobody
can delegate is a contradiction. So the property is expressed as ownerOnly: ['/'] instead: every path
under this plugin refused to anyone but the owner. Same answer, reached from the paths rather than
from a kind, and the first real use of a mechanism that landed the same day. The property is real —
there is one physical screen and it is the owner's.

Not finished, and BLOCKERS.md says so rather than the commit implying otherwise: the websocket is
dormant because a plugin cannot claim a WebSocket provider, host setup needs a reboot and no manifest
can express that, and there is no artwork.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 00:41:24 +00:00

2.7 KiB

Blockers — desktop extraction, 2026-08-21

Decisions taken without asking, and things that stop this being finished. Written as they were hit.

1. Host setup cannot be expressed by a manifest — left manual

setup/setup-desktop.sh installs ubuntu-desktop and gdm3, rewrites /etc/gdm3/custom.conf to force Xorg (x11vnc cannot mirror Wayland), enables auto-login so a session owns :0, installs Brave from its own apt repository, removes GNOME Keyring, and needs a reboot.

osDependencies installs packages. It cannot reconfigure a display manager, and nothing in the plugin contract can. So the manifest declares only x11vnc — the one honest package check — and the script is shipped for the owner to run by hand.

This is the agreed next piece of plugin architecture, deferred deliberately: the shape of a declared, sudo-run, reboot-aware setup step should be designed against a real case rather than guessed at, and this is that case. Until then the plugin installs and starts, and the desktop it mirrors has to exist already.

2. The websocket is not mounted, and a plugin cannot mount one

api/websocket.ts moved with everything else and is dormant. A plugin contributes api/router.ts (HTTP) and a sidecar; there is no way for it to claim a WebSocket provider — pluginPermissions in mount.ts sets api and routes and never ws, and server.tsx's handler map is a literal.

It was already switched off in the platform (commented out since 2026-08-13), so nothing regressed. But /desktop cannot work again until either the plugin contract grows sockets or this is rewritten onto the sidecar proxy. Recorded rather than worked around.

3. No artwork

assets/icon.png and assets/splash.png are absent — I cannot draw them, and the marketplace and dock fall back to the manifest's icon glyph (MonitorSmartphone) plus color. The OfficerIcons repository has a OffDesktop-shaped gap too. Marked here so it is a known absence rather than a broken image.

4. The permission changed shape, deliberately

It was kind: 'execution' in the platform registry, meaning "runs as the server owner and cannot be shared". A plugin permission has no kind and the manifest contract refuses one, on the grounds that a permission nobody can delegate is a contradiction.

So it is expressed as ownerOnly: ['/'] instead — every path under the plugin refused to anyone but the owner, which is the same answer by a different route. That mechanism landed the same day (docs/plugin-route-authorization.md) and this is its first real use.

The property being protected is real: x11vnc mirrors the single physical display the owner is logged into. Two accounts granted this would see the same screen, which is the owner's.