Skip to content

feat(capture): MITM proxy — streaming detection + record-to-trace #56

Description

@sepehr-safari

Scope

The headless heart of the flagship. A cp ↔ studio ↔ csms WebSocket
man-in-the-middle: accept the downstream charge point, dial the upstream CSMS,
pump frames both ways, decode each into a canonical event (#55), run detection
as events accumulate, and record the canonical trace to disk. Fully headless
and CI-testable — no GUI, no runner.

Deliverables

  • src/capture/proxy.zig: socket accept/dial + bidirectional frame pump.
    Studio is transparent — every frame is forwarded verbatim to the other
    peer while a copy is tapped for decode. Ping/pong and close are relayed
    faithfully.
  • Streaming detection: run the engine's detection over the accumulated
    event window as events arrive (batched), surfacing the current failure set.
    Several rules are O(n²), capped at detection.max_events_for_detection;
    until the O(n) rewrite (perf(engine): O(n) detection rules for dataset-scale traces #36), streaming re-runs within that cap and says so.
    The final failure set on the recorded trace must equal a cold offline
    detectFailures over the same trace.
  • Record-to-trace: write each canonical event as a JSONL line (the engine's
    .jsonl input format) so a recording re-opens in Studio and the toolkit
    unchanged.
  • In-process integration test (the S5 exit criterion): wire a scripted
    charge-point client and a scripted/echo CSMS server through the proxy
    in-process; assert (a) frames relay correctly end-to-end, (b) the recorded
    trace re-parses, and (c) re-detection on the recording yields the identical
    failure set. These are test doubles in the harness — not the shipped
    CP-sim / CSMS-mock products (those stay post-0.5, per the non-goals).

Hardening

The proxy sits on untrusted sockets on both sides: carry #54's frame bounds
through; cap per-session event/byte totals; never let a hostile peer drive
unbounded allocation; a decode error on one frame is recorded/skipped, not
fatal to the session.

Acceptance criteria

  • The in-process CP ↔ proxy ↔ CSMS integration test passes in CI on macOS +
    Linux: relay correctness + recording re-parses + re-detection identical.
  • Both native build and native test green.

Dependencies

#54, #55. Related: #36 (O(n) detection makes true per-event streaming cheap).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions