Reference
Choose the network identity, then measure the exit you received.
Weles separates the requested proxy type from the observed exit-IP class. The current source provides a basic WHOIS preflight, reputation and geography enrichment, platform policy, burn history, and specialist audits; it does not expose one public proxy-quality CLI command or a scalar quality score.
Three different labels#
| Layer | Values | What it means |
|---|---|---|
Requested route type | isp | residential | mobile | What the trajectory asks the router to supply. This comes from task policy or an approved override; it is a requirement, not proof of the exit received. |
WHOIS class | residential | datacenter | unknown | What src/proxy/quality/classify.ts infers from the exit IP's organization and netname using maintained organization lists. |
Reputation result | clean | proxy | hosting | mobile | unknown | What src/proxy/policy.ts derives from ip-api proxy, hosting, and mobile flags while retaining country, timezone, ISP, organization, ASN, and reverse DNS as evidence. |
Why choose each route#
| Route | Use it when | Tradeoff |
|---|---|---|
Datacenter | The target permits automation, the work is public or stateless, account reputation is irrelevant, and low cost, bandwidth, and stable infrastructure matter most. | Usually cheapest and fastest, but hosting ASNs are easy to identify. The basic registration preflight rejects a detected datacenter exit. |
Residential | The target evaluates consumer-network reputation, or discovery and registration need an ordinary household ISP exit. Use a sticky identity when one session must keep the same IP. | Better consumer-network resemblance, but rotating pools can change country or IP, inherit another customer's burn history, and break account-to-IP continuity. |
ISP / static residential | A long-lived account must return through one stable, consumer-looking network identity across login, challenge, health, and later actions. | The preferred account-bound route in current task policy. More expensive and scarce; an ISP-branded pool can still terminate on a datacenter ASN, so the actual exit must be checked. |
Mobile | The product is mobile-first, the platform expects carrier traffic, or a reviewed comparison needs a cellular-network counterfactual. | Carrier ASN and CGNAT can provide strong consumer provenance, but exits rotate, geolocation is coarse, latency and cost are higher, and shared carrier addresses can already be challenged. |
Direct | The platform accepts worker egress and the action does not need a separate account-bound network identity. | Simplest path with no proxy failure mode, but it exposes the worker's own network identity and must not be substituted for a required proxy. |
Current policy#
taskNetworkRequirements(action, platform) is the central declared policy. It chooses direct egress for GitHub, Product Hunt, and Pangram; other account-bound platforms currently request an ISP route, normally in the US. A trajectory must not silently fall back to another type. Pangram registration therefore goes out directly unless PANGRAM_REGISTRATION_PROXY_URL names a proxy.
Provider capability is tracked separately by provider and action. Known failures can exclude a provider, pause a platform when none works, and prefer an exact prior pass before a same-platform pass or an untried provider; price breaks ties inside the same evidence tier. Prices come only from the proxy_rate_cards Weles runtime setting in Skarbiec ({"rates": {"<provider>": {"per_gb": <price>}}}); Weles carries no price of its own, and a provider without a rate there is never chosen. An account session tries every ranked provider in order until one resolves an exit; when none does it fails with proxy_unavailable and names the providers tried without an exit, the providers failing this action in proxy_capability_matrix, and the providers with no rate in proxy_rate_cards, so an empty rate card reads as exactly that.
A provider row is a `weles-*-proxy` Skarbiec item. Its provider is derived from the endpoint host (providerFromHost) or declared as `provider` in the item's context, and its pool type is what the context declares as `proxy_type`: isp, mobile or residential. Nothing is read from the display name. A row that declares no `proxy_type` cannot answer a typed request: resolveProxy lists it in the preflight diagnostics with rejected_reason proxy_type_undeclared, and the LinkedIn rotating-pool probes list it under results as skipped with reason proxy_type_undeclared and print which item to fix. The probes' include lists (LINKEDIN_ROTATING_DISCOVERY_INCLUDE, LINKEDIN_WPROBE_INCLUDE) are `provider[/type]` entries such as `oxylabs/mobile,packetstream`.
Sticky-session credentials are one shape per provider (stickyCredentials in src/proxy/sources/provider_credentials.ts), used by the resolver, by pinned-proxy hydration and by the probes alike; a static ISP pool gets its base credentials unchanged.
Resolver CONNECT and address-service diagnostics#
The account-session resolver checks the proxy's CONNECT answer and reads the exit address through a tunnel owned by this process. Set WELES_PUBLIC_ADDRESS_URL in the worker's environment file to an absolute HTTPS URL returning the caller's IP address as plain text. There is no built-in third-party address service. Credentials and fragments in that URL are refused; path, query and an explicit port are retained. Machine public-address diagnostics use the same declaration, but ask it directly rather than through the account proxy.
For example, a deployment-controlled address service can be declared as WELES_PUBLIC_ADDRESS_URL=https://address.example.com/ip in the environment file. Replace the reserved example host with the actual service before use. When the run names a target host, the initial CONNECT checks that target; otherwise it checks the declared service host and port. Exit sampling still uses the declared service in either case.
A missing or invalid declaration names WELES_PUBLIC_ADDRESS_URL in the resolver's preflight_error; machine diagnostics record the failed configuration-resolution operation. An unreadable exit address retains its CONNECT, TLS, HTTP or body-validation cause instead of silently using the worker's own address. CONNECT refusal records connect_failed with the socket's actual cause, including each address and code in an aggregate failure. An observed response records numeric connect_status when its status line parses; a rejected response also retains that line in rejected_reason with the connect_answered prefix. A successful CONNECT does not record a separate status-line field. A failed top-up enqueue remains an attempt diagnostic, not a successful retry or a funded account.
CONNECT framing is read through its terminating empty line even when TCP splits the response across packets. A close before that boundary retains the incomplete response as its cause; it is not treated as a zero status. Bytes received beyond the CONNECT headers stay available to the TLS reader.
Both direct machine capture and tunneled exit reads validate the plain-text body as an IP address. HTTP success with HTML, JSON or any other non-IP body is a failure, not machine.public_ip. Machine capture_failures retains the failed field and operation together with the complete nested transport causes; process failures also keep their exit status and stderr.
This is the resolver's internal library contract, not a new public proxy-check command. The separate basic WHOIS check below is unchanged. Changing an environment declaration does not establish that its service, proxy or consumer works.
Qualifying resolver exit-address reads#
Run node tests/proxy/exit-address.mjs in the product checkout on an isolated qualification host. Declare WELES_SOURCE_REVISION as the exact clean source revision. Supply WELES_TEST_TUNNEL_SHA256, WELES_TEST_ADDRESS_SERVICE_SHA256, WELES_TEST_MACHINE_SHA256, WELES_TEST_CAPTURE_FAILURES_SHA256 and WELES_TEST_ERROR_CHAIN_SHA256 from the matching build's dist/proxy/resolve/exit/tunnel.js, dist/utils/runtime/public-address.js, dist/diagnostics/versions/machine.js, dist/diagnostics/versions/failures.js and dist/_shared/error-chain/index.cjs respectively. The journey checks tracked source against HEAD and retains source and executable-module digests; declarations alone do not qualify a build.
Load WELES_TEST_PROXY_URL through the qualification environment from the real isolated fixed-exit proxy credential, including its explicit HTTP proxy port. WELES_TEST_EXIT_IP must be that proxy's independently established exit address, and WELES_TEST_WORKER_PUBLIC_IP must independently identify direct worker egress. WELES_PUBLIC_ADDRESS_URL must name the actual plain-text HTTPS address service. WELES_TEST_NON_IP_ADDRESS_URL must name a real HTTPS endpoint answering HTTP success with HTML, JSON or another non-IP body; it must not simulate a provider. WELES_TEST_REFUSED_PROXY_URL must name a controlled endpoint that really refuses TCP connections; it is not a fabricated proxy server. Never point refusal qualification at an operator-owned production proxy.
The journey exercises actual missing-service and insecure-service refusals, an actual socket ECONNREFUSED and the real authenticated CONNECT plus HTTPS exit read. Fresh processes run the product's actual asynchronous machine capture through network settlement, inspect machine.public_ip and capture_failures, and compare successful direct capture with the independently declared worker address. Both consumers must reject the real non-IP response; the machine's real refused HTTPS connection must retain its nested connection code. No request is mocked, no top-up is called and no browser is launched. This does not prove all resolver policy branches. Reports under build/real-tests/proxy-exit-address retain invocation, source revision, module identities, process results, observed failures and returned addresses without proxy credentials. A missing input, unavailable dependency, unexpected response or wrong exit is failed qualification, not a pass. Inspect the final report and process exit status; source inspection or a recorded service URL is not execution evidence.
Basic datacenter check#
preflightProxy(proxyUrl) in src/proxy/quality/preflight.ts is the available reusable basic check. It asks api.ipify.org for one external IPv4 address through the proxy, classifies that IP from WHOIS, and returns { ok, ip, classification?, error? }. classification contains ip, quality, org, netname, source, and the matched organization term when one exists.
The basic rule rejects datacenter and accepts residential or unknown. Unknown is not a high-quality verdict: it means the maintained WHOIS lists could not classify the network. This check has no numeric score, supports IPv4 only, caches by IP, and does not by itself prove country, stickiness, browser routing, WebRTC safety, or platform acceptance.
import { preflightProxy, summarizePreflight } from './dist/proxy/quality/preflight.js';
const result = await preflightProxy(process.env.PROXY_URL);
console.log(summarizePreflight(result));
// preflight ACCEPT|REJECT ip=<exit> quality=residential|datacenter|unknown org="..."Reputation, geography, and network history#
| Function or state | Answers |
|---|---|
verifyExitReputation(exitIp) | Whether ip-api marks the exit clean, proxy, hosting, mobile, or unknown; also returns country, region, city, timezone, ISP, organization, ASN, and reverse DNS. |
verifyExitCountry(exitIp, expectedCc) | Whether the observed exit country matches the requested country: match, mismatch, or unknown. |
allBurnKeys(exitIp) | The exact IP, /24, /19, and optional ASN keys used to join failures across related exits. |
probeLedgerStats() | Observed clean/challenge rate overall, over seven days, and per /19 network when a probe ledger exists. |
isBurned / markBurned | Whether an endpoint has known failure history and the signal/platform that marked it. |
resolveProxy(...) | Provider selection, sticky identity, endpoint attempts, country/reputation/platform probes, and the final routed proxy used by a session. |
What low quality means#
Weles does not currently reduce quality to one number. An exit is unsuitable when it violates the requested route, is classified as datacenter for a sensitive account flow, is flagged proxy or hosting by reputation data, has the wrong country, changes during a sticky session, differs between node and browser, leaks a direct address through WebRTC or IPv6, appears in burn history, or reaches a platform challenge where a controlled comparison reaches the intended form.
A failed website run alone is not a proxy-quality result. Burn attribution needs controlled runs that retain the proxy identity, browser/persona, challenge outcome, and terminal signal so a trajectory or fingerprint defect is not mislabeled as a bad IP.
Specialist audits and current limitation#
scripts/debug/proxy_quality_audit.mjs, browser_proxy_leak_audit.mjs, and linkedin_dedicated_proxy_readiness_audit.mjs model the richer checks: direct-versus-proxy exit, browser routing, IPv4/IPv6 and WebRTC leaks, dedicated/static declaration, and platform-specific readiness.
These scripts are diagnostic source, not a supported public command. In the current checkout they import dist/proxy/quality.js while the corresponding src/proxy/quality.ts source file is absent; therefore this documentation does not present them as a reproducible public entrypoint. There is currently no weles proxy check command.