Self-service operator trials
On this page
Purpose
A participant should be able to test Skein at a convenient time, without asking a coordinator to exchange files or start machines. This service automates the existing finite, relay-only discovery trial. It does not introduce a new Core protocol or turn the coordinator into a network membership authority.
Flow
The participant explicitly starts a trial. The helper sends public enrollment identities over HTTPS and receives a plan bound to those identities plus a random, short-lived session capability. Their private keys remain local.
The coordinator starts an ephemeral test peer and relay restricted to the two transport identities. The participant starts its existing Rust node, posts its signed introduction, and queries the test peer. The test peer independently probes the participant through its running endpoint. Native code validates signatures, scopes, expiry and configured relay destinations. Neither direction uses an inbound host port or direct UDP transport.
The service reports success only when its outgoing query returns a verified Beacon and its listener records a completed authenticated query from the participant. The helper also requires its own native probe and node process to succeed. After expiry, both sides shut down and the helper saves a public diagnostic report. No language model, model API key, Sprite provisioning, or human scheduling is needed for these deterministic checks.
Bounds and trust
The service allows eight active trials and at most 240 starts per rolling hour per service process. Up to four additional requests may queue for five seconds; overflow and timeouts return a retryable refusal. HTTP handling is bounded to 16 concurrent requests, so one request waiting for a peer does not block all others. The participant runs for 60 seconds; the test peer for 75. A relay subprocess has a 120-second failsafe and is terminated at trial cleanup. Completed results are independently retained until five minutes from their trial start, with a hard cap of 240 records. New trials do not overwrite another participant’s result. Expired records are pruned automatically. Process restart invalidates sessions and resets the in-memory quota. There is no persistent participant archive.
Enrollment is provisional and is not a proof of identity ownership. Actual queries require authenticated transport and signed introductions. An attacker can consume trial capacity with manufactured enrollments; the global quota bounds our work but does not provide Sybil resistance or fair scheduling. Busy users must retry later.
The shared HTTPS proxy caps connections at 96, bounds headers and bodies, and limits coordinator HTTP requests to 20 per second with a burst allowance of 24. Native request/response bounds, four active handlers, and relay identity/byte limits remain unchanged. These are operational limits, not a proof against Internet-scale denial of service. The proxy and coordinator are project-operated, single-instance availability dependencies.
Random session tokens authorize only access to one trial's introductions and result. They are not included in reports or request logs. The coordinator accepts no supplied URLs, executable paths, or commands. Its relay destination and native binaries are operator configuration. The service runs unprivileged on one 1 GiB, two-shared-CPU Fly machine; temporary identities are generated at runtime and removed after each trial.
Implementation and verification
scripts/operator-service/coordinator.py orchestrates the unchanged Rust binaries. Nginx bounds and routes HTTPS-edge traffic to the coordinator and eight fixed loopback relay ports. A public slot selector in each signed relay URL selects the backend; it grants no access by itself. Every slot has separate temporary identities, a separate native peer and relay process, and its own relay identity allowlist. Stopping one slot’s relay closes its connections without affecting other slots. Iroh’s query-free /ping probe checks the shared HTTPS origin; authenticated registration and discovery separately check the selected relay. scripts/operator/operator-trial.sh drives native, Docker, or source-built clients. The downloadable native wrapper pins this helper's SHA-256. No participant Python installation is needed; Python is confined to service orchestration and test tooling.
Local checks cover malformed identities, lease exclusivity, expiry, capability refusal, quota exhaustion, duplicate submissions, oversized HTTP requests and recovery after incomplete headers. Run:
python3 scripts/test_operator_trial_coordinator.py
python3 scripts/test_operator_trial_http.py
The second command expects the locally running proxy on loopback port 18880. Public end-to-end tests use scripts/test_operator_self_service.py and retain results in docs/results/operator-self-service-v1/. Native, Docker and the pinned installer flow passed against Fly. See the results summary. Infrastructure is configured in fly.operator-trial.toml. Source and release images contain no runtime keys or account credentials.
Interpretation
A successful report demonstrates a synthetic discovery exchange between the participant's node and project-operated infrastructure. It does not demonstrate independent relay operation, removal of project bootstrap dependencies, meaningful semantic retrieval, or global scale. Those remain separate experiments.
Eight-slot Fly verification
Eight simultaneous clients completed reciprocal discovery using distinct relay URLs and peer identities. Cross-session introductions were refused. A ninth request was refused within the queue bound. A separate abandonment run checks that one missing participant does not prevent the other seven from completing.
During a 24-second sample after reciprocal exchanges, all 16 native processes remained active. Their summed RSS was approximately 141 MiB, with roughly 733 MiB available on the VM. Whole-VM CPU was below 1% during that waiting period. These measurements exclude startup and sustained query load; RSS sums count shared pages more than once. They are not throughput or adversarial-load benchmarks.
The first concurrent attempt failed before discovery because the proxy did not serve Iroh’s query-free reachability probe. That attempt is retained as a failure; the corrected route passed the subsequent eight-client run. See eight-slot results and docs/results/operator-eight-v1/ for reports and limits. Reproduce with:
python3 scripts/test_operator_eight.py --output outputs/eight-reproduction
python3 scripts/test_operator_eight.py --abandon-one --output outputs/eight-abandonment