An MCP access token is a stateless JWT good until it expires, so deleting
the client row revoked nothing already handed out — on the MCP endpoint or
on the REST API, which takes the same token directly. Both doors now look
the client up by the `client_id` the token has always carried, so tokens
already in circulation are held to it too.
A dashboard's `locked` setting stopped the client drawing a control and
nothing else; the server took a publish from a panel showing it anyway. It
now bounds the panel's write scope, resolved live where a flow drives the
flag, exactly as the client resolves it. Reads are untouched — read-only is
not blind — and so is a querying chart's request, which is how that tile
reads rather than something anyone touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CL9zvnnvcp1mvA8o7impxk
Follows the portal: the noun is "instance" everywhere the app says it —
UI strings, CLI output, error details, docs and comments. The wire keys
(`instance_id`, `instance_token`) and the hub route this calls move with it.
An existing cloud.json is adopted rather than refused: without the key
alias the dataclass fails to parse, which the caller swallows and reads as
"never enrolled" instead of "reconnect".
`instance_key` on a node type becomes `target_key`. It means the outside
thing a node points at, which is a different sense of the word, and keeping
both would put two meanings of "instance" in one codebase.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015YrQnKV3bnQd4K342y8tKj
A wheel whose top-level module is `app` collides with anything else in a
user's venv, so the package that is about to be published takes the name
it is published under. Only the Python package moves; the repo, the
Docker WORKDIR and the compose project keep theirs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>