open-standards/joule-code/joule-code-rs/crates/joule-moq-room/room.example.toml
Transaction Science c517bf1c85 Merge CO4b #424 (co-performance in the live room) into train/live-room
By meaning:
- joule-moq GrantHead: one attribute reader (CO4b's grant_attrs, checked
  arithmetic, UTF-8 keys and values) in place of AGE's byte-slice reader;
  `minor` and `age` are read from the same attrs CO4b keeps, with AGE's rules.
- joule-moq-room: roles(co, audience_input) is CO4b's role set, fed to PP's
  descriptor(); grant(age) and grant_with(age, ai) keep both callers (the
  age-admitted grant and the AI participant's); PP's refuses_publisher check;
  attributes in key order age, ai, audience_input / latency_budget_ms, order.
  The HTTP proof challenge (live-rooms §10.5.3) is proof_challenge(), beside
  PP's Privacy Pass challenge(); both route tables and doc tables kept.
- Page: both imports; the grant request carries `ai` and, on a 401, the
  Privacy Pass token; snapshot keeps age and co. startRoomService takes both
  `co` and `extra`. room.e2e.mjs carries scenarioAge and scenarioCo whole,
  `age,co` in the default list.
- SPEC: CO4b's revised close of the co-performance paragraph, then AGE's
  and exploration's paragraphs as they were.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 03:42:23 -04:00

81 lines
3.9 KiB
TOML

# joule-moq-room: an example configuration. Nothing secret belongs here: the keys are a
# file of their own (`joule-moq-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 names 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
[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).
[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