Files
lume-ctrl/docs/m0-spike.md
T
2026-08-20 22:10:00 +08:00

3.9 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 ready startup page through /json/list, connects to that target's webSocketDebuggerUrl, and navigates to a controlled loopback fixture. The fixture runs in a separate process and waits for a CDP trigger before generating 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], WebSocket payloads are never persisted, and bodies over the configured limit are represented by {state:"omitted",reason:"size_limit",bytes:N}.

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 for controlled responses.
Body size limit Pass 2 KiB fixture is 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.
Client disconnect Pass A second CDP client disconnects; browser process remains alive.
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.
Top-level loopback navigation Intermittent This build can report Inspector.detached: Render process gone before the request reaches the fixture; rerun preserves the same local reproduction condition.

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 for the observed Inspector.detached startup failure. Every failed attempt is retained in attempt_failures; other errors fail immediately.