flare v0.10.0 moves the toolchain onto Mojo 1.0.0 and MAX 26.5.0 (both stable, out of nightly), closes the remaining h2spec conformance gaps, and lands a breaking cut of the prelude. 70 commits since v0.9.0.
Toolchain
- Mojo pin widened to
>=1.0.0,<1.1.0; MAX pin to>=26.5.0. Both now resolve off the stablemaxconda channel instead ofmax-nightly. json,mojodoc, andmozzare pinned to their own new tagged releases (v0.3.0,v0.1.0,v0.2.0) instead of trackingmain, so aflarecheckout resolves deterministically.- The API renames that came with 1.0.0 are done throughout: pointer arithmetic and
.load/.free/memcpyon theirunsafe_names,.bitcast[]to.unsafe_bitcast[],__del__to__deinit__,ImplicitlyDestructibletoDeinitable, and thereadargument convention toimm.
Breaking: prelude cut from 454 symbols to 125
flare.prelude re-exported everything, including wire-format internals (encode_varint, qpack_encode_field_section, huffman_encode, ...). It now exports exactly what the root flare package exports, generated from that list rather than hand-maintained. WithCancel, ok_json, Body, and ChunkSource moved into the root surface, since their absence there was the actual bug. Migration: import from the owning module -- from flare.http2 import Http2Connection, from flare.quic import encode_varint, from flare.runtime import Reactor.
HTTP/2 conformance
h2spec now runs for real in the conformance CI job instead of being advertised-only. The gaps it found are closed: connection errors are reported with GOAWAY and frame shape is validated, header blocks decode atomically, DATA/WINDOW_UPDATE enforce stream state and flow control, and buffered responses respect the peer's send window.
HTTP client and streaming
HttpClient.get_streaming_tls()-- streaming download over HTTPS;get_streaming()previously raised there and pointed callers at the bufferedget().- Chunked request bodies decode on the
Handlerpath. - Streaming responses coalesce chunks per pump / per writable edge instead of one write per chunk, with a bulk-copy on the framing path -- a latency and syscall-count win on the streaming benchmark.
Fixes
- WebSocket: RSV1 without a negotiated extension is now rejected (RFC 6455).
- SSE: the idle keep-alive heartbeat is rate-limited.
- ASan:
test_h3_0rtt_e2e,test_tls_acceptor, andtest_tls_server_ffiretry up to three times on the forked-loopback timing flake instead of trusting a single run.
Server
bind_many() (multiple bind addresses) and num_workers>=2 can now be combined -- previously raised. Each (address, worker) pair gets its own SO_REUSEPORT listener.
Docs and testing
docs/features.md and docs/architecture.md corrected against what the code actually does (streaming chunk-coalescing contract, the retired io_uring bufring 64-conn crash claim, the prelude surface). tests/test_prelude_surface.mojo is a new ratchet asserting the prelude and root package export the same entities. A new interop test exercises flare's client against a server it did not write (and vice versa). Comments and docstrings across the codebase, tests, and README also got a pass: stale pre-1.0 nightly/1.0.0b1/1.0.0b2/rc0 version tags are gone, and where the underlying limitation is still real the note stays, just without the dated label.
Known limits (tracked for v0.10.x)
- QUIC server-side loss-driven retransmit and send pacing are still not wired -- design landed (
docs/superpowers/specs/2026-08-11-quic-server-loss-recovery-design.md), implementation pending. get_streaming_tls()(download) andsend_chunked()(upload) still pin ALPN tohttp/1.1-- design for h2/h3 negotiation landed (docs/superpowers/specs/2026-08-11-http-client-streaming-h2-h3-design.md, tracked as #5), implementation pending.- The HTTP/3 client still rejects request bodies larger than one packet.
- The io_uring bufring handler stays opt-in (
FLARE_BUFRING_HANDLER=1).
Full inventory in docs/features.md.
Full Changelog: v0.9.0...v0.10.0