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:
- Proxy exit IP country
- DNS resolver country
- WebRTC public IP (must be in the same
/16as the proxy exit) - Browser timezone (IANA TZ database, e.g.
America/New_York) - 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 buildStructs§
- Accept
Language Accept-Languageheader value (RFC 7231 §5.3.5).- Coherence
Context - Snapshot of the network-identity vectors that the
CoherencePortvalidates. - Coherence
Policy - Policy configuring how [
crate::manager::ProxyManager::acquire_proxy_with_coherence] reacts to aCoherenceVerdict::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§
- Coherence
Verdict - Outcome of a single coherence evaluation.
- Mismatch
Field - Field on which two coherence vectors disagreed.
- Mismatch
Severity - How serious a given mismatch is for downstream routing.
Traits§
- Coherence
Port - Network-identity coherence port.
Type Aliases§
- Boxed
Coherence Port - Shared-ownership type alias for a
CoherencePortimplementation.