External plugin integration¶
QuantumAtlas plugins share one manifest and capability model with two
orthogonal axes (ADR 0001):
kind—builtin(first-party, compiled intoqatlasd, runs in-process as Go) orexternal(third-party, a separate process speaking JSON-RPC to the host).transport— meaningful only forexternal:socket(the plugin dials into the host's WebSocket endpoint and authenticates with a connect secret) orstdio(the host spawns the plugin executable fromspawn.commandand talks JSON-RPC over its stdin/stdout, the LSP/DAP model).
The first-party theorems plugin is kind=builtin. It needs no
integration steps: it is compiled into qatlasd and appears in
/api/v1/plugins as connected on boot. It reads through a server-side
git pull --ff-only checkout and exposes a uniform
POST /api/<id>/sync/pull + GET /api/<id>/sync/status pair.
This guide covers connecting a third-party external plugin. (The
external transports are retained for genuine third-party plugins; no
first-party plugin uses them.)
Architecture (socket transport)¶
qatlasdloads plugin manifests fromQATLAS_PLUGINS_DIR.The external plugin connects to
QATLAS_RPC_WS_BINDand sendsinitializewith{id, secret, abi_version}.qatlasdreplies with granted scopes and host capabilities.The plugin calls host capabilities and publishes events over that connection.
The WebSocket transport is message-framed JSON-RPC: each WebSocket message is one JSON object.
Server configuration¶
QATLAS_PLUGINS_DIR=/path/to/qatlasd/plugins
QATLAS_RPC_WS_BIND=127.0.0.1:8799
QATLAS_PLUGIN_CONNECT_SECRET=<shared-secret>
Plugin manifest¶
Place the manifest at $QATLAS_PLUGINS_DIR/<id>/plugin.json:
{
"id": "my-plugin",
"name": "My external plugin",
"version": "1.0.0",
"abi_version": "1",
"kind": "external",
"transport": "socket",
"spawn": null,
"contributes": {
"capabilities": ["myplugin.do-thing"],
"subscribes": [],
"publishes": ["myplugin.completed"]
},
"needs": ["papers:read"]
}
For transport=stdio, set "spawn": {"command": "my-plugin", "args": [...]}
instead of null; the host spawns the process and frames JSON-RPC over its
stdio.
Host capabilities¶
After initialize, the plugin can call these host-shared capabilities (the
host core carries no plugin-domain methods — ADR 0003):
Method |
Purpose |
Scope |
|---|---|---|
|
Return cached paper markdown bytes |
|
|
Return minimal paper metadata |
|
|
Return the works a paper cites (currently a stub; resolvable via |
|
|
Publish plugin events |
— |
Smoke test¶
Start
qatlasdwith the external plugin manifest inQATLAS_PLUGINS_DIR.Start the plugin pointed at
ws://127.0.0.1:8799/rpcwith the shared secret.Confirm the plugin is connected:
curl -s "$QATLAS_SERVER_URL/api/v1/plugins" -H "Authorization: ******"
The plugin should show
status: "connected".
Troubleshooting¶
Symptom |
Check |
|---|---|
Plugin is |
Manifest location and |
WebSocket closes during initialize |
|
|
Paper markdown is not cached in the configured RAW/S3 backend |
Capability call returns insufficient-scope |
Manifest |