Decision log

Implementation decisions are recorded in docs/decisions.md in three sections: Protocol, Architecture, and Operational.

Current protocol decisions

DecisionRationale
SSE event type data (not message)Matches PROTOCOL.md exactly; message is the browser default, protocol uses explicit data type
SSE control event uses typed struct with camelCasePrevents field name typos, ensures consistent serialization
Binary detection: everything not text/* or application/jsonMatches PROTOCOL.md binary encoding rule
One event: data per stored messagePreserves message boundaries per conformance tests
SSE idle close default 60s, configurableSpec says SHOULD ~60s; configurable allows tuning
Idempotent close returns 204Same status for initial and repeated close
Stream-Closed: true on all success responses for closed streamsConsistent header presence lets clients detect closure without HEAD

Current architecture decisions

DecisionRationale
acid backend uses sharded redb with fixed hash routingPreserves per-stream ordering while enabling concurrent writes across shards; manifest prevents silent routing drift
No in-place migration from file-* to acid (current limitation)Keeps first ACID iteration safer; migration tooling can be added separately

Current operational decisions

DecisionRationale
Health check at /healthz outside /v1/stream/Health checks are infrastructure, not protocol API
Sessions + bidirectional DB sync replaces Electric-only testSessions pattern is the primary production use case
CORS: allow all origins by default, configurable via DS_HTTP__CORS_ORIGINSNot part of protocol semantics; production restricts via env var/proxy

Decision format

Each decision in the full log includes:

  1. Decision: clear statement of what was decided
  2. Category: protocol, architecture, or operational
  3. Reference: spec/test (protocol) or subsystem/scope (architecture/operational)
  4. Rationale: why this choice was made
  5. Date: when the decision was made

When ambiguous on protocol behavior, decisions reference the corresponding gap in docs/gaps.md.