Drivers
A Driver is a named, reusable contract every Backend, Application, and recording aligns against. It declares the wires the Backend must expose, the worker handles consumers can address, and the configuration the user supplies on those handles.
TL;DR
- A Driver is a published contract row with three orthogonal child collections — endpoints (wires), workers (general-purpose worker presence promises addressed by alias), fills (config on those aliases).
- A Application references two drivers:
needs_driveris the live wire contract (transport follows UX needs — WebRTC, WS, HTTP), andtaps_driveris the capture and replay contract (always HTTP, both directions, written to durable cloud blobs). - A Backend satisfies a driver through
EndpointAliaseson its vertices. Nodriver_idcolumn on the Backend; alignment is byrole→endpoint_namematch. - Recording enumerates
taps_driver.RequiredEndpoints(both directions), validates the Backend has a vertex per endpoint, and either overlays an HTTP tap URL on the worker (server-mirrored) or asks the Application to dual-send (client-uploaded).
Mental model — contract, not implementation
A Driver is upstream of everything: a Backend, an Application, and a recording all align against it without knowing each other's internals. Multiple Applications can subscribe to the same Driver and consume different Backends that all satisfy it. A different Backend with a different choice of object-detection component can serve the same Application as long as both honor the Driver's contract surface.
The three collections are intentionally independent:
driver: forklift_perception
┌─────────────────────────────────────────────────────────────────┐
│ endpoints │
│ ├─ frames ingress [webrtc, http] required │
│ ├─ detections egress [http, sse] required │
│ └─ telemetry egress [ws, http] │
│ │
│ workers (promises) │
│ └─ detector fulfills role: detections │
│ │
│ fills (config on the worker behind an alias) │
│ ├─ detector.classes metadata user-supplied │
│ └─ detector.confidence param pinned to 0.5 │
└─────────────────────────────────────────────────────────────────┘
RequiredWorker is the most-misunderstood collection. It does not pin a component, a version, or a vertex. It promises that a worker fulfilling the named role is reachable at the alias, with whatever capabilities its component contract exposes — metadata_schema snapshots (class-id → label maps, tokenizer vocabs, audio sample-rate maps), runtime queries, command / control hooks, fill targets. Metadata fetch is the most common reason consumers care, not the only one.
Two drivers per Application
The Application manifest references two driver IDs:
| Field | Contract role | Transport |
|---|---|---|
needs_driver_id | What the Application pushes in and consumes out at runtime. | UX-driven: WebRTC for low-latency video, WS for event streams, HTTP for request / response. |
taps_driver_id | What the recorder captures and the replay re-serves. | Always HTTP, both directions. |
The two driver IDs often point at the same driver row. Same channels, same (role, name) keying. Live consumption picks the needs_driver transport; recording picks the taps_driver HTTP overlay. The Application's render code is identical between live and replay because the channel identity is the contract, not the wire.
Backend alignment
A Backend satisfies a Driver through EndpointAliases on its vertices. For every RequiredEndpoint the Driver declares, some vertex in the Backend must have EndpointAliases[role] == endpoint.name, and that vertex's worker must accept at least one transport in the endpoint's allow-list, in the right direction.
The alias mechanism is what decouples the Driver from the graph: an operator can swap out a YOLO detector for a different vendor's detector, and as long as the new vertex re-uses the same alias, the Driver's contract is unbroken.
How recording uses taps_driver
A recording is anchored to a taps_driver_id (typically the same one the Application's manifest declares). At start, the server enumerates taps_driver.RequiredEndpoints (both ingress and egress), validates the Backend has a vertex per endpoint via the alias map, and decides per-channel how the capture happens:
- Server-mirrored. The vertex's worker exposes
urlandheadersparameters (everyoutput_*_httpworker, everyinput_*_httpworker). At deploy time the platform overlays the per-channel tap URL and anAuthorizationheader onto the vertex's bound values. The worker pushes each frame through the tap surface; the Backend graph itself is untouched. - Client-uploaded. The vertex's worker cannot mirror (WebRTC ingress that streams in browser-side, custom workers without an HTTP mirror). The recording response flags
needs_client_upload: truefor that channel, and the Application dual-sends each input frame through the recording's client-upload surface while it also pushes to the live ingress.
Finalize freezes a per-channel snapshot — direction, socket_role, endpoint_name, worker_alias, media_kind, schema, and the metadata map sourced from required_fills of kind metadata — into the replay manifest. Playback re-emits the same (role, name) keys the Application's needs_driver would have produced live, only with cloud-presigned URLs in place of live container URLs.
Channels the recording did not capture this session still appear in the manifest's endpoints[] list so the player can render the full driver-contract surface (an empty pane for an uncaptured egress, a placeholder for an uncaptured ingress).
Run it
Drivers are authored upstream (catalog, Application authoring) and referenced by Applications and recordings. The Application manifest is where most users meet a Driver — see /concepts/applications for the manifest shape and /concepts/replays for the recording / playback surface that consumes taps_driver.
Related
- Applications — references drivers through
needs_driver_idandtaps_driver_id. - Backends —
EndpointAliasesis the alignment mechanism. - Replays — capture and playback over
taps_driver. - Solutions — the published unit bundling Backend + Application + driver alignment.