Four things the guards and the review caught, all of them real:
- app/api/connect.py: GET /connect/status carried a bare @jwt_required(),
which the jwt-only census forbids for a new route (609 vs a ceiling of
608). It is an admin read of pairing state, so it takes @admin_required
— the same door the rest of the admin surface uses, API-key capable by
way of auth_required() like its neighbours.
- connect_policy._systemctl ran systemctl through raw subprocess, one over
the raw-subprocess ceiling. run_privileged() adds sudo when the panel is
not root, so the fail2ban repair now works off a packaged install
instead of reporting a permission error nobody can act on.
- connect_client.hello_headers assumed the end-to-end key fields were
always there. build_hello() drops them rather than fail the connection,
so a panel that could not read its X25519 key would KeyError on the
long-poll fallback — exactly the path taken when things are already bad.
- status() called resolve_cloud_url(), which raises on a URL with no
scheme. A typo in SERVERKIT_CLOUD_URL should surface when you pair, not
turn `serverkit connect status` and the Settings panel into an error.
Both connect threads are now classified in the thread-ownership registry:
the relay loop is a process loop, and a signed command is bounded delivery
whose record lives in the control plane.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018q56AfqpgKjio4n9KYubvZ