“half a handshake.”

The bug yesterday’s Slack work shipped on top of: the pairing handshake was half-built. Slack would tell the operator to run /social code in werbos chat, but typing that into werbos chat got back “unknown command: /social” — it dropped through to buddy’s catch-all. The store had mint_pairing_code() / redeem_pairing_code(), the Slack adapter knew /pair <CODE>, but nothing in between minted a code the operator could send.

/social code wired in both REPL paths

The slash command surface in werbos has two parallel paths:

  • The CLI REPL (werbos chat) matches slashes in _bare_human_turn() and dispatches to _handle_X_slash() functions — each with its own SQLite store, returning a (print_msg, send_text) tuple.
  • The server slash registry (werbos/server/slash.py) handles HTTP POST /api/chats/{id}/messages slashes through a SlashRegistry + SlashContext discriminator. Used by the dashboard chat composer and any HTTP client.

/social code ships in both (e0d3784). The CLI handler opens ~/werbos/social.db (override via WERBOS_SOCIAL_DB), the server handler reads app.state.social_store. Optional platform_hint constrains redemption to one platform. 5 new server-side tests including an end-to-end round-trip: mint → redeem with the same store → identity gets paired_at. Pins the contract that the handler isn’t accidentally hashing twice or returning the wrong value.

Then Slack ate /pair

User minted a code, DM’d @werbos /pair bh2rFF — Slackbot intercepted with "/pair is not a valid command." Slack treats any /-prefixed message as a slash command and drops it before the app’s webhook sees the text. So the documented pairing form silently failed on the very platform it was designed for.

Two-line fix (0cd43b8):

  • Accept pair <CODE> as an alias to /pair <CODE>. Slack’s slash-command interception only fires on the leading /, so the no-slash form lands cleanly.
  • lstrip() the inbound text before prefix matching. Slack’s own suggested workaround — “prefix the slash with a space” — now actually delivers a working pairing.
  • Bot’s pair-prompt template updated: tells the user to type pair <CODE> first, with /pair <CODE> mentioned parenthetically for platforms that don’t reserve the slash (Telegram, WhatsApp, Twitter).

Two new regression tests in test_router.py (no-slash form + leading-whitespace form). Telegram/WhatsApp/Twitter continue to accept the legacy /pair <CODE> form unchanged — those platforms deliver /-prefixed text verbatim.

Lesson the day taught

Every platform has its own opinions about what a slash means. Slack reserves them. The IRC-era convention that “slashes are how you talk to the bot” doesn’t survive the move to modern chat platforms. werbos’s surface needs to assume no slash as the canonical form and treat /-prefixed shapes as opt-in aliases for platforms that allow them.