pixellint

Pixellint 0.35.0 deepens six rulepacks and adds local HAR replay.

Pixellint 0.35.0 deepens six existing destination packs: HubSpot browser pixels, LiveRamp ATS envelope retrieval, LiveRamp ATS envelope refresh, Outbrain, the published legacy Flashtalking FTrack transport and Matomo. The inventory remains 161 vendor packs across 85 vendors. This release also adds local HAR request import and validation replay to the CLI, Rust API, JavaScript package, MCP server and browser playground.

The work follows concrete gaps in the existing source inventory. Some gaps need a stronger check, such as counting repeated query values or validating every forwarded IP. Others need a more accurate model of the destination parser. A useful validator must recognize the value that the documented parser actually reads and distinguish an unavailable capture field from a field that was visibly omitted.

All 320 new evaluation cases match their recorded expected outcomes in 0.35.0, compared with 174 in 0.34.0. That is 146 improved outcomes, including one newly detected error case and 27 cases where prior errors clear. The separate frozen stored corpus of 8,550 artifacts has zero finding or selection changes. These are measured local results, with the source cases and stored replay reported separately.

HubSpot counts repeated targeting values in the original query.

The inspected HubSpot browser SDK emits at most five repeated tc values for the reviewed targeting surface. Earlier request-body machinery could check occurrence limits in a captured request, but the bare URL path lacked the same primitive. The new check counts values in URL queries for the existing reviewed pixel routes, including percent-encoded parameter names and empty values.

The count belongs to the decoded parameter name. A different spelling of a case-sensitive key does not become tc, and fragment text does not become a query parameter. Placeholder values still occupy a submitted occurrence, even when their eventual text is unknown. The result is a source-backed warning for an observable producer limit without guessing the targeting value itself.

This closes a specific published SDK gap. It does not establish backend acceptance, portal membership or the activation of an arbitrary tracking domain. Custom event labels and optional business identifiers retain the limits recorded in the audit. The source cases include boundary counts and related encodings so the release can demonstrate the exact behavior that changed.

LiveRamp checks each forwarded IP while respecting ambiguous call modes.

Both LiveRamp ATS packs gain complete literal IP-chain syntax checks for X-Forwarded-For. A captured chain can contain IPv4, IPv6 or a mixture with horizontal whitespace. Every literal member is checked, including values supplied on repeated header lines. An empty member, malformed IP or a hostname in the chain produces an advisory syntax finding.

The official retrieval and refresh guides require the header for server-to-server integrations. Pixellint applies that absence requirement when the captured implementation mode is established. Repeated atype values that disagree, contain an unresolved placeholder or leave the mode ambiguous cannot prove that a server call occurred. The validator defers a missing-header error in that context while retaining the observations it can establish.

This also corrects prior false errors caused by treating one repeated server-mode value as decisive. Agreeing server values still establish the requirement. Visible malformed values remain inspectable where the source establishes their scope. Placement authorization, approved geography, actual consent collection and the validity of a returned envelope still require external state that a request capture does not contain.

Outbrain validates the calendar values in its documented timestamp forms.

Outbrain publishes eight timestamp representations for its server-to-server integration. The deeper pack checks the calendar and clock values in those forms, covering leap years, month and day limits, hour conventions and literal numeric timezone offsets. A date with a familiar shape can still contain an impossible day, and this release now distinguishes those cases.

The checks remain advisories because the documented representations do not expose the collector runtime parser. Named or localized timezone text remains opaque. Pixellint does not infer a timezone database version, daylight-saving transition or locale from a string that the vendor has not fully specified. Retained UTC Z acceptance is an explicit compatibility behavior, not a newly claimed vendor format.

The new cases exercise supported representations and their calendar boundaries through both URL and captured-request inputs. This adds depth to the existing destination pack without imposing a made-up registry of event labels or browser-only fields. Account event configuration, attribution history and the full generated browser pixel schema remain separate gaps in the source inventory.

FTrack reconstructs the fingerprint relation for a bounded producer layout.

The public legacy FTrack producer exposes a relationship between its indexed browser fingerprint representation and an unsigned MurmurHash value. This release reconstructs that relationship for the pinned, recognizable layout and reports an advisory when the supplied values disagree. Executed producer variants provide the expected output independently of the Rust validator.

That reconstruction has explicit boundaries. Unknown or ambiguous layouts stay unvalidated, and a public producer observation does not become a universal private collector requirement. The original source already permits caller configuration and runtime differences. The pack keeps those distinctions visible instead of extending one reconstructed layout to every possible FTrack payload.

The legacy XDomainRequest branch also needs form decoding when the request visibly has no Content-Type header. A destination-specific hint now enables that path only when the necessary header absence is observed and the body is available. Unknown or redacted MIME and compression context block the inference. An observed unsupported compression format remains an informational limitation, while a known invalid request method still produces its normal finding.

Matomo bulk events follow the pinned PHP scalar readers more closely.

Matomo bulk events can carry query strings that PHP parses before vendor field readers interpret their values. The deeper profile models one form decode, scalar key normalization and last-value shadowing in the pinned PHP 8 source. If a scalar parameter appears twice, the last value read by the server profile can change the result. Checking both raw occurrences as independent final values gives the wrong answer for that profile.

Native PHP execution and pinned Matomo readers supply the comparison oracle. The release also corrects comma float handling: validation can use normalized text, while conversion still casts the original string. Portable source cases cover that distinction. The profile does not claim to resolve bracketed parameter trees, sanitizer-sensitive forms or behavior controlled by runtime configuration.

Capture availability is part of this contract. An unavailable JSON entity might contain the complete bulk event list. Pixellint therefore avoids inventing missing single-event URL fields when that body cannot be inspected. Supplied query values and the observed method still receive their checks. Unknown Content-Encoding likewise prevents payload interpretation without suppressing known query or header violations.

HAR import keeps the request evidence local and preserves its representation.

The HAR adapter extracts recorded requests for offline validation. Replay means running the validator over the capture; it does not resend requests to destination vendors. Local browser file import and paste use the same engine behavior as the CLI and JavaScript API. HAR and complete-request input avoid the playground sample-upload and query-sharing paths.

Each imported request retains its original URL, duplicate query ordering, method, ordered header lines and raw body text where those fields are inspectable. Occurrence provenance connects the result to its HAR entry. The adapter does not rebuild wire bytes from parsed queryString or postData.params fields, and it does not invent a Content-Type header from a postData mimeType annotation.

HAR request extraction has declared limits. Encoded body extensions, unavailable entity bytes, unsupported character encodings and ambiguous representations remain explicit availability states. Compressed request entities are not silently decoded into assumed payloads. The adapter does not validate the full HAR response, timing or page schema, and an archive can contain unrelated destinations for which no protocol pack applies.

Capture clocks and credential policies prevent speculative findings.

By default, HAR validation uses each entry's recorded startedDateTime. An explicit reference-time override takes precedence across the archive. Missing or invalid capture timestamps require an override instead of silently using the day of validation. Repeated requests with different capture clocks retain their distinct evaluation context, which matters for rules that compare event ages.

Chrome documents that sanitized HAR export omits sensitive headers such as Authorization and Cookie. The importer offers unknown, Chrome-sanitized and complete header policies. The default treats omitted credential headers as unknown. The Chrome policy records the known export limitation, while complete means that observed header absence can support an absence check. Present credential values remain observed unless they are explicitly declared redacted.

Incomplete capture context produces an informational finding and defers checks that depend on unavailable facts. It does not disable all request validation. A visible bad method, malformed query value or invalid non-redacted header remains actionable. Alternative authentication carriers are evaluated with the same distinction. These policies describe the measured fields; they do not guarantee that an archive or a generated report is free of sensitive data.

The evaluation records corrected outcomes as well as additional detection.

The 320 new cases combine independent producer executions, primary-source boundaries and separately labeled authored mutations. The previous version matches 174 expected outcomes, and the release matches all 320. All 146 improvements are reviewed. One case gains error detection and 27 clear a prior error, so the total improvement cannot be described as 146 new errors caught.

The 601 retained source cases are evaluated separately. Of those, 598 preserve their historical expected outcomes. Three intentionally gain source-backed warnings: two FTrack fingerprint cases and one HubSpot targeting-count case. All 601 match the reviewed current expectations, with no unreviewed oracle regressions. Two additional LiveRamp golden corrections concern conflicting repeated call modes and sit outside that 601-case corpus.

An oracle match means the local result agrees with the recorded source-based expectation. It does not measure remote acceptance or customer precision and recall. Producer executions, mutation cases and retained goldens overlap some of the same protocol surfaces, so their counts are not additive vendor specification coverage. The public aggregate report preserves these distinctions and links back to the per-pack audit.

The frozen stored corpus remains unchanged and has clear sampling limits.

The release comparison reuses the verified 8,550-artifact D1 snapshot read on October 9, 2026 at 11:20:41.145938 UTC. It contains 108 URL artifacts, 8,397 VAST artifacts and 45 JSON artifacts, with zero complete HTTP captures. A fresh read for this round was blocked by Cloudflare authorization error 7403, so this report does not claim to include artifacts added after the frozen snapshot.

Every stored artifact retains its previous finding and selection profile compared with 0.34.0. The replay records 284 errors, 728 warnings and 1,615 informational findings in both versions. The number of artifacts containing an error stays at 216. Vendor packs remain selected for 4,398 artifacts, with 2,554 core-only and 1,598 directory-only artifacts. There are no engine exceptions.

Zero stored changes are a compatibility result for this corpus. They cannot measure the practical gain of HTTP transport or HAR checks because the snapshot contains no complete captures. Source-authored request cases provide that evidence for this release. The published report contains aggregate counts and whole-corpus fingerprints, with no stored sample values or private capture contents.

Native, npm and browser builds agree on the reviewed results.

Verification includes 520 passing workspace tests and green source and infrastructure CI. Full native report comparisons cover the frozen stored corpus, all retained source cases and all new source cases. The npm comparison suite passes 19,300 comparisons, and the browser WASM suite independently passes 19,300. Each includes 18,942 full-corpus comparisons and 358 single-entry controls across the old and new versions.

The HAR-specific suite adds 72 complete import and validation comparisons across eight archives, all three header policies, recorded entry clocks and explicit overrides. Independent review exercises 96 universal-condition guard validations and 18 SDK capture controls. Those controls check that unknown fields defer dependent assertions while observed method, query and header violations remain visible.

A final compiler-lint adjustment changed the hash loop to typed chunks without changing the algorithm. Equivalence checks cover 32,808 vectors, and all 9,471 candidate native corpus reports remain byte-identical before and after that adjustment. These checks support the shipped behavior within the documented scope. Unpublished collector contracts, account state and unavailable runtime context remain visible gaps for later work.

Sources

Contract pages

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

Validate a local HAR or HTTP capture Docs