Skip to content

fix(whatsapp): preserve auth on terminal disconnects#93076

Merged
mcaxtr merged 3 commits into
mainfrom
fix/whatsapp-preserve-terminal-auth
Jun 15, 2026
Merged

fix(whatsapp): preserve auth on terminal disconnects#93076
mcaxtr merged 3 commits into
mainfrom
fix/whatsapp-preserve-terminal-auth

Conversation

@mcaxtr

@mcaxtr mcaxtr commented Jun 14, 2026

Copy link
Copy Markdown
Member

Summary

  • Preserve WhatsApp Web credentials on passive logged-out/conflict terminal monitor disconnects; the monitor now stops the listener without calling logoutWeb.
  • Remove the process-local terminal auth marker entirely and derive QR/CLI relink behavior from actual saved-auth/socket outcomes.
  • When saved auth exists with no active listener, bootstrap it first: a valid session recovers without QR, while a 401 clears auth once through logoutWeb and then surfaces one replacement QR.
  • Keep forced relink and explicit logout as the explicit owners of auth cleanup, and keep gateway web.login.start from stopping a running channel until a non-forced QR flow actually takes over.

Verification

  • node scripts/run-vitest.mjs extensions/whatsapp/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.ts extensions/whatsapp/src/connection-controller.test.ts extensions/whatsapp/src/auth-store.test.ts extensions/whatsapp/src/logout.test.ts extensions/whatsapp/src/login.coverage.test.ts extensions/whatsapp/src/login-qr.test.ts src/gateway/server-methods/web.start.test.ts
  • pnpm check:test-types
  • git diff --check
  • .agents/skills/autoreview/scripts/autoreview --mode local
  • run-whatsapp-qa-branch.sh --pr 93076

Real behavior proof

Behavior addressed: WhatsApp passive monitor terminal disconnects no longer remove saved credentials, while explicit login/relink/logout flows still own stale-auth cleanup.

Real environment tested: Local OpenClaw WhatsApp unit/e2e harness and gateway server-method harness in the branch worktree. Live WhatsApp QA also ran on the local maintainer host against PR 93076 using the default driver account, work SUT account, configured/redacted QA group, and mock-openai.

Exact steps or command run after this patch: node scripts/run-vitest.mjs extensions/whatsapp/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.ts extensions/whatsapp/src/connection-controller.test.ts extensions/whatsapp/src/auth-store.test.ts extensions/whatsapp/src/logout.test.ts extensions/whatsapp/src/login.coverage.test.ts extensions/whatsapp/src/login-qr.test.ts src/gateway/server-methods/web.start.test.ts; pnpm check:test-types; git diff --check; .agents/skills/autoreview/scripts/autoreview --mode local; run-whatsapp-qa-branch.sh --pr 93076

Evidence after fix: Focused Vitest passed 3 shards: 2 gateway test files with 10 tests, 1 e2e file with 26 tests, and 5 WhatsApp extension files with 66 tests. Test typecheck and diff whitespace checks passed. Autoreview reported no accepted/actionable findings. Live WhatsApp QA ran 35 discovered scenarios and passed 35/35 with 0 failures and 0 skipped.

Observed result after fix: Passive logged-out/conflict monitor paths preserve auth files. QR login returns already-linked only with an active listener, recovers valid saved auth without QR when no listener exists, clears 401 stale auth once before a replacement QR, and fails clearly when cleanup reports auth still present. Forced relink still clears auth before QR generation, and non-forced gateway login failures do not stop a running channel before QR takeover. Live WhatsApp proof covered DM canary, pairing gate, group mention/audio gating, command replies, reply context, inbound image/audio/structured messages, outbound media/document/poll, message actions, access control, reply chunking, stream final accounting, native /new, status reactions, allowlist quiet behavior, and native approval flows.

Live WhatsApp QA artifacts:

  • Branch/head tested: fix/whatsapp-preserve-terminal-auth @ 86cdb86014156c6877d4e3223680ac59f9e6ec4d
  • Base tested: origin/main @ ac1042b09b5cfa4dcee7bfe1f8e5ae7771d4a35a
  • Report: .artifacts/qa-e2e/whatsapp-full-pr-93076-20260615-040153/whatsapp-qa-report.md
  • Evidence summary: .artifacts/qa-e2e/whatsapp-full-pr-93076-20260615-040153/qa-evidence.json
  • Observed messages: .artifacts/qa-e2e/whatsapp-full-pr-93076-20260615-040153/whatsapp-qa-observed-messages.json

What was not tested: No live-provider model call was run; the live WhatsApp lane used mock-openai. No manual real-device QR scan or real conflict-session reproduction was run outside the automated QA lane.

@openclaw-barnacle openclaw-barnacle Bot added channel: whatsapp-web Channel integration: whatsapp-web size: L maintainer Maintainer-authored PR labels Jun 14, 2026
@clawsweeper

clawsweeper Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 15, 2026, 12:47 AM ET / 04:47 UTC.

Summary
The branch moves WhatsApp Web credential cleanup from passive terminal monitor stops into explicit logout, forced relink, and stale-auth login recovery, and defers gateway web-login channel stops until QR takeover.

PR surface: Source +7, Tests +298. Total +305 across 9 files.

Reproducibility: yes. by source inspection: current main calls logoutWeb from terminal logged-out/conflict monitor stop paths, and the PR removes that passive cleanup while adding targeted harness coverage. I did not run a live WhatsApp logout/conflict reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • Auth Cleanup Ownership: 4 passive cleanup calls removed, 2 explicit cleanup paths active. Credential deletion moves from terminal monitor stop handling to login recovery and forced relink, which is the central session-state decision before merge.

Stored data model
Persistent data-model change detected: persistent cache schema: extensions/whatsapp/src/login.coverage.test.ts, serialized state: extensions/whatsapp/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Refresh or revalidate against current main because newer WhatsApp socket-bound changes landed after the PR base.
  • Get explicit maintainer acceptance for preserving auth after passive terminal disconnects.

Risk before merge

  • [P1] Merging intentionally changes WhatsApp Web credential lifecycle: passive terminal logged-out/conflict monitor stops preserve saved auth, and stale auth cleanup moves to later login recovery, forced relink, or explicit logout.
  • [P1] The broader gateway terminal-disconnect restart-loop fix remains in fix(gateway): stop terminal WhatsApp restart loops #78511 or a replacement, so this PR should not be treated as the complete availability fix.
  • [P1] The PR should be refreshed and revalidated against current main because main moved after the PR base and now includes newer WhatsApp socket-bound changes touching the same area.
  • [P1] Required CI is not green at inspection time, although the observed lint failure is outside the touched WhatsApp and gateway files.

Maintainer options:

  1. Accept The Credential Lifecycle Shift
    Maintainers can land after current-main validation if they accept passive terminal disconnects preserving auth and login/relink/logout owning cleanup.
  2. Request Real Conflict/QR Proof
    Before merge, maintainers can ask for redacted real-device logged-out or conflict-session relink proof if the harness and live QA summary are not enough.
  3. Keep Restart Loop Separate
    Review this PR for credential lifecycle only and keep fix(gateway): stop terminal WhatsApp restart loops #78511 or a rebased replacement responsible for gateway restart-loop behavior.

Next step before merge

  • [P2] Protected maintainer/member PR changes WhatsApp session-state lifecycle and needs maintainer acceptance plus current-main validation, not an automated repair lane.

Security
Cleared: The diff changes WhatsApp auth lifecycle and gateway web-login code/tests without adding dependencies, workflows, package scripts, lockfiles, or new code-execution surfaces.

Review details

Best possible solution:

Land this credential-preservation slice only after maintainers accept the session-state lifecycle shift, refresh it against current main, and keep the restart-loop guard tracked separately.

Do we have a high-confidence way to reproduce the issue?

Yes, by source inspection: current main calls logoutWeb from terminal logged-out/conflict monitor stop paths, and the PR removes that passive cleanup while adding targeted harness coverage. I did not run a live WhatsApp logout/conflict reproduction in this read-only review.

Is this the best way to solve the issue?

Yes for the credential-preservation slice. The patch stays in the WhatsApp plugin and gateway web-login boundary, uses existing saved-auth/listener outcomes instead of new state, and leaves the broader restart-loop fix to the linked gateway PR.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 7e0128ae659d.

Label changes

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P2: This is a bounded WhatsApp Web auth-preservation bug fix with channel-specific blast radius while the broader availability work remains separate.
  • merge-risk: 🚨 session-state: The PR changes when WhatsApp Web credentials are preserved, cleared, and considered recoverable after terminal disconnects.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The external-contributor proof gate does not apply to this member-authored, maintainer-labeled PR; the PR body still reports focused harness proof and live WhatsApp QA.
Evidence reviewed

PR surface:

Source +7, Tests +298. Total +305 across 9 files.

View PR surface stats
Area Files Added Removed Net
Source 4 104 97 +7
Tests 5 511 213 +298
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 9 615 310 +305

What I checked:

  • Repository policy applied: Root and scoped extension/gateway AGENTS.md files were read; the review applied the maintainer-label protection, plugin/gateway boundary guidance, and session-state merge-risk guidance. (AGENTS.md:1, 7e0128ae659d)
  • Scoped policy read: The extension and gateway scoped guides were read; the PR keeps WhatsApp-owned lifecycle behavior in the plugin and only adjusts the gateway web-login method boundary. (extensions/AGENTS.md:1, 7e0128ae659d)
  • No matching maintainer note: The only maintainer note present is telegram-specific, so no WhatsApp or gateway maintainer note changed this review. (.agents/maintainer-notes/telegram.md, 7e0128ae659d)
  • Current main deletes auth on passive terminal stops: Current main still has clearTerminalWebAuthState calling logoutWeb from logged-out/conflict setup and close stop paths, which is the central behavior the PR changes. (extensions/whatsapp/src/auto-reply/monitor.ts:145, 7e0128ae659d)
  • PR preserves auth on passive terminal stops: At PR head, terminal logged-out/conflict handling reports relink or restart instructions without calling logoutWeb from the monitor path. (extensions/whatsapp/src/auto-reply/monitor.ts:395, 86cdb8601415)
  • PR moves stale-auth cleanup to login recovery: At PR head, waitForWhatsAppLoginResult handles one logged-out restart by closing the socket, calling logoutWeb, verifying leftover auth when cleanup reports false, and replacing the socket. (extensions/whatsapp/src/connection-controller.ts:311, 86cdb8601415)

Likely related people:

  • mcaxtr: Recent merged history includes WhatsApp socket lifecycle work, bounded startup waits, and QR timeout recovery in the same monitor, connection-controller, and login-qr area this PR changes. (role: recent WhatsApp lifecycle contributor; confidence: high; commits: 7d8b000bf78a, dd2083c7ec51, f613f32b227e; files: extensions/whatsapp/src/auto-reply/monitor.ts, extensions/whatsapp/src/connection-controller.ts, extensions/whatsapp/src/login-qr.ts)
  • vincentkoc: Current blame for the passive terminal auth cleanup, login result handling, QR shortcut, and gateway stop behavior points to Vincent Koc's recent current-main commit. (role: current-main line owner; confidence: high; commits: 58369825063f; files: extensions/whatsapp/src/auto-reply/monitor.ts, extensions/whatsapp/src/connection-controller.ts, extensions/whatsapp/src/login-qr.ts)
  • steipete: GitHub file history shows repeated recent work in src/gateway/server-methods/web.ts and WhatsApp QR/timing surfaces adjacent to this change. (role: adjacent gateway and WhatsApp login contributor; confidence: medium; commits: a8154f425c0c, b09cab4ebd2c, db3c4ba8d33d; files: src/gateway/server-methods/web.ts, extensions/whatsapp/src/login-qr.ts, extensions/whatsapp/src/socket-timing.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 14, 2026
@mcaxtr mcaxtr self-assigned this Jun 14, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. P2 Normal backlog priority with limited blast radius. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 14, 2026
@openclaw-barnacle openclaw-barnacle Bot added the gateway Gateway runtime label Jun 15, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jun 15, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 15, 2026
@mcaxtr
mcaxtr force-pushed the fix/whatsapp-preserve-terminal-auth branch from 1dcb9be to 86cdb86 Compare June 15, 2026 02:59
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jun 15, 2026
@mcaxtr
mcaxtr force-pushed the fix/whatsapp-preserve-terminal-auth branch from 86cdb86 to 35928fb Compare June 15, 2026 23:34
@mcaxtr
mcaxtr merged commit 52d9d16 into main Jun 15, 2026
165 checks passed
@mcaxtr
mcaxtr deleted the fix/whatsapp-preserve-terminal-auth branch June 15, 2026 23:50
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 16, 2026
* fix(whatsapp): preserve auth on passive terminal stops

* fix(whatsapp): recover stale web auth during relink

* fix(gateway): defer channel stop until qr takeover
crh-code pushed a commit to crh-code/openclaw that referenced this pull request Jun 18, 2026
* fix(whatsapp): preserve auth on passive terminal stops

* fix(whatsapp): recover stale web auth during relink

* fix(gateway): defer channel stop until qr takeover
badgerbees pushed a commit to badgerbees/openclaw that referenced this pull request Jul 8, 2026
* fix(whatsapp): preserve auth on passive terminal stops

* fix(whatsapp): recover stale web auth during relink

* fix(gateway): defer channel stop until qr takeover
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: whatsapp-web Channel integration: whatsapp-web gateway Gateway runtime maintainer Maintainer-authored PR merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: L status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant