mcp-scraper 0.35.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/bin/api-server.cjs +26406 -21015
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +3 -3
- package/dist/bin/mcp-scraper-cli.cjs +51 -7
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +48 -5
- package/dist/bin/mcp-scraper-cli.js.map +1 -1
- package/dist/bin/mcp-scraper-install.cjs +2 -2
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +2 -2
- package/dist/bin/mcp-stdio-server.cjs +944 -215
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +8 -8
- package/dist/bin/paa-harvest.cjs +125 -70
- package/dist/bin/paa-harvest.cjs.map +1 -1
- package/dist/bin/paa-harvest.js +4 -4
- package/dist/chunk-345BQXZH.js +712 -0
- package/dist/chunk-345BQXZH.js.map +1 -0
- package/dist/{chunk-M2S27J6Z.js → chunk-44HZLHDV.js} +10 -1
- package/dist/chunk-44HZLHDV.js.map +1 -0
- package/dist/chunk-4HO66323.js +7 -0
- package/dist/chunk-4HO66323.js.map +1 -0
- package/dist/{chunk-BWXLTWF7.js → chunk-4ZIJ3BKZ.js} +6 -4
- package/dist/chunk-4ZIJ3BKZ.js.map +1 -0
- package/dist/{chunk-NPMW5HUS.js → chunk-5RULXBJ7.js} +879 -237
- package/dist/chunk-5RULXBJ7.js.map +1 -0
- package/dist/chunk-AN3VQARU.js +684 -0
- package/dist/chunk-AN3VQARU.js.map +1 -0
- package/dist/{chunk-XVVNKASZ.js → chunk-ANCGXUQJ.js} +118 -73
- package/dist/chunk-ANCGXUQJ.js.map +1 -0
- package/dist/{chunk-3HBPKR5G.js → chunk-D7LM5QZN.js} +3 -3
- package/dist/{chunk-4ZB3X6BQ.js → chunk-E5UEELA7.js} +16 -2
- package/dist/{chunk-4ZB3X6BQ.js.map → chunk-E5UEELA7.js.map} +1 -1
- package/dist/{chunk-ZID3WQID.js → chunk-FQI5PFE7.js} +9 -71
- package/dist/chunk-FQI5PFE7.js.map +1 -0
- package/dist/chunk-G3P3ZDB4.js +69 -0
- package/dist/chunk-G3P3ZDB4.js.map +1 -0
- package/dist/{chunk-YRGSEY5L.js → chunk-G7KAVJ3F.js} +2 -2
- package/dist/{chunk-YRGSEY5L.js.map → chunk-G7KAVJ3F.js.map} +1 -1
- package/dist/{chunk-62DQAWPF.js → chunk-IFYER7O4.js} +367 -42
- package/dist/chunk-IFYER7O4.js.map +1 -0
- package/dist/chunk-O2MCWFXQ.js +499 -0
- package/dist/chunk-O2MCWFXQ.js.map +1 -0
- package/dist/chunk-QZXKQB7Y.js +414 -0
- package/dist/chunk-QZXKQB7Y.js.map +1 -0
- package/dist/{db-YAI5AQOI.js → db-N6MPVMEF.js} +8 -2
- package/dist/{extract-bundle-ONWZVV55.js → extract-bundle-M4SDJG3V.js} +284 -98
- package/dist/extract-bundle-M4SDJG3V.js.map +1 -0
- package/dist/index.cjs +129 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +4 -4
- package/dist/location-data-repository-Z4NQOU5Y.js +35 -0
- package/dist/{server-GKUTC73B.js → server-ZIGAFKOL.js} +10791 -7629
- package/dist/server-ZIGAFKOL.js.map +1 -0
- package/dist/site-extract-repository-PGQZNW6V.js +62 -0
- package/dist/site-extract-repository-PGQZNW6V.js.map +1 -0
- package/dist/{worker-645BZPEK.js → worker-EBB6CTGW.js} +7 -7
- package/docs/hosted-location-data.md +108 -0
- package/docs/mcp-tool-craft-lint.generated.md +6 -3
- package/docs/mcp-tool-manifest.generated.json +1253 -222
- package/docs/mcp-tool-quality-spec.md +1 -1
- package/docs/specs/connected-services-control-plane-decoupling-spec.md +1044 -0
- package/docs/specs/kernel-stealth-captcha-test-matrix.md +278 -0
- package/docs/specs/multimodal-image-memory-architecture-spec.md +1022 -0
- package/docs/specs/unified-credit-and-scheduled-execution-billing-spec.md +36 -27
- package/package.json +6 -5
- package/dist/chunk-62DQAWPF.js.map +0 -1
- package/dist/chunk-BWXLTWF7.js.map +0 -1
- package/dist/chunk-M2S27J6Z.js.map +0 -1
- package/dist/chunk-NPMW5HUS.js.map +0 -1
- package/dist/chunk-R7EETU7Z.js +0 -419
- package/dist/chunk-R7EETU7Z.js.map +0 -1
- package/dist/chunk-U44TPRST.js +0 -130
- package/dist/chunk-U44TPRST.js.map +0 -1
- package/dist/chunk-XVVNKASZ.js.map +0 -1
- package/dist/chunk-YR4LJ6AQ.js +0 -7
- package/dist/chunk-YR4LJ6AQ.js.map +0 -1
- package/dist/chunk-YV2FUEBX.js +0 -851
- package/dist/chunk-YV2FUEBX.js.map +0 -1
- package/dist/chunk-ZID3WQID.js.map +0 -1
- package/dist/extract-bundle-ONWZVV55.js.map +0 -1
- package/dist/server-GKUTC73B.js.map +0 -1
- package/dist/site-extract-repository-L6BHWVDU.js +0 -30
- /package/dist/{chunk-3HBPKR5G.js.map → chunk-D7LM5QZN.js.map} +0 -0
- /package/dist/{db-YAI5AQOI.js.map → db-N6MPVMEF.js.map} +0 -0
- /package/dist/{site-extract-repository-L6BHWVDU.js.map → location-data-repository-Z4NQOU5Y.js.map} +0 -0
- /package/dist/{worker-645BZPEK.js.map → worker-EBB6CTGW.js.map} +0 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# Kernel stealth, CAPTCHA, proxy, and localization test matrix
|
|
2
|
+
|
|
3
|
+
Status: executable direct-Kernel smoke runner implemented; product-contract gates specified below.
|
|
4
|
+
|
|
5
|
+
## Objective
|
|
6
|
+
|
|
7
|
+
Determine which Kernel configuration reliably reaches and extracts localized Google Search and Maps results, while proving that MCP Scraper preserves the requested egress mode, waits for the managed solver correctly, reports evidence honestly, charges correctly, and cleans up every resource.
|
|
8
|
+
|
|
9
|
+
This is deliberately two test systems:
|
|
10
|
+
|
|
11
|
+
1. A direct Kernel capability matrix isolates browser, proxy, and solver behavior. It has one attempt per cell and no product fallback.
|
|
12
|
+
2. An MCP Scraper product-contract matrix verifies retry policy, extraction, diagnostics, billing, and cleanup after the direct matrix identifies promising configurations.
|
|
13
|
+
|
|
14
|
+
Do not use a production retry result to compare proxy families. Today, `harvest` can switch an explicit `location` request to `none` after two failures. That contaminates the experiment.
|
|
15
|
+
|
|
16
|
+
## What counts as proof
|
|
17
|
+
|
|
18
|
+
- A CAPTCHA was solved only when Kernel emits a terminal `captcha_solve_result` with `status: success` **and** the page becomes usable afterward.
|
|
19
|
+
- A client-side wait expiring is not a solver failure. Record it separately from Kernel `failure`, `timeout`, and `abandoned` outcomes.
|
|
20
|
+
- A Google Sorry page is a challenge outcome, never a ranking result.
|
|
21
|
+
- A new proxy ID does not prove a new exit IP. Record both the proxy resource and observed egress.
|
|
22
|
+
- A residential cell passes only if the requested mode remained effective. Direct or ISP fallback cannot be credited to residential.
|
|
23
|
+
- One successful probabilistic run is a smoke result. Promotion requires repeated success.
|
|
24
|
+
|
|
25
|
+
## Test layers
|
|
26
|
+
|
|
27
|
+
### Layer 0 — deterministic release gates
|
|
28
|
+
|
|
29
|
+
These tests are mocked or fixture-driven, incur no Kernel spend, and must gate every release.
|
|
30
|
+
|
|
31
|
+
| ID | Situation | Test to create | Required assertion |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| U01 | Explicit residential fails | `explicit_location_never_downgrades_without_allowProxyFallback` | No attempt changes to `none` unless the caller explicitly enabled fallback. |
|
|
34
|
+
| U02 | Resolver returns no location proxy | `location_resolution_without_proxy_id_fails_before_browser_launch` | Browser launch never occurs and the terminal code is `proxy_unavailable`. |
|
|
35
|
+
| U03 | Authorized fallback occurs | `fallback_response_reports_requested_mode_effective_mode_and_fallback_used` | Requested, effective, and fallback fields remain distinct. |
|
|
36
|
+
| U04 | Configured fallback is used | `configured_fallback_does_not_claim_residential` | Result cannot be labeled location/residential. |
|
|
37
|
+
| U05 | Managed solver clears a challenge | `challenge_clearance_records_terminal_success_and_stable_page` | Two consecutive clear checks plus successful solver telemetry are required. |
|
|
38
|
+
| U06 | Client waits expire | `challenge_wait_matrix_preserves_client_and_kernel_outcomes` | Exercise 2.5s, 10s, 30s, 60s, and abort; no outcome collapsing. |
|
|
39
|
+
| U07 | Challenge briefly clears and returns | `transient_clear_does_not_pass_stability_check` | Reappearing challenge remains blocked. |
|
|
40
|
+
| U08 | Maps is challenged | `maps_challenge_waits_for_managed_solver_before_rotation` | Maps uses the shared solver wait rather than throwing immediately. |
|
|
41
|
+
| U09 | Maps solver succeeds | `maps_solver_clearance_continues_in_same_session` | Extraction continues without creating a fresh session. |
|
|
42
|
+
| U10 | Maps wait is aborted | `maps_abort_during_solver_wait_closes_session_once` | One close, one delete, no retry after abort. |
|
|
43
|
+
| U11 | Proxy resources differ but exit does not | `distinct_proxy_ids_with_same_observed_ip_set_exit_reused` | Cell is flagged `exitReused`; it is not counted as a fresh exit. |
|
|
44
|
+
| U12 | Egress evidence is missing | `missing_egress_probe_makes_proxy_verdict_unknown_not_pass` | Proxy verdict is unknown. |
|
|
45
|
+
| U13 | Residential geo is wrong | `residential_success_requires_observed_geo_match` | Location mismatch fails the location cell. |
|
|
46
|
+
| U14 | Kernel default proxy is requested | `kernel_default_mode_does_not_disable_default_proxy` | Browser update never sends `disable_default_proxy: true`. |
|
|
47
|
+
| U15 | Direct stealth is requested | `direct_stealth_disables_default_proxy_and_keeps_solver` | Update happens before navigation and solver remains enabled. |
|
|
48
|
+
| U16 | Headless is requested | `requested_browser_mode_matches_kernel_create_and_response` | Request, returned Kernel mode, telemetry, and billing agree. |
|
|
49
|
+
| U17 | A challenged session times out | `solver_timeout_preserves_session_when_handoff_enabled` | Session remains active for a bounded signed handoff instead of immediate deletion. |
|
|
50
|
+
| U18 | Handoff is resumed | `resume_after_handoff_uses_original_session_and_cleans_up` | Original session is used, then deleted exactly once. |
|
|
51
|
+
| U19 | Handoff is unauthorized or expired | `expired_or_wrong_owner_handoff_is_rejected` | No session URL or token is leaked. |
|
|
52
|
+
| U20 | Visible desktop pack says Businesses | `extracts_businesses_local_pack_fixture` | Cards, CIDs, URLs, ratings, and positions are structured. |
|
|
53
|
+
| U21 | Visible desktop pack says Places | `extracts_places_local_pack_fixture` | Parser does not depend on one English heading. |
|
|
54
|
+
| U22 | Visible mobile pack uses different markup | `extracts_mobile_local_pack_fixture` | Mobile cards are structured. |
|
|
55
|
+
| U23 | Pack is visible but parser returns zero | `visible_pack_with_zero_parsed_cards_emits_parser_miss` | A parser miss is explicit, not a silent empty pack. |
|
|
56
|
+
| U24 | SERP succeeds and optional snapshots throw | `successful_serp_survives_page_snapshot_transport_failure` | SERP is returned with a snapshot warning. |
|
|
57
|
+
| U25 | One snapshot fails | `partial_success_charges_only_started_snapshots` | SERP plus attempted snapshots are settled; no blanket extraction failure. |
|
|
58
|
+
| U26 | Direct session billing retries | `browser_session_settlement_is_atomic_and_idempotent` | Retry cannot double-charge after debit succeeds and row update fails. |
|
|
59
|
+
| U27 | Challenge diagnostics are formatted | `outbound_challenge_diagnostics_redact_tokens_and_full_ip` | Sorry query tokens, task IDs, session IDs, and full IPs stay internal. |
|
|
60
|
+
| U28 | Matrix artifact repeats a cell | `matrix_recorder_preserves_every_repetition` | Key is `runId + cellId + repetition`; no last-write collapse. |
|
|
61
|
+
| U29 | Budget abort fires | `matrix_budget_abort_still_cleans_every_resource` | Browser, session, proxy, profile, and terminal artifact are all finalized. |
|
|
62
|
+
|
|
63
|
+
Required local-pack fixtures:
|
|
64
|
+
|
|
65
|
+
- `tests/fixtures/serp/local-pack-businesses-desktop.html`
|
|
66
|
+
- `tests/fixtures/serp/local-pack-places-desktop.html`
|
|
67
|
+
- `tests/fixtures/serp/local-pack-mobile.html`
|
|
68
|
+
|
|
69
|
+
### Layer 1 — direct Kernel capability matrix
|
|
70
|
+
|
|
71
|
+
Run sequentially. Each cell gets one browser, one target navigation, no retry, and no fallback. Enable only Kernel's default operational telemetry set so CAPTCHA events are captured without recording page content or credentials.
|
|
72
|
+
|
|
73
|
+
For the standard reCAPTCHA demo, the runner attempts one checkbox click to trigger the challenge when the widget permits it. If Kernel's automatic solver has already locked the widget in a loading state, it does not take over or solve manually: it waits and requires a response token plus a usable submitted demo page.
|
|
74
|
+
|
|
75
|
+
#### Capability controls on Google's reCAPTCHA demo
|
|
76
|
+
|
|
77
|
+
| Cell | Stealth | Egress | Solver expected | Purpose |
|
|
78
|
+
|---|---:|---|---:|---|
|
|
79
|
+
| A | off | direct | no | Direct negative control. |
|
|
80
|
+
| B | on | Kernel default static ISP | yes | Kernel's recommended bundled mode. |
|
|
81
|
+
| C | off | explicit ISP | no | Network-matched negative control for D. |
|
|
82
|
+
| D | on | same explicit ISP | yes | Isolates solver effect on a stable ISP exit. |
|
|
83
|
+
| E | off | explicit residential | no | Network-matched negative control for F. |
|
|
84
|
+
| F | on | same explicit residential | yes | Tests managed solver with residential egress. |
|
|
85
|
+
| G | on | direct after `disable_default_proxy` | yes | Network-matched solver comparison against A. |
|
|
86
|
+
|
|
87
|
+
Cell pass rules:
|
|
88
|
+
|
|
89
|
+
- Negative control: the test is valid if the challenge remains and no managed-solver success is claimed.
|
|
90
|
+
- Solver cell: `captcha_solve_result.status === "success"`, response token appears, and submitted demo becomes usable.
|
|
91
|
+
- No challenge exercised: `not_challenged`, not a solver pass.
|
|
92
|
+
- hCaptcha entitlement absence: `unsupported_for_org`, not solver failure.
|
|
93
|
+
|
|
94
|
+
#### Initial Google Search cells
|
|
95
|
+
|
|
96
|
+
Fixed input:
|
|
97
|
+
|
|
98
|
+
- query: `florist Nashville TN`
|
|
99
|
+
- location/UULE: `Nashville, TN`
|
|
100
|
+
- target: `genysflowers.com`
|
|
101
|
+
- device: desktop
|
|
102
|
+
- wait cap: 30 seconds for smoke; longer caps are separate cells
|
|
103
|
+
|
|
104
|
+
| Cell | Egress | Browser | Session | Purpose |
|
|
105
|
+
|---|---|---|---|---|
|
|
106
|
+
| S01 | direct + managed solver | headless | fresh | Known clean-egress baseline. |
|
|
107
|
+
| S02 | Kernel default ISP + managed solver | headless | fresh | Test the configuration Kernel says generally has better pass rates. |
|
|
108
|
+
| S03 | ZIP 37203 residential + managed solver | headless | fresh | Compare exact residential targeting. |
|
|
109
|
+
| S04 | direct + managed solver | headful | fresh | Isolate headless detection on direct egress. |
|
|
110
|
+
| S05 | Kernel default ISP + managed solver | headful | fresh | Isolate headless detection on Kernel's bundled proxy. |
|
|
111
|
+
| S06 | ZIP 37203 residential + managed solver | headful | fresh | Isolate headless detection for residential. |
|
|
112
|
+
| S07 | ZIP 37209 residential + managed solver | headless | separate run | Detect ZIP-specific proxy reputation or inventory. |
|
|
113
|
+
| S08 | winning proxy | headless | second navigation in same session | Measure session warming. |
|
|
114
|
+
| S09 | winning proxy | headless | new session with warmed profile | Measure persisted state. |
|
|
115
|
+
|
|
116
|
+
For every cell capture:
|
|
117
|
+
|
|
118
|
+
- requested and returned stealth/headless values;
|
|
119
|
+
- whether Kernel's default proxy was disabled;
|
|
120
|
+
- proxy type, resolution source, and masked resource suffix;
|
|
121
|
+
- diagnostic egress IP, city, region, postal code, country, and organization;
|
|
122
|
+
- target-domain challenge classification;
|
|
123
|
+
- every terminal `captcha_solve_result` field;
|
|
124
|
+
- client wait duration versus Kernel solver duration;
|
|
125
|
+
- organic count, local-pack count, Geny's organic ranks, and location evidence;
|
|
126
|
+
- browser close, session deletion, proxy deletion, profile deletion;
|
|
127
|
+
- elapsed session time and modeled browser cost.
|
|
128
|
+
|
|
129
|
+
Residential IPs can rotate per connection. An IP diagnostic against another host is supporting evidence, not proof of the exact IP Google saw.
|
|
130
|
+
|
|
131
|
+
### Layer 2 — direct Google Maps matrix
|
|
132
|
+
|
|
133
|
+
Use `florist` + `Nashville, TN`, target business `Geny's Flowers`.
|
|
134
|
+
|
|
135
|
+
| Cell | Egress | Browser | ZIP |
|
|
136
|
+
|---|---|---|---|
|
|
137
|
+
| M01 | direct + managed solver | headless | — |
|
|
138
|
+
| M02 | Kernel default ISP + managed solver | headless | — |
|
|
139
|
+
| M03 | residential + managed solver | headless | 37203 |
|
|
140
|
+
| M04 | residential + managed solver | headless | 37209 |
|
|
141
|
+
| M05 | winning egress | headful | winner |
|
|
142
|
+
| M06 | winning egress | headless | same-session second search |
|
|
143
|
+
|
|
144
|
+
The same challenge state machine and telemetry requirements apply to Search and Maps.
|
|
145
|
+
|
|
146
|
+
### Layer 3 — MCP Scraper product-contract matrix
|
|
147
|
+
|
|
148
|
+
Run only after Layer 1 identifies viable configurations.
|
|
149
|
+
|
|
150
|
+
| Cell | Product surface | Requested mode | Hard assertions |
|
|
151
|
+
|---|---|---|---|
|
|
152
|
+
| P01 | `/serp-intelligence/capture` | `none` | Effective direct, UULE present, cleanup true, no fallback. |
|
|
153
|
+
| P02 | `/serp-intelligence/capture` | `location`, 37203 | Effective residential, geo evidence, no silent direct success. |
|
|
154
|
+
| P03 | `/maps/search` | `none` | Shared solver wait, structured results or explicit terminal challenge. |
|
|
155
|
+
| P04 | `/maps/search` | `location`, 37203 | Effective residential, no mode downgrade, complete attempt evidence. |
|
|
156
|
+
| P05 | SERP plus snapshots | winner | Optional snapshot failure preserves the SERP. |
|
|
157
|
+
| P06 | challenged handoff | winner | Signed first-party handoff resumes original session and settles once. |
|
|
158
|
+
|
|
159
|
+
Billing assertions:
|
|
160
|
+
|
|
161
|
+
- Search holds 14 Credits, settles to 4 when headless or 14 when headful, and refunds a failed capture.
|
|
162
|
+
- Maps Search costs 5 Credits and refunds failure.
|
|
163
|
+
- Direct Kernel experiments do not touch the MCP Scraper wallet.
|
|
164
|
+
- Browser mode used for billing must equal the mode Kernel reports.
|
|
165
|
+
|
|
166
|
+
## Adaptive replication
|
|
167
|
+
|
|
168
|
+
Do not run the full Cartesian product immediately.
|
|
169
|
+
|
|
170
|
+
1. Run A–G once as capability smoke.
|
|
171
|
+
2. Run S01–S06 once, then run S07 as a separate ZIP-targeted comparison.
|
|
172
|
+
3. Repeat the two best solver-enabled configurations three times on:
|
|
173
|
+
- `florist Nashville TN`
|
|
174
|
+
- `wedding florist Nashville TN`
|
|
175
|
+
- `flower delivery Nashville TN`
|
|
176
|
+
4. Cross only the winner with headful/headless, same/fresh session, and cold/warm profile.
|
|
177
|
+
5. Run Search and Maps ten times each at controlled cadence before promotion.
|
|
178
|
+
6. Run a 24-hour soak only after the winner is stable.
|
|
179
|
+
|
|
180
|
+
Randomize configuration order within each query block. Do not run Google cells concurrently; concurrency itself changes rate-limit pressure and invalidates the comparison.
|
|
181
|
+
|
|
182
|
+
## Promotion gates
|
|
183
|
+
|
|
184
|
+
A configuration is promotable only when:
|
|
185
|
+
|
|
186
|
+
- every successful run's effective egress equals its requested egress;
|
|
187
|
+
- there are zero silent fallbacks and zero cleanup leaks;
|
|
188
|
+
- solver success has terminal Kernel telemetry plus usable page evidence;
|
|
189
|
+
- requested location is matched or the result is explicitly unknown/failing;
|
|
190
|
+
- a one-off winner reproduces at least three times;
|
|
191
|
+
- the final soak shows at least a 20 percentage-point success-rate improvement over direct control;
|
|
192
|
+
- median and p95 latency remain within the product timeout budget;
|
|
193
|
+
- Search and Maps both use the same challenge state machine;
|
|
194
|
+
- billing settlement matches the effective browser mode.
|
|
195
|
+
|
|
196
|
+
## Cost and stop controls
|
|
197
|
+
|
|
198
|
+
Phase 1 defaults:
|
|
199
|
+
|
|
200
|
+
- concurrency: 1;
|
|
201
|
+
- maximum sessions: 13 for the executable smoke runner, 18 for the expanded phase;
|
|
202
|
+
- per-session wall cap: 60 seconds;
|
|
203
|
+
- no automatic cell retry;
|
|
204
|
+
- no automatic proxy-family fallback;
|
|
205
|
+
- modeled browser spend cap: $0.05 for one expanded phase, excluding proxy/bandwidth charges;
|
|
206
|
+
- full IPs only in local mode-0600 JSON; rollups mask IPs and resource IDs.
|
|
207
|
+
|
|
208
|
+
Stop immediately on authentication/plan/quota failure, two failed session deletions, an effective-mode mismatch, three consecutive proxy-family setup failures, or the session/time/spend cap.
|
|
209
|
+
|
|
210
|
+
## Executable runner
|
|
211
|
+
|
|
212
|
+
Implemented files:
|
|
213
|
+
|
|
214
|
+
- `tests/live/harness/kernel-captcha-matrix.ts`
|
|
215
|
+
- `tests/live/serp/kernel-stealth-captcha-matrix.live.test.ts`
|
|
216
|
+
|
|
217
|
+
Run the direct smoke matrix only:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
LIVE=1 \
|
|
221
|
+
KERNEL_CAPTCHA_MATRIX=1 \
|
|
222
|
+
KERNEL_CAPTCHA_MATRIX_SCOPE=smoke \
|
|
223
|
+
KERNEL_CAPTCHA_MATRIX_WAIT_MS=30000 \
|
|
224
|
+
npx vitest run --reporter=basic --config vitest.live.config.ts \
|
|
225
|
+
tests/live/serp/kernel-stealth-captcha-matrix.live.test.ts
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The runner creates isolated ISP and residential proxy resources, runs cells sequentially, reads CAPTCHA telemetry through Kernel's current REST endpoint, writes a mode-0600 JSON artifact and masked Markdown rollup, and deletes every browser session and disposable proxy.
|
|
229
|
+
|
|
230
|
+
## Exploratory evidence from 2026-07-17
|
|
231
|
+
|
|
232
|
+
- The seven capability controls produced no attributable managed-solver proof. Several stealth cells emitted `captcha_solve_result` events marked `other:success`, but the target challenge remained visible and the event host/path fields were null. The runner correctly does not count those events as a solve.
|
|
233
|
+
- S01–S03 (headless direct, Kernel-default ISP, and ZIP-targeted residential) all reached Google's unusual-traffic challenge in the initial run.
|
|
234
|
+
- S04 and S05 (headful direct and headful Kernel-default ISP) returned usable localized Search pages without encountering a challenge.
|
|
235
|
+
- S06 (headful residential) used Nashville diagnostic egress but remained challenged after the 30-second wait despite repeated unattributed `other:success` events.
|
|
236
|
+
- These are one-run exploratory outcomes, not promotion evidence. No configuration has yet proven managed CAPTCHA solving, and any apparent winner must be replicated under randomized order and controlled cadence.
|
|
237
|
+
|
|
238
|
+
Masked evidence:
|
|
239
|
+
|
|
240
|
+
- `output/kernel-stealth-captcha-matrix-2026-07-17.md`
|
|
241
|
+
- `output/kernel-stealth-captcha-matrix-2026-07-17-headful.md`
|
|
242
|
+
|
|
243
|
+
## Concurrent default-ISP versus direct evidence from 2026-07-17
|
|
244
|
+
|
|
245
|
+
One 20-request headful, stealth-enabled burst prepared ten city pairs and released every Google navigation within 3 milliseconds of one shared barrier. The Kernel-default lane omitted `proxy_id` and kept the default proxy enabled; the direct lane omitted `proxy_id` and explicitly sent `disable_default_proxy: true`.
|
|
246
|
+
|
|
247
|
+
- Clean extracted-SERP success: default 0/10; direct 7/10.
|
|
248
|
+
- Google `/search` access without a challenge: default 2/10; direct 9/10.
|
|
249
|
+
- Google Sorry-page blocks: default 8/10; direct 1/10.
|
|
250
|
+
- Every cell reported its intended effective mode; there was no retry, fallback, setup failure, or cleanup leak.
|
|
251
|
+
- Four unblocked pages had no results at the first post-`domcontentloaded` inspection, so this one burst reports access and extraction separately. The runner now waits an identical bounded 1.5 seconds before inspection on future runs.
|
|
252
|
+
|
|
253
|
+
This is evidence for this account's simultaneous 20-session workload, not a general claim about all Kernel default ISP exits. See `output/kernel-default-vs-direct-serp-burst-2026-07-17.md` and `docs/decisions/2026-07-17-kernel-default-isp-serp-burst-experiment.md`.
|
|
254
|
+
|
|
255
|
+
## Current known gaps the matrix must expose
|
|
256
|
+
|
|
257
|
+
- Search waits only 2.5 seconds by default for Kernel's solver.
|
|
258
|
+
- Maps does not call the shared solver-wait path.
|
|
259
|
+
- Explicit location can silently switch to direct egress.
|
|
260
|
+
- BrowserDriver cannot represent Kernel's default stealth ISP because it disables the default whenever no explicit proxy ID is present.
|
|
261
|
+
- `config.headless` can disagree with the mode actually sent to Kernel.
|
|
262
|
+
- Current Kernel SDK dependency is 0.52.0; the current npm release is 0.79.0, and 0.52.0 exposes no telemetry surface in its types. The runner uses Kernel's documented REST telemetry endpoint until the SDK is upgraded.
|
|
263
|
+
- Existing live rollups key by fallback path and collapse repeated cells.
|
|
264
|
+
- Local-pack extraction has no real DOM fixture tests.
|
|
265
|
+
- Optional page-snapshot transport failure can discard an otherwise successful SERP.
|
|
266
|
+
|
|
267
|
+
## Official Kernel references
|
|
268
|
+
|
|
269
|
+
- [Stealth mode and CAPTCHA handling](https://www.kernel.sh/docs/browsers/bot-detection/stealth)
|
|
270
|
+
- [Bot-detection recommendations](https://www.kernel.sh/docs/browsers/bot-detection/overview)
|
|
271
|
+
- [Telemetry overview](https://kernel.sh/docs/browsers/telemetry/overview.md)
|
|
272
|
+
- [Telemetry categories](https://kernel.sh/docs/browsers/telemetry/categories.md)
|
|
273
|
+
- [CAPTCHA telemetry schema](https://kernel.sh/docs/api-reference/browser-telemetry/stream-telemetry-events-via-sse.md)
|
|
274
|
+
- [Telemetry readback](https://kernel.sh/docs/api-reference/browser-telemetry/read-telemetry-events-for-a-browser-session.md)
|
|
275
|
+
- [ISP proxies](https://www.kernel.sh/docs/proxies/isp)
|
|
276
|
+
- [Residential proxies](https://www.kernel.sh/docs/proxies/residential)
|
|
277
|
+
- [Profiles](https://www.kernel.sh/docs/auth/profiles)
|
|
278
|
+
- [Browser pools](https://www.kernel.sh/docs/browsers/pools/overview)
|