Files
lume-ctrl/docs/m0-spike.md
T

4.3 KiB

M0 CDP network spike

Run against the Clark binary declared by clark-browser 0.2.1:

cd ../clark-browser
python3 -m clarkbrowser fetch
cd ../lume-ctrl
M0_CDP_PORT=40746 M0_HTTP_PORT=40745 \
  CLARK_BINARY_PATH="$HOME/.clarkbrowser/chromium-148.0.7778.96/chrome" npm run spike
npm test

The two explicit loopback ports make the recorded run directly comparable; omit them to select free ports automatically, or change them if already occupied.

The spike starts only loopback listeners and uses generated, one-day self-signed TLS material in a temporary directory. Chromium accepts that local certificate with --ignore-certificate-errors; no proxy, CA installation, traffic interception, VNC, or external fixture is involved. artifacts/m0-events.sample.jsonl is the sanitized event output and artifacts/m0-report.json is the run result/resource snapshot.

Connection and schema

Clark is launched directly with --remote-debugging-address=127.0.0.1. The runner waits on /json/version, discovers the startup page through /json/list, connects to its webSocketDebuggerUrl, and navigates to the already-listening loopback fixture before triggering test traffic. This avoids clarkserve's current 0.0.0.0 default; a protected gateway and short-lived credentials remain required outside a local Spike.

Every JSONL line has schema_version, session_id, target_id, and kind. HTTP records use request_id; WebSocket records use the CDP requestId as connection_id. Kind-specific fields are nested under request, response, headers, body, or error. Query strings are removed, sensitive headers are replaced by [REDACTED], and WebSocket payloads are never persisted. Response bodies are safe by default: a fetched body is recorded as {state:"fetched",storage:"omitted",reason:"default_body_policy",bytes:N} with no content; oversize and unavailable bodies retain distinct structured states.

Coverage and limits

Case Clark 0.2.1 / Chromium 148.0.7778.96 Evidence or limit
HTTP request → response → finished Pass Same request_id asserted for /ok, /large, and /secure.
Failed HTTP request Pass Unused loopback port produces loadingFailed; error text retained.
HTTPS without MITM Pass Direct browser connection to local TLS fixture; no network intermediary.
WebSocket lifecycle and frames Pass Created, handshake, sent, received, and closed share one connection_id; payload omitted.
getResponseBody success Pass Called after loadingFinished; fetched bytes are recorded but content is omitted by default.
Sensitive response body Pass Random secret fixture is fetched; serialized JSONL is asserted not to contain its value.
Body size limit Pass 2 KiB fixture is reported as size_limit and not persisted with the 1 KiB default.
Body unavailable Pass Calling on the failed request returns the original CDP error as structured cdp_error.
Target close Pass Target connection closes; browser process remains alive.
CDP disconnect/reconnect Pass Browser-side target close triggers the real socket close callback; the browser stays alive and a new target accepts a verified CDP command.
Cookie / Authorization / Set-Cookie Pass Network.*ExtraInfo values are redacted before JSONL serialization.
Cache-specific body availability Not covered Cache behavior varies by response/cache mode; retain optional-body semantics in M1.
Sustained high-rate WebSocket Not covered M0 stores metadata only; add frame/event caps before M1 load testing.
Multi-target/session isolation Not covered Explicitly M1 scope.
Startup Page.navigate Intermittent This build can report Inspector.detached: Render process gone; the exact startup failure is bounded and recorded.

The resource numbers are a one-time ps snapshot of the browser process tree, not a benchmark. Repeat under the intended container limits before setting capacity targets.

The runner restarts Clark at most three times only from the local startup navigation/readiness block, and only after CDP reports the exact detached reason Render process gone.. Every failed attempt is retained in attempt_failures; a timeout without that reason and every post-startup error fail immediately with the original message.