The console routes to nodes (rendezvous), so it is the single public
port: server -> :8081 (no host forward), console -> :8080, 8090
forward dropped. Verified: node unreachable from host, routed
workstream creation lands on turnstone-vm-main at 127.0.0.1:8081,
route/command proxy works, cluster view tracks the workstream.
Default node_id is {hostname}_{random-per-boot}, so every boot
inserted a new services row and the console probed stale ones (409
node_id mismatch -> 'not found' node pages). Pin TURNSTONE_NODE_ID
(one upserted row) and TURNSTONE_ADVERTISE_URL to loopback — the
guest's slirp IPv6 lands in the SSRF guard's never-allowed lane.
Also drop the futile /etc/hostname baking (podman regenerates it at
boco build).
Console (cluster dashboard + admin panel) starts as a background
daemon under marvin on :8090, sharing the same config.toml and SQLite
DB (WAL multi-writer). Forwarded via run.sh and exposed through
tailcat; same login as the server.
Arch image with turnstone (venv), dev toolkit, rootless podman; boots
via boco (virtiofs shares, direct UID mapping for nested virtiofs).
sshd ops channel + turnstone-server as guest marvin; state (SQLite db,
config, work) on host shares; LLM via the TensorX OpenAI-compatible
gateway (https://api.tensorx.ai/v1), reachable from the guest through
both slirp layers with no relay.