Summary
DAP_TRACE=1 writes every frame of every MinimalDapClient in the proxy worker — parent connection, adopted child connection, release connections — into one dap-trace-<sessionId>.ndjson, with records of the shape {ts, direction, payload}. There is no field saying which connection carried the frame, and each client numbers its own seq space independently starting at 1.
For single-connection adapters that's fine. For js-debug's parent/child topology it makes the trace ambiguous exactly where it matters most: the #513 investigation needed to answer "did this pause go to the root session or the target session?", and the trace cannot say — two initialize requests with seq: 1 from two different sockets are byte-identical in the file.
What it cost in practice
During the #513 root-cause work (this trace: parent attach at 16:18:24.175, child adoption at .337, the swallowed pause at .342):
16:18:24.340 out request initialize {"clientID": "mcp-child-175aaa8b…"} <- child (identifiable only by clientID)
16:18:24.342 out request pause {"threadId": 0} <- which socket??
16:18:24.343 out request setExceptionBreakpoints <- child config
Whether the pause went out on the parent socket (js-debug root: silent no-op) or the child socket (swallowed pre-attach) had to be reconstructed by correlating wall-clock timestamps against [MinimalDapClient] Dispatching '<cmd>' to child session lines in a different log file — workable once, but exactly the kind of manual joining a trace exists to avoid.
Suggested
Add a connection tag to each trace record, e.g. conn: "parent" / conn: "child:<pendingId8>" / conn: "release:<pendingId8>":
MinimalDapClient already knows which role it plays at construction time for children (ChildSessionManager creates them) — a constructor option traceLabel defaulting to "parent" would do it.
- Keep the record shape otherwise unchanged so existing tooling that reads
{ts, direction, payload} keeps working.
Optionally also include the client's clientID-style instance id in the header line the worker logs when tracing is enabled, so a reader can map labels to sockets without opening the code.
Environment
main @ 946054b (post-#514/#515), Linux, Node 22.22.3. Found while root-causing #513.
Summary
DAP_TRACE=1writes every frame of everyMinimalDapClientin the proxy worker — parent connection, adopted child connection, release connections — into onedap-trace-<sessionId>.ndjson, with records of the shape{ts, direction, payload}. There is no field saying which connection carried the frame, and each client numbers its ownseqspace independently starting at 1.For single-connection adapters that's fine. For js-debug's parent/child topology it makes the trace ambiguous exactly where it matters most: the #513 investigation needed to answer "did this
pausego to the root session or the target session?", and the trace cannot say — twoinitializerequests withseq: 1from two different sockets are byte-identical in the file.What it cost in practice
During the #513 root-cause work (this trace: parent attach at
16:18:24.175, child adoption at.337, the swallowed pause at.342):Whether the pause went out on the parent socket (js-debug root: silent no-op) or the child socket (swallowed pre-attach) had to be reconstructed by correlating wall-clock timestamps against
[MinimalDapClient] Dispatching '<cmd>' to child sessionlines in a different log file — workable once, but exactly the kind of manual joining a trace exists to avoid.Suggested
Add a connection tag to each trace record, e.g.
conn: "parent"/conn: "child:<pendingId8>"/conn: "release:<pendingId8>":MinimalDapClientalready knows which role it plays at construction time for children (ChildSessionManagercreates them) — a constructor optiontraceLabeldefaulting to"parent"would do it.{ts, direction, payload}keeps working.Optionally also include the client's
clientID-style instance id in the header line the worker logs when tracing is enabled, so a reader can map labels to sockets without opening the code.Environment
main @ 946054b (post-#514/#515), Linux, Node 22.22.3. Found while root-causing #513.