Worker protocol

Versioned NDJSON over stdin/stdout. Implemented in parallax-protocol (PROTOCOL_VERSION = 1).

Envelope

Every line is one JSON object:

{
  "v": 1,
  "id": "<uuid>",
  "op": "execute",
  "ok": true,
  "payload": { },
  "error": null
}
FieldRole
vProtocol version — mismatch → ProtocolViolation
idCorrelation id (request/response)
opOperation name
okPresent on responses
payloadOp-specific JSON
error{ code, message, diagnostic? } on failure

Operations

opDirectionPurpose
helloreq/respNegotiate version; report host/adapter versions
executereq/respRun source; optional capture list → PIR bindings
restorereq/respMaterialize PIR bindings in a fresh context
pingreq/respLiveness
shutdownreq/respWorker exits

Execute request (abbrev.)

{
  "source": "state = {'a': 1}",
  "filename": "demo.py",
  "capture": ["state"],
  "limits": { "timeout": 30000, "max_output_bytes": 1048576 }
}

limits.timeout is milliseconds (serde of ExecutionLimits).

Execute response (abbrev.)

{
  "stdout": "",
  "stderr": "",
  "duration_us": 1234,
  "bindings": { "state": { "t": "map", "entries": [] } },
  "exception": null,
  "success": true
}

Worker locations

Workers are embedded in the adapter crates and materialized under the system temp directory at runtime:

RuntimeEmbedded sourceTemp file
Pythonadapters/python/worker.py%TEMP%/parallax-workers/python_worker.py
JavaScriptadapters/js/worker.js%TEMP%/parallax-workers/js_worker.js

Timeouts

The core wraps each request in tokio::time::timeout. On expiry the worker process is killed and the caller receives ExecutionTimeout.