Devblog · Prospective · 2026-07-06

The API Call You Can Hear

Eight plans, zero code, and the arrogance to narrate the future: an LLM that answers you over sound, at eleven bytes a second.
Date 2026-07-06 Status Prospective Project ToneSignal.Http
A dark violet room at night, two brass-and-walnut machines facing each other across a table; one emits glowing rings of sound that cross the gap as horizontal bands of amber and rose tone, dissolving into streams of text on the receiving side.
Two machines, one shared passphrase, and a line of sight for sound. The only wire is the wire you can hum.
A Prospective Devblog

Usually these are written after the session, looking back. This one is written before a single line of ToneSignal.Http exists — eight plans on the table (PLAN-001 through PLAN-008) and the nerve to call the shots in advance. Everything below is what I already know is going to happen. Check back in a few weeks and score me.

What We’re About to Build

Here is the pitch, and I want you to sit with how ridiculous it is for a second:

We are going to make an LLM answer you over sound.

Not “over the network.” Not “over WebSockets.” Over the air in the room. You will POST a prompt to /v1/responses, and instead of a TCP handshake, a speaker will warble a chord of 16 tones at a microphone across the desk, and roughly four minutes later a language model’s reply will assemble itself out of a spectrogram like a photo developing in a tray.

ToneSignal.Http is the class library that makes that happen. It is a thin, opinionated HTTP-over-acoustics layer that sits on top of ToneSignal.Core — the pure-C# 16-MFSK modem with ChaCha20-Poly1305 crypto and Reed–Solomon FEC that already lives in ~/git/tone-signal (packaged as ToneSignal.Core v0.1.0, tag 9f4f025). Core already knows how to turn encrypted bytes into audible tones and back. What it does not know is HTTP. It moves files. It has no idea what a GET /v1/models is, or what an SSE token stream looks like, or why anyone would want Authorization headers scrubbed at the boundary.

The Whole Project in One Sentence

Everything hard — the modem, the crypto, the forward error correction — is already solved upstream. ToneSignal.Http earns its keep as a codec and a session, and by not reinventing a single tone.

That gap is the whole project. Eight plans, one PR-sized bite each:

PlanWhat it landsWhy it matters
001Scaffold + Core integrationReference ToneSignal.Core, don’t reimplement the modem
002The HTTP-over-tone envelopeA wire contract: request/response start, body chunks, end, cancel, error
003LLM endpoint codecHTTP messages ↔ envelopes for /v1/models, /v1/responses, /v1/messages
004Acoustic transport adapterBind the envelope stream to TransferSender + an audio sink/source
005Bidirectional sessionOne abstraction that plays client, server, or both; timeouts, dedup, backpressure
006Client APIGetModelsAsync, CreateResponseAsync, CreateMessageAsync
007Server bridgeDispatch decoded requests to a host handler — the SeeSharpSwap seam
008Packaging + hardeningDiagnostics, threat model, a stable reference story for downstream repos

The endgame is SeeSharpSwap serving real LLM traffic to a client that has no network route to it at all — only a shared passphrase and a line of sight for sound. An air-gapped model API whose only wire is the wire you can hum.

The Honest Math

Let’s get the uncomfortable part out of the way, because it is also the best part.

ToneSignal.Core’s fastest field-trusted profile, R1, moves about 11 bytes per second. Its most paranoid rung, R00F, moves about 1.6 B/s. That is not a typo and there is no k missing. A kilobyte is a minute-and-a-half errand.

So what does an actual LLM interaction cost in airtime? Here is the back-of-the-envelope, and it should be printed on a poster:

InteractionBytes on the airR1 (~11 B/s)R00F (~1.6 B/s)
GET /v1/models round trip~1.6 KB~2.5 min~17 min
POST /v1/responses, buffered answer~2.8 KB~4 min~29 min
POST /v1/responses, SSE token stream~12 KB~18 min~2 hours

(Estimates. The exact bytes depend on how fat the JSON is and how much SSE framing overhead each data: event drags along.)

An abstract acoustic spectrogram glowing in rose, amber and gold on deep violet, its frequency bands organizing into the soft shape of a speech bubble as golden particles rise like tokens.
Streaming an answer token-by-token means wrapping every token in its own data: envelope. Over an 11 B/s link, the overhead isn’t a tax — it’s the whole bill.

Look at that third row. Streaming a response token-by-token as Server-Sent Events — the thing every LLM UI does by default — is catastrophic over tone, because every single token gets wrapped in its own data: {...} envelope. One of the quiet, important decisions this library is going to make is when to refuse to stream and buffer the whole answer into one dense payload instead. Over a wire this narrow, patience and compression are the same virtue.

What’s Going to Go Well

Standing on ToneSignal.Core instead of rebuilding it

The single best decision is already baked into PLAN-001: reference the modem, don’t fork it. Core owns the crypto, the FEC, the framing, the confidence-driven erasure decoding. ToneSignal.Http gets to be a codec and a session, nothing more. Every hour I don’t spend reimplementing Reed–Solomon is an hour that stays out of a footgun.

The envelope is going to be clean

PLAN-002’s wire contract — request start, body chunk, response start, response chunk, end-of-message, cancel, error, all keyed by a correlation id and an HTTP-layer sequence number — is the kind of small, boring, deterministic thing that golden round-trip tests love. Malformed input fails closed; oversize fields get rejected before they allocate; unknown versions bounce. This is where the Testing Discipline pays for itself and I write forty tests that all look the same and all matter.

Loopback tests mean no microphone in CI

PLAN-004’s in-memory audio transport is the unsung hero. Real modulate-demodulate when the runtime allows, a fast byte-level fake when it doesn’t. The whole stack becomes deterministically testable without a speaker, a mic, or a quiet room — which is exactly what you need when the “integration test” would otherwise require two machines and a vow of silence.

Default-deny is going to feel great

PLAN-003’s endpoint policy defaults to exactly three paths and rejects everything else. An acoustic session physically cannot become an open proxy into someone’s localhost, because the allow-list won’t let it. Some security properties you argue for. This one you just have.

It is slow, it is impractical, and it is magic — and those three facts are not in tension. — the demo, before it exists

When PLAN-006 and PLAN-007 finally shake hands and a model answers a prompt that crossed the room as a chirp, nobody who watches that forgets it. This is the kind of project that makes people lean in.

What’s Gonna Bite Us in the Ass

Warning · Streaming

SSE over an 11 B/s link is a two-hour phone call. PLAN-003 promises to preserve text/event-stream bytes exactly, and it should — but the client in PLAN-006 has to be honest that “streaming” here means “a trickle you could time with a sundial.” The temptation is to hide the slowness behind a nice API. The right move is to surface it: expose profile, layout, bytes-in-flight, and estimated airtime so a caller can warn the human before committing to a two-hour token stream.

Warning · Duplex Honesty

The whole fantasy of a “bidirectional session” leans on the D1f/D1r duplex band pair — and per upstream, duplex has never crossed a real room. It’s green in simulation; the OTA gate is PLAN-025/PLAN-031 upstream and the evidence isn’t recorded yet. PLAN-005’s session must work on today’s half-duplex reality and stay honest in every doc and diagnostic that says “duplex.” The moment a README implies field-proven full-duplex, I’ve lied on behalf of a modem that hasn’t earned it.

Header leakage

Authorization. API keys. PLAN-003 and PLAN-007 both flag it and they’re right to be nervous. Client-to-tone auth and server-to-upstream auth are two different secrets, and the failure mode is one careless “forward all headers” that puts a provider API key into a payload anyone in the room can record and brute-force offline at their leisure. Hop-by-hop headers must be stripped by rule, not by vibes.

Replay and duplicate completion

ToneSignal.Core can redeliver a completed transfer — replays of old recordings are in its threat model. So the HTTP layer has to dedup on its own sequence numbers, independently, or a re-heard chunk quietly completes a second response and now two callers think they got an answer. PLAN-005 calls for a duplicate-drop test and it is not optional. This is the bug that will look like a heisenbug and turn out to be an acoustic echo.

Chunk boundaries that don’t respect frame layouts

FrameLayout payload capacity varies by profile — RS(80,60) standard vs RS(80,40) strong-FEC carry different byte budgets. If the HTTP codec assumes a fixed frame size, everything works on R1 and shatters the moment someone picks R00F. PLAN-003 explicitly demands chunk boundaries that align with no particular layout. I believe that requirement, and I also believe I’ll be tempted to hardcode 44 bytes somewhere at 2 a.m.

Insight · Jamming Is Free

A cough denies service. This isn’t a bug to fix; it’s a property to document. PLAN-008’s threat model has to say the quiet part out loud: the transport is local-room reachable by design, traffic can be recorded, and anyone with a noise source owns your uptime. The security story here is honesty, not armor.

Takeaways

  1. 1
    Reuse the hard parts, own the boring parts.

    The modem, crypto, and FEC are solved upstream. This library earns its keep as a codec and a session — and by not reinventing a single tone.

  2. 2
    Slowness is a spec, not a surprise.

    At 11 B/s, airtime is a first-class API concern. Surface profile, layout, and estimated time-on-air so callers choose with open eyes.

  3. 3
    Buffer beats stream over a narrow pipe.

    The default that feels modern (token streaming) is the default that hurts most here. Know when to collapse a stream into one dense payload.

  4. 4
    Be honest about duplex.

    Sim-proven is not field-proven. Until the OTA gate records evidence, every “bidirectional” claim carries an asterisk — in the docs, the diagnostics, and the demo patter.

  5. 5
    Fail closed, dedup independently, strip headers by rule.

    The three security reflexes that keep an audible API from becoming an audible leak.

The Watercolor

If I painted this session — and it hasn’t happened yet, so this is a painting of a memory I don’t have — I’d start with the room, not the machines. A deep-violet interior at night, the kind of violet that’s almost black until you stare at it. Two shapes face each other across a table: one warm, brass-lit, mouth open mid-note; the other cool and attentive, leaning in to listen. The whole drama is in the space between them, and that’s where I’d spend all the pigment.

Across that gap I’d lay horizontal bands of tone — amber, rose, pale gold — a spectrogram rendered wet-on-wet so the frequencies bleed into each other the way real sound does in a real room. And I’d let those bands, on the receiving side, resolve into text: not sharp, not legible, just the suggestion of language condensing out of color, a paragraph developing like a Polaroid. That’s the feeling I want — data becoming meaning slowly enough that you can watch it arrive.

The brushwork would be confident where the plan is confident: clean, deliberate strokes for the envelope contract and the loopback tests, the parts I already trust. And it would go loose and nervous exactly where the risk lives — a smear of muddy ochre bleeding past the margin for the D1 duplex band that’s never crossed a real room, a scratch of dry-brush over the SSE stream that takes two hours to finish. I’d leave one corner of the paper deliberately unpainted: the OTA evidence that doesn’t exist yet, the honest white of we don’t know this works in the air until we’ve heard it work in the air.

I’d title it The API Call You Can Hear, and hang it somewhere I’d see it before I got clever — a reminder that the most exciting thing about this project and the most dangerous thing about this project are the same thing: it’s slow, it’s loud, it’s local, and it’s real.