WhatsApp is planned for Phase 2.B.4, but PicoClaw actually offers two distinct donors: a bridge-based adapter and an optional build-tagged native adapter. A future Gormes porter needs to treat those as different decisions, not one blended implementation.
Status
Gormes does not yet ship WhatsApp. The upstream Hermes docs currently describe a built-in Baileys bridge flow, while PicoClaw supports:
Evidence level:
Donor code for this dossier was verified against the external sibling repo at
/home/xel/git/sages-openclaw/workspace-mineru/picoclaw.The donor commit inspected for this research was
6421f146a99df1bebcd4b1ca8de2a289dfca3622.The upstream donor repo is
https://github.com/sipeed/picoclaw.Any
pkg/...ordocs/...path listed below is relative to that donor root, not relative to the Gormes repo.Current Gormes status and operator-facing behavior were verified in-tree against
gormes/docs/content/upstream-hermes/user-guide/messaging/whatsapp.md.a thin bridge-based WebSocket adapter in
picoclaw/pkg/channels/whatsapp/whatsapp.goan optional in-process
whatsmeowadapter inpicoclaw/pkg/channels/whatsapp_native/whatsapp_native.go, compiled behind thewhatsapp_nativebuild tag
That means the donor question is not just “how do we port WhatsApp?” but also “which operational model does Gormes want to own?”
Keep the boundary explicit: PicoClaw is donor input for channel-edge WhatsApp mechanics. Gormes architecture, release model, and deployment ergonomics remain authoritative.
Why This Adapter Is Reusable
The bridge and native donors are useful for different reasons.
- The bridge path is reusable as the thinnest possible WhatsApp edge: websocket connect, JSON message pump, simple send path, and straightforward inbound shaping.
- The native path is reusable as an operational blueprint for QR login, SQLite-backed device state, reconnect logic, and direct
whatsmeowmessage handling without an external sidecar. - The command tests in both variants are valuable because they prove an important policy: generic commands such as
/helpand/neware forwarded upward, not consumed locally by the adapter.
The donor becomes less reusable where it hardcodes bridge payload shapes or relies on build tags and library-specific lifecycle details.
Picoclaw Donor Files
- Provenance note: the following
pkg/...anddocs/...paths are relative to the external donor root/home/xel/git/sages-openclaw/workspace-mineru/picoclawat commit6421f146a99df1bebcd4b1ca8de2a289dfca3622, not relative to the Gormes repo. picoclaw/pkg/channels/whatsapp/whatsapp.gopicoclaw/pkg/channels/whatsapp/whatsapp_command_test.gopicoclaw/pkg/channels/whatsapp_native/whatsapp_native.gopicoclaw/pkg/channels/whatsapp_native/whatsapp_command_test.gopicoclaw/pkg/channels/whatsapp_native/whatsapp_native_stub.gopicoclaw/docs/guides/chat-apps.mdgormes/docs/content/upstream-hermes/user-guide/messaging/whatsapp.md
What To Copy vs What To Rebuild
Copy candidates:
- From the bridge path: the minimal inbound and outbound message shape, allow-list check placement, and “adapter does not execute generic commands” policy.
- From the native path: QR login flow, persistent device store setup, reconnect backoff, graceful stop sequencing, and direct JID parsing.
- From both command tests: preserve the contract that
/help,/new, and similar commands go to the shared runtime.
Rebuild in Gormes-native form:
- Bridge protocol details.
picoclaw/pkg/channels/whatsapp/whatsapp.goassumes a very specific websocket JSON schema with fields liketype,from,chat,content, andmedia. That is donor input, not a stable Gormes contract. - Build-tag packaging.
picoclaw/pkg/channels/whatsapp_native/whatsapp_native_stub.gois useful only if Gormes chooses the same optional-compile strategy. - Session storage and path layout. PicoClaw’s native path writes a SQLite store under a configurable local directory; Gormes should align that with its own config and state conventions.
- Upstream Hermes product behavior such as unauthorized-DM handling, bridge lifecycle UX, and risk messaging should come from Gormes product docs, not from PicoClaw.
Gormes Mapping
- The bridge donor maps to a future
internal/whatsapp/bridge.goif Gormes wants an external sidecar or embedded bridge process. - The native donor maps to a future
internal/whatsapp/native.goif Gormes wants direct in-process ownership of WhatsApp connectivity. handleIncomingMessagein the bridge path andhandleIncomingin the native path both map conceptually to the same Gormes responsibility: sanitize inbound content, attach sender/chat metadata, preserve message ID, then hand off to the kernel-facing gateway layer.reconnectWithBackoff,Stop, and the QR-path startup logic are the most reusable parts of the native donor if Gormes adoptswhatsmeow.- The stub file maps to a release decision, not a runtime design. If Gormes does not want build-tag fragmentation, do not port that pattern.
Implementation Notes
- Decide the operating model first. If Gormes wants the simplest parity path with upstream Hermes docs, a bridge-based adapter is the lower-friction start. If Gormes wants one self-contained Go binary, the native path is the better donor.
- The bridge adapter is operationally light but only as good as the bridge contract behind it. Its code is mostly wiring, not durable WhatsApp domain knowledge.
- The native adapter contains the more valuable engineering: persistent pairing state, reconnect control, QR flow, stop-versus-reconnect race handling, and message send validation when pairing is incomplete.
- If Gormes adopts a native implementation, port the shutdown and reconnection safeguards, not just the happy path.
whatsapp_native.gois strongest in lifecycle handling. - If Gormes stays bridge-based first, still borrow the native tests’ policy around command passthrough and sender/chat metadata.
Risks / Mismatches
- The bridge donor is only reusable if the bridge exists and remains maintained. Its websocket payload schema is not portable by itself.
- The native donor depends on
whatsmeow, QR pairing, and a local session store. That increases binary complexity, operational support burden, and test surface. - The
whatsapp_nativebuild tag creates a split-brain release model. That may be acceptable for PicoClaw, but it may be the wrong trade-off for Gormes. - Upstream Hermes currently documents a Baileys-based bridge experience. A future native Gormes implementation would need documentation and operator UX updates, not just code.
Port Order Recommendation
- Decide whether Gormes wants bridge-first or native-first ownership.
- If bridge-first, port only the thin adapter ideas from
picoclaw/pkg/channels/whatsapp/whatsapp.goand keep the bridge contract explicitly external. - If native-first, port lifecycle pieces from
picoclaw/pkg/channels/whatsapp_native/whatsapp_native.gobefore worrying about parity extras. - In either case, port the command-passthrough tests early.
- Treat build-tag strategy as a product and release decision, not an automatic code reuse choice.
Code References
picoclaw/pkg/channels/whatsapp/whatsapp.go:Start,Stop,Send,listen,handleIncomingMessage.picoclaw/pkg/channels/whatsapp/whatsapp_command_test.gopicoclaw/pkg/channels/whatsapp_native/whatsapp_native.go:Start,Stop,eventHandler,reconnectWithBackoff,handleIncoming,Send,parseJID.picoclaw/pkg/channels/whatsapp_native/whatsapp_command_test.gopicoclaw/pkg/channels/whatsapp_native/whatsapp_native_stub.gopicoclaw/docs/guides/chat-apps.mdgormes/docs/content/upstream-hermes/user-guide/messaging/whatsapp.md
Recommendation: adapt pattern only.