fix(gateway): log websocket handshake phase#93402
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 7, 2026, 11:25 PM ET / 03:25 UTC. Summary PR surface: Source +39, Tests +116. Total +155 across 5 files. Reproducibility: yes. by source inspection: current main's timeout and pre-connect close paths omit phase metadata, while the PR body includes after-fix live output from a real local Node http/ws server and client. I did not rerun the runtime repro in this read-only review. Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this focused Gateway diagnostics change after maintainer review and exact-head checks pass, then let the linked canonical issue close through the merge. Do we have a high-confidence way to reproduce the issue? Yes, by source inspection: current main's timeout and pre-connect close paths omit phase metadata, while the PR body includes after-fix live output from a real local Node http/ws server and client. I did not rerun the runtime repro in this read-only review. Is this the best way to solve the issue? Yes. Tracking a closed monotonic phase in the existing Gateway WebSocket connection and message-handler lifecycle is narrower than adding protocol, config, client, or provider surface, and prior review feedback corrected the credential-phase placement and phase naming. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 082bd4513088. Label changesLabel justifications:
Evidence reviewedPR surface: Source +39, Tests +116. Total +155 across 5 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
| deviceTokenCandidateSource, | ||
| } = connectAuthState; | ||
| if (hasSharedAuth || bootstrapTokenCandidate || deviceTokenCandidate || device) { | ||
| advanceHandshakePhase("auth_credentials_received"); |
There was a problem hiding this comment.
Small placement question: this runs after resolveConnectAuthState(...), but that helper already performs async auth work. If the connection stalls there, the last phase would still be ws_upgrade_started even though credential material was present in the connect params. Would it be better to advance this phase immediately after observing raw auth/device material?
| "auth_credentials_received", | ||
| "auth_validated", | ||
| "session_attached", | ||
| "subscriptions_registered", |
There was a problem hiding this comment.
I think this phase name may be misleading. The current connect flow does not actually register session/message subscriptions here; those happen later through RPC methods such as sessions.subscribe and sessions.messages.subscribe.
This point seems closer to initial hello/snapshot/features preparation, so maybe initial_state_prepared or hello_payload_prepared would describe the existing flow more accurately.
There was a problem hiding this comment.
Good catch. Addressed in c0c91c6: moved auth_credentials_received before async auth resolution and renamed subscriptions_registered to hello_payload_prepared.
c0c91c6 to
d3f16bf
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
d3f16bf to
022581d
Compare
|
Land-ready maintainer proof for exact head
The original Windows/npm environment was not rerun. The changed phase tracker is platform-independent; Linux Node 24 proof and hosted cross-platform CI cover the touched behavior. |
|
Merged via squash.
|
* fix(gateway): log websocket handshake phase * fix(gateway): clarify websocket handshake phases
* fix(gateway): log websocket handshake phase * fix(gateway): clarify websocket handshake phases
Summary
phase=<value>on preauth handshake timeout and pre-connect close logs, with matching structured metadata.auth_credentials_receivedand only advances that phase when a shared/device/bootstrap credential is actually present.Linked context
Closes #79603
Related #79654, the older closed attempt that mixed in extra surfaces and initially lacked contributor real behavior proof.
This follows the issue's latest requested narrow replacement shape: Gateway WebSocket handshake diagnostics only.
Real behavior proof (required for external PRs)
handshake timeoutandclosed before connectlogs now include the last completed phase, so operators can distinguish a connection that only reached the WebSocket upgrade/challenge stage from later auth/session phases.node --import tsx, realnode:httpserver, realwsWebSocketServer, realwsclient, temporary empty OpenClaw config and state dir.src/gateway/server/ws-connection.ts, configuredpreauthHandshakeTimeoutMs: 250, openedws://127.0.0.1:<port>, did not send aconnectrequest, and waited for the production preauth timer to close the socket.phase=ws_upgrade_started, and the structured close context includes"phase":"ws_upgrade_started".phasein the timeout or pre-connect close contexts; [Bug]: [Feature]: Add handshake phase logging to gateway/ws subsystem #79603 and the ClawSweeper issue review identify that source-level gap.Tests and validation
git diff --check— passed after rebase conflict resolution.node scripts/run-vitest.mjs src/gateway/server/ws-connection.test.ts— passed, Gateway shard selected 4 files / 44 tests.node scripts/run-vitest.mjs src/gateway/server/ws-connection/message-handler.post-connect-health.test.ts— passed, Gateway shard selected 4 files / 92 tests.node_modules/.bin/oxfmt --check src/gateway/server/ws-connection.test.ts src/gateway/server/ws-connection.ts src/gateway/server/ws-connection/message-handler.post-connect-health.test.ts src/gateway/server/ws-connection/message-handler.ts src/gateway/server/ws-types.ts— passed.PNPM_CONFIG_VERIFY_DEPS_BEFORE_RUN=false corepack pnpm tsgo:core— passed..agents/skills/autoreview/scripts/autoreview --mode branch --base upstream/main— clean, no accepted/actionable findings.phase=ws_upgrade_startedin both warn lines.Note: a combined two-file local Vitest invocation hit the harness timeout before useful output, so the same two directly relevant files were rerun separately and both passed.
Regression coverage added in
src/gateway/server/ws-connection.test.tsfor monotonic phase advancement, pre-connect close log metadata, timeout log metadata, and omitting phase metadata after a connection reachesready.Known validation limitation: the full CI matrix is left to GitHub after this push; local proof stayed focused on the touched Gateway surface.
Risk checklist
Did user-visible behavior change?
Yes— failure logs gain a low-cardinalityphasetoken and structured field.Did config, environment, or migration behavior change?
NoDid security, auth, secrets, network, or tool execution behavior change?
NoWhat is the highest-risk area? Misleading diagnostics if phase advancement does not match the actual handshake path.
How is that risk mitigated? Phase values are a closed enum, advancement is monotonic, credential receipt only advances when credentials are actually present, and tests lock the timeout/pre-connect/ready cases.
Current review state
Next action: waiting for CI, ClawSweeper review, and maintainer review.
Author-side work complete for the narrow fix. The earlier autoreview finding about
auth_token_receivedbeing misleading was addressed by switching toauth_credentials_receivedand gating it on actual credential presence.