WAI toolchain decision 11: joule-moq-relay builds wai-relay, joule-moq-room wai-room, and joule-moq-ingest wai-ingest. wai dev finds them by those names (WAI_RELAY_BIN, WAI_ROOM_BIN), and the quickstart archive, the release workflow, the examples' workflow, the browser tests, the interop scripts, the example host script, the Scoop manifest and the crates' READMEs and example configurations name them so. Wire and record identifiers that carry a crate's name (joule-moq-relay/session-summary/2, joule-moq-ingest/session/1, the relay's MOQT implementation string) and the log variables (JOULE_MOQ_*_LOG) are unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
151 lines
8.4 KiB
TOML
151 lines
8.4 KiB
TOML
# wai-room (crate joule-moq-room): an example configuration. Nothing secret belongs here: the
|
|
# keys are a file of their own (`wai-room keygen <path>` makes it, mode 0600), outside every
|
|
# repository, and the relay knows the clock's token by its SHA-256 alone.
|
|
|
|
# The HTTP service, on loopback behind the front that serves the room's page.
|
|
listen = "127.0.0.1:9682"
|
|
# The path the front serves the service under, when it strips it (`/room-api`): a grant's proof
|
|
# over HTTP, and a watch room's join proof, name the path the page addressed.
|
|
public_prefix = "/room-api"
|
|
keys = "/path/to/keys.toml"
|
|
# The relay's WebSocket endpoint, for the clock's own session (loopback).
|
|
relay_url = "ws://127.0.0.1:9681/moq"
|
|
# Exit with status 70 past this resident memory (MiB), for the supervisor to restart it.
|
|
max_resident_mb = 256
|
|
|
|
[room]
|
|
# Publishers at once, those whose grants are still waited for among them; the composition
|
|
# lays out this many tiles.
|
|
max_publishers = 4
|
|
max_present = 16
|
|
# A grant's life, in seconds.
|
|
publisher_grant_s = 1200
|
|
viewer_grant_s = 1800
|
|
# How long a publisher's grant holds its place before its tracks appear.
|
|
join_wait_s = 90
|
|
# Grants one room takes; then a new room starts once it is empty.
|
|
max_grants = 64
|
|
# Every room end-to-end encrypted (WAI confidentiality): a confidentiality record, an MLS
|
|
# group whose external sender is the clock, and the room's log of MLS messages. Such a room
|
|
# is never recorded, and its viewers are not members of its group.
|
|
e2ee = false
|
|
# Every room watches this file together (WAI co-watch): served whole, named by the room's
|
|
# co-watch policy, with its duration in milliseconds. Empty for rooms that watch nothing. A
|
|
# watch room is not also end-to-end encrypted, admitted by age or a room with co-performance.
|
|
watch_source = ""
|
|
watch_duration_ms = 0
|
|
# The actions every principal of a watch room may control: 1 play, 2 pause, 4 seek, 8 rate.
|
|
watch_control = 15
|
|
# The skew window the clock states, in milliseconds: a whole number of seconds.
|
|
watch_window_ms = 5000
|
|
|
|
# The service keeps one conversation (WAI live-messaging): an end-to-end encrypted room whose
|
|
# members message one another, and its history store, which survives a restart (ciphertext,
|
|
# receipts and signed records only). It needs no relay; nothing else is kept beside it (no
|
|
# watch room, co-performance, admission by age, `[world]`, `[remote]`, `[room] e2ee` or `[call]`).
|
|
# [messaging]
|
|
# store = "/path/to/conversation" # the history store's directory, made when absent
|
|
# max_members = 16
|
|
# admit = "open" # "open": any key that proves itself; "listed": `members`
|
|
# members = [] # 64 hexadecimal digits each, for "listed"
|
|
# grant_s = 604800 # a member's grant's life, at most 1 209 600 (fourteen days)
|
|
# max_text = 4096 # the conversation statement's bounds (WMC1)
|
|
# max_reaction = 16
|
|
# retention_days = 0 # 0: no bound stated
|
|
|
|
# The service's room is a call (WAI live-messaging §10): a caller places it by a proof of its
|
|
# key, rings each invitee with an invitation it signs, held in the invitee's inbox; the clock
|
|
# signs a missed call at each deadline; the grants come with the call.
|
|
# [call]
|
|
# ring_ms = 30000 # how long an invitation rings, 1 000 to 300 000
|
|
# media = 3 # bit 0 audio, bit 1 video
|
|
# max_invitees = 8
|
|
# max_inbox = 32 # invitations one inbox holds
|
|
|
|
[co]
|
|
# Co-performance (WAI co-performance): either value above 0 gives each room a co-performance
|
|
# policy the authority signs, served with the room. The audience-input power every viewer's
|
|
# grant carries: the most inputs it may send to one selection window (1 to 255; 0: none).
|
|
audience_input = 0
|
|
# Every publisher's latency budget in milliseconds: a later object is marked, never mixed
|
|
# unmarked (0: none).
|
|
latency_budget_ms = 0
|
|
# Which publishers hold the direct power, to state turn schedules, hand any turn over and open
|
|
# selection windows: "first" (the room's first publisher), "publishers" or "none".
|
|
lead = "first"
|
|
# Whether a publisher may ask for a grant that marks it an AI participant (its `ai` attribute).
|
|
ai = true
|
|
# How often the clock states each participant's fidelity, in seconds (0: when a lead asks).
|
|
fidelity_every_s = 30
|
|
# How long after a window closes the clock commits to it, for inputs still in flight (ms).
|
|
commit_after_ms = 1500
|
|
# How far ahead a schedule a page asks for starts, and a handover takes effect, at least (ms).
|
|
lead_ms = 300
|
|
# The objects the clock logs in one room; past it, it still marks, and logs no more.
|
|
max_objects = 200000
|
|
# The relay holds the floor and the audience's inputs once its configuration has the `[floor]`
|
|
# lines `relay-lines` prints (commented out there).
|
|
|
|
# Every room carries a shared world (WAI live-worlds): the authority signs its world statement,
|
|
# every publisher's grant is an actor's (the attribute world = act, no media), and the clock
|
|
# records each actor from its world track. The relay needs the commented world lines
|
|
# `relay-lines` prints: the door that holds each world track to its owner's key, and the window
|
|
# that keeps the room's world tracks for pages that enter late.
|
|
# [world]
|
|
# model_id = "<64 hexadecimal digits>" # the world model (wai.world.model's model header)
|
|
# seed = 0
|
|
# width = 64
|
|
# height = 64
|
|
# fps = 24
|
|
# max_op_bytes = 4096 # 136 to 65536
|
|
# max_ops = 64 # ops one object holds, 1 to 4096
|
|
|
|
[rate]
|
|
# Grants per client address: this many at once, then one more every this many seconds.
|
|
client_burst = 6
|
|
client_every_s = 20
|
|
# And for everyone together.
|
|
global_burst = 120
|
|
global_every_s = 10
|
|
|
|
# Every room admits by age (WAI age-assurance §5.6): a grant request carries a Privacy Pass
|
|
# token (RFC 9577, type 0x0002 of RFC 9578), and the grant states its threshold. Absent: rooms
|
|
# admit anyone. The keys are the issuers' public keys, RFC 9578 §6.5's SubjectPublicKeyInfo in
|
|
# hexadecimal; operating an issuer, and its attester, is not the service's.
|
|
# [age]
|
|
# window_s = 3600 # the windows an admission receipt counts in
|
|
# token_window_s = 600 # a challenge's redemption context holds for this window and the next
|
|
# max_nonces = 65536 # nonces kept a window; past it, no further token of that window
|
|
# origin = "room.example" # the service's server name; absent, the request's Host
|
|
# receipts_out = "/path/to/age-receipts.jsonl"
|
|
# [[age.issuers]]
|
|
# name = "issuer.example"
|
|
# keys = [{ threshold = 16, spki = "<hex>" }, { threshold = 18, spki = "<hex>" }]
|
|
# [[age.ratings]] # the room's rating: one entry per scheme
|
|
# scheme = "https://ratings.example/scheme"
|
|
# value = "16"
|
|
# min_age = 16
|
|
|
|
# Every room is a remote desktop room (WAI remote-desktop): one host's screen shared into it. The
|
|
# host is the key `host` names, or, empty, the first key that presents an invitation the room's
|
|
# authority signed (`wai-room invite <keys.toml>`). Not also e2ee, a watch room, a room with
|
|
# co-performance, one admitted by age or a world room. The relay holds the host's screen to its key
|
|
# with a door:
|
|
# [[receipts.door]] prefix = ["*", "*", "screen"], trust_field = 1.
|
|
# [remote]
|
|
# host = "" # 64 hexadecimal digits, or empty for an invitation
|
|
# width = 1280 # the screen profile's size and rate
|
|
# height = 720
|
|
# fps = 30
|
|
# allow = "none" # who may ask for a controller's grant: "all", "listed" or "none"
|
|
# controllers = [] # the keys that may, for "listed"
|
|
# control = 3 # a controller's classes: 1 pointer, 2 keys, 4 touch, 8 clipboard
|
|
# max_age_ms = 1000 # the age bound no host's screen in effect may exceed
|
|
# lead_ms = 500 # a grant exchange takes effect at least this far ahead
|
|
# max_records_per_principal = 100000 # the most records of each principal but the host the clock holds; at the
|
|
# # bound it cuts and removes that principal, and the session goes on. This one
|
|
# # bites first: a two-hour session at ten input statements a second is 72000, and a
|
|
# # flood at the policy's 120 events a second reaches it in about 14 minutes
|
|
# max_records = 1000000 # the most records of a session's principals, the host's among them; at the bound
|
|
# # it ends the session. A safety net: ten times the bound per principal, above a host
|
|
# # and four controllers each at its bound (800000)
|