pixellint

Pixellint 0.40.0 inspects explicitly captured gzip request bodies.

Compression can hide an existing payload contract.

A destination pack can recognize an endpoint and still be unable to inspect its event body. That happens when a capture preserves gzip bytes but the validator expects text. The URL, method and observed headers remain useful, yet event fields are inaccessible until the body has been represented and decoded correctly. A clean set of transport findings cannot establish that the hidden event payload satisfies its destination rules.

Mixpanel Import is the first documented workflow for the change. Its API supports JSON arrays and NDJSON, and allows gzip to reduce transferred bytes. Pixellint already has contracts for imported event fields. The new minor makes those existing checks available for a supported compressed capture, rather than creating a second schema that behaves differently merely because the request used compression.

The feature has two parts: an explicit envelope field for binary request bytes, and a bounded decoder in the shared engine. The capture tells Pixellint what was observed. The decoder prepares inspectable content when the encoding and media type support it. Endpoint selection continues to determine which destination contracts run on the resulting body.

An explicit Base64 field preserves the captured bytes.

The HTTP envelope adds body_base64 as an alternative to the raw text body field. It represents the original request bytes using standard Base64 with the required padding. The two fields are mutually exclusive because competing representations would leave the engine unable to establish which body it is validating. Supplying both is a capture-shape problem, not an event-field problem.

Base64 belongs to the capture representation. It does not mean that the browser or server sent a Base64 event body to the vendor. After decoding the envelope field, the engine has the original wire bytes. The observed Content-Encoding header then determines whether those bytes need gzip decoding before the media parser can inspect them.

The implementation requires an explicit field instead of guessing from text that resembles an encoded blob. Existing raw string captures describe the representation their exporter actually retained. Malformed Base64 receives a precise capture finding. The engine does not repair missing required padding, select a different alphabet or reinterpret an arbitrary text body in an effort to manufacture a parseable event.

Observed transport fields remain available when a body is opaque.

The gzip path requires one observed Content-Encoding value identifying gzip. Header spelling and value casing follow the capture parser’s supported handling. Missing capture context is not permission to infer that header from a magic prefix. Repeated or conflicting encoding declarations retain an information finding, because the local tool cannot assume which interpretation the receiving stack used.

Unknown codecs and unsupported encoding combinations retain an information finding and leave dependent body assertions unvalidated. A raw text body paired with gzip does not establish the original compressed wire bytes. That representation therefore keeps its existing deferral. The explicit binary field enables the new inspection path. When Content-Encoding is observably absent or identifies identity, binary UTF-8 content can use the ordinary media parser without decompression.

A body deferral does not hide the rest of the observed request. The endpoint, scheme, method, query and available authentication headers still provide evidence for their existing checks. When a capture marks a header unavailable or redacted, the engine preserves that fact. An exporter’s omission does not become a claim that the request was sent without the header.

The decoder validates the complete gzip stream.

Recovering a readable prefix is insufficient evidence for the original body. The decoder checks gzip framing, member boundaries, trailer integrity and the end of the input. Concatenated members contribute their decoded content in order. An invalid later member cannot be ignored simply because the first member already contains something that resembles JSON.

Integrity controls cover corrupt data, truncation, incorrect checksums and size trailers, optional header fields and trailing bytes outside the accepted framing. A malformed stream produces a body-integrity finding and stops dependent event assertions. That keeps a decoder failure separate from a missing event name, which could otherwise be an artifact of inspecting incomplete recovered content.

Successful decompression also needs an inspectable character representation for the selected media parser. Known JSON or NDJSON carrying invalid UTF-8 produces a content error. Non-JSON binary data outside local UTF-8 inspection produces an information deferral, without a vendor-rejection claim. The engine does not silently replace undecodable bytes before checking event values. Compression and text decoding both need to complete before the body rules can provide meaningful results.

Local resource bounds produce information findings.

A small compressed input can expand into a large body, so the local decoder checks bounds before and during decoding. It allows up to 16 MiB of original wire bytes, 16 MiB of decoded bytes, 1,024 gzip members and a combined 64 KiB of header bytes per member. An encoded-length preflight also limits allocation before Base64 decoding. These are local work bounds, separate from a destination’s request-size policy.

When an input exceeds a local decoder bound, an information finding explains that the body remains unvalidated. The engine can still report independent observed transport findings. It does not assert that a vendor refused the request solely because Pixellint declined to allocate more memory or inspect additional members.

The body-size distinction also matters below the decoder. Compressed wire length and decoded entity length are different measurements. Existing payload assertions receive the decoded content size when that is the quantity their source describes, while the original wire length remains separate. The feature does not resolve an ambiguous vendor MB unit by inventing a stricter byte threshold.

Mixpanel’s existing rules inspect the recovered events.

Mixpanel documents application/json and application/x-ndjson for Import, with Content-Encoding: gzip supported for either representation. After supported decoding, the corresponding parser can expose the same event scopes that an observable uncompressed capture provides. JSON arrays and newline-delimited records still need their own framing checks before individual event fields are evaluated.

The existing Import pack checks event name and the required time, distinct_id and $insert_id properties. A compressed event missing $insert_id reaches that existing requirement, rather than passing because the body stayed opaque. A valid event retains its normal outcome when expressed through a correctly captured compressed body. These paired controls are central to the release review. The pack also checks the documented ceiling of 2,000 events per Import batch. Exact total request bytes remain a recorded source gap because the same documentation gives conflicting limits.

Compression does not provide missing account context. Service-account permissions, configured projects, remote ingestion outcomes and actual retry history remain outside a local event-body check. The existing source gaps around size-unit interpretation also remain explicit. The feature deepens an inspectable request representation; it does not certify the complete Mixpanel service contract or whether an individual request was accepted.

HAR captures retain their original availability facts.

The explicit binary envelope is separate from the HAR adapter. HAR response content has a documented Base64 representation, but an exporter’s request postData encoding extension does not establish a universal request standard. The adapter does not invent request bytes by interpreting every encoding or _encoding field as equivalent to Pixellint’s body_base64 field.

A caller that actually retained the original request bytes can build the explicit HTTP envelope and state the observed headers. If the exporter retained only decoded text, parameter summaries or redacted content, that evidence needs its corresponding availability context. A body marked unavailable or redacted bypasses decoding and dependent assertions, even if other capture fields happen to resemble a usable representation.

This keeps replay evidence traceable. Requests retain their capture locations and reference clocks, and the engine never sends the captured request to a collector. A user can compare a raw text capture with an explicit binary capture without pretending that one was exported in the other form. The practical requirement is to preserve what the capture actually contains.

Independent controls and replay measure the supported change.

The reviewed release passes 70 authored request controls. The previous version matches the expected result on 10 of those controls, and 0.40.0 matches all 70, giving 60 improved outcomes across accepted requests, deliberate payload errors, malformed streams and local resource deferrals. Complete native, Node WASM and browser WASM reports agree across 210 comparisons. The expectations were authored from the source contracts before engine execution. Python-produced bytes and hashes also pass 25 independent Node checks, and a separate adversarial review passes 95 controls, including actual default resource boundaries.

The frozen D1 comparison covers all 8,836 stored artifacts with both versions using identical capture clocks. Findings remain unchanged: 324 errors and 769 warnings, with 250 artifacts carrying errors. That corpus contains no explicit binary request captures, so it demonstrates retained behavior rather than compressed-body detection gains. Another 708 complete-report native and WASM comparisons cover every JSON and URL paste plus VAST representatives of each selected-pack and finding signature. The aggregate replay report publishes counts and evidence hashes without publishing customer artifacts.

The candidate passes 565 Rust tests, workspace Clippy with warnings denied, formatting, npm checks and the current source-review checks for all 164 vendor packs. This release carries the same reviewed decoder into the native packages, npm, CLI, MCP and browser engines on Pixellint and Vastlint. Unsupported codecs, missing decoding context and local resource limits remain explicit information gaps. Local decoding does not establish vendor acceptance, account permissions or remote delivery.

Sources

Contract pages

The dated argument is above. These pages are the field lists.

Inspect a captured request Docs