Trust
Every claim on this page is checkable from outside the process. Where a claim rests on a test, the test is named.
What it can reach
-
It connects out only, to the endpoints you list in
--endpoints, and to nothing else. - It accepts no inbound connections. There is no listener, which is why the container image declares no ports.
- It never touches your inference API. That is a different port and a different protocol, and this process speaks neither.
- It holds no credential to your engine or your API. The only secret it holds is the pseudonymization key you give it.
- It writes to one directory. Moving records anywhere else is a separate process you configure and can decline to run.
What leaves the process
Records carry block hashes, sizes, tiers, timestamps, counters, and identity scope. They never carry token ids, text, or tensors. This is structural rather than filtered: there is no field in the model in which content could travel.
The complete, field by field enumeration is section 2 of the contract. It is the only enumeration, deliberately, so that a field cannot exist in one list and be forgotten in another.
Check it yourself, with no engine attached
This needs the binary but no engine, no socket and no fleet, so it is the first thing to run once you have an artifact and the last thing that needs any cooperation from us. Until then, what follows is our transcript of its output rather than something you have watched happen, and it is worth reading in that spirit.
$ infertap --show-payload > sample.jsonl
{"kind":"store","block_id":"9c4e…a41e",
"content_id":"4a1f…7b02",
"n_tokens":16,"tier":"GPU",
"spec_kind":"full_attention",
"instance_id":"i0","dp_rank":0,"group_idx":0,
"at_ms":1785153670000.0}
That output is byte compared against the live path by test
(main::shown_payload_byte_equals_the_live_chain_output), so the record it shows
you is the record that ships, as a property rather than a promise.
The shipped form on disk is Apache Parquet, one file per sealed segment. JSON Lines is the write ahead form and internal to the process: a sealed segment is converted to its Parquet twin, the twin is verified against the record count before it is renamed into place, and the write ahead file is deleted once that twin exists. What your pipeline reads, and what a reviewer should plan to read, is Parquet. The JSON above is the same record model in a form you can read without tooling.
Two identity spaces appear on one record. block_id is the engine's own, comparable
only inside the process that computed it. content_id is derived from what the
block holds, so it is the same value on every node. Both are pseudonymized before they leave
the host, and the contract explains why they
are
never joined. Token ids were on the wire and have no representation here.
The socket is the engine's decision
Any consumer of KV cache events needs the publisher turned on, and that puts tokenized prompt content on a ZMQ socket. vLLM offers no authentication or encryption for it, and its default endpoint binds every interface, so it is secured by where you put it rather than by configuration. That is true whether you run llm-d, AIBrix, LMCache, or this. All of them read the same field off the same socket, because deriving a fleet stable identity has no other source.
What differs is what happens next. Token values are read in exactly one place, to derive
content_id, and dropped in that scope. No token reaches a record, and every
identity is pseudonymized before it leaves the host.
Resource envelope
The process carries one fixed-purpose map and nothing else: engine block keys
to portable content identities, the state that makes a fleet-stable
content_id derivable at all. Its population equals the engine's resident set:
an entry is created on store and deleted when the last tier's remove releases it, so it
grows with residency, never with traffic. It is bounded by the declared resident-block
capacity (--resident-blocks, derived from your tier sizes with the arithmetic in
the install guide), and at that bound it refuses new identities and declares each
refusal in band, scoped to the affected cache and window. Figures over a refusal
window become stated lower bounds, never bent numbers.
The map's size, its refusal count, and the count of blocks it could not resolve ride
every heartbeat (content_bridge_entries,
content_bridge_evicted, content_unresolved), so its behavior is
continuously visible in your own record stream. A tap restart empties it: blocks stored
before the restart stay unresolved (counted, never guessed) until they are stored again or
the engine itself restarts, which resyncs everything by construction.
| Structure | Bound | Basis |
|---|---|---|
| Payload before decode | 16 MiB | Rejected and counted at the socket. Mean payload 6.5 KiB and maximum 16 KiB in a synthetic capture of 2026-07-27, not a production fleet |
| Identity map (engine keys → portable identities) | Declared resident-block capacity | Delete-on-evict keeps population equal to the engine's resident set: single-digit megabytes at typical GPU block counts, stable across GPU generations. At the cap, new identities are refused and declared, never invented; size and refusals ride every heartbeat |
| Other per-event state | None | Structural: one counter and the provenance map |
| Egress audit set | Per record, cleared each emit | Structural, constant space |
| Pending event buffer | One batch | Structural, drained each poll |
Enforced a second time by the unit file
The shipped systemd unit (packaging/systemd/infertap.service) makes this page's
claims something your kernel enforces rather than something we assert. Each
directive cites the section it operationalizes.
| Claim above | Kernel enforcement |
|---|---|
| Writes to one directory | ProtectSystem=strict with the segments directory as the sole
ReadWritePaths entry |
| No privileges, no shell-outs | DynamicUser, NoNewPrivileges, an empty
CapabilityBoundingSet, SystemCallFilter=@system-service |
| Out only, no listener | RestrictAddressFamilies=AF_INET AF_INET6 with
IPAccounting, and no port ever declared |
| Bounded resources | MemoryMax 1 GiB, TasksMax 16,
LimitNOFILE 256 |
The failure mode is that our process dies, never that your node does. The limits are enforced by the operating system rather than by our code being careful, so a defect in this process cannot consume the resources your engine needs. If it exceeds its bound it is killed, and the gap in the record stream is counted and declared rather than silent.
Disk
Records accumulate in one directory, bounded by --max-disk-bytes, which defaults
to 16 GiB. The bound is enforced by scanning that whole directory, so both forms and any
conversion temporary count against it rather than escaping it. Peak disk is that cap plus the
one active segment still being appended to. Past the cap the oldest sealed segments are
reclaimed, and the loss is recorded twice: in band as a record naming exactly what went, and
structurally as a gap in the segment sequence. Disk pressure only builds while shipping is
failing, since a shipper deletes on success.
Two things are deliberately outside the cap. Orphan files left by a crash, because the process will not delete data it never got to ship. And the active segment, which cannot be reclaimed without losing the record that declares the reclamation.
What is not published
Steady state memory, CPU, and scaling against event rate are not stated here, because they have not been measured on a production fleet and a number we have not measured is a claim rather than a figure. The bounds above are enforced ceilings and structural properties, which are checkable today. Measured envelopes will be published when there is a fleet to measure.
The same line applies to the payload figures above, which is why they carry the word synthetic. They come from a capture against a test engine rather than from production traffic, and a figure that does not say so is borrowing credibility from an observation nobody made.
Failure behavior
- A sealed segment is complete or it does not exist. An abrupt kill can tear the write ahead file it was appending to, and that is handled where it happens: the torn trailing record is discarded and counted at recovery, and conversion fails closed rather than producing a Parquet twin that silently dropped a record. Nothing reaches your pipeline in a half written state, because the twin is verified before it is renamed into place.
- Drops are counted, never silent. Lost messages are detected from sequence gaps and reported on heartbeats. A publisher restart is not a drop and is not counted as one.
- An unrecognized event kind is skipped and counted, never fatal, so an engine upgrade that adds an event does not stop the stream.
- A departure without a stop record is the anomaly signal. A clean exit writes one. A kill or a crash does not, and that absence is what a reader keys on.
Supply chain
Rust, nine direct dependencies in the default build, each justified in one sentence inside the
test that enforces the list, and unsafe_code forbidden at the crate root. The
ninth is the Parquet encoder for the shipped form, carried with its default features off so the
base build still needs no C toolchain. The live transport binds libzmq, the
reference implementation the publisher uses, and is the one optional dependency, behind a
feature flag so the default build has no system dependency at all.
Source and terms
The agent and the analyzer are commercial software; the agent's source is not published, and terms accompany your deployment. What is public, Apache 2.0 and permanently, is the verification substrate: the record contract and its conformance corpora. The stream format belongs to you and to anyone who wants to read it; the implementation is ours.
This page's discipline is that no claim asks you to trust unpublished code. Each one is checkable at the boundary, where the evidence is yours:
- Input is a read-only subscription to your engine's own documented telemetry socket: passive, out of band, holding no credential.
- Output is files on your disk under the public specification: capture your own stream and check it against the spec and corpora, field for field.
-
--show-payloadprints exactly what ships, byte-compared against the live path by test, with no engine attached. It needs the artifact and nothing else of ours, which is what makes it the first check available to you and one we cannot stage. - The boundary is kernel-enforced by the shipped unit file above: outbound only, one writable directory, no privileges. Your operating system holds these properties even if you extend no trust to the binary.
- Source review under NDA is available where your review process requires reading code.
To leave
Stop the unit and delete a directory. There is nothing else to undo.