Skip to main content

Module coherence

Module coherence 

Source
Expand description

Network-identity coherence port trait and supporting types.

The 2026 scraping guide (docs/dev/project/scraping-guide-2026-llm-context.md §“WebRTC coherence rule”, L2839) requires five orthogonal vectors to agree before a request is sent:

  1. Proxy exit IP country
  2. DNS resolver country
  3. WebRTC public IP (must be in the same /16 as the proxy exit)
  4. Browser timezone (IANA TZ database, e.g. America/New_York)
  5. Browser Accept-Language

A mismatch on any of these vectors is the “WebRTC Trap” (L3135-3138) — one of the highest-signal anti-bot tells in the field. The CoherencePort trait captures this check as a pure, stateless function that consumes a CoherenceContext and returns a CoherenceVerdict; the default implementation in adapters::coherence::DefaultCoherenceValidator (behind the coherence-validation cargo feature) applies the rule above.

The trait lives in the always-compiled ports::coherence module so the crate::manager::ProxyManager plumbing can reference it uniformly with or without the feature; only the default validator is feature-gated, mirroring the T96 BayesianObserver / ThompsonStrategy pattern.

§Module-level example

use std::net::IpAddr;
use std::str::FromStr;
use stygian_proxy::ports::coherence::{
    AcceptLanguage, CoherenceContext, CoherencePolicy, CoherencePort,
    CoherenceVerdict, IsoCountry, Locale, MismatchField, MismatchSeverity, Tz,
};

// A clean US context: every vector agrees.
let ctx = CoherenceContext {
    proxy_geo_country: Some(IsoCountry::new("US").unwrap()),
    dns_resolver_country: Some(IsoCountry::new("US").unwrap()),
    browser_locale: Locale::new("en-US").unwrap(),
    browser_timezone: Tz::new("America/New_York").unwrap(),
    accept_language: AcceptLanguage::new("en-US,en;q=0.9").unwrap(),
    webrtc_local_ip: None,
    webrtc_public_ip: Some(IpAddr::from_str("192.0.2.42").unwrap()),
    proxy_ip: Some(IpAddr::from_str("192.0.2.7").unwrap()),
};

// Without a validator the verdict is "Unknown"; the trait itself is
// always-compiled but the default implementation lives behind the
// `coherence-validation` feature.
let verdict = ctx.evaluate();
assert!(verdict.is_unknown());
assert_eq!(verdict.unknown_reason(), Some("no_coherence_validator"));

// Policies are independent of the validator: the default is
// advisory-only.
let policy = CoherencePolicy::advisory();
assert!(!policy.is_hard_fail(MismatchField::ProxyGeoVsDns));
let policy = CoherencePolicy::hard_fail_on(MismatchField::ProxyGeoVsDns);
assert!(policy.is_hard_fail(MismatchField::ProxyGeoVsDns));
assert_eq!(policy.severity(MismatchField::ProxyGeoVsDns), MismatchSeverity::Hard);
let _ = ctx; // suppress unused warning under no-features build

Structs§

AcceptLanguage
Accept-Language header value (RFC 7231 §5.3.5).
CoherenceContext
Snapshot of the network-identity vectors that the CoherencePort validates.
CoherencePolicy
Policy configuring how [crate::manager::ProxyManager::acquire_proxy_with_coherence] reacts to a CoherenceVerdict::Mismatch.
IsoCountry
ISO-3166-1 alpha-2 country code (e.g. US, GB, PK).
Locale
BCP-47 locale tag (e.g. en-US, fr-FR).
Tz
IANA timezone identifier (e.g. America/New_York, Europe/London).

Enums§

CoherenceVerdict
Outcome of a single coherence evaluation.
MismatchField
Field on which two coherence vectors disagreed.
MismatchSeverity
How serious a given mismatch is for downstream routing.

Traits§

CoherencePort
Network-identity coherence port.

Type Aliases§

BoxedCoherencePort
Shared-ownership type alias for a CoherencePort implementation.