fix: honor context in waitForPair and waitForHello - #6
Conversation
waitForPair (6m) and waitForHello (30s) selected only on deadline, bridge errors, and frames. SIGINT during first-run pairing or hello stayed blocked until timeout. Honor the process context in both selects. Map cancel at the pair/run call sites to a clean exit, matching the reconnect loop. Signed-off-by: Sebastien Tardif <[email protected]>
|
🦞👀 Pull request received. I will update this pull request when review starts. |
|
Codex review: needs maintainer review before merge. Reviewed September 3, 2026, 4:57 AM ET / 08:57 UTC. ClawSweeper reviewWhat this changesThe PR threads process cancellation into bridge pairing and hello waits so interrupted Merge readiness✅ Ready for maintainer review Keep open: current main still waits only on timeout, bridge errors, and frames during pairing and hello, so SIGINT/SIGTERM cannot end those waits promptly. This focused PR adds the missing cancellation path with direct regression coverage and credible real-process proof. Priority: P2 Review scores
Verification
How this fits togetherClawgo connects a headless node to the OpenClaw bridge, performs pairing when needed, and waits for the bridge hello before starting node services. Process signals should cancel these connection-stage waits and return control to the CLI. flowchart LR
A[User starts clawgo] --> B[Bridge connection]
B --> C[Pairing or hello wait]
D[SIGINT or SIGTERM] --> C
C --> E[Start node services]
C --> F[Clean command exit]
Before mergeNone. Agent review detailsSecurityNone. Review metrics
Technical reviewBest possible solution: Land this narrow cancellation repair after ordinary maintainer review so bridge setup obeys the CLI's existing signal-handling expectation. Do we have a high-confidence way to reproduce the issue? Yes—current main's source provides a high-confidence path: connect to a silent bridge, begin pairing or hello, then send SIGINT/SIGTERM; the waits have no cancellation select. The contributor also supplied before/after terminal evidence for the pairing path. Is this the best way to solve the issue? Yes—the PR reuses the existing process context and applies it only to the two blocking waits, preserving successful handshake and timeout behavior. AGENTS.md: not found in the target repository. Codex review notes: model internal, reasoning high; reviewed against c6e46796a1c8. LabelsLabel justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (12 earlier review cycles; latest 8 shown)
|
What Problem This Solves
clawgo run(andclawgo pair) already installsignal.NotifyContextfor SIGINT and SIGTERM. After a first-run connect,waitForPair(6 minutes) andwaitForHello(30 seconds) selected only on the deadline,c.errs, and incoming frames.Ctrl+C during pairing or hello therefore did nothing until that deadline fired. The inner reconnect loop already returns on
ctx.Done(). These two waits did not.This PR threads the process context into both waits and returns on
ctx.Done(), matching the reconnect-loop pattern from #5. On cancel,run/pairclose the client and exit 0, same as the rest of the run loop.The wait functions were introduced in
f601408(2026-01-04) without a cancel case.Evidence
Before (binary from
upstream/main). Silent TCP acceptor, empty token, SIGINT duringwaitForPair. Process still running 2.027s later:After (this patch). Same silent acceptor and SIGINT. Process exits 0 in 0.017s:
Canceled wait returns
context.Canceledbefore the 6m/30s deadline. Without thectx.Done()case the same command failed; with it, it passed:Real behavior proof
Behavior or issue addressed: SIGINT during first-run pairing or hello no longer waits out the 6 minute / 30 second deadline.
Real environment tested: macOS 26.6.2 (Darwin 25.6.0 arm64), go1.27.0, clawgo built from this branch at
/tmp/oc-pr-clawgo-F002. Compared against a binary built fromupstream/main.Exact steps or command run after this patch: Started a silent TCP acceptor. Wrote a state file with no token. Ran
clawgo run -bridge 127.0.0.1:$PORT -mdns=false -tts-engine none -chat-subscribe=false. Afterrequesting pairing, sent SIGINT. Also rango test ./cmd/clawgo -run TestWaitForPairCancelUnblocks|TestWaitForHelloCancelUnblocks -count=1 -timeout 15s -vbefore and after thectx.Done()case.Evidence after fix: terminal output from the patched binary:
The unfixed binary stayed up:
Observed result after fix: After SIGINT during pairing,
clawgo runreturned in 0.017s with exit 0. The unfixed binary was still inwaitForPair2.027s later.What was not tested: Live pairing against a real OpenClaw gateway, and a 30s hello wait against a gateway that accepts the pair but never sends hello-ok. Hello cancel uses the same select as pair and is covered by
TestWaitForHelloCancelUnblocks.Command:
go test ./cmd/clawgo -run 'TestWaitForPairCancelUnblocks|TestWaitForHelloCancelUnblocks' -count=1 -timeout 15s -vand liveclawgo runplus SIGINT against a silent TCP acceptor.Observed: red step failed at 2.00s (
did not return after cancel). Green step passed at 0.00s. Live patchedclawgo runexited 0 in 0.017s after SIGINT; unfixed binary still running at 2.027s.Expected: cancel unblocks both waits with
context.Canceledbefore the 6m/30s deadline; SIGINT during pairing exits the process promptly.Time: 11:11:30 PDT
Date: 2026-08-29
Environment: macOS 26.6.2, Darwin 25.6.0 arm64, go1.27.0 darwin/arm64