2. System Messages
The CTRL_* control-message family that keeps a Psyclone system alive: what each message does, who sends and consumes it, and what is honestly implemented.
How system messaging works
System control messages are ordinary DataMessages whose type lives in reserved type-subtype ranges: 10001–10004 (low-level), 10200–10306 plus 10297–10299 (PsyAPI control), 10998/10999 (intersystem), and the CTRL_NODE_* family used by the multi-node protocol. Human-readable names for these types are registered at startup. Three built-in types/contexts are also registered when a node configures: PsyControl, Psyclone.Ready (which doubles as the default context) and Psyclone.Shutdown.
CTRL_SYSTEM_READY — this is why components wake up when the system starts, even without an explicit Psyclone.Ready trigger.Control-message catalogue
Status: Shipped = sender and consumer wired · Stub = declared/parsed only.
| Message | ID | Purpose | Sender → Consumer | Status |
|---|---|---|---|---|
CTRL_TEST | 10001 | Test type | test code | Shipped |
CTRL_LOGPRINT | 10002 | Forward a log line from an external process/space to node logging | PsySpace → Node | Shipped |
CTRL_PING / CTRL_PING_REPLY | 10003/10004 | Liveness ping between nodes and consoles | Node → Networking | Shipped |
CTRL_SYSTEM_READY | 10200 | “System is up” broadcast; the type behind every DefaultComponentTrigger and the Psyclone.Ready default context | Node → all components | Shipped |
CTRL_PROCESS_INITIALISE | 10201 | Initialise an external process/space | PsySpace → space runtime | Shipped |
CTRL_PROCESS_GREETING | 10202 | Process announces itself after connecting | PsySpace → Node | Shipped |
CTRL_PROCESS_SHUTDOWN | 10203 | Ask a process/space to shut down | PsySpace/Node → Node | Shipped |
CTRL_CONTEXT_CHANGE | 10297 | Context switch notification; <trigger context="X"> compiles to this type; PsyProbe can inject one from the UI | Node/PsyProbe/cranks → SubscriptionEngine | Shipped |
CTRL_SYSTEM_SHUTDOWN | 10298 | Whole-system shutdown; sent to all nodes and queued to every process | Node shutdown/terminate → all nodes/processes | Shipped |
CTRL_SYSTEM_SHUTTINGDOWN | 10299 | “Shutdown in progress” notification | declared and type-registered; no live sender found | Stub |
CTRL_TRIGGER | 10300 | Wraps a fired trigger delivered to a crank or space | Node → PsySpace/Networking | Shipped |
CTRL_QUERY / CTRL_QUERY_REPLY | 10301/10302 | On-demand query round-trip (<query> / API query) | crank API ↔ catalog/whiteboard | Shipped |
CTRL_PULLCOMPONENTDATA | 10303 | Space pulls component data/parameters from its node | PsySpace → Node | Shipped |
CTRL_CREATECUSTOMPAGE | 10304 | Ask PsyProbe to create a custom page/tab | API → PsyProbe | Shipped |
CTRL_ADDSUBSCRIPTION | 10305 | Runtime subscription add from an API client (XML identical to module spec) | PsyAPI → Node | Shipped |
CTRL_RETRIEVESYSTEMIDS | 10306 | Client retrieves type/context/component ID maps | API client → Node | Shipped |
CTRL_INTERSYSTEM_QUERY / _REPLY | 10998/10999 | Query between separate Psyclone systems (InterSystemManager) | PsyAPI/InterSystemManager ↔ remote Node | Shipped |
Node-to-node sync messages (CTRL_NODE_*)
A second family of control messages is internal to the multi-node protocol: join and handshake, time synchronisation, ID/component/subscription sync with SUCCESS/FAILED replies, status and performance maps, cross-node context activation, signals and remote queries. The family: WELCOME, JOIN, TIMESYNC(_REPLY), NODEMAP(_REQUEST), STATUSMAP, PERFSYNC, SYNC_REQ/REPLY, CONFIG(_SUCCESS/_FAILED), SYNC_ID / CONFIRM_ID / CANCEL_ID (+_SUCCESS/_FAILED), CONTEXT_ACTIVE, SIGNAL, QUERY(_SUCCESS/_FAILED), SYNC_COMPONENT(±), SYNC_SUBSCRIPTION(±) and CTRL_PSYPROBE_CREATECUSTOMPAGE(±). Shipped as a family — multi-node networking is working core functionality. Notably, CTRL_NODE_CONTEXT_ACTIVE propagates context activation across nodes, so context handling (including simultaneous multiple contexts) works system-wide.
Operators rarely interact with these directly, but they appear in Network/Sync topic logs at higher verbose levels — useful when diagnosing node join or sync failures (see Distributed Admin).
Context-related triggers
| Syntax | Behaviour | Status |
|---|---|---|
<trigger context="X"> | Fires when context X is activated (type forced to CTRL_CONTEXT_CHANGE) | Shipped |
<post context="X"> | Posting changes the active context | Shipped |
<context name="X">...</context> | Scopes a component's triggers/posts to that context | Shipped |
| PsyProbe UI context injection | Operators can switch contexts from PsyProbe | Shipped |
<trigger system="context..."> | Alternative attribute syntax (see below) | Roadmap |
system= triggers Stub
The newer spec documentation describes a generic system-event trigger syntax: <trigger system="context">, system="context:context2", system="key" and system="key:value". None of these are handled by the current code — there is no parsing of a system attribute anywhere in the trigger path, so they are documentation-only. The implemented equivalent for context events is <trigger context="X">, which internally becomes a CTRL_CONTEXT_CHANGE subscription. There is currently no mechanism for the generic system="key:value" event form.
system= trigger attributes, they are silently ignored. Convert context cases to context="..." triggers; other cases have no working substitute yet.Detecting control messages in your own code
Custom catalogs must recognise query control messages to serve replies:
if (inMsg->getType() == PsyAPI::CTRL_QUERY) {
uint32 id = (uint32)inMsg->getReference();
// ... build reply ...
api->queryReply(id, PsyAPI::QUERY_SUCCESS, replyMsg);
}if inMsg.getType() == cmsdk.PsyAPI.CTRL_QUERY:
id = inMsg.getReference()
# ... build reply ...
api.queryReply(id, cmsdk.PsyAPI.QUERY_SUCCESS, replyMsg)Similarly, out-of-context posting surfaces as POST_OUTOFCONTEXT (-3) from postOutputMessage — a direct consequence of a CTRL_CONTEXT_CHANGE having deactivated the crank's context. See the User Guide chapter on Contexts and Catalogs.