Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Current scenarios:
- `server-initiated-external-source` (Client enters and leaves `external_source` mid-stream): start the server first, then the client. The client transitions to `external_source` and back; the harness verifies the server emits the right `group/update` and `stream/end` and that the previous group is restored. Per the audit only SendspinKit exposes a client-side API; no client in the matrix declares the `external-source-client-api` capability yet, so every case fails fast
- `server-initiated-multi-server-arbitration` (Client arbitrates between two connected servers): two servers connect to one client with different `connection_reason` values; the harness verifies the client sends `client/goodbye` with `'another_server'` on the right socket and ends up speaking to the right server per the spec's decision table. Per the audit only sendspin-cpp and sendspin-cli implement these rules; no client in the matrix declares the `multi-server-arbitration` capability yet, so every case fails fast
- `server-initiated-static-delay` (Client applies configured `static_delay_ms`): start the server first, then the client. The client is configured with a non-zero `static_delay_ms`; the server pre-compensates and the harness asserts the client's actual emission time matches `T − static_delay_ms` within the spec's drift tolerance. Per the audit, `sendspin-rs` and `SendspinKit` parse the field but never apply it (highest-severity bug); seven SDKs don't persist across restarts. No client in the matrix declares the `static-delay-applied` capability yet, so every case fails fast
- `server-initiated-volume-curve` (Server calibrates client volume curve): start the server first, then the client. The server sets `volume = 50`, the client plays a known fixture, and the harness measures the peak amplitude and asserts the spec's perceptual curve (`0.5^1.5 ≈ 0.354`, ≈ −9 dB) vs. the non-conformant linear gain (≈ −6 dB). Per the audit, sendspin-go and sendspin-js apply linear `vol/100` gain today. No client in the matrix declares the `volume-perceptual-curve` capability yet, so every case fails fast

## Current coverage

Expand Down
1 change: 1 addition & 0 deletions src/conformance/implementations.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"external-source-client-api",
"multi-server-arbitration",
"static-delay-applied",
"volume-perceptual-curve",
),
),
),
Expand Down
21 changes: 21 additions & 0 deletions src/conformance/scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,26 @@
)


SERVER_INITIATED_VOLUME_CURVE = ScenarioSpec(
id="server-initiated-volume-curve",
display_name="Server calibrates client volume curve",
description=(
"Start the server first, then the client. The server sets `volume = 50`, "
"the client plays a known fixture, and the harness measures the peak "
"amplitude of the recorded output and asserts it matches the spec's "
"perceptual curve (`0.5^1.5 ≈ 0.354` × original, ≈ −9 dB). A "
"non-conformant linear-gain client outputs ≈ `0.5` × original (≈ −6 dB). "
"Per the audit, sendspin-go and sendspin-js apply linear `vol/100` gain "
"today; sendspin-jvm and sendspin-dotnet need follow-up audits."
),
initiator_role="server",
preferred_codec="pcm",
required_role_families=("player",),
verification_mode="capability-only",
required_capability="volume-perceptual-curve",
)


SERVER_INITIATED_STATIC_DELAY = ScenarioSpec(
id="server-initiated-static-delay",
display_name="Client applies configured `static_delay_ms`",
Expand Down Expand Up @@ -290,6 +310,7 @@
SERVER_INITIATED_EXTERNAL_SOURCE,
SERVER_INITIATED_MULTI_SERVER_ARBITRATION,
SERVER_INITIATED_STATIC_DELAY,
SERVER_INITIATED_VOLUME_CURVE,
)

SCENARIOS: dict[str, ScenarioSpec] = {scenario.id: scenario for scenario in SCENARIO_LIST}
Expand Down