Skip to main content

Relay

The relay is where your client connects. It exposes the same PolicySession.Run as a station and pipes your stream onto the runner waiting for your job id. It runs on the workstation behind a port-forward today and can move to a cloud host without changing what you send.

Pairing

  • One client stream per job at a time. A second connection to a live job is refused with JOB_BUSY.
  • If the client stream is lost while the runner remains attached, a new connection presenting the same job id is paired to that runner. The runner's handling of the interruption is described under rules.
  • A job id nobody is waiting for is refused with UNKNOWN_JOB.

Polling job status

Service JobStatus, package se3labs.eval.policy.v1. Its messages are msg.StatusRequest and msg.Status:

service JobStatus {
rpc Get(StatusRequest) returns (Status);
}

message StatusRequest { string job_id = 1; }

message Status {
string job_id = 1;
string state = 2; // CREATED … SUCCEEDED / FAILED / CANCELLED
uint32 episode_index = 3;
uint32 episodes_total = 4;
map<string, uint32> outcomes = 5; // success, failure, indeterminate, invalidated
int64 updated_unix_ms = 6;
string message = 7;
}

From the command line:

se3labs eval status --job job_… --address relay.example.com:7443
se3labs eval status --job job_… --address relay.example.com:7443 --json

The runner pushes status on every state transition. The relay keeps it in memory and, when started with --snapshot, in a JSON file that survives a restart. Nothing else is stored.

from se3labs.eval import policy

status = policy.get_status("job_…", "relay.example.com:7443")
print(status.state, status.episode_index, "/", status.episodes_total, dict(status.outcomes))

get_status raises grpc.RpcError with status NOT_FOUND for a job id the relay has never seen.

Transport security

The relay listens in plaintext on the LAN today. The client's --secure flag and serve_policy(secure=True) use TLS with system roots for when the relay moves off the LAN.