Sign every inference. Even the streaming ones.
These are fast Ed25519 receipts that stay off the hot path. We measured 11.59µs against a 100µs budget, so the call never waits on signing. An ML-DSA-65 post-quantum anchor locks the session at close. Five layers of protection built for HIPAA voice, PCI call centers, and agentic streams. You can check it offline on a laptop, no secret key needed.
Voice and streaming inference broke every receipt design before this one.
A three-minute HIPAA voice call packs in hundreds of model turns. Older designs made you pick two out of three: fast, tamper-proof, or checkable offline. You never got all three at once.
Sign every turn inline
This adds milliseconds to every segment. Your latency budget is gone before the first packet even ships. Voice gets choppy, and people switch to the next vendor.
Sign once at session close
This is fast on the wire. But if someone tampers with a segment in the middle of the stream, you won't see it until the call ends. And if they also tamper with the close, you might never see it. There's no way to catch a mid-stream tamper.
Verify online with a key holder
Here the auditor has to call your service just to check a receipt. Now the audit depends on you staying online. That's not how compliance works. PCI and HIPAA reviewers need to check things on their own hardware.
One hot path, one off path, and one post-quantum close.
The producer never waits on signing. The sidecar never blocks the producer. The post-quantum anchor never runs on the hot path. You get three separate lanes and one proof you can check.
HOT PATH OFF PATH AT SESSION CLOSE -------- -------- ---------------- producer --> enqueue(seg) ----+ ( voice / LLM stream ) | v +---------------------+ +-----------------------+ | sidecar queue | ---> | per-segment receipt | | (non-blocking) | | Ed25519, off-path | +---------------------+ +-----------------------+ | v chain of segment receipts ( hash- linked, tamper- detectable ) | v +-------------------+ | ML-DSA-65 anchor | <-- session.close() | PQ-finalized | +-------------------+ | v one verifiable proof ( offline, zero-secret )
Every layer makes the receipt harder to attack and easier to check.
We built these in the order D, C, A, B, E, but you can read them in any order. Each one stands on its own. All five are tied into the same signature chain, so tampering with any of them breaks verification.
Drops, resumes, and transfers stay one record.
A dropped connection, a network change, or a transfer to a human agent never breaks the chain. The next segment after the gap carries a continuation block that points back to both the session root and the prior segment's fingerprint.
- sidecar.mark_interruption(cause=transport_close|network_change|transfer)
- sidecar.mark_transfer(to_handler=did:...) for warm-handoff scenarios
- verify_chain accepts seq jumps iff a continuation block is present
- a missing continuation block means the chain gets rejected as incomplete
Every segment names whether the model or the other person said it.
source_role is required on every SegmentInput. It's tied into the segment's signature, so tampering with attribution breaks verification. The asserts field spells out the limit clearly: this tells you who spoke within the session, not who that person really is.
- source_role: "model_side" | "counterparty_side" (required field)
- asserts: stream_provenance_only; source_role_is_origin_not_identity
- tamper test: flipping source_role on one segment fails offline verify
- no overclaim: the receipt never says who the other person actually is
The "~0ms" claim is measured and signed, not just asserted.
The sidecar measures its own hot-path overhead on every enqueue call and embeds {max, p99, mean, declared_budget_us, within_budget, n_samples} in the SessionReceipt. This measurement is tied into the post-quantum signature. Change it, and verification fails.
- measured max in smoke test: 11.59 µs against a 100 µs declared budget
- within_budget = (max ≤ declared_budget_us): this is reported, not just claimed
- changing declared_budget_us after the fact breaks ML-DSA-65 verification
- n_samples is reported so the auditor can see how many samples were tested
Live receipts and sealed sessions look different, on purpose.
Every segment receipt carries verification_state="live_provisional" and sig_alg="ed25519". The SessionReceipt at close carries verification_state="sealed" and sig_alg="ML-DSA-65". So auditors and downstream systems can never mix up a per-segment receipt with the final session anchor.
- segment receipts: live_provisional / Ed25519 (fast, off-path)
- session receipt: sealed / ML-DSA-65 (post-quantum substrate)
- verify path picks the right algorithm based on the state field
- there's no way to replay a live receipt as a sealed one
PCI and PHI never land in the receipt, but the receipt still proves they were there.
A card number, a social security number, or a medical record value gets redacted in the input before the segment is even enqueued. Only {pos, class, commit, in_boundary} go into the receipt. The plain text never enters the chain. Later, an authorized auditor who has the secret key and the value can prove the held value matches the committed span.
- redact_text(cleartext, spans) → (redacted_text, span_dicts, salts)
- commit = SHA-256(domain || salt || class || value): you can't reverse this to get the original value
- verify_disclosure(span, salt, value) is the check that reveals only what's needed
- wrong value fails, wrong salt fails, wrong class fails
We proved it works, we measured the numbers, and we tested that tampering gets caught.
Both test suites run from a fresh checkout. There are five base criteria and five reinforcement criteria. All ten pass. We measured the bench overhead on a 200-segment stream running at a 300ms cadence.
Acceptance smoke 10 of 10 pass
- 1✓~0ms added latency on the live stream
- 2✓Session receipt reconstructs from the segment chain
- 3✓Offline zero-secret verify of the whole chain
- 4✓Tampering one segment breaks the chain
- 5✓PQ-finalize session root post-stream and verify offline
- 6✓Layer D: live_provisional segments vs. sealed session
- 7✓Layer C: latency measurement within budget, tied into the post-quantum signature
- 8✓Layer A: drop and resume verifies end to end through the continuation block
- 9✓Layer B: source_role is tied in, and tampering breaks verification
- 10✓Layer E: PCI data never appears in the receipt, and selective disclosure matches
Bench & latency attestation
This test ran 200 segments at a 300ms cadence. The off-path approach held up from start to finish. These numbers ship with every session receipt as signed evidence.
Wrap your stream, issue receipts, and check them offline.
The sidecar sits right next to your producer, whether that's an LLM emitter, voice text-to-speech, or an agentic loop. You call enqueue() for each segment, and it returns right away. At session close, you get back one post-quantum-finalized receipt. Anyone with the public keys can check the whole chain offline.
from hive_stream import StreamSidecar, SegmentInput, Grounding, LiveSigner, PQFinalizer from hive_stream.boundary import ComplianceBoundary from hive_stream.redaction import redact_text # 1. open a sidecar. (the hot path is whatever follows; this runs once per session) sidecar = StreamSidecar( session_id="did:hive:tenant:my-call-center", model_ref="mir:hivecompute/voice-pci-v1", live=LiveSigner.from_key(LIVE_ED25519_KEY), pq=PQFinalizer.from_key(PQ_MLDSA_KEY), declared_budget_us=100, ).start() # 2. for each segment in the live stream: this is the hot path for seg in voice_stream: redacted_input, spans_in, salts_in = redact_text(seg.heard, seg.pii_spans_in) redacted_output, spans_out, salts_out = redact_text(seg.said, seg.pii_spans_out) sidecar.enqueue(SegmentInput( seq=seg.i, t_start=seg.t0, t_end=seg.t1, input_window=redacted_input, output=redacted_output, model_ref="mir:hivecompute/voice-pci-v1", grounding=Grounding(score=seg.grounding_score, claims_root=seg.claim_hash), boundary=ComplianceBoundary(in_scope=True, pii_class="phi"), source_role="model_side", # Layer B redacted_spans=spans_in + spans_out, # Layer E )) # enqueue() returns right away. signing happens off the hot path. # 3. mid-stream interruption? just one line. (Layer A) if transport.dropped(): sidecar.mark_interruption(cause="transport_close") # 4. close the session: this makes the ML-DSA-65 post-quantum anchor session_receipt = sidecar.close_session() # session_receipt.verification_state == "sealed" (Layer D) # session_receipt.latency_attestation (Layer C) # verify offline anywhere: # from hive_stream.session import verify_chain # ok, why = verify_chain(sidecar.chain, LIVE_PUBLIC_KEY)
Built for streams that have to hold up to an audit the next business day.
This is for anywhere a model is talking to a person about regulated material.
HIPAA voice
Telehealth intake, behavioral health sessions, and voice agents that touch PHI. Layer E keeps the data type on the receipt while keeping the actual data out of it.
PCI call centers
Card-not-present voice flows where card numbers have to be auditable without ever landing in log storage. Your PCI scope shrinks, and what you can prove to an auditor grows.
Agentic streaming
Long-running agent loops where the model talks to other models or tools for hours at a time. Continuity, Layer A, means transfers and reconnects all stay part of one record.
LLM proxies for regulated industries
If you resell inference to banks, insurers, or hospitals, AFiR-Stream is the first thing your customers' auditors will ask for.
The signer is live. Not a slide.
The AFiR-Stream signer runs in production today at receipts.thehiveryiq.com. It signs a segment off the hot path, seals the session at close, and checks the chain. Every response is a real Ed25519-signed envelope, and the sealed session shows its ML-DSA-65 post-quantum anchor.
curl -sS https://receipts.thehiveryiq.com/v1/afir-stream/examples | python3 -m json.tool
Measured, not marketed. The example session seals seven segments with a worst-case off-path signing latency of about 12µs against a declared 100µs budget. The hot path is never blocked. These latency numbers show the system is alive and working, not a production SLA.
smoke/smoke_afir_stream.py) and bench (bench/bench_afir_stream.py) checked into the AFiR-Stream substrate. The receipt schema and offline verifier ship with the API key. SiGR, MiR, GCA, GiTM, QPuF, AFiR-CacheSign, and AFiR-Manifest are live at /.