Magic Link Booking Verification lets a guest prove booking linkage through the booking email already on file, without exposing private booking details in chat or email.
Current Implemented Components
Current verification implementation:
Candidate Booking Lookup Helper v0
Magic Link Verification Token + Session State v0
Magic Link Verification endpoints v0
Resend-backed verification email delivery
guest-agent retry/status intent hardening
verified-session recognition after magic-link consumption
verification expiry metadata tracked in pending guest-agent state
magic-link URL hardening to avoid duplicated paths
guest reservations seed/test UI
guest reservations availability calendar
server-side Guest Agent seed-booking proxy
Engine seed-booking and availability endpoints
This is implemented live-development infrastructure. The live smoke proves the guest-agent behavior below on https://guest.hellolucia.ai/. It is not a production-readiness claim.
Conservative Candidate Matching
Candidate lookup can use:
booking ID + surname
booking ID + arrival date
unique full name + arrival date
Weak claims do not auto-send.
Weak claims include:
name only
booking ID only
service overlap
airport pickup overlap
Service overlap is never evidence.
Candidate lookup exposes no private fields.
Guest-Agent Booked Verification Flow
Current guest-agent behavior:
"I'm already booked" starts verification path
Lucia asks for booking-identifying details without asking for guest email
guest claim fragments are remembered across turns
name-only remains weak
booking-ID-only remains weak
strong claim triggers Engine /claims then /requests when Engine permits it
guest receives safe copy that a secure verification link was sent to the booking email on file
"Can you send it again?" resends only when safe pending claim context exists or a fresh strong claim is provided
"Am I verified now?" checks Engine session status and does not resend
before link click, status check remains unverified without sending a new link
after link click, Lucia recognizes the verified session
already verified sessions do not receive unnecessary new verification links
verified sessions can receive booking-specific planning help within product/operator boundaries
Completed live product loop:
guest opens https://guest.hellolucia.ai/reservations
guest creates a controlled/test Villa reservation using an owned/test email
Engine persists a seed booking record in booking truth
reservation receives a booking ID
booking appears in Admin calendar
operator Lucia can answer that the guest has a confirmed booking
guest opens https://guest.hellolucia.ai/
guest says they are already booked
guest provides booking ID or safe booking-identifying details
Engine sends magic-link verification email to the booking email on file
guest clicks email
Engine shows branded verification result page matching the email design
guest returns to Lucia
guest session is verified
guest Lucia can provide booking-specific planning
Example strong claim proven live:
My husband Ethan Cole booked it - the booking number is 29110004.
Lucia must not show:
booking email
raw token
magic link
booking-private details
payment data
private notes
Engine Token State
Engine token facts discovered by inspection:
token TTL is currently 30 minutes
TTL is hardcoded in Engine, not env-controlled
token generation uses 32 random bytes from Node crypto CSPRNG
encoded raw token length is 43 base64url characters
raw token is HMAC-SHA256 hashed before storage
Engine stores token hash, not raw token
tokens are one-time consumable
verified sessions are stored in Engine state
Guest Agent stores verification_expires_at as safe pending verification metadata. It is not the token, booking email, magic link, or booking-private data.
Endpoint Family
Current verification endpoint family:
claim lookup
verification request
magic token consume
verified session check
Engine POST /v1/guest/booking-verification/requests returns expires_at.
Verification status must come from Engine session state. A strong booking claim is not itself verification.
Reservations and Availability Boundary
Current reservation/calendar behavior:
Guest Agent /reservations uses Engine availability truth
browser does not call Engine directly
Guest Agent Netlify function signs server-to-server requests with LUCIA_SEED_BOOKING_SECRET
no Engine URL, HMAC, signature, or secret is exposed to the browser
Engine availability endpoint: POST /v1/guest/seed-bookings/availability
Engine seed booking endpoint: POST /v1/guest/seed-bookings
both endpoints are feature-gated and protected by seed-booking env plus HMAC boundary
Villa Valentin v0 reservation rules:
minimum stay is 3 nights
same-day checkout/check-in is allowed
booking ranges represent nights
blocked ranges use [check_in, check_out) semantics
example: Aug 18 -> Aug 22 blocks nights Aug 18, 19, 20, 21; Aug 22 may be selected as a new arrival date
unavailable, held, and booked nights are represented in the calendar
checkout/turnover days can be represented visually as split/half-day cells
Calendar interaction doctrine:
available dates are selectable
unavailable, held, and booked dates give feedback instead of acting broken
selected arrival can be cleared
selected departure can be cleared
earlier date restarts selection
minimum-night violations give clear feedback
overlap conflicts explain the issue without leaking guest or booking details
selected arrival, departure, and in-range nights are visually distinct
clear-date recovery exists
reduced-motion behavior is respected
This is a controlled guest-facing seed/test reservation loop and architecture proof. It is not a full public booking engine, payment system, Lodgify replacement, auth system, or production OTA integration.
Shipped Guest-Agent Hardening
Shipped in lucia-guest-agent on main:
59c2687ac34430252ce1d00841175543f40725df - harden guest verification retry flow
36b64c11019bf1f5160e57ac8029645a4806e628 - track guest verification link expiry
a7a63ae8afcb3c7a483fa73e334cdd8eef939121 - add guest reservations seed UI
cc0922b71779ec4caca9c1c2df4251ca76995013 - show build tag on guest reservations page
ab00fc138145559f0af413f5ed119d33f97ff92a - add guest reservations availability calendar
f90fb327e856518bfb50af6262ba681699f34d3d - fix guest reservations availability window
f6c52d959482a5f19233da6a5773416f3b9e1986 - harden guest verification arrival-date claims
51a47fbc94acf74517e149936df7e960733d301f - polish guest reservations calendar interactions
Current live Guest Agent build evidence:
Guest Agent build: 51a47fb
These hashes are engineering release evidence. They are not product-version doctrine.
Shipped Engine Support
Shipped in engine-v0.1.3.6:
e8c9adbec19b130dbd904baf2932e05cdf278f24 - add guest seed booking endpoint
6c8c56c50b7547559a030de4a89e875b4c13adee - brand guest verification result page
73fed6d4ed2e40d6987343bf336501d0fda49957 - add guest seed booking availability
Current live Engine evidence:
Engine build includes seed booking endpoint
Engine build includes branded verification result page
Engine build includes seed booking availability endpoint
Admin build observed: 2cb83f0
Eval Labs observed: 413489f
Live Guest-Agent Smoke Recorded
The live smoke on https://guest.hellolucia.ai/ proved:
already-booked orientation enters the verification path
Lucia requests booking-identifying details without asking for guest email
strong claim sends a secure verification link to the booking email on file
chat does not expose booking email, raw token, magic link, or private booking data
resend intent sends a fresh secure verification link when safe pending context exists
status-check intent checks session status and does not resend
before link click, session remains unverified
after link click, Lucia recognizes the verified session
verified session can support booking-specific planning for the reservation
already verified sessions do not receive unnecessary new verification links
multi-turn weak claim stays inside verification flow instead of drifting into concierge arrival planning
This is evidence of shipped guest-agent behavior. It is not a replacement for broader Eval Labs coverage or production readiness review.
Validation Evidence
Guest Agent validations passed:
node --check public/lucia-lab/lucia-lab-agent.js
node --check netlify/functions/ask.mjs
npm run smoke:guest-verified-session
npm run check
git diff --check
Engine validations passed:
npm run guest-seed-booking:smoke
npm run guest-verification:smoke
npm run guest-verification-routes:smoke
npm run guest-booking-candidate:smoke
git diff --check
Doctrine to Preserve
Magic-link verification must preserve:
booking-email-only delivery
never ask guest for their email as a delivery destination
never let guest-entered email control verification delivery
never expose booking email, raw token, magic link, payment data, private notes, or booking-private data in chat
never expose booking ID of conflicting records, raw state, tokens, HMAC, signatures, Engine URLs, internal errors, or payment data
strong booking claim is not itself verification
verification status must come from Engine session state
booking ID or safe booking claim is not itself verification
resend intent and status-check intent are separate
"Am I verified now?" checks status; it does not resend
"Send it again" resends only with safe pending claim context or a fresh strong claim
already verified sessions should not resend
booking-specific guest planning begins only after magic-link verification
operator/Admin side can reason over booking truth according to its own access boundary
Arrival-Date Claim Handling
The multi-turn weak claim bug is fixed:
Kitkat Candybar
I arrive on the 7th of September
This now stays inside verification flow instead of drifting into concierge arrival planning. If a yearless date can be safely inferred from client_today, it can be used. If not, Lucia asks for the full arrival date including year.
Future Property Onboarding Layer
The v0 Villa reservation rules should eventually become owner/operator-configured property settings:
minimum nights
same-day turnover allowed
check-in/check-out rules
property/unit availability rules
booking windows
hold/confirmed/tentative statuses
guest-facing reservation constraints
Future work should productize this configuration without weakening the current privacy and verification boundaries.
See Also