drogna

A demonstration harness. Every number in it is invented.

V1 record — describes retired software; superseded for V2 by srd.md, constitution 2.0.0 and ADR-0027.

ADR-0008: Control messages reach the client by WebSocket upgrade at the proxy

Status: Accepted Date: 26 August 2026 Requirements: SRD FR-31, FR-40, FR-41, FR-45, FR-46, FR-52; Constitution VII, X Raised by: feature 013's specification

Context

The client must show the control loop cycling in real time, messages crossing component boundaries, and component illumination driven by heartbeats (FR-46, FR-52, FR-45). All of that traffic lives on the control namespace of the broker. The SRD does not say how it reaches a browser.

One option is ruled out before the argument starts. FR-31 is explicit that the publisher announces new runs as events and that consumers subscribe, "because the query layer has no notification mechanism" — nothing polls the query layer for freshness. So the client subscribes to something; the question is only to what, and through what.

Feature 013's specification raised this rather than assuming it, because the answer changes the reverse proxy's path policy materially, and path policy is the whole of FR-40 and FR-41.

Three options were weighed.

A read-only relay service subscribing to the control namespace and pushing server-sent events over plain HTTP GET. Attractive because the proxy stays purely path-prefix based, which is the premise FR-40 rests on, and because a relay is structurally incapable of letting a browser publish. Rejected on cost: it is a nineteenth component in a system whose component list the client renders as a fixed eighteen-box layout, and it would need its own liveness, its own failure mode and its own box.

A direct browser connection to the broker, bypassing the proxy. Simplest, and the most honest about what is actually happening. Rejected: it puts a listening port outside the reverse proxy, contradicting FR-41's default-deny on everything else and Constitution X, and it makes the leakage tests harder to reason about because there would be two ways into the system with different policies.

Decision

The reverse proxy carries a WebSocket upgrade location at a dedicated path prefix, proxying MQTT-over-WebSockets to the broker. The client subscribes through it.

Everything stays behind one reverse proxy, under one access policy, and the component count stays at eighteen.

Consequences