The idea
The server publishes the whole topology document and, after it, each change as its own record with its own revision. The console paints the first topology immediately and paces the changes after it. A removal publishes the change and then the whole document, each with its own revision.
A tap on console.tap.<subject> keeps the records of one subject in a bounded ring. A call on a service subject is one record with one of three outcomes.
-
answered - The reply was received and correlated with the request. The record carries the round trip in milliseconds.
-
refused - The server refused the request by name before dispatch. The record carries the refusal.
-
unanswered - No reply by the call's deadline. A late reply is discarded. A one-way request is unanswered at once, named reply_not_requested.
Why it matters
A service’s round trip is read from its records, not estimated. A subscriber that fell behind is told how many records it missed.
How it works
The console reads taps over the WebSocket. The ticket’s subscribe turns the same records into notification lines in an MCP host.
{"jsonrpc":"2.0","method":"notifications/message","params":{"level":"info","logger":"liminal.studio","data":{"device":"127.0.0.1:7600","service":"studio","subject":"jobs.studio","from":"connection 5","outcome":"answered","at_ms":1791272000123,"words":"jobs.studio: answered, 2 B from connection 5","tap":"local:call:5:1"}}}