[Repo Assist] fix(connection): operator client always connects as operator, never node role#721
Conversation
…ode role GatewayClientFactory created the operator (chat) client with bootstrapPairAsNode: credential.IsBootstrapToken. For bootstrap tokens (QR-code and setup-code pairing) this set bootstrapPairAsNode: true, which caused GetConnectRole() to return "node" — permanently locking the tray app in node role with no device-token upgrade path. Every reconnect re-used the bootstrap token, GetConnectRole() returned "node" again, and chat.send was rejected with "unauthorized role: node". Fix: set bootstrapPairAsNode: false unconditionally for the operator client. The operator (chat) client should always connect as "operator" regardless of credential type. The node-platform client has its own creation path (NodeConnector) which sets bootstrapPairAsNode as needed. Updated GatewayClientFactoryTests to reflect the corrected behaviour and added a regression test in OpenClawGatewayClientTests covering the bootstrap-token operator-role case. Closes #720 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Codex review: needs maintainer review before merge. Reviewed June 8, 2026, 10:15 AM ET / 14:15 UTC. Summary Reproducibility: yes. from source inspection, not from a live run: current main passes Review metrics: 3 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrow factory change with regression tests after required build/CI and redacted live QR/setup-code pairing proof show operator chat works and node-mode pairing still works. Do we have a high-confidence way to reproduce the issue? Yes from source inspection, not from a live run: current main passes Is this the best way to solve the issue? Unclear until live gateway proof: the patch is the narrowest client-side fix and preserves the separate NodeConnector path, but maintainers need proof that operator-role bootstrap pairing is accepted and mints the expected device token. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 37b0ea672037. Label changesLabel changes:
Label justifications:
Evidence reviewedWhat 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
|
🤖 This PR was created by Repo Assist, an automated AI assistant.
Closes #720
Root Cause
GatewayClientFactory.Create()constructed the operator (chat) client withbootstrapPairAsNode: credential.IsBootstrapToken. For QR-code and setup-code pairing — where the credential is always a bootstrap token — this setbootstrapPairAsNode: true. That flag causedGetConnectRole()to return"node"instead of"operator", putting the tray in a permanent loop:bootstrapPairAsNode = true→ role"node""node"chat.sendrejected:unauthorized role: nodeFix
Set
bootstrapPairAsNode: falseunconditionally inGatewayClientFactory.Create(). The operator (chat) client should always connect as"operator"regardless of credential type. The node-platform client has its own separate creation path (NodeConnector) which setsbootstrapPairAsNodeas needed.Changes
src/OpenClaw.Connection/GatewayClientFactory.csChange
bootstrapPairAsNode: credential.IsBootstrapToken→bootstrapPairAsNode: false.Added a comment explaining the invariant.
tests/OpenClaw.Connection.Tests/GatewayClientFactoryTests.csUpdated
Create_BootstrapCredential_PairsAsNode(nowCreate_BootstrapCredential_PairsAsOperator) to assert the corrected behavior.tests/OpenClaw.Shared.Tests/OpenClawGatewayClientTests.csAdded
OperatorClient_WithBootstrapToken_ConnectsAsOperatorRoleregression test.Trade-offs
bootstrapPairAsNode: truepath inOpenClawGatewayClient(node token storage, operator handoff) is preserved for the node-platform client. This PR only changes which value the operator-client factory passes — theOpenClawGatewayClientlogic itself is unchanged.Test Status
./build.ps1): GitVersion MSBuild task requiresGITHUB_ENVpath present on CI runner; not available in agent environment (pre-existing infrastructure limitation)Add this agentic workflows to your repo
To install this agentic workflow, run