Skip to content

SMOODEV-3066: carry the OTP proof on the widget's resume probe - #56

Open
brentrager wants to merge 1 commit into
mainfrom
SMOODEV-3066-widget-otp-proof
Open

SMOODEV-3066: carry the OTP proof on the widget's resume probe#56
brentrager wants to merge 1 commit into
mainfrom
SMOODEV-3066-widget-otp-proof

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

What

Follow-up to #54 (merged, released as part of 🦋 #55). This is the client half of
the SMOODEV-3066 identity-scoped resume: the fingerprint probe now carries
the browser's OTP proof so the server can allow a CRM-linked match for the
same contact.

POST /internal/resume-by-fingerprint
{ agentId, browserFingerprint, verifiedSessionId?, email? }

Both new fields are optional and meaningful only together — the widget already
holds both in its store (verifiedEmail, verifiedEmailSessionId). The server
does not trust the email; it re-reads its own verification row, which expires 30
minutes after the OTP.

Lands safely before the server half. chat-ws parses this body as an
untyped Json<Value> (rust/chat-ws/src/routes.rs:279-283), so the wrapper
running today ignores both fields.

The ordering is the actual bug

clearSession() drops the session-scoped OTP proof by design, and both
probe sites — the dead pointer (#54) and dead-session recovery (#54) — call it
before probing. Reading the proof afterwards would always find nothing,
silently, on exactly the population the server change exists to help: identified
visitors.

So it is read first, and a test fails if that is ever reordered. Positive
control: moving the read back after clearSession() fails
carries the OTP proof on the probe — including after a dead pointer clears it
and nothing else.

Also pinned from the SMOODEV-3066 contract

No code needed for these — this client never parses reason, it logs and
exposes the string verbatim and starts fresh on anything that is not
resumable: true. Two tests pin that it stays true:

  • an unknown reason behaves as start-fresh, so the server can add names
    without a client release
  • no identity fields are sent when the browser holds no proof

Not built

The identity_required → offer OTP → re-probe flow. It is multi-step UI, inert
until the server half is live, and a product decision (when to interrupt a
visitor with a verification prompt). The reason string already reaches the UI
layer, so it is a small addition when someone wants it.

Shipping

Same three steps as #54 — merge → merge the 🦋 release PR → bump
CHAT_WIDGET_VERSION in the monorepo's apps/web/lib/smantha.ts. The pin bump
is not done here.

Jira: SMOODEV-3066 (server half: rust/chat-storage + rust/chat-ws, by
identity-resume)
Follows: #54

🤖 Generated with Claude Code

…ssion eats it

The identity-scoped resume (SMOODEV-3066) lets a CRM-linked participant match
when the caller proves the same contact, via optional verifiedSessionId + email
on the probe. Both fields already sit in the widget store.

The ordering is the part that bites: clearSession() drops the session-scoped OTP
proof by design, and both probe sites (dead pointer, dead-session recovery) call
it before probing — so reading the proof afterwards would always find nothing,
silently, on exactly the visitors the server change exists to help. Read first.

chat-ws parses this body as an untyped JSON value, so the new fields are ignored
by the wrapper running today and this can land before the server half.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 010e04f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@smooai/chat-widget Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant