Harness Protocol¶
Protocol Reference¶
trust-harness Protocol¶
trust-harness is the canonical deterministic executor for fast ST automation
outside the full runtime lifecycle.
It is designed for:
- agent repair loops
- CI validation
- docs/examples that need executable behavior
- future website sandboxes and local-model evaluation loops
Transport¶
- process-local only
- newline-delimited JSON over
stdin/stdout - one request per line, one response per line
Each response is either:
{"ok":true,"data":{...}}
or:
{"ok":false,"error":{"kind":"invalid_argument","message":"...","data":null}}
Commands¶
| Command | Purpose |
|---|---|
load |
Load one or more ST sources into a fresh harness |
reload |
Reload source(s) while preserving retain semantics where supported |
cycle |
Execute one or more cycles |
set_input |
Set a named input/global/program variable |
get_output |
Read a named output/global/program variable |
set_access |
Write a VAR_ACCESS binding |
get_access |
Read a VAR_ACCESS binding |
bind_direct |
Bind a named variable to a direct I/O address |
set_direct_input |
Write to a direct input address |
get_direct_output |
Read from a direct output address |
advance_time |
Advance virtual time without executing a cycle |
run_until |
Cycle until a named output matches an expected value |
restart |
Restart the harness runtime (cold or warm) |
snapshot |
Return watched values without executing more work |
Source Loading¶
Single-source load:
{"cmd":"load","source":"PROGRAM Main\nEND_PROGRAM\n"}
Multi-source load:
{"cmd":"load","sources":["PROGRAM Main\nEND_PROGRAM\n","FUNCTION_BLOCK Fb\nEND_FUNCTION_BLOCK\n"]}
load performs an initial cycle and fails if that first cycle reports runtime
errors.
reload uses the same source / sources parameters.
Cycle Control¶
Advance ten cycles while moving virtual time forward by 10 ms each cycle:
{"cmd":"cycle","count":10,"dt_ms":10,"watch":["q","et"]}
Advance virtual time only:
{"cmd":"advance_time","duration_ms":25}
Take a passive snapshot:
{"cmd":"snapshot","watch":["motor_run","fault","et"]}
I/O Manipulation¶
Set input:
{"cmd":"set_input","name":"start_pb","value":{"type":"BOOL","value":true}}
Get output:
{"cmd":"get_output","name":"motor_run"}
Write/read VAR_ACCESS:
{"cmd":"set_access","name":"RemoteSpeed","value":{"type":"INT","value":42}}
{"cmd":"get_access","name":"RemoteSpeed"}
Bind/read direct I/O:
{"cmd":"bind_direct","name":"start_pb","address":"%IX0.0"}
{"cmd":"set_direct_input","address":"%IX0.0","value":{"type":"BOOL","value":true}}
{"cmd":"get_direct_output","address":"%QX0.0"}
Bounded Run Loop¶
{
"cmd":"run_until",
"name":"q",
"equals":{"type":"BOOL","value":true},
"dt_ms":10,
"max_cycles":5,
"watch":["q","et"]
}
If max_cycles is exceeded, the protocol returns:
{
"ok": false,
"error": {
"kind": "run_until_timeout",
"message": "run_until exceeded 5 cycles before 'q' matched the expected value",
"data": {
"name": "q",
"max_cycles": 5,
"expected": {"type":"BOOL","value":true}
}
}
}
Restart¶
{"cmd":"restart","mode":"cold"}
{"cmd":"restart","mode":"warm"}
Typed Value Format¶
The protocol uses a stable typed JSON shape.
Common scalar examples:
{"type":"BOOL","value":true}
{"type":"INT","value":7}
{"type":"DINT","value":42}
{"type":"REAL","value":1.5}
{"type":"TIME","nanos":30000000}
{"type":"STRING","value":"hello"}
Structured examples:
{"type":"ARRAY","dimensions":[[0,1]],"elements":[{"type":"BOOL","value":true},{"type":"BOOL","value":false}]}
{"type":"STRUCT","type_name":"MyStruct","fields":{"enabled":{"type":"BOOL","value":true}}}
{"type":"ENUM","type_name":"Mode","variant":"Auto","numeric":1}
{"type":"NULL"}
Error Kinds¶
Current stable error.kind values:
invalid_requestinvalid_argumentnot_loadedcompile_errorruntime_errorruntime_cycle_errorrun_until_timeout
Current Observability Scope¶
The protocol currently returns watched value snapshots. Full trace streaming is still deferred, but the watch output is already enough for:
- timer/state assertions
- small repair loops
- deterministic evidence capture in docs and CI
That keeps the surface small while still making the harness useful today.