Summary
Three related local-transport hardening issues:
1. Queue unbounded
_transport.py:194 enqueues outbound messages with no cap. The re-queue path on disconnect (_transport.py:176) also uses put_nowait. A long extension outage = unbounded memory growth.
2. Reconnect loops forever
_transport.py:148-184 retries localhost:9847 forever (capped at 30s per attempt). A user who deploys with no api_key (default = local mode) and no VS Code extension running keeps a daemon thread retrying forever while events queue up. Typical misconfig; silent failure.
3. No auth on the WS port
The SDK sends serialized WindowSummary payloads to whatever process responds first on 127.0.0.1:9847. Any local process can squat the port and silently sink all telemetry. Low risk on a dev machine, but easy to harden.
Fix
- Cap the queue (e.g.
asyncio.Queue(maxsize=1000)) with drop-oldest. Log a single warning on first drop; reset on reconnect. - After N consecutive failed connects (e.g. 10), give up and emit
on_error once. Detect "no api_key AND first connect failed" and warn loudly. - Lightweight handshake: SDK opens, sends
{"type":"hello","sdk":"recost-py","version":...}; extension replies {"type":"ack"}. On no-ack within N ms, drop the connection without sending payloads. Coordinated change in the VS Code extension repo.
Files
recost/_transport.pytests/test_transport.py- coordinated change in the extension repo
Priority
P1 — common misconfig (no extension) silently leaks memory; trivially squat-able local port.
Summary
Three related local-transport hardening issues:
1. Queue unbounded
_transport.py:194enqueues outbound messages with no cap. The re-queue path on disconnect (_transport.py:176) also usesput_nowait. A long extension outage = unbounded memory growth.2. Reconnect loops forever
_transport.py:148-184retrieslocalhost:9847forever (capped at 30s per attempt). A user who deploys with noapi_key(default = local mode) and no VS Code extension running keeps a daemon thread retrying forever while events queue up. Typical misconfig; silent failure.3. No auth on the WS port
The SDK sends serialized
WindowSummarypayloads to whatever process responds first on127.0.0.1:9847. Any local process can squat the port and silently sink all telemetry. Low risk on a dev machine, but easy to harden.Fix
asyncio.Queue(maxsize=1000)) with drop-oldest. Log a single warning on first drop; reset on reconnect.on_erroronce. Detect "noapi_keyAND first connect failed" and warn loudly.{"type":"hello","sdk":"recost-py","version":...}; extension replies{"type":"ack"}. On no-ack within N ms, drop the connection without sending payloads. Coordinated change in the VS Code extension repo.Files
recost/_transport.pytests/test_transport.pyPriority
P1 — common misconfig (no extension) silently leaks memory; trivially squat-able local port.