Skip to content
Cascading Labs QScrape VoidCrawl Yosoi

Challenge Escalation

Challenge escalation is the bridge between detection and recovery. VoidCrawl keeps ownership of the browser session, captures a neutral event, and exposes enough coordinates for an operator or trusted resolver to clear the wall in the same tab.

V1 is manual by design: open VNC or noVNC, clear the wall, mark the event resolved, then resume the session. VoidCrawl still does not forge tokens, outsource puzzle solving, or hide that a challenge happened.

Event contract

capture_challenge combines:

  • the last session_navigate anti-bot verdict,
  • a live DOM captcha probe,
  • optional accessibility summary for triage,
  • same-tab attach coordinates: websocket_url, target_id, session_id,
  • optional operator links: vnc_url, novnc_url.

Presence-only CDN signals are telemetry. Active challenge verdicts and active DOM captcha widgets are blocking events.

Start a visible browser

Use the headful Docker stack when you need a browser an operator can see:

docker compose -f docker/docker-compose.headful.yml up

Open noVNC in a browser:

http://127.0.0.1:6080

Native VNC is also available for lower latency:

vnc://127.0.0.1:5900

If the MCP host starts voidcrawl-mcp, set these environment variables in that host’s MCP config:

VOIDCRAWL_NOVNC_URL=http://127.0.0.1:6080
VOIDCRAWL_VNC_URL=vnc://127.0.0.1:5900

You can also pass novnc_url and vnc_url directly to capture_challenge.

Manual operator flow

  1. Open a stateful headful session.
{ "headful": true, "port": 9222 }
  1. Navigate to the target.
{ "session_id": "SESSION_ID", "url": "https://example.com", "timeout_secs": 30 }
  1. Capture the active wall.
{
"session_id": "SESSION_ID",
"novnc_url": "http://127.0.0.1:6080",
"vnc_url": "vnc://127.0.0.1:5900"
}
  1. Clear the challenge through noVNC or VNC in the visible browser.

  2. Mark the event resolved.

{
"session_id": "SESSION_ID",
"event_id": "EVENT_ID",
"resolver": "manual_vnc",
"note": "operator cleared challenge in noVNC"
}
  1. Wait for resolution. By default this re-probes the DOM before resuming.
{ "session_id": "SESSION_ID", "event_id": "EVENT_ID", "timeout_secs": 10 }
  1. Continue the session, then close it when done.
{ "session_id": "SESSION_ID" }

Capture result shape

A blocking event returns the evidence and attach coordinates a resolver needs:

{
"challenge": {
"event_id": "EVENT_ID",
"url": "https://example.com/",
"status": "captured",
"blocking": true,
"antibot": {
"vendors": ["cloudflare"],
"challenged": true,
"challenge_vendor": "cloudflare"
},
"dom_captcha": {
"kind": "turnstile",
"widget_rendered": true,
"active": true
},
"attach_coordinates": {
"websocket_url": "ws://127.0.0.1:9222/devtools/browser/...",
"target_id": "TARGET_ID",
"session_id": "SESSION_ID",
"novnc_url": "http://127.0.0.1:6080",
"vnc_url": "vnc://127.0.0.1:5900"
}
}
}

Resolver hook

Automated resolvers use the same event and attach to the existing tab. They should not launch a new browser for the challenge.

Rules:

  • Attach with { websocket_url, target_id } from attach_coordinates.
  • Keep recipes domain-scoped and explicitly enabled.
  • Mark exactly one outcome: mark_challenge_resolved or mark_challenge_failed.
  • If resolution fails, rotate identity or fail with the captured evidence.
ToolPurpose
capture_challengeCapture evidence, DOM captcha state, and same-tab attach coordinates.
mark_challenge_resolvedRecord that an operator or resolver cleared the event.
mark_challenge_failedRecord that the wall could not be cleared.
wait_for_challenge_resolutionWait for the outcome and optionally re-probe the DOM before resuming.

FAQs

Does challenge escalation solve captchas automatically?

No. The shipped flow captures evidence and same-tab attach coordinates, then lets a human operator clear the wall through VNC or noVNC. Future resolvers use the same event contract, but automatic resolution is opt-in and domain-scoped.

When should I call capture_challenge?

Call it after session_navigate or a stateful action lands on an active wall. CDN presence alone is telemetry; a blocking anti-bot verdict or active DOM captcha is what makes a challenge event useful.

Why same-tab attach coordinates?

The warm cookies, target URL, browser fingerprint, and challenge widget all live in the existing tab. Resolvers attach to that tab by websocket_url and target_id instead of opening a fresh browser that would get a different challenge.