CURATE / Admin
Last synced June 30, 2026
Process Overview
What happens when
you tap Curate
CurateVIP runs more infrastructure per member tap than most search products run per page view. Seven coordinated stages — pre-computed venue pools, multi-layer AI validation, live credential intelligence, a six-guard post-filter chain, vision classification, and an editorial content engine — resolve to exactly three venue cards in under 30 seconds. Here's every step.
Speed Engine — Always On
Before any of the steps below run, results may already be waiting. The Speed Engine works continuously in the background — scraping Michelin, Forbes, Lartisien, and dozens of award sources, scoring every venue it finds, and pre-loading ranked pools for every market, intent, and environment combination. By the time a member taps CURATE, we’ve often already done the work. The pipeline below only runs when the pool doesn’t have a ready answer — which gets rarer with every pipeline run.
Full architecture → System Docs §11 — The Speed Engine
01 Cache Check
What happens
The moment you tap Curate, the backend runs two sequential cache checks before any AI is called. If either hits, the member gets their results instantly — no Claude call, no Brave Search queries, zero marginal AI cost.
Layer 0 — Precomputed Venue Pools
Sub-100ms delivery. The Speed Engine runs every Sunday, autonomously scraping Michelin, Forbes, Lartisien, and 30+ award queries per market, scoring every venue 0–100, and pre-ranking pools for every market × intent × environment combination. The result is a table (precomputed_venue_pools) that the curation pipeline reads before doing anything else. A pool hit returns pre-ranked, pre-classified venues in under 100ms with no AI inference. This is the primary delivery path for any established market — and it gets richer with every weekly pipeline run.
Layer 1 — Result Cache
On a pool miss, the backend checks market_venue_cache for a previously generated full curation result for this exact market + intent + environment combination. On a hit: the saved result streams instantly. Lifetime: 7 days. This layer catches cold-path results on repeat lookups before the pool is built for a new market.
On a full miss
No pool, no cached result — runs the full pipeline (Steps 2–7). This happens on the very first request for a new market before the Speed Engine has run, or after a manual cache reset. The full result is written to market_venue_cache at the end of Step 7 and immediately available as a Layer 1 hit for the next request.
02 Web Research — Quality Signals
What happens
Before Claude is called, the backend fires a batch of Brave Search queries to pull in live credential signals. These run in parallel so they all finish at the same time. The raw snippets become Claude's grounding context and are also held for the Signal Guard check in Step 4.
Why before Claude
Without live signals, Claude picks from training data alone — which goes stale. Running searches first means Claude sees real, current awards and press before it decides anything.
Cache
Search results are cached in Supabase for 7 days per market × category. If fresh results exist, no searches fire and the cached snippets are used directly.
TABLE — 14 Searches
01Michelin star restaurants {city} 2024 2025
02site:guide.michelin.com {city} restaurant
03James Beard Award winner nominated restaurants {city}
04site:jamesbeard.org award {city}
05"World's 50 Best" restaurants {city}
06Robb Report best restaurants {city}
07Wine Spectator Grand Award restaurants {city}
08"Food & Wine" best new restaurants {city}
09"Conde Nast Traveler" OR "Travel + Leisure" best restaurants {city}
10Forbes Travel Guide Five Star restaurants {city}
11site:forbestravelguide.com {city} restaurant
12Eater best restaurants {city}
13site:eater.com {city} best restaurants
14top 10 best restaurants {city} 2024 2025
STAY — 9 Searches
01Forbes Travel Guide Five Star hotels {city}
02AAA Five Diamond hotels {city}
03"Leading Hotels of the World" {city}
04"Relais Chateaux" {city}
05"Small Luxury Hotels" {city}
06"Conde Nast Traveler" Gold List hotels {city}
07"Travel + Leisure" World's Best hotels {city}
08Robb Report best hotels {city}
09top 10 best luxury hotels {city} 2024 2025
SOCIAL — 6 Searches
01best cocktail bars {city} award recognized James Beard
02"Tales of the Cocktail" Spirited Award {city}
03James Beard "Outstanding Bar" {city}
04Robb Report best bars cocktail lounges {city}
05"World's 50 Best Bars" {city}
06top 10 best cocktail bars {city} 2024 2025
02B TABLE — How Restaurants Are Discovered New — July 2026
What happens
When a member taps CURATE on TABLE, the same pool-first flow runs — but the TABLE pools are fed by a dedicated restaurant intelligence pipeline that runs weekly, doing the research a fanatic would do and more: every award body, every critic institution, and every heat signal, across all seven markets.
Two credential systems
Prestige (durable): Michelin stars, Bib Gourmand, and “Selected” guide entries; James Beard winners, finalists, and semifinalists; Wine Spectator awards; La Liste; World’s 50 Best; Bon Appétit / Esquire / NYT best-new lists; each market’s critic institution (LA Times 101, Seattle Times, Phoenix Mag, Miami New Times, Nashville Scene). Scene (decaying): Eater Heatmap, Infatuation Hit List, Resy hardest-reservation coverage, “best new” press, see-and-be-seen vocabulary, chef-pedigree signals (“from the team behind…”). Cool is a credential system too — it is just written by different publications.
Why both
A three-star tasting room and a celebrity scene room are both correct answers — for different members. Canlis tops the Provision pool; a Toca Madera–class room tops Pulse. Venues are ranked WITHIN their CCTF environment, never against other environments, so the scene engine fills exactly the environments the award path underserves.
Heat decays
Scene signals only count if re-confirmed within ~9 months. The weekly run means genuinely hot venues keep re-confirming themselves; last year’s flash fades out of the pool automatically. Prestige never decays — a star is a star.
Noise gate
A discovered restaurant must have a Michelin Guide entry, OR any prestige signal, OR two independent fresh scene signals before it is even considered. One blog calling a place hot is noise; Eater Heatmap plus Infatuation Hit List is a pattern. Full architecture → System Docs §24.
03 Claude Picks the Venues
What happens
All the search snippets get handed to Claude Sonnet as context, alongside the member's speed profile, their resolved CCTF environment tier, and a reference list of every venue already vetted for that market (the seed). Claude reads all of it and selects venues that match — streaming them back as it goes.
Streaming
Claude streams venue objects as JSON as it writes them. The frontend begins extracting and rendering cards before Claude has even finished. The first card typically appears within 3 seconds on a cache miss.
The wild card
Claude is instructed to include one cross-tier discovery pick — a venue just outside the member's primary environment that it judges to be a strong match anyway. This comes last in the stream.
What Claude sees
Member environment tier + adjacent tiers for cross-tier picks, live quality signal block (the Brave Search snippets from Step 2), seed reference sweep (confirmed and blocked venues for the market), hard disqualifier rules, and the full quality floor definition.
04 Every Pick Gets Checked
What happens
As each venue comes back from Claude, it runs through six filters in sequence. Anything that fails a filter is dropped silently — it never reaches the member.
The Six Guards (run in this order)
1
Signal Guard
A second Claude call (Haiku, fast + cheap) checks each venue name against the raw Brave Search snippets from Step 2. Any venue that does not appear in the live search results — meaning no evidence trail — is dropped. Seed-confirmed venues bypass this check entirely.
2
Geo Guard
Removes any venue outside the requested market. Prevents Claude from hallucinating venues in adjacent cities.
3
Tier Guard
Removes venues whose CCTF environment classification does not match the member's resolved tier. Keeps the result tightly on-profile.
4
Seed Block
Hard-removes any venue marked blocked: true in seed.js. Permanent exclusions — chains, off-standard hotels, venues that have declined in quality — never make it through regardless of what Claude picks.
5
Env Block
Removes venues whose declared environment is structurally incompatible with the requested category. Also strips environment-specific blocks set via environment_blocked in seed.js.
6
Surrounding Block
Removes venues from outside the core market unless the member explicitly checked "include surrounding areas" on the dashboard.
05 Photos Get Attached
What happens
Each venue that passes all six guards gets photos pulled in parallel — multiple venues fetch simultaneously so this doesn't add sequential wait time.
Source priority
1. Explicit photo override in seed.js — bypasses all fetching entirely. 2. The venue's own website og:image tag, validated by a Haiku vision check (must show interior or ambiance — not a menu, logo, or exterior). 3. Google Places top photos, each checked by Haiku vision in parallel. First one that passes wins.
Fast fetch mode
Per-card lazy load (/api/venue-photo) skips the vision check to avoid rate limits and returns the first 3 Places photos directly. Used after the initial stream completes.
06 Cards Appear on Screen
What happens
Venues stream to the member one by one as they clear the filters and get photos attached. The member is not staring at a blank screen waiting for all six — cards appear progressively as each one completes.
Order
Venues arrive in the order Claude chose them, which reflects its confidence ranking. The wild card arrives last with a distinct visual treatment.
Timing
Cache hit: under 2 seconds. Cache miss (cold path): first card in ~3 seconds, full set in 15–30 seconds depending on market size and photo availability.
07 Result Gets Saved
What happens
Once the full stream completes, the entire result — all venues plus the wild card — is written to market_venue_cache in Supabase, keyed by market + intent + environment.
Effect
The next member (or the same member) requesting the same market × intent × tier gets an instant cache-hit response. No AI call, no searches, no cost — just the saved result streamed directly.
Lifetime
7 days. After that the cache entry expires and the next request runs the full pipeline again, pulling fresh search signals and a fresh Claude pick.
Cost per cold run
~$0.004–0.007 USD total. Claude Sonnet curation call: ~$0.004–0.006. Google Places photo lookups: ~$0.002. Pool hits: $0.00. Cache hits: $0.00. Unit economics improve with scale — the fraction of requests served from precomputed pools (zero marginal AI cost) increases with every weekly pipeline run. As pool coverage deepens across all market × intent × environment combinations, the marginal cost per curation trends toward zero.
08 The Member Books New — July 2026
What happens
The three curated cards are the end of the curation pipeline — not the end of the journey. When a member opens a STAY venue and taps Book, CurateVIP hands off to our branded booking layer with the hotel and dates already selected. Curation stays entirely ours; fulfilment is handled by our White Label partner.
Two paths
27 of 37 STAY venues exist in LiteAPI inventory and deep-link to our branded White Label site (book.curatevip.ai) — a dark, gold, CurateVIP-skinned booking experience where Nuitee is merchant of record. The other 10 venues are not in LiteAPI and fall back to an Expedia affiliate deep link. Both earn commission.
Deep link
The Book button builds book.curatevip.ai/hotels/{liteApiId}?checkin=…&checkout=…&occupancies=… — the member lands on the exact hotel, dates pre-filled, never touching a search box.
Why not book in-app
Taking payment ourselves would make CurateVIP the merchant of record — triggering PCI scope, Seller of Travel registration in CA/FL/HI/WA, and refund/chargeback liability. Routing through the White Label keeps all of that with Nuitee while we keep the brand, the commission, and the curated experience. Full architecture → System Docs §23.
System Documentation
When you tap Curate
When a member taps Curate, CurateVIP executes more coordinated infrastructure than most search engines run per query. A two-tier pre-computation check (precomputed pools + 7-day result cache) resolves most requests before any AI is called. On a full cache miss: 14+ parallel Brave Search queries fire, Claude Sonnet curates against live credential signals, a six-guard post-filter chain validates every pick, Haiku vision-classifies photos, and editorial FEEL/WHY prose is served from a permanent per-venue content cache. This is what separates a curation engine from an AI wrapper. Here's exactly how every layer works.
01
Tap Curate
Skeletons appear
02
Cache Check
Instant on hit
03
Claude Streams
Cache miss ~3s
04
Guards Run
3-filter chain
05
Vision Classify
Non-seed venues
06
DB Cache
FEEL/WHY applied
07
Photos Load
OG check + sorted
00 The CURATE Principle

"Return the best 3 matching venues for this speed tier in this market. Never hold back a great match because it's well-known."

CURATE's job is to return the best 3 matches for the member's speed tier. Full stop. For Vanguard members, the Four Seasons and Ritz-Carlton ARE the answer. For Sanctuary, Atelier, and Estate members, a lesser-known discovery is usually the better match — but never exclude a great match simply because it's well-known.

The test
Does the result genuinely match this member's speed tier at ultra-luxury caliber? That's the only test. Not "have they heard of it" but "is it the right answer for their speed?"
00A Quality Over Count New — June 30

"1 exceptional venue + honest contextMessage is always better than 3 mediocre venues with no message."

The platform's entire value is curation credibility. A member who sees a mediocre or questionable venue loses trust in every other recommendation. The AI is explicitly instructed: never stretch a venue's fit to clear a count threshold. If in doubt, the answer is no.

Thin Market Honesty
When contextMessage fires
Whenever the AI cannot find 3 venues it is fully confident belong at this caliber with no hesitation. This is quality-based, not count-based. Even if there are 3 results, if the AI isn't certain about one of them, contextMessage should be set.
When contextMessage is null
Only when there are 3 or more venues the AI is fully, unambiguously confident in. If any doubt exists, set the message.
Example message
"Seattle is thin on luxury outdoor dining — weather-permitting patios typically open June through September. The venue below genuinely earns it; we'd rather tell you than pad the list."
contextMessage placement
Rendered above the venue listings, not below. 16px Cormorant Garamond italic, rgba(255,255,255,0.72), gold left border. Always the first thing the member reads when results are thin.
The Core Principle in Code (server.js prompt)

NEVER: stretch a venue's fit to clear a count threshold. If you are uncertain whether a venue belongs, the answer is no. Return 1 or 2 venues with a contextMessage rather than 3 venues where one is a compromise.

00B The Problem We Solve — Member Time Value New — June 30

"You've spent hours on this before. Scrolling photos, reading reviews, trying to feel whether a room matches your mood. We built CurateVIP so you never have to do that again."

The Research Problem Every Luxury Traveler Knows

CurateVIP was built around a specific, real frustration. When a high-net-worth traveler arrives in an unfamiliar city and wants to find the right restaurant or hotel — not just any good one, but the one that matches how they experience spaces — they face a research process that is broken in several distinct ways. The time cost is real, the error rate is high, and no existing product solves it.

What a Thorough Search Actually Costs
Step 1 — Source navigation ~14 min
A thorough traveler opens 14 tabs: Michelin Guide, James Beard Foundation, Forbes Travel Guide, Eater, Robb Report, Wine Spectator, Food & Wine, Condé Nast Traveler, World's 50 Best, and more. Just navigating each site, finding the city-specific section, and locating the relevant award or list takes roughly a minute per source. This is before reading a single result.
Step 2 — Reading each source ~42–56 min
Each source covers the city differently — some by award tier, some by category, some by year. Reading and noting relevant venues takes 3–4 minutes per source. Across 14 sources: 42–56 minutes of active reading, and most sources surface different venues with no overlap, so nothing can be skipped.
Step 3 — Compile and cross-reference ~45–60 min
Now the traveler has a raw list — dozens of venues across 14 sources with no structure. Compiling it into something usable means identifying which venues appear in multiple lists (a meaningful signal), which awards are recent vs. years old, which are venue-level credentials vs. chef-level accolades that don't actually belong to the current restaurant. This step is deceptively slow. A thorough job takes 45–60 minutes. Most travelers give up halfway through and go with whatever name felt most familiar — which is exactly how bad recommendations happen.
Step 4 — Match to personal taste ~60 min+ (often 2–3 hrs)
This is the step that breaks people. The traveler now has a shortlist of credentialed venues and no way to know which one is actually right for them tonight. So they open each restaurant's website, scroll their Instagram, read Google and Yelp reviews, look at interior photos, try to feel whether the energy of the room — the lighting, the crowd, the vibe — is what they want. It sounds like it should take 10 minutes. It rarely does. For a thorough traveler comparing 6–8 venues, this step alone runs 60 minutes conservatively. Many people spend 2–3 hours here. And at the end of it, they still aren't sure — because photos lie, reviews are generic, and nothing tells you whether this place matches how YOU experience spaces.
Step 5 — Credential verification Most people skip this entirely
The final step a truly diligent traveler would take: verify that the awards they found actually belong to the venue as it exists today — not a chef who left, not a prior location, not an award earned 8 years ago before a change of ownership. Almost no one does this. The ones who skip it occasionally book a table based on credentials that no longer apply and wonder why the experience didn't match expectations.

Conservative total: 2.5–3 hours per destination. For a traveler visiting a new city on a 3-day trip, researching where to eat and stay properly would consume most of a day. Most people don't do it properly — they default to what they've heard of, or ask a concierge, or rely on a recommendation from someone whose taste they only partially share. The research problem is real. The cost is high. And until CurateVIP, no product solved it.

What CurateVIP Does Instead
Steps 1–3 replaced entirely
All 14 sources are queried in parallel via Brave Search API. Results are extracted by Claude Haiku into a structured credential map. Cross-referencing, recency validation, and credential attribution (chef awards at prior employers do not transfer) are all enforced automatically at three layers of the pipeline. What takes a thorough researcher 2+ hours to compile is assembled in under 30 seconds.
Step 4 eliminated — not compressed
The taste-matching step — the one that costs most travelers an hour or more and still leaves them uncertain — is not compressed. It is eliminated. The Speed Tier profile built during CurateVIP onboarding captures how the member actually experiences spaces: what they notice first walking into a hotel lobby, whether they want to disappear or be seen, whether the food or the room is the reason they're there. Venues are matched to that profile before they ever reach the member. The member doesn't scroll and wonder. They receive three venues and immediately recognize that these are right for them.
Step 5 automated
Credential attribution is enforced at the Haiku extraction prompt, the signal block formatter, and the Sonnet curation prompt. Awards follow venues, not chefs. The step most travelers skip is the step CurateVIP handles automatically.
The Number

~360× faster than a thorough manual research session. And the manual version still doesn't match the member's taste profile, verify credential attribution, apply chain disqualifiers, or classify venues by primary environment.

Approved Marketing Copy
Hero line
"What used to take 3 hours of research across 14 tabs. Now takes 30 seconds."
Pain-point line
"You've spent hours on this before. Scrolling photos, reading reviews, trying to feel whether a room matches your mood. We built CurateVIP so you never have to do that again."
Precision line
"We check 14 authoritative sources in 30 seconds and hand you the three venues that match exactly how you dine or travel."
Authority line
"The research your travel advisor would take a week to compile — delivered in the time it takes to read this sentence."
01 Overview
Model
Claude Sonnet 4.6: one call that generates and self-verifies in a single pass.
Cache-first
Before calling Claude, server checks market_venue_cache for a stored result matching market + intent + environment. Hit: results returned instantly, $0.00 Sonnet cost. Miss: Claude called, result cached asynchronously.
Quality standard
Ultra-luxury caliber: properties operating at the level of Forbes Five Star, Michelin Key, or AAA Five Diamond. Formal credentials are reference points, not a hard gate.
Streaming
On a cache miss, Claude's response is streamed via SSE. First card ~3s, all 3 by ~7s. Skeleton cards fill the space while streaming.
Final output
Up to 3 venue cards + 1 Wild Card. Claude returns fewer than 3 if it cannot confidently identify enough qualifying properties. A short honest list beats a padded one.
Cost per AI run
~$0.004–0.007 USD (one Sonnet call, max 1,200 tokens). Cache hits cost $0.00.
04 Post-Filter Chain Updated — June 30

After Claude returns its venue list, four sequential server-side filters run in order before anything is sent to the client. The Signal Guard runs first — it is the only filter that requires a live Haiku call. The remaining three are mechanical checks against seed.js flags.

0
Signal Guard — Live Evidence Validation
A Haiku AI validation pass that checks each of Sonnet's proposed venue names against the raw Brave Search snippets collected in Phase 1. For each venue, Haiku returns one of three states: found (venue appears in live results — passes), not_found (no live evidence trail — rejected if not seed-confirmed), uncertain (indirect or ambiguous reference — always passes). Venues in seed.js with confirmed: true bypass this guard entirely. Runs only on cache misses (when fresh Brave Search data is in memory). On cache hit: skipped — the curation result was already validated on first run. Logged as [signal-guard] in Railway. Cost: ~$0.001–0.002 per run. Added June 30, 2026.
1
Seed-Block Filter
Removes venues marked blocked: true in seed.js. These are venues confirmed too casual, wrong tier, or otherwise not appropriate for the platform regardless of environment. Logged as [seed-block] in Railway.
2
Environment-Block Filter
Removes venues that are valid on the platform generally but are blocked for THIS specific environment. Controlled by environment_blocked: ['Verandah'] on a seed entry. Venue stays available for other environments; only stripped when the requested environment matches. Logged as [env-block].
3
Surrounding Filter
When includeSurrounding is false (default), removes all venues marked surrounding: true in seed.js. These are venues in the surrounding metro area that should only appear when the member explicitly checks the toggle. Logged as [surrounding-block].

Signal Guard bypass: Set confirmed: true on a seed entry to exempt it from Signal Guard validation. Use for venues with thin web presence that you have manually verified.

Adding a blocked venue: Set blocked: true on the seed entry. The venue is excluded from Claude's calibration prompt AND stripped from final results.

Adding an environment block: Set environment_blocked: ['Verandah'] on the seed entry. The venue remains available in all other environments.

Named examples: Canlis and Goldfinch Tavern both have environment_blocked: ['Verandah'] — they're valid indoor Seattle dining venues but should never appear when a member requests Verandah (physically-outdoors) results.

04B Beta Configuration New — June 30

Live beta uses a pared-down environment set and market list. All hidden items are commented out in code — not deleted — and can be re-enabled with a single line change.

Active Markets
Live for beta
Scottsdale · Seattle · Maui · Santa Barbara
Hidden (commented out)
Bellevue · Miami · Nashville · Los Angeles · Charleston
File
DashboardPage.jsx — MARKETS array, lines 56–67. Re-enable by uncommenting the relevant object.
Hidden Environments (Beta)
Verandah — hidden from TABLE & SOCIAL
Verandah is hidden from member-facing selections in both TABLE and SOCIAL for Phase 1. Members whose quiz result maps to Verandah (social) are assigned Gallery. Wild card adjacency map confirmed safe.
Vanguard — hidden from STAY
Vanguard is hidden from the stay speed selector for Phase 1. Wild card adjacency map confirmed safe.
File
DashboardPage.jsx — EXPLORE_SPEEDS object. Move environment string from comment back into the array to re-enable.
Surrounding Areas Labels (per market)
Seattle
"Include Eastside & Woodinville" — checkbox only appears when Seattle is selected
Scottsdale
"Include Greater Phoenix" — checkbox only appears when Scottsdale is selected
Maui
"Include Upcountry, Hana & North Shore" — checkbox only appears when Maui is selected
Santa Barbara
No surrounding areas — checkbox does not appear
04C Live Credential Spinner & Member Communication New — June 30

While the backend is fetching live credential signals and running Claude, the member sees a sequential narration of every source being checked — not a spinning wheel. This communicates that real work is happening on their behalf and builds trust that results are genuinely curated, not cached or random.

Source Sequences by Category
TABLE (8 sources)
Michelin recognition → James Beard Awards → World's 50 Best → Robb Report → Wine Spectator → Food & Wine → Condé Nast Traveler → Searching top restaurants in [City]
STAY (9 sources)
Forbes Five Star hotels → AAA Five Diamond → Leading Hotels of the World → Relais & Châteaux → Small Luxury Hotels → Condé Nast Traveler Gold List → Travel + Leisure World's Best → Robb Report hotels → Searching top hotels in [City]
SOCIAL (5 sources)
World's 50 Best Bars → Tales of the Cocktail → James Beard bar nominations → Robb Report bars → Searching top bars in [City]
Timing — Spread Across 25 Seconds

Each source message is displayed for Math.floor(25000 / msgCount) milliseconds, spreading all sources evenly across ~25 seconds regardless of how many sources the category has. The full curation averages ~36 seconds — this ensures the member sees meaningful activity for the majority of that wait, not a 7-second flash followed by 29 seconds of a static spinner.

TABLE: 8 × 3,125ms = 25s  |  STAY: 9 × 2,778ms = 25s  |  SOCIAL: 5 × 5,000ms = 25s

Status Messages — After Sources Complete
"Found X verified venues · Curating just for you…"
Shown as soon as the first Claude response chunk arrives, or when the source list finishes — whichever comes first. The count comes from a server-sent event: status SSE payload with credentialedVenueCount. If the count is 0, shows "Curating just for you…" with no count.
"Paired X match(es) just for you"
Shown when the final validated venue list arrives (SSE event: venues). Immediately followed by each venue name with a ✓ checkmark, one per 650ms.
Phase 1 — SOCIAL Tab Hidden

Decision (June 30, 2026): The SOCIAL tab is disabled for Phase 1 beta. The button remains visible in the UI at 40% opacity with a "COMING SOON" badge — it is not removed from the interface. This approach signals the product roadmap to members and investors without implying the feature doesn't exist. Re-enable by removing the comingSoon flag from the CATEGORIES map in DashboardPage.jsx.

Implementation
const comingSoon = key === 'social' — sets opacity: 0.4, cursor: default, disabled={true}, and renders a "COMING SOON" sub-label. onClick is undefined (not a no-op) so click does nothing. Single-line change to re-enable.
02 Generation: Quality Standard

The full quality floor — qualifying credentials, named disqualifiers, and the "floor without credentials" rule — is documented in the IP Methodology tab, Section D. That is the authoritative source. The short operational summary: ultra-luxury caliber only. Forbes Five Star, Michelin Key, AAA Five Diamond, Relais & Châteaux, and flagship brands (Aman, Four Seasons, Ritz-Carlton, Rosewood) all qualify. TripAdvisor, Five Star Alliance, and AAA Four Diamond do not. Formal credentials are reference points — not a mandatory gate — but the spirit of the floor must be met.

Key rule
If you are uncertain whether a venue clears the floor, it does not clear the floor. The quality floor is what makes CURATE trustworthy. Without it, it's an opinionated list. With it, it's a methodology.
04A Environment Quick Reference Updated — June 30

One-line operational summaries for daily use. Full canonical definitions, primary tests, and disqualifiers are in IP Methodology tab, Section C — that is the authoritative source. Never update the AI prompt or seed classifications without checking Section C first.

Vanguard (STAY)
The brand name alone is the reason. Four Seasons, Ritz-Carlton, Rosewood, Aman, Fairmont, St. Regis.
Atelier (STAY)
Architecture is the primary identity. The design concept is the lead editorial narrative.
Sanctuary (STAY)
Privacy and restoration are the product. Intimate, hushed, zero scene.
Estate (STAY)
Genuine historical heritage. Old-world architecture. A story predating modern luxury brands.
Provision (TABLE)
Organic energy, full bar, real conversation, excellent food. Not manufactured — no DJ or bottle service.
Couture (TABLE)
The room takes you somewhere else. Design-as-destination. You'd go for the room as much as the food.
Shadow (TABLE & SOCIAL)
Dark, considered, atmospheric. Mood is the amenity. You had to know it was there.
Verandah (TABLE & SOCIAL)
The table or bar surface is physically outside, under the sky. Not indoors with views — actually outside. Hidden from TABLE and SOCIAL for Phase 1.
Pulse / Electric (TABLE & SOCIAL)
Scene, energy, the right crowd. Being seen is part of the value.
Gallery (SOCIAL)
Design you feel before you see. Intimate, selective, visually intelligent.
Named Environment Blocks (seed.js)

environment_blocked field: A venue valid on the platform for some environments can be blocked from others. Set environment_blocked: ['Verandah'] to strip that venue when the requested environment matches — without removing it from other environments.

Current blocks: Canlis — environment_blocked: ['Verandah'] (Provision/Couture, never Verandah). Goldfinch Tavern — environment_blocked: ['Verandah'] (indoor glass-walled room at Four Seasons). See IP Methodology §F (Canlis worked example) for the full classification rationale.

06 Include Surrounding Areas Updated — June 30

A checkbox beneath the location dropdown expands the venue pool beyond the core market. The label is market-specific (not a generic "surrounding areas"). Only appears for markets that have surrounding areas defined.

How It Works
Toggle behavior
Checking the box after results are already shown automatically fires a new curation — no extra button needed. The includeSurrounding state change triggers a useEffect that calls handleCurate() if hasCurated is true. Unchecking does the same.
Reset on market change
Switching markets auto-unchecks the surrounding areas checkbox and sets includeSurrounding = false.
Frontend filter
MARKETS array in DashboardPage.jsx now has hasSurrounding and surroundingLabel per market. Checkbox only renders when hasSurrounding: true.
Backend — seed filter
(includeSurrounding || !v.surrounding) — surrounding venues are invisible to Claude's calibration prompt when toggle is off. They appear in the seed reference block when toggle is on.
Backend — post-filter
Even if Claude surfaces a surrounding venue from its training data, the surrounding post-filter strips it from finalVenues when !includeSurrounding. This is the safeguard that the seed filter alone doesn't cover.
Surrounding Venues in seed.js
Flag
surrounding: true on any seed entry marks it as a surrounding venue. No other changes needed.
Seattle surrounding venues
Willows Lodge (STAY), The Herbfarm (TABLE), Salish Lodge (STAY), The Barking Frog (TABLE — Provision, not Verandah)
Scottsdale surrounding venues
Royal Palms (STAY), The Global Ambassador (STAY), Wren & Wolf (TABLE), Théa at Global Ambassador (TABLE), Steak 44 (TABLE)
Maui surrounding
No surrounding venues currently flagged — Maui metro covers the full island for our caliber level.
Santa Barbara
No surrounding areas — Montecito is part of the core metro. No checkbox shown.
05 Per-Card Photo Loading
Architecture
Text-first. Member reads venue name, FEEL, and WHY immediately while photos load behind the scenes. Previous architecture fetched all photos before showing results (4–8s delay). Text-first delivers decision content in ~3s.
TABLE photo order
Slot 1: OG image from venue website (if interior). Slots 2–4: Google Places interior shots. Slots 4–5: food photos. OG food shots appended at end, not promoted to slot 1. Logos/graphics silently dropped.
Cache
venue_photos table (Supabase), 7-day TTL. Cache hit = sub-100ms, no Google call.
Photo proxy
All photos proxied through Railway (/api/photo) to avoid CORS. Browser-cached 24 hours.
10 Caching + Show More
Layer 0: market_venue_cache — Selection Cache
Key
market + intent (dining/stay/social) + environment. All three must match for a hit.
Cache hit
Returns stored venues JSON immediately. No Claude call, zero Sonnet cost, sub-100ms.
TTL
No automatic expiry. Clear manually: DELETE FROM market_venue_cache WHERE market = 'seattle';
When to clear
After updating seed.js for a market (new venues, reclassification, blocking changes). The content cache (venue_ai_content) does not need clearing — it's keyed by venue name.
Layer 1: venue_ai_content — FEEL/WHY Cache (Permanent)
Scope
Permanent. Once a venue's FEEL/WHY is generated it's stored indefinitely. One row serves all users. Same copy for every member who sees a venue.
Layer 2: venue_photos — Photo Cache (7-Day TTL)
Expiry
7 days. After expiry, Google Places is re-queried so photos stay reasonably fresh.
Layer 3: Browser Session (Zustand)
Scope
In-memory, resets on page refresh. Switching market/intent and back shows previous result instantly.
Show More
Mechanism
Fresh /api/curate call with currently displayed venue names as excludeVenues. Claude returns 3 new venues it hasn't shown yet. Wild card not included in Show More batches.
11 The Speed Engine — Autonomous Discovery Pipeline New — July 2026

"The Speed Engine runs while members sleep. It finds, evaluates, and pre-loads every qualifying venue into precomputed pools — so when a member taps CURATE, the answer is already there."

The Speed Engine is CurateVIP’s autonomous discovery and pre-computation layer — the infrastructure that makes the member experience feel instant. It runs every Sunday on Railway, completely independently of any member action, executing a four-scraper pipeline that pulls structured data from Michelin’s rendered DOM, Lartisien’s paginated city listings, Forbes’s award-winners JSON API, and 30 targeted Brave Search queries per weekly run. Every discovered venue is scored 0–100 across 13 weighted signals, evaluated by Claude Haiku for CCTF environment classification, passed through a quality gate, and pre-ranked into precomputed_venue_pools — one row per market × intent × environment combination. The result: the first time a member taps CURATE in any market, the answer is likely already there. The system gets faster and more complete with every weekly run, compounding its advantage over any product that discovers venues in real time.

Phase 1 — 4 Scrapers
Michelin Scraper (v7)
Puppeteer headless Chrome renders Michelin Guide hotel listings per market. Selectors: .card__menu-content for hotel cards, .michelin-award for Key recognition. Extracts name, Michelin Key status, guest score, member privileges. Writes to michelin_hotels. Technology: Puppeteer DOM — not Brave Search. Ground truth from Michelin's own rendered pages.
Lartisien Scraper (v3)
Puppeteer renders Lartisien city listing pages at /hotels/united-states/{slug}. Walks pages via ?page=N until no new hotel slugs appear. City-keyword filtering strips promoted non-market cards. Names extracted from h2/h3 inside hotel links. Markets: Scottsdale, Los Angeles, Santa Barbara. Seattle and Maui skipped (no Lartisien coverage). Writes to lartisien_hotels.
Forbes Scraper
Direct JSON API: fetches forbestravelguide.com/award-winners.json — 2,400+ properties as structured JSON. No browser required. Filters to propertyType: 'HOTEL' then by city name. Ratings stored: FIVE_STAR, FOUR_STAR, RECOMMENDED. One API fetch covers all 5 markets. Writes to forbes_hotels.
Broad Search Scraper
6 Brave Search queries per market: AAA Five Diamond, Relais & Châteaux, Leading Hotels of the World, Small Luxury Hotels, Condé Nast Gold List, T+L World's Best. 5 markets × 6 queries = 30 searches. Hotel names from page titles after stripping award and site suffixes. Writes to broad_search_hotels.
Market coverage per scraper
Market Michelin Lartisien Forbes Broad Search
Scottsdale
Los Angeles
Santa Barbara
Seattle✗ (no coverage)
Maui✗ (no coverage)
Lartisien does not list Seattle or Maui properties — those markets use only 3 scrapers. All others get full 4-scraper coverage.
Broad Search name-extraction (July 2026 fix)
Early runs stored article titles instead of hotel names (e.g. “Best Luxury Hotels in Scottsdale, AZ 2026” or “Here Are the Top Resorts”). Fixed in broadSearchScraper.js extractHotelName() with two enhancements. (1) Strip patterns: em-dash subtitle strip (/\s*[—–]\s*.+$/) removes everything after an em/en dash; geographic suffix strip removes “ in City, ST 2026” patterns. (2) Generic title guards: new patterns reject any extracted name that starts with “the best”, “review of”, or article-opener phrases (this is / these are / here are / here’s / why / how / what / inside / meet / proud / discover / explore / introducing / welcome / find / ranked / rated / voted), ends in punctuation (.!?), ends with a year, or is longer than 8 words. If all these checks fail to produce a clean name, extractHotelName() returns null and the scraper skips that result entirely. Bad DB rows from pre-fix runs were cleaned via Supabase SQL (DELETE FROM broad_search_hotels WHERE name ~ pattern).
scrape_log contract
Every scraper writes a scrape_log entry on success AND error, including source, market, new_venues count, status, and error_message. The AdminDiscoveryPage polls scrape_log for status: 'complete' or status: 'error' to track pipeline progress in real time. If a scraper cannot write to scrape_log, it logs at CRITICAL severity — this breaks the frontend polling contract.
Phase 2 — Quality Scoring (0–100 Points)

engine/qualityScore.js reads all 4 scraper tables to compute a composite score per venue. Stored in venue_quality_scores.

Michelin Key
+25 pts
Forbes Five Star
+25 pts
AAA Five Diamond
+20 pts
Michelin guest score ≥ 19
+15 pts
Lartisien listed
+15 pts
Relais & Châteaux
+12 pts
Leading Hotels of the World
+10 pts
Michelin guest score 18.5–18.99
+8 pts
Seed confirmed (manual)
+8 pts
Condé Nast Gold List
+7 pts
T+L World's Best
+7 pts
Robb Report
+5 pts
Michelin member privileges
+3 pts
3+ source-bucket convergence
+10 pts  — buckets: michelin / forbes / editorial / luxury_curation
2 source-bucket convergence
+5 pts  — total score capped at 100
Phase 3 — Discovery Bridge (3 Passes)

services/discoveryBridge.js evaluates venues from each scraper table not already in seed or pending queue. Three sequential passes with an identical sub-pipeline:

Pass 1 — Michelin source
Reads michelin_hotels. Per venue: dedup check against seed.js + pending_venues → Brave Search enrichment (description + location context) → cross-reference Forbes + Lartisien tables → Claude Haiku classifies (CCTF environment + quality_pass) → computeQuickScore() → upsert to pending_venues.
Pass 2 — Forbes source
Reads forbes_hotels. Same sub-pipeline: dedup → enrich → cross-reference Michelin + Lartisien → Haiku classify → upsert.
Pass 3 — Broad Search source
Reads broad_search_hotels. Same sub-pipeline: dedup → enrich → cross-reference all 3 tables → Haiku classify → upsert.
Claude Haiku classification
Receives: venue name, description, location, scraped signals, cross-reference hits. Returns: environment (CCTF tier — Atelier, Sanctuary, Estate, Vanguard) and quality_pass: true/false. This is the quality gate decision for each discovered venue.
Error philosophy
Dedup query errors: warn + continue (assume venue exists — conservative, prevents false duplicates). Cross-source lookup errors: warn + continue (signal absent this run; quality score will be lower). Delete-before-rewrite failure: throw immediately — abort market, prevent stale/fresh data mix. Batch upsert failures: tracked per batch, thrown as aggregate after processing.
Phase 4 — Quality Gate
quality_pass: true
Venue status = 'approved'. Goes live immediately — included in the next precompute run without any manual review.
quality_pass: false
Venue status = 'pending'. Enters the admin review queue. Requires manual approval before appearing in member curations.
Storage
pending_venues holds all discovered venues in both states. Approved venues enter precompute. Pending venues wait in the queue.
Phase 5 — Precompute
What it does
services/precompute.js reads all non-blocked seed venues plus approved discovered venues per market. Ranks by quality score × intent affinity × environment match. Writes to precomputed_venue_pools — one row per market + intent + environment combination.
Delete-rewrite integrity
Old pool rows are deleted before new rows are written. Delete failure → throw immediately (prevents a stale/fresh pool mix). Any batch write failure is tracked and thrown after completion. These are the highest-severity guards in the entire pipeline.
Output
precomputed_venue_pools — queried by the curation pipeline for instant results when a member taps CURATE. A pool hit = sub-100ms delivery. The entire Speed Engine exists to make this table complete and accurate.
Pipeline Endpoints
Full pipeline (cron + manual)
POST /internal/run-scrapers with x-cron-secret header — all 4 scrapers → discovery bridge (3 passes) → precompute (all markets). Monitored via AdminDiscoveryPage polling scrape_log.
Discovery only
POST /internal/run-discovery — bridge only, no re-scraping. Use when scraper data is fresh but re-classification or re-scoring is needed.
Precompute only
POST /internal/precompute-all-markets — reruns precompute only. Use after manually approving pending venues to push them into live pools immediately without waiting for the next full pipeline run.
Cron Schedule & Railway Setup
When it runs
Every Sunday via two Railway Cron services running against the same backend repo. Cron Service 1 fires at 2:00 AM UTC Sunday (0 2 * * 0) and runs all 4 scrapers + quality score recompute. Cron Service 2 fires at 4:00 AM UTC Sunday (0 4 * * 0) and runs precompute for all markets. The 2-hour gap gives scrapers time to complete before precompute starts building pools from fresh data.
Railway cron service setup (Phase 4C)
One-time setup in Railway dashboard:
1. Open the curatevip-backend project in Railway.
2. Click New Service → Cron.
3. Set Source to the same backend repo (curatevip-web, /backend path).
4. Cron Service 1 — Schedule: 0 2 * * 0   Start Command: curl -fsS -X POST $API_BASE_URL/internal/run-scrapers -H "Authorization: Bearer $INTERNAL_CRON_SECRET" -H "Content-Type: application/json"
5. Cron Service 2 — Schedule: 0 4 * * 0   Start Command: curl -fsS -X POST $API_BASE_URL/internal/precompute-all-markets -H "Authorization: Bearer $INTERNAL_CRON_SECRET" -H "Content-Type: application/json"
6. Set environment variables on each cron service: INTERNAL_CRON_SECRET (same value as main API service) and API_BASE_URL=https://api.curatevip.ai.
7. Deploy both services. Railway will run them on the defined schedule permanently.

Until Phase 4C is configured in Railway, the pipeline can be triggered manually via the Admin → Discovery tab Run Pipeline button (or directly via POST /internal/run-scrapers).
Authentication
All /internal/* endpoints require the x-cron-secret header with value equal to INTERNAL_CRON_SECRET env var. This is a different secret from ADMIN_SECRET (which protects /api/admin/*). Never expose either value in logs or screenshots.
12 Discovery Mandate

"Before you pick a venue, sweep the full geography and the full reference stack."

Geographic sweep
Claude is explicitly instructed not to anchor to the main luxury hotel corridor or the first results that surface. The full metro geography is always in scope.
Reference sweep
Local awards ('Aipono, Hale 'Aina, James Beard nominees), global credentials (Relais & Châteaux, Michelin, Forbes), local publications (Maui No Ka 'Oi, Phoenix Magazine, The Infatuation city guides).
Why it was added
Maui TABLE deep-dive (June 2026) revealed that default AI behavior missed The Restaurant at Hotel Wailea (Relais & Châteaux), nyloS (14-seat chef's table, 'Aipono Gold), and Nobu Maui. All three required explicit reference sweep to surface.
13 Multi-Environment Wild Card System
Detection
server.js scans all seed entries for the current market + category. Any venue appearing in 2+ environment entries is flagged as a multi-environment venue and promoted as a priority wild card candidate.
How to create
Add a separate seed entry for each environment the venue qualifies in. Same name, same city, same market, same category — different id and environment value. The detection code finds both entries and flags the venue automatically.
Example (Maui)
KOAST seeded as both Provision and Verandah. Mama's Fish House as both Couture and Provision. Cane & Canoe as both Couture and Verandah.
14 Chain Disqualifiers — STAY vs TABLE

Hotel chain disqualifiers apply to STAY recommendations only. A great restaurant at a disqualified hotel still qualifies for TABLE on food quality, environment, and experience alone.

STAY Disqualified (Restaurants Still Qualify for TABLE)
Marriott (including JW Marriott, Autograph Collection, Renaissance)
Westin / Sheraton / W Hotels / Le Méridien (Marriott portfolio)
Hyatt Regency / Hyatt Place / Hyatt Centric / Thompson Hotels
Hilton / DoubleTree / Embassy Suites / Curio Collection / Conrad
Wyndham / Ramada / La Quinta / Days Inn
15 AI-First Architecture

"Live credential intelligence is the signal. Seed data is the calibration. Claude's judgment is the engine." Updated — June 30

Layer 1 — Live credential intelligence
At curation time, the system fires parallel Brave Search queries across up to 22 authoritative sources (Michelin, James Beard, Forbes, Robb Report, Condé Nast, etc.). Claude Haiku extracts structured credential signals from raw snippets. This block is fed to Claude Sonnet before any recommendation is made. Claude does not recall credentials from training memory — it reasons from live data fetched seconds before it responds. Cached 7 days per market + category.
Layer 2 — Seed data calibration
Quality anchor: shows Claude what ultra-luxury looks like in this specific market. Environment calibration: confirmed classifications give Claude concrete examples to reason from. Blocked venues are excluded from the calibration prompt so Claude never considers them. Seed data does NOT constrain Claude to a pre-approved list — it calibrates Claude's judgment, which then surfaces any qualifying venue it knows, seeded or not.
Layer 3 — Claude's judgment
Claude Sonnet synthesizes live credential signals + seed calibration + the member's speed profile + the quality floor + attribution rules into a ranked recommendation. Its training provides the background knowledge of venues; the live intelligence and seed layers provide the current-state context. Claude returns fewer than 3 venues if confidence isn't there — judgment, not padding.
Adding a new market
Step 1: add market to MARKETS object in seed.js (name, state, metro cities). Step 2: add pill to MARKETS array in DashboardPage.jsx. That's it — Claude curates immediately using live intelligence + its training knowledge. Seed venues are optional and can be added any time to deepen calibration.
16 The Scout — Reservation Platform Detector

"The Scout goes ahead of the member, finds the reservation door, and comes back with the right link."

Trigger
POST /api/find-reservation — called when a member views a venue detail page. Fires once, caches 30 days.
4-step pipeline
00 Supabase Cache → 01 Google Places (get website) → 02 Puppeteer headless crawl (PRIMARY) → 03 HTTP regex scan (FALLBACK) → 04 Google CSE fallback (scoped to OpenTable, Resy, SevenRooms, Tock domains)
Cache policy
Successful finds only — 30-day TTL. "Not found" results are never cached so The Scout retries fresh on every visit until it finds something.
Reserve button fallback
If platform found: links directly. If only website found: { platform: 'Website', url: venueWebsite }. If nothing found: Reserve button hidden or disabled.
17 Database Schema Updated — July 2026
Supabase Tables
members
id, first_name, last_name, email (UNIQUE), phone, city/city_2/city_3, invite_code (UNIQUE), member_number, invited_at, accepted_at, profile_completed_at, status (invited·accepted·complete), speed_profile (JSONB), stay_answers/table_answers/social_answers (JSONB)
invite_requests
id, full_name, first_name, last_name, email, city, net_worth, travel_frequency, note, status (pending·approved·rejected·waitlisted), created_at
venue_ai_content
venue_name (PK), market, category, environment, feels_like, match_note, description, luxury_credential — Permanent, no TTL
venue_photos
venue_name (PK), photos (text[]), fetched_at — 7-day TTL
venue_reservation_links
venue_name (PK), city, platform, url, checked_at — 30-day TTL
market_venue_cache
id (PK), market, intent, environment, venues (JSONB), wild_card (JSONB), updated_at — Manual clear only (SELECTION CACHE: Layer 0)
Speed Engine Tables New — July 2026
michelin_hotels
id, market, name, michelin_key (bool), guest_score (float), member_privileges (bool), scraped_at — UNIQUE on (market, name)
lartisien_hotels
id, market, name, scraped_at — UNIQUE on (market, name). Markets: scottsdale, los-angeles, santa-barbara only (seattle + maui skipped, no coverage)
forbes_hotels
id, market, name, forbes_rating (FIVE_STAR · FOUR_STAR · RECOMMENDED), forbes_uri, city, scraped_at — UNIQUE on (market, name)
broad_search_hotels
id, market, name, query_tag (aaa_five_diamond · relais_chateaux · leading_hotels · small_luxury · conde_nast_gold · tl_worlds_best), scraped_at — UNIQUE on (market, name)
pending_venues
id, market, name, description, environment (CCTF tier), quality_pass (bool), status (pending · approved · rejected), quality_score (0–100), signals (JSONB), source (michelin · forbes · broad_search), discovered_at, reviewed_at
venue_quality_scores
venue_id (FK to seed venue id), market, quality_score (0–100), signals (JSONB breakdown of each signal scored), computed_at — UNIQUE on (venue_id, market)
precomputed_venue_pools
id, market, intent (dining · stay · social), environment (CCTF tier), venue_list (JSONB ordered array), computed_at — cleared and fully rewritten on each precompute run. Queried by curation pipeline for sub-100ms pool hits.
scrape_log
id, source (michelin · lartisien · forbes · broad_search · discovery · precompute), market, new_venues, key_changes, status (complete · error), error_message, created_at — append-only. AdminDiscoveryPage polls for status = 'complete' or 'error'.
Speed Profile SQL Override
UPDATE members
SET speed_profile = '{"stay":"atelier","table":"couture","social":"shadow","stayLabel":"The Atelier","tableLabel":"The Couture","socialLabel":"The Shadow"}'
WHERE email = 'member@example.com';
18 Future Features
Curate Book (embedded reservations)
Built, off by default. Flip USE_EMBEDDED_BOOKING = true in VenueDetailPage.jsx line 11 to re-enable instantly. Off because Tock blocks iframe embedding (X-Frame-Options: DENY).
Affiliate IDs
OpenTable: email affiliates@opentable.com. Resy: email partnerships@resy.com. Once live, add applyAffiliateParams() in server.js to append before URL is returned.
Google OAuth — production
Currently in Testing mode. Needs Publish in Google Cloud Console to allow accounts outside the test list. Task #36.
Beta Re-enable Checklist
Add Verandah back to EXPLORE_SPEEDS.dining in DashboardPage.jsx
Add Vanguard back to EXPLORE_SPEEDS.stay in DashboardPage.jsx
Uncomment additional markets in MARKETS array (Bellevue, Miami, Nashville, etc.)
Publish Google OAuth app (Testing → Production)
99 The Definition Drift Rule

The single biggest source of classification errors in this project was definitions evolving in conversation while old code ran with stale definitions. Four Seasons was tagged Estate in the AI prompt while Vanguard was simultaneously defined as brand flagships. These errors required human intervention to catch, multiple times.

The Rule: Definition First. Always.
1. Definitions live here
This document is the source of truth. Not the AI prompt. Not seed.js. Not a conversation. Here.
2. Order of operations
Update this doc → update ENV_DEFINITIONS in server.js → update seed.js. In that order. Never the reverse.
3. Never update code mid-conversation
Confirming a definition in chat and immediately coding it without updating this doc is how drift happens. Lock it here first.
Pre-Change Checklist
Definition updated in this doc
ENV_DEFINITIONS in server.js matches this doc
Named examples in AI prompt match this doc
All properties in seed.js classified per this doc
Hit RESET on dashboard after deploying to clear Zustand cache
Clear market_venue_cache in Supabase for any affected markets
20 Tech Stack
Backend
Node.js / Express on Railway. Single server.js entry point + extracted engine modules (engine/curate.js, engine/taxonomy.js, engine/scoring.js) + services layer (websearch.js, broadSearchScraper.js, michelinScraper.js, lartisienScraper.js, precompute.js, discoveryBridge.js, qualityScore.js, reservationScout.js).
Frontend (web)
React + Vite on Vercel. Shared Supabase auth. React Native (Expo) mobile app in progress — same backend, same Supabase instance.
Database
Supabase (Postgres). Tables: venues, market_venue_cache, venue_content_cache, venue_photo_cache, vision_classifications, precomputed_venue_pools, michelin_hotels, forbes_hotels, lartisien_hotels, broad_search_hotels, pending_venues, venue_quality_scores, scrape_log, admin_credentials, members, classification_corrections.
AI
Anthropic API. Claude Sonnet 4.6 for curation + FEEL/WHY editorial. Claude Haiku for credential extraction, CCTF classification, Signal Guard, photo vision check.
Search
Brave Search API. 14+ queries per curation run. 30 targeted queries per weekly Speed Engine run. Privacy-respecting, personalization-free results — more reliable than Google for extracting award-program hotel lists from editorial sources.
21 Two-Model AI Architecture
Claude Sonnet — The Curator
Handles all member-facing decisions: venue selection against the member’s CCTF speed profile, FEEL editorial prose, WHY personalization copy. Receives the full live credential signal block, the seed calibration layer, the quality floor definition, and the member’s speed tier. Every recommendation that reaches a member passes through Sonnet’s editorial judgment. Cost: ~$0.004–0.006 per cache-miss curation run. Cached result: $0.00.
Claude Haiku — The Validator
Handles all background validation and classification: Signal Guard (found / not_found / uncertain per candidate venue), CCTF environment classification in the Speed Engine Discovery Bridge, credential extraction from raw Brave Search snippets, photo vision check (interior / ambiance pass/fail). Fast, cheap, purpose-specific. Cost: ~$0.0003–0.002 per call depending on task.
Why two models
Sonnet’s editorial judgment and contextual reasoning are the right tool for curation. Haiku’s speed and cost efficiency are the right tool for classification and validation at pipeline scale. Swapping either model changes an API call, not the architecture — the system is provider-agnostic at the model level. The split also isolates cost: Sonnet runs once per result set (cached 7 days), Haiku runs on every validation task (individually cheap at scale).
Decision boundary
Any decision requiring editorial taste, contextual judgment, or member personalization = Sonnet. Any decision requiring fast binary classification, structured extraction, or validation of a specific factual claim = Haiku. The boundary is stable: Sonnet curates, Haiku validates.
22 Key Files Reference
Engine
engine/curate.js
Core curation pipeline. Cache check → credential queries → Sonnet curation → Signal Guard → post-filters → photo/vision → editorial. Called per member tap from server.js.
engine/taxonomy.js
All CCTF taxonomy constants. ENV_COLORS, INTENT_MAP, speed tier names, environment definitions, wild card adjacency map. Single source of truth imported by curate.js and server.js.
engine/scoring.js
computeSpeedProfile() — maps member CCTF quiz answers to intent affinity scores. Used to rank venues against member preferences when serving from precomputed pools.
Services
services/michelinScraper.js
Puppeteer headless Chrome. Renders Michelin Guide hotel pages, parses .card__menu-content + .michelin-award. Extracts: name, Michelin Key, guest score, member privileges. Writes to michelin_hotels.
services/lartisienScraper.js
Puppeteer + ?page=N pagination. Renders Lartisien city listing pages, walks pagination until exhausted, city-keyword filters to remove cross-market contamination. Writes to lartisien_hotels.
services/forbesScraper.js
Single HTTP fetch of award-winners.json. Returns 2,400+ Forbes-rated properties as structured JSON. No Puppeteer. Filters to propertyType: ‘HOTEL’ then city. Writes to forbes_hotels.
services/broadSearchScraper.js
Brave Search API award-query scraper. 6 query templates per market × 5 markets = 30 queries/run. extractHotelName() with 20+ pattern guards strips article titles to clean hotel names. Writes to broad_search_hotels.
services/discoveryBridge.js
3-pass discovery pipeline (Michelin → Forbes → Broad Search). Per venue: dedup → Brave Search enrichment → cross-reference all scraper tables → Haiku classification → upsert to pending_venues. Auto-approve / pending-review routing.
services/precompute.js
Ranks and writes precomputed_venue_pools. Reads seed + approved discovered venues, scores by quality × intent × environment, writes ranked pools. Delete-before-rewrite integrity (throw on delete failure).
services/qualityScore.js
13-signal quality scoring model (0–100). Reads all 4 scraper tables to compute per-venue composite scores. Convergence bonus logic. Writes to venue_quality_scores.
services/websearch.js
Live credential intelligence. Fires 14–22 parallel Brave Search queries at curation time, feeds raw snippets to Haiku extraction, assembles the signal block for Sonnet. Also contains formatSignalsBlock().
services/reservationScout.js
Reservation link discovery for TABLE venues. Puppeteer crawls venue’s own site to find the booking platform (OpenTable, Resy, SevenRooms, Tock). Results cached 30 days in venue_reservation_links. Hardcoded overrides for bot-blocking sites.
23 Booking & Fulfilment — White Label New — July 2026

CurateVIP does not process bookings or take payment directly. STAY venues that exist in LiteAPI inventory deep-link to a branded White Label booking site on our own domain; the rest fall back to Expedia affiliate links. Curation is ours; fulfilment — and its regulatory burden — belongs to the partner.

Routing (VenueDetailPage.jsx)
27 LiteAPI venues
Book button → book.curatevip.ai/hotels/{liteApiId} with checkin / checkout / occupancies. Mapped in WHITELABEL_HOTEL_IDS (venueId → lp-id). Nuitee is merchant of record.
10 non-LiteAPI venues
Not in LiteAPI — the White Label cannot book them. Fall back to Expedia affiliate deep link (EXPEDIA_AFFILIATE_URLS / getExpediaUrl()). This is their only booking path. (1 Hotel Seattle, Lotte, Hermosa Inn, Global Ambassador, San Ysidro Ranch, Chateau Marmont, Sunset Tower, Faena, The Setai, Soho Beach House.)
Master flag
USE_WHITELABEL_STAY_BOOKING. True = White Label + Expedia fallback (current). False = restores the legacy in-app LiteAPI booking panel + Expedia everywhere. The in-app panel (StayBookingPanel.jsx) is preserved behind this flag as a failsafe.
The White Label Site
Platform
LiteAPI / Nuitee Connect White Label — a free hosted booking site on our LiteAPI account. Nuitee handles payments, confirmations, cancellations, and 24/7 guest support. We set the commission markup; payouts weekly.
Domain
book.curatevip.ai — custom domain (CNAME to CloudFront), SSL auto-issued via AWS ACM. Set in the Nuitee dashboard (Settings → Domains) plus 3 DNS records at Porkbun: one CNAME for the domain, two CNAMEs for SSL validation.
Theming
~30KB custom CSS + custom JS injected via the Nuitee dashboard (Settings → Custom code). Matches curatevip.ai: gold #ba9f75, near-black background, Cormorant Garamond + Inter. Overrides Nuitee’s design tokens (root-cause fix for their blue), hides global search / reviews / rating categories, converts room sizes to sq ft, strips “1 x” room-count prefixes. Source of truth: whitelabel-assets/curatevip-whitelabel-FINAL.css + curatevip-whitelabel.js.
Inventory guard
The White Label is restricted to our curated hotels via the dashboard inventory allow-list. Combined with deep-linking straight to hotel pages, members never encounter generic global search.
Integrity monitor
A daily scheduled task loads a White Label hotel page and asserts theme integrity (dark background, gold tokens, search hidden, sq ft conversion ran). Alerts only on failure — catches breakage if Nuitee renames CSS classes in a frontend update. The theme depends on their internal class names, so this is the early-warning system.
Why Not Merchant-of-Record
The decision
Taking payment directly would make CurateVIP merchant of record: PCI DSS scope, Seller of Travel registration in CA / FL / HI / WA (which apply based on customer residence and cover most of our markets), plus refund/chargeback and E&O exposure. Routing through the White Label keeps all of that with Nuitee while we keep the brand, the commission, and the experience. RateHawk was abandoned for the same reason — it required a travel-agent license we could not secure. Confirm the exact structure with a travel-industry attorney before ever taking payment in-app.
24 TABLE Intelligence Engine New — July 2026

The restaurant counterpart to the Speed Engine (§11). Two signal families — durable prestige and decaying scene heat — feed the same discovery bridge, quality scoring, admin review queue, and precomputed pools. Rides the existing Sunday cron; no new infrastructure.

Sources & Services
services/restaurantScraper.js
Puppeteer renders guide.michelin.com restaurant listings (paginated /page/N). Extracts stars (count of michelin-star_8519.svg badges), Bib Gourmand (Bibendum svg), Selected (in guide, no badge), price tier, cuisine. Verified selectors 2026-07-18. Coverage: LA, Santa Barbara, Miami, Nashville. Seattle / Scottsdale / Maui have no Michelin restaurant guide — a redirect guard detects Michelin’s silent fallback (observed: Seattle → District of Columbia) and treats it as no coverage. Writes michelin_restaurants.
services/tableSearchScraper.js
14 Brave queries per market across two families. PRESTIGE: beard_winner, beard_nominee, wine_spectator, la_liste, worlds_50_best, best_new_national, nyt_best, local_critic. SCENE: eater_heatmap, infatuation_hit, resy_hot, best_new_local, scene_vibe, chef_pedigree. Restaurant queries return list articles (“38 Essential…”), so page-title extraction cannot work — instead one Haiku pass per market extracts venue names from tag-labelled snippets (same snippet-extraction pattern as websearch.js). Writes one row per venue×tag to table_search_signals with family + found_at.
For non-Michelin markets
Seattle, Scottsdale, and Maui discovery runs entirely on Beard + editorial + local critics + scene signals — this is precisely why the multi-source design exists.
TABLE Quality Scoring (engine/qualityScore.js)
Dispatch
computeQualityScore() routes category === 'TABLE' venues to computeTableQualityScore(). STAY logic untouched.
Michelin tiers
+35 three stars · +30 two · +25 one · +12 Bib Gourmand · +8 Selected. Being in the guide at all means an inspector approved it.
Prestige signals
+20 Beard winner · +10 Beard finalist/semifinalist · +10 La Liste · +10 World’s 50 Best · +8 Wine Spectator · +7 each: national best-new, NYT, local critic.
Scene signals (decay)
+7 Eater Heatmap · +7 Infatuation Hit List · +6 Resy hot · +5 best-new local · +4 scene vocabulary · +4 chef pedigree. Counted ONLY if found_at is within 270 days — the weekly cron refreshes found_at on every re-confirmation, so current heat persists and stale heat expires without any manual pruning.
Convergence + cap
Buckets: michelin / beard / editorial / scene. 3+ buckets +10, 2 buckets +5. Cap 100. Scene alone maxes ~33 — a pure-vibe venue surfaces in its environment pool but cannot outrank a starred institution within the same environment. Cross-environment competition never happens: pools are ranked per market × intent × environment.
Discovery Bridge (Pass 4)
Gate
Candidate must have: a Michelin Guide entry (any tier), OR ≥1 prestige signal, OR ≥2 fresh scene signals. The two-source scene rule is the noise filter.
Classification
Haiku classifies each candidate into TABLE environments — Provision (food-primary), Couture (composed experience), Pulse (scene dining: the room is the event), Verandah (open-air identity) — using live Brave context, the chain-restaurant rule, and the shared human-corrections learning loop (classification_corrections).
Flow
Gate → classify → quick-score → pending_venues (category TABLE) → auto-approve on quality_pass or admin review → weekly precompute ranks approved venues into the TABLE pools members draw from. Migration: 008_table_discovery.sql. Cron: TABLE scrapers + Pass 4 added to POST /internal/run-scrapers.
25 Learning Loop — How the AI Improves From Correction & Behavior New — July 2026

Every classification call in the Speed Engine (STAY and TABLE alike) now runs on Claude Fable 5 — the frontier model, reserved for this one judgment because it is the single decision in the pipeline that reaches a member directly. Fable does not decide cold, and it is not a "set once" choice either. Two feedback signals accumulate over time and are injected into every future classification prompt, so the system carries memory of what it has gotten right and wrong — and a third, ongoing discipline keeps the model itself current as Anthropic's lineup evolves.

Signal 1 — Quality-Bar Corrections (live, feeding decisions today)
What it captures
Every time an admin approves or denies a discovered venue, the system checks whether that decision AGREED or DISAGREED with what the AI had recommended. Agreement confirms the AI was right and teaches nothing new. Disagreement is the signal: it means the AI's judgment on whether a venue belongs in the pool at all — not which environment it fits, the more fundamental quality-bar call — was wrong.
How the lesson is written
On disagreement, a lightweight model (Haiku) writes a 1–2 sentence lesson from the venue's name, market, the AI's original rationale and confidence, and the human's decision (plus any note the admin entered on denial). The lesson is stored in quality_corrections, distinct from the pre-existing classification_corrections table (which teaches environment/category placement, e.g. Provision vs. Pulse). This is a parallel loop for the higher-stakes decision: existence in the pool, not bucket placement.
How it reaches Fable
Every classifyVenue()/classifyTableVenue() call fetches the most recent quality-bar disagreements (up to 8, scoped to STAY or TABLE) and injects them into the prompt as worked examples before the AI renders its own judgment on the current candidate. The correction loop is therefore live from the moment it fires — no retraining, no delay, no separate deployment.
Signal 2 — Member Engagement (accumulating now, not yet scored)
What it captures
Every tap on Book Now (STAY) or Reserve (TABLE) — and Check Availability — in the member app fires a fire-and-forget log to venue_engagement. This is treated as a positive signal in its own right: a member choosing to act on a venue is real behavioral evidence that the curation was right, distinct from editorial theory. A completed LiteAPI/Nuitee booking (via webhook, once registered) logs separately as booking_completed — the true demand signal, one step stronger than click intent. Tracking is wrapped so a failure can never break or delay the member's actual booking flow.
Why it is not scored yet
Weighting engagement into quality_score from a handful of early clicks risks letting one curious tap distort a venue's standing before the data means anything. The data accumulates starting July 2026; once weeks of real signal exist, a bounded demand nudge will be added deliberately — the same discipline applied to the Fable model upgrade itself — rather than guessing at weights from zero history.
Model Currency — Keeping Fable the Right Choice, Not Just the Original One
What it means
Because this classification call is the one decision in the pipeline that reaches a member directly, which model runs it is treated as a decision to revisit, not a setting made once and forgotten. Before adopting or holding a model here, current published documentation is checked to confirm it is genuinely the frontier tier — not simply the newest name — and that the cost delta is justified by the risk of showing a member the wrong venue.
Precedent
This classification step moved from Haiku (cheap, high-volume extraction tier — still used for lightweight tasks like lesson-writing and name parsing) to Sonnet, then to Fable 5, after research corrected an assumption that Sonnet was still the current top tier when a newer frontier model (Fable 5) had since shipped. That correction is now the standing practice: any time Anthropic ships a materially new model, it gets checked against current documentation before deciding whether this decision should move to it.
Cost per AI run: ~$0.004–0.007 USD. One Claude Sonnet 4.6 call (max 1,200 output tokens) ≈ $0.004–0.006. Google Places photo lookups ≈ $0.002. Cache hits cost $0.00.  ·  The Scout: Puppeteer crawl fires once per venue (~10s), cached 30 days. All subsequent Reserve button taps serve from cache in under 100ms.  ·  Doc version: July 19, 2026 (b) — §25 Learning Loop expanded with the Model Currency discipline (verifying Fable stays the frontier choice as new models ship) and clarified engagement wording (Book Now / Reserve taps as a positive signal). July 19 (a): §25 Learning Loop added (Fable 5 quality-bar correction feedback + member engagement tracking). July 18 (b): §24 TABLE Intelligence Engine + Curate Process §02B. Earlier July 18: §23 Booking & Fulfilment + Step 08. Prior (July 9): Speed Engine, error handling audit, quality scoring, precomputed pools.
■ Confidential — Trade Secret Documentation
The CCTF Engine
Curate Classification & Taxonomy Framework
A proprietary methodology for mapping hospitality venues to member psychological states using a two-axis classification system. This document constitutes the internal methodology specification for the CCTF Engine — a trade secret asset of RMK Group LLC, DBA CURATEvip. Prepared for internal use, IP counsel review, and qualified investor due diligence under NDA.
TRADE SECRET — CONFIDENTIAL. This document contains proprietary methodology, decision logic, classification rules, and worked examples constituting trade secrets of RMK Group LLC. Unauthorized disclosure, reproduction, or use is prohibited. Access to this document should be logged and limited to authorized personnel, legal counsel, and investors under executed NDA and IP-assignment agreements.
A What the CCTF Engine Is

“CCTF solves the problem no luxury travel product has solved: mapping a specific person’s psychological state to a specific room at a specific moment. Every other luxury product matches budgets to star ratings. CCTF matches psychological appetite to spatial character — and does it autonomously, at scale, backed by a self-improving discovery pipeline that gets more complete every week.”

Most luxury travel products match venues to budgets, categories, or star ratings. None of them model the member's psychological appetite at the moment of travel. The CCTF Engine is the methodology that makes this possible.

The Core Innovation
Two-axis classification
Every interaction has two axes: the member's Speed Tier (their psychological appetite) and the venue's Environment (its physical and social character). A curation is a match between these two axes — not a keyword search, not a category filter, not a rating lookup.
Three intent categories
Members are profiled separately for STAY (hotel), TABLE (dining), and SOCIAL (bars, lounges, experiences). The same member can be Vanguard for hotels (hotel-as-social-scene), Couture for dining (design-immersive), and Shadow for social (atmospheric). These are independent axes, not a single preference score.
The vocabulary is proprietary
Atelier, Sanctuary, Vanguard, Estate, Provision, Couture, Pulse, Electric, Shadow, Verandah, Gallery — these names are not borrowed from the hotel industry. They were created specifically for this system. Each name encodes a precise definition with positive indicators and hard disqualifiers. The vocabulary itself is a moat.
The system is deterministic
Given a venue's physical and social characteristics, its Environment classification can be determined by following the decision protocol. The same trained evaluator applying the same protocol to the same venue always reaches the same classification. This is what makes it a methodology, not a personal opinion, and what makes it legally protectable as trade secret.
The AI is an accelerant, not the engine
Claude is used to apply the CCTF methodology at scale — surfacing and classifying venues, validating picks against live signals, generating editorial FEEL/WHY content. The methodology predates and governs the AI. The AI executes; the CCTF Engine decides. This distinction matters legally (the methodology is protectable independent of any AI provider) and commercially (the system is provider-agnostic — swapping Claude for a different model changes an API call, not the architecture).
B The Three-Axis Member Profile

During onboarding, members complete a psychographic intake for each of the three intent categories. The questions are designed to reveal underlying preference patterns through indirect questions — they do not ask "what kind of hotel do you like?" They ask questions whose answer patterns map to a Speed Tier.

Axis 1
STAY
Hotel and resort preference. Tiers: Vanguard, Sanctuary, Atelier, Estate. Maps to the member's identity relationship with the property.
Axis 2
TABLE
Dining preference. Tiers: Provision, Couture, Pulse, Shadow, Verandah. Maps to the social and atmospheric environment they seek at the table.
Axis 3
SOCIAL
Bar, lounge, and experience preference. Tiers: Electric, Shadow, Verandah, Gallery. Maps to energy level and scene preference.
Output
Speed Profile
A three-key object: {stay:"atelier", table:"couture", social:"shadow"}. This governs every curation the member receives. It can be updated by the member at any time.

The indirect-question design: Members do not select "Atelier" from a list. They answer questions about how they experienced their last hotel stay, what they noticed first when they walked into the lobby, whether they wanted to hide away or be seen. The speed profile emerges from the pattern of answers. This prevents gaming and reveals genuine preference, not aspirational self-image.

C Speed Tier Taxonomy — Full Classification Reference

Each tier has a canonical definition, a primary test question, and explicit disqualifiers. The definition is the authoritative source. Anything not in code or prompt that conflicts with these definitions is wrong.

STAY Tiers
Vanguard — STAY [HIDDEN — PHASE 1]
"The hotel IS the scene. The lobby buzzes, the bar is where the night starts, the pool deck is where people end up. Checking in feels like walking into an event."
Primary test: Does the hotel itself generate social energy — is the lobby, bar, and pool a destination in their own right, not just amenities? Would a guest say they went for the experience of being inside that hotel's social ecosystem, not just to sleep there? Note: brand prestige alone does not make a hotel Vanguard. A globally recognized flagship in a quiet, service-first property is Sanctuary. The scene must actually exist at that specific property — the energy has to be real, not implied by the name.
Disqualifiers: Quiet, service-first hotels regardless of brand prestige (Sanctuary). Design-forward properties where architecture is the primary identity (Atelier). Historic grand dames (Estate). Any hotel where the primary reason to stay is rest, privacy, design, or heritage rather than being inside the hotel's social scene.
Phase 1 status: Vanguard is a fully defined STAY tier but is not presented to members in Phase 1. It will be enabled as inventory in scene-forward markets (Miami, Los Angeles, Las Vegas, etc.) reaches sufficient depth. The tier definition, classification logic, and seed architecture are complete and ready for activation.
Atelier — STAY
"Architecture is the reason. The building has a point of view and the design is the primary editorial narrative."
Primary test: Would a design-conscious guest specifically seek this property out because of what was built — the materials, the spatial decisions, the architectural concept? If the design is primarily decorative (nice interiors) rather than conceptual (a bold architectural statement), it is not Atelier.
Disqualifies: Global brand flagships (Vanguard). Wellness/spa as primary identity. Properties primarily known for location or history. "Boutique" hotels with good design but no strong architectural concept.
Sanctuary — STAY
"Relaxation is everything. Intimate, hushed, restorative. The world waits outside."
Primary test: Does the property's fundamental promise center on privacy, quiet, and escape from stimulation? Would the guest be disappointed if the lobby was busy and social? If yes: Sanctuary.
Disqualifies: Spa resorts where the treatments are the primary draw (the spa is a feature; sanctuary is a disposition). Properties in dense urban cores where street energy enters the building. Scene-forward properties of any kind.
Estate — STAY
"History and heritage are the product. Genuine age. Old-world architecture. A story that predates modern luxury brands."
Primary test: Does the property derive its identity from documented historical provenance — actual age, documented past, architectural heritage? A property that "feels classic" or has been designed to look old is not Estate. The history must be real.
Disqualifies: Modern luxury brand flagships regardless of aesthetic. Properties built after 1960 with traditional design. Properties where the historical story is primarily marketing language rather than documented provenance.
TABLE Tiers
Provision — TABLE
"The kitchen is everything. Food-primary, chef-driven. The room is irrelevant — it could be gorgeous, plain, or anywhere in between. You are here because of what the kitchen does."
Primary test: Would a serious food critic rate this restaurant purely on the strength of what the kitchen produces — with zero consideration for the room, the energy, or the scene? If yes: Provision. Signals: James Beard Awards, Michelin recognition, tasting menus, prix fixe formats, exceptional sourcing, chef reputation. NOTE: quiet and unhurried dining is a POSITIVE signal for Provision, not a disqualifier. The room does not need to have energy to qualify.
Disqualifiers: Venues where the buzz, scene, or energy is the primary draw (that is Pulse). Venues where the room design is the primary draw (that is Couture). Do NOT reclassify a food-primary venue as Couture because the room is architecturally beautiful — if the food is the reason to go, it is Provision regardless of the room.
Couture — TABLE
"The physical design of the room is the primary reason a guest specifically seeks out this venue. The space is so visually singular and intentionally art-directed that a design-conscious diner would choose it for the room itself."
Primary test: "Would I go here even if the food were merely competent (not exceptional)?" If yes: Couture. CRITICAL DISTINCTION FROM PROVISION: if the primary reason a guest would choose this venue is the food, the chef, or the culinary experience — even if the room is stunning — that is Provision, not Couture. A beautiful room does not make a venue Couture.
Disqualifiers: Any venue whose primary identity is culinary, regardless of how architecturally notable or beautiful the room is. Fine dining, tasting menus, prix fixe, and chef-driven restaurants — even those with striking interiors — are Provision. Couture is reserved for rooms so visually distinctive that the design itself would draw a design-conscious guest independent of the food.
Pulse — TABLE
"Scene and energy are the product. The dining room buzzes — loud on purpose, alive at full tilt. You are there for the night as much as the meal."
Primary test: Is the room charged with intentional social energy — high volume, live crowd, momentum that builds through the evening? Is the scene itself a reason to be there, not just background to the food? If yes: Pulse. This is the buzzy, high-energy TABLE tier. It is distinct from Provision (food-first, quiet) and from Couture (design-first, immersive).
Disqualifiers: Quiet, food-first venues (Provision). Design-as-destination rooms (Couture). Outdoor-primary venues (Verandah). Note: Shadow is a SOCIAL-only tier and does not apply to TABLE.
Verandah — TABLE [HIDDEN IN BETA] & SOCIAL
"PHYSICALLY OUTDOORS is the primary identity. The table itself is outside, under the sky, in open air. The guest is not inside looking at a view."
Primary test: Is the dining or drinking surface itself physically outside — not behind glass, not through a window, not on a covered terrace that is functionally indoors? The test: could it rain on the guest? If no glass separates the guest from the sky: Verandah.
Disqualifiers: Indoor restaurants with outdoor views through glass walls. Glassed-in terraces. Indoor rooms with large windows facing nature. Covered patios where glass or roofing creates an indoor feeling. Any venue where "outdoor" is a visual amenity rather than the physical condition of the experience.
Beta status: Verandah is a defined TABLE tier and exists in the seed data, but is currently hidden from member-facing TABLE selections. It is active and fully available in SOCIAL. Verandah will be enabled for TABLE in a future release once the venue inventory is sufficient across all markets.
SOCIAL Tiers
Electric — SOCIAL
"Scene-driven social energy. The right crowd, the room is alive and buzzy. The night usually starts or ends here."
Primary test: Is the room actively charged with social energy — the crowd, the noise level, the sense that this is where the night is happening? Is being in this room with the right people a genuine part of the value? If yes: Electric. This is the SOCIAL equivalent of Pulse for TABLE — buzzy, crowd-forward, alive.
Disqualifiers: Quiet, atmospheric venues (Shadow). Design-contemplative venues (Gallery). Outdoor-primary venues (Verandah). Any venue where the energy is calm, considered, or intimate.
Shadow — SOCIAL
"Dark, considered, atmospheric. Mood is the amenity. You had to know it was there."
Primary test: Is low visibility a feature, not a bug? Is the room deliberately dark, intimate, and discovered rather than promoted? Would high visibility or a busy, loud room fundamentally change what makes it special? Shadow is a SOCIAL-only tier — it applies to bars, cocktail lounges, and social venues, not to dining rooms.
Disqualifiers: Bright, open rooms. High-visibility spots. Loud or energy-forward venues (Electric). Venues where being seen is part of the value proposition. Dining rooms of any kind — Shadow is SOCIAL only.
Gallery — SOCIAL
"Design you feel before you see. Intimate, selective, private-feeling. A room with a point of view."
Primary test: Does the space have a distinct visual and spatial identity that makes it feel curated and considered — not merely well-decorated, but designed with intent? Is the atmosphere intimate and selective rather than open and social? Would a design-conscious guest choose it as much for the room as for the crowd?
Disqualifiers: High-energy, crowd-forward venues (Electric). Purely atmospheric, dark venues without design identity (Shadow). Outdoor-primary venues (Verandah). Mainstream bars or lounges with no distinct design concept.
Verandah — SOCIAL [HIDDEN — PHASE 1]
Verandah applies to SOCIAL venues using the same definition as TABLE above — a bar, terrace, or rooftop where the drinking surface is physically outside, under open sky.
Same primary test as TABLE: the guest is physically outdoors, not behind glass. Could it rain on them? If yes: Verandah.
Same disqualifiers as TABLE Verandah — glass walls, covered indoor terraces, and venues where "outdoor" is a view amenity rather than the actual physical condition.
Phase 1 status: Verandah is hidden from member-facing SOCIAL selections in Phase 1, alongside TABLE. The tier definition, classification logic, and seed architecture are complete. Members whose quiz result maps to Verandah are assigned Gallery for Phase 1. Will be activated once outdoor venue inventory is sufficient across all markets.
D The Quality Floor — Ultra-Luxury Caliber Definition

"The quality floor is what makes CURATE trustworthy. Without it, it's just an opinionated list. With it, it's a methodology."

Every venue that appears in CURATE must clear the quality floor before Environment classification even begins. A venue that is a perfect Verandah but does not clear the quality floor is not in CURATE. The Environment taxonomy describes the type of experience. The quality floor describes the standard of execution.

Qualifying Signals (sufficient, not required)
Forbes Travel Guide
Five Star only. Four Star is mid-luxury and does not clear the floor.
Michelin Guide
1, 2, or 3 Keys (hotels). 1, 2, or 3 Stars (restaurants). Bib Gourmand does not qualify — it is a value indicator, not a luxury indicator.
James Beard Awards
Winner OR nominated. Nomination alone is a strong quality signal — the nomination process is rigorous and regional semifinalists represent the highest caliber of culinary achievement in their market.
AAA
Five Diamond only. Four Diamond is a full tier below. This distinction is frequently misunderstood in the industry.
Global collections
Relais & Châteaux, Leading Hotels of the World, Small Luxury Hotels of the World, Preferred Hotels Legend Collection.
Flagship brands
Aman, Four Seasons, Ritz-Carlton, Rosewood: flagship tier only. Sub-brands or midscale extensions do not qualify.
Recognized publications
Condé Nast Traveler Gold List, T+L World's Best (top-ranked entries only, not merely mentioned), Robb Report Best Hotels / Best Restaurants, World's 50 Best Restaurants, World's 50 Best Bars.
Wine Spectator Grand Award
The highest wine program recognition — fewer than 100 restaurants worldwide hold this designation at any given time. A strong signal of commitment at the ultra-luxury level.
Tales of the Cocktail — Spirited Awards
The premier international recognition for bar programs. Winner or nominated signals SOCIAL venues operating at the highest caliber of craft and hospitality.
How Credentials Are Verified — Live at Curation Time

The CCTF Engine does not rely solely on training data for credential validation. At the moment of every curation, the system queries live web sources via Brave Search API to fetch current credential signals for the market and category being curated. Results are cached for 7 days per market and refreshed automatically. This means Claude receives up-to-date Michelin, James Beard, Forbes, Robb Report, and other signals before making recommendations — not frozen training memory. If a venue has lost credentials, changed ownership, or closed since Claude's training cutoff, the live signal layer surfaces that information and Claude adjusts its recommendations accordingly.

Credential Attribution Rule — Critical Curation Error New — June 30

Chef awards earned at a prior employer do NOT transfer to the chef's current restaurant. This is the single most common credential misattribution error in AI curation. A James Beard Award belongs to the venue where it was earned, not to wherever that chef works today.

The rule
Only attribute an award to a venue if the source text explicitly names that venue — by its current name — as the recipient. "Chef X won James Beard at Restaurant A, and now runs Restaurant B" → Restaurant A gets the credential. Restaurant B gets nothing from that fact.
Worked example — Tomo Seattle
Chef Brady Williams won the James Beard Award at Canlis. He later opened Tomo, a neighborhood restaurant in White Center (a working-class district of Seattle, located in a former adult video store). Robb Report covered the opening and mentioned the award. AI systems incorrectly attribute the James Beard credential to Tomo. The correct attribution: Canlis gets "James Beard Award winner." Tomo gets no credential from that fact. Tomo is also blocked in seed.js: wrong neighborhood, wrong price tier, wrong physical setting — chef pedigree does not override any of these.
Three-layer enforcement
(1) Haiku extraction prompt includes a CRITICAL rule section with the Brady Williams / Canlis / Tomo example. (2) formatSignalsBlock() guidance in websearch.js: credentials are DISCOVERY SIGNALS not admission tickets — chef pedigree at prior employers is context, not a credential for the current venue. (3) server.js curation prompt: CREDENTIAL INTERPRETATION section — "Is this credential FOR THIS VENUE, or did the chef earn it at a previous restaurant?" is the first test applied before any recommendation is made.
Tomo Seattle — blocked entry
{ id: 'tomo-seattle', blocked: true, description: 'Neighborhood restaurant in White Center, located in a former adult video store. Chef Brady Williams earned his James Beard Award at Canlis — Tomo itself has no equivalent venue-level credentials. The physical setting, neighborhood, and price tier do not meet CurateVIP caliber. Do not recommend regardless of chef pedigree.' }
Disqualified Regardless of Other Signals
TripAdvisor Travelers' Choice: a participation award, not a quality threshold.
Five Star Alliance: a booking aggregator, not an accreditation body. Does not confer quality certification.
AAA Four Diamond: a common misunderstanding. This is mid-luxury, not ultra-luxury.
Regional "best of" awards from local lifestyle publications: signal local popularity, not caliber.
Chain properties in the Marriott, Hilton, Hyatt portfolios (for STAY): these brands operate at scale that is structurally incompatible with ultra-luxury consistency. Their restaurants are evaluated separately on merit.
The Floor Without Credentials

Formal credentials are reference points, not a mandatory gate. A venue can clear the quality floor without any credential if: it operates at a price point and service standard consistent with Five-Star hospitality, it appears in the curated editorial of major luxury travel publications (not rankings, editorial coverage), and a knowledgeable evaluator applying the CCTF protocol would immediately recognize it as ultra-luxury. Conversely, having a credential does not automatically clear the floor — the credential must reflect the actual current state of the property.

E The Classification Decision Protocol

The protocol is the sequence of questions applied in order to any candidate venue. The protocol is what makes classification deterministic and reproducible by any trained evaluator, independent of personal taste.

1
Does this venue clear the quality floor?
Apply the quality floor criteria. Formal credentials, price point, editorial presence, and evaluator judgment all factor in. One strong qualifying signal is sufficient.
Pass → proceed to step 2.
Fail → stop. The venue does not enter CURATE regardless of any other characteristic.
2
What category does this venue serve? (STAY / TABLE / SOCIAL)
A hotel is STAY. A restaurant is TABLE. A bar, lounge, or experience is SOCIAL. Some properties serve multiple categories — each is classified independently. A hotel's restaurant is classified as TABLE on its own merits, separately from the hotel's STAY classification.
Pass → proceed with the correct category's tier set.
3
Apply the Primary Test for each tier in sequence. Which tier does the venue belong to?
Work through the tier list for the venue's category. Apply the Primary Test for each tier. Stop at the first tier whose Primary Test yields yes and whose disqualifiers yield no. If no tier yields a clean yes, the venue does not clear classification — it has no Environment and cannot be recommended. This is valid and expected. Not every ultra-luxury venue maps cleanly to a tier.
Clean match → record the Environment. Proceed to step 4.
No clean match → the venue is confirmed, quality-cleared, and seeded as blocked: false but not actively recommended (no Environment). Can be revisited if a new tier is added.
4
Does this venue qualify for multiple environments?
Some venues genuinely embody two distinct environments — not as a compromise, but as two separate valid identities. A restaurant with an iconic outdoor terrace (Verandah) and an immersive indoor room (Couture) is a genuine dual-environment venue. Dual classification is conservative: both Primary Tests must yield clean yes answers with no disqualifiers from either tier.
Dual match → seed the venue with both environments (separate seed entries). Flag as wild card candidate.
5
Is this venue in the core market or surrounding area?
Surrounding area venues (e.g., Woodinville relative to Seattle) are flagged surrounding: true and only surface when the member actively opts in via the surrounding toggle. Core market venues are always included.
Core → seed with no surrounding flag. Surrounding → seed with surrounding: true.
6
Are there any environment-specific blocks needed?
A venue that is valid on the platform for some environments may be incorrect for others. Example: Canlis in Seattle is a valid Provision/Couture dining venue, but it is incorrectly classified as Verandah (indoor, glass-walled). Setting environment_blocked: ['Verandah'] keeps it in the platform but prevents it from surfacing in Verandah curations.
No blocks needed → seed is final. Blocks needed → add environment_blocked array.
F Worked Examples — Classification Walkthroughs

Each example shows the full protocol applied to a real venue. These walkthroughs prove the system is deterministic and consistently applicable to hard cases. A library of worked examples is what makes a methodology credible to a diligence team or IP attorney.

Canlis
Seattle, WA — TABLE Evaluation
1
Quality Floor
Canlis is a James Beard Award–winning institution operating since 1950. It holds consistent top rankings in regional and national publications. Price point, service level, and editorial presence all clear the floor. Pass.
2
Category
Restaurant. TABLE evaluation applies.
3
Couture Test (initial, incorrect)
First pass classified Canlis as Couture, citing the 1950 Roland Terry A-frame architecture and the Lake Union glass-wall room as design-as-destination. This was wrong. The Couture test asks: "Would you go for the room as much as the food?" At Canlis, the answer is no. The room is spectacular backdrop — the food and the occasion are the reason. Architectural significance is not the same as design-as-destination.
4
Provision Test (correct)
Provision requires food-primary identity, excellent execution, and organic room energy. Canlis is formal and occasion-driven rather than buzzy — but "buzzy" describes one expression of Provision energy, not the only one. The fundamental Provision identity is: the food is the point, the room serves the food, and the experience is alive because the people and the kitchen are exceptional. Canlis clears this. James Beard credential = the food is the reason. The room, as beautiful as it is, is in service of the dining experience, not the other way around.
5
Environment Block
environment_blocked: ['Verandah'] — unchanged. The glass-walled room is definitionally not Verandah regardless of classification. The block remains a safeguard against AI hallucination.
6
Classification Principle Illustrated
This case establishes a key rule: notable architecture in a dining room does not make a venue Couture. The architecture must be the primary reason a guest chooses the venue. When the food is the primary reason — regardless of how beautiful the room is — the venue is Provision. The protocol caught the error on challenge; a trained evaluator should catch it before challenge by applying the Couture test strictly.
Corrected Classification: Provision · Seattle TABLE
environment_blocked: ['Verandah']. Surrounding: false (core market). Initial Couture classification challenged and corrected — food-primary identity requires Provision. Seed updated June 2026.
The Herbfarm
Woodinville, WA — TABLE Evaluation (Surrounding Area)
1
Quality Floor
9-course prix fixe, $300–$400 per person, James Beard Award recognition, national editorial coverage in Bon Appétit, Food & Wine, and travel publications. Clears the floor comfortably.
2
Category
Restaurant. TABLE evaluation applies.
3
Couture Test (initial, incorrect)
First pass classified The Herbfarm as Couture, on the basis that the 9-course storytelling format is "immersive in spirit." This was wrong for the same reason as Canlis: Couture requires design-as-destination. The dining room at The Herbfarm is pleasant and pastoral — it is explicitly not a room that takes you somewhere else architecturally or aesthetically. Applying the Couture label because no other tier felt perfect is exactly the kind of compromise the protocol is designed to prevent.
4
Provision Test (correct)
The Herbfarm's entire identity is food. The 9-course menu is built around the farm, the season, and the kitchen's storytelling. The prix fixe format is formal and quiet — not buzzy — but the Provision identity is not about energy level, it is about the primacy of the food and the excellence of the kitchen. The Herbfarm is Provision in its deepest sense: you go because of what they cook, how they source it, and what the kitchen has to say. The room is the stage. The food is the performance.
5
Location
Woodinville, WA — part of the Seattle surrounding area (Eastside & Woodinville). Not in Seattle's core market geography.
6
Taxonomy Note
Both Canlis and The Herbfarm reveal the same gap: the taxonomy currently has no tier for formal, quiet, food-primary dining that isn't buzzy. Provision covers this well conceptually (food-first, excellent kitchen) but its operational description leans toward energy and atmosphere. A future "Ceremony" or "Kitchen" tier may eventually be needed for prix fixe, tasting-menu, and chef's-table formats where the room is incidental and the culinary narrative is everything. For now, Provision is the correct classification — it is food-primary, and that is the core of Provision.
Corrected Classification: Provision · surrounding: true · Seattle TABLE
Only surfaces when member checks "Include Eastside & Woodinville." Wild card candidate. Initial Couture classification challenged and corrected — food-primary identity requires Provision. Seed updated June 2026.
nyloS
Wailea, Maui, HI — TABLE Evaluation
1
Quality Floor
14-seat chef's table. 'Aipono Award Gold (Hawaii's most respected restaurant awards, operated by the Maui No Ka 'Oi Magazine). Not broadly credentialed nationally, but clears the floor via format (ultra-intimate chef's table) and the strongest available local credential. This is a Discovery Mandate venue — not surfaced by global signals, surfaced by geographic sweep of local reference sources.
2
Category
Restaurant (chef's table format). TABLE evaluation applies.
3
Tier Classification
Shadow test: Is it dark, considered, known only to those who seek it out? 14-seat chef's table — by definition, you had to know it was there. Intimate, deliberate, no scene. The format itself embodies Shadow. Strong match. Couture adjacency: the chef's table format is immersive in the culinary sense. Dual-environment candidate.
4
Dual Environment
Shadow (primary) + Couture (secondary) — the Shadow identity is cleaner. The Couture lean is noted but not seeded as a separate entry due to limited seat inventory (14 seats means limited demand capacity — the venue is better served as a Shadow anchor than split across two environments).
Classification: Shadow · Maui TABLE
Discovery Mandate venue — surfaced by Maui-specific reference sweep, not global signals. Example of why the geographic and reference-source sweep is mandatory. Seed confirmed June 2026.
Four Seasons Resort Maui at Wailea
Wailea, Maui, HI — STAY Evaluation
1
Quality Floor
Four Seasons flagship. Forbes Five Star. AAA Five Diamond. Clears easily.
3
Vanguard test
Is the booking decision driven primarily by the brand name? Yes — Four Seasons Maui is booked by guests who trust the Four Seasons brand to deliver a consistent flagship experience. The brand is the primary identity. The location (Wailea beachfront) is a secondary factor.
4
Atelier disqualifier check
Is the design so architecturally distinctive that it overrides the brand identity? No. The Four Seasons Maui has beautiful grounds and a well-designed resort, but a guest does not choose it over the Ritz-Carlton Kapalua because of an architectural concept. The brand is primary. Atelier disqualified.
Classification: Vanguard · Maui STAY
The key distinction: Four Seasons is CALIBER (it clears the quality floor for any tier) but its IDENTITY is Vanguard (the brand name is the reason). A Sanctuary member who books the Four Seasons is compromising — they should be recommended Lumeria Maui or Hana-Maui Resort. The classification is what makes the match possible. Seed confirmed June 2026.
Soho House (Hypothetical)
Any Market — Would It Qualify?
1
Quality Floor
Soho House is a global membership club with properties across major cities. It is a design-forward, scene-forward brand with strong editorial presence. However: it operates at a mid-luxury price point (~$200–$350/night equivalent for hotel rooms), it does not hold Forbes Five Star or AAA Five Diamond accreditations at any property, and it is explicitly a social club first, hotel second. The quality floor is not cleared on its own signals.
2
Brand structure
Soho House has extended into the Electric House (more mass-market) and other sub-brands. The core brand operates at a price point and service standard below the ultra-luxury floor. Its value proposition is social access, not hospitality excellence.
3
The CURATE member test
Would a Vanguard member staying at the Aman Tokyo feel the recommendation to stay at Soho House was appropriate? No. Would a Sanctuary member seeking privacy find Soho House aligned? No — it is intentionally social. The brand is designed for young creative professionals, not ultra-high-net-worth travelers. The markets overlap at the edges but are not the same.
Result: Does Not Qualify
Soho House does not clear the quality floor for CURATE. It is a legitimate hospitality brand with real market position, but its position is mid-luxury social membership, not ultra-luxury hospitality. This classification is not a judgment of Soho House's quality — it is a statement about the quality floor CURATE maintains. The distinction between "good" and "ultra-luxury" is what makes CURATE's curation credible. Not everything good belongs.
G The Wild Card Architecture

"The wild card is the recommendation the member didn't think to ask for but immediately recognizes as right."

The three main results match the member's declared Speed Tier. The Wild Card is selected from an adjacent tier — a venue that is sufficiently close to the member's profile that it's within reach, but distinctly different enough to expand their vocabulary. The wild card is the engine's most sophisticated output.

Multi-environment venues
The primary wild card source. Any venue that qualifies under two or more environments is a candidate. Example: KOAST in Maui qualifies as Provision (energy, food, full bar) AND Verandah (outdoor deck with ocean views) AND Couture (distinctive design identity). A member who requested Provision gets KOAST as a wild card pointing at both its Verandah and Couture identities — expanding their vocabulary in one recommendation.
Adjacency mapping
Each Speed Tier has defined adjacent tiers — tiers close enough in character that a member could plausibly enjoy them. Provision ↔ Couture (both energy and food forward, but different atmospheres). Shadow ↔ Couture (both considered and design-aware, but different light levels). These adjacencies are hardcoded in the server logic.
Discovery Mandate integration
Wild cards are also drawn from the Discovery Mandate sweep — venues the geographic and reference-source sweep surfaced that the AI might not have included in the main three. These tend to be locally-credentialed, not globally-credentialed venues: the ones a member couldn't find on their own but immediately recognizes as right. See System Docs §12 (Discovery Mandate) for the full sweep protocol and the Maui deep-dive that originated it.
What the wild card is not
The wild card is not a "fourth recommendation" or an overflow slot. It is editorially distinct from the main three. It is positioned as "outside your usual" and styled differently in the UI. Its purpose is vocabulary expansion — helping the member discover adjacent tastes they didn't know they had.
H Competitive Differentiation & Moat

The question a buyer asks: "What would it cost a competitor to replicate this?" Here is the honest answer for each layer of the moat.

The Vocabulary
Atelier, Sanctuary, Vanguard, Estate, Provision, Couture, Pulse, Electric, Shadow, Verandah, Gallery — these names encode precise definitions developed over multiple iteration cycles. A competitor could copy the names in a day. They could not copy the definitions, the disqualifiers, the decision protocol, or the worked-example library that makes the system deterministic without years of the same iteration.
Why it matters: the vocabulary is the user interface for the classification system. A different vocabulary requires starting the member profiling and seed data from scratch.
The Seed Data
Every venue in seed.js was manually researched, evaluated against the quality floor, run through the classification protocol, and confirmed. The seed data is both a reference library for the AI and a proprietary training signal — it tells Claude what ultra-luxury looks like in each specific market. A competitor starting today with a blank seed file gets generic LLM responses. CURATE's AI gets calibrated, market-specific responses anchored to confirmed classifications.
Why it matters: seed data accumulates over time. The more markets are seeded, the harder it is to replicate. This is a compounding moat, not a static one.
The Classification System as a Learning Loop
Each member's speed profile is a data point. As members use the platform, their curations reveal revealed preferences — venues they tapped into, venues they skipped, how their speed profile updated over time. This data can train a future model that predicts speed tier drift (a Provision member becoming more Shadow over time). No competitor has this data because no competitor has built this classification system.
Why it matters: the platform gets smarter with every member interaction. A competitor launching today starts with no revealed preference data. CURATE has a head start that compounds.
The Two-Axis Display
The curation results are displayed with Speed Tier language visible to the member — they see "Couture" on their card, they see "Shadow" on the wild card. Over time, members internalize the vocabulary and start using it to describe what they want ("I'm looking for something more Shadow this trip"). This is a brand vocabulary lock-in mechanism: members become fluent in a language only CURATE speaks.
Why it matters: once a member speaks the vocabulary, switching to a competitor requires relearning how to express their own preferences. This is a powerful retention mechanism with no direct competitor parallel.
The Surrounding Areas Architecture
The surrounding areas system — with per-market labels, auto-re-curation on toggle, server-side filtering, and seed-level flags — is an expansion mechanism that allows CURATE to deepen each market without adding new markets. Most travel products define geography by city. CURATE defines it by experience radius, which scales laterally (more surrounding areas) as well as vertically (more markets).
Why it matters: it gives CURATE a natural growth path within existing markets before requiring the operational investment of new market entry.
The Live Credential Intelligence Layer New — June 30
Before every curation, the system fires 22 parallel queries via Brave Search API across authoritative sources — Michelin, James Beard, Forbes, Robb Report, Condé Nast Traveler, Leading Hotels of the World, and 16 others — and runs the results through Claude Haiku to extract structured credential signals. This signal block is fed to Claude Sonnet alongside the seed data and member profile. The live signal block is the primary discovery source: a venue not in seed.js must appear in live signals to be included unless it holds a primary credential. Training knowledge is a supplement of last resort — not the primary discovery engine. This prevents training-memory-only recommendations from reaching the curation output without live validation. A custom attribution rule — enforced at three separate layers of the pipeline — prevents the most common AI curation error: attributing a chef's prior awards to their current restaurant. Results are cached 7 days per market. See Section H1 for the full technical pipeline.
Why it matters: every competitor who builds an AI curation product will encounter the same credential misattribution errors and the same "hallucinated award" problems. CurateVIP has already identified, documented, and systematically enforced the fixes. That institutional knowledge — encoded into the seed data, the extraction prompt, the signal formatter, and the Sonnet curation prompt — is not available from any API.
The Speed Engine — Autonomous Discovery Pipeline New — July 2026
Four scrapers run every Sunday on Railway with zero human intervention: Michelin v7 (Puppeteer headless Chrome, DOM selectors .card__menu-content + .michelin-award), Lartisien v3 (Puppeteer + ?page=N pagination across city listing pages with keyword filtering), Forbes (direct award-winners.json API — 2,400+ structured properties, no browser required), and Broad Search (6 targeted Brave Search queries × 5 markets = 30 award-source queries per run). Every discovered venue is scored 0–100 across 13 weighted signals, evaluated by Claude Haiku for CCTF environment classification, and passed through a quality gate. Auto-approved venues enter precomputed_venue_pools immediately; borderline cases route to admin review. The precompute engine rebuilds ranked pools for every market × intent × environment combination each Sunday. A competitor who calls the same APIs gets real-time latency and per-query AI cost on every curation. CurateVIP's curation is served from a pool that was built before the member arrived — and that pool grows deeper with every weekly pipeline run.
Why it matters to an investor: this is a compounding data moat. Each Sunday run adds newly discovered venues, raises quality score accuracy, and deepens pool coverage. The pools are not static — they are a living asset that improves without anyone touching a keyboard. A new entrant cannot buy this week of pool depth. They can only wait for their own pipeline to run long enough to approach it. By the time a competitor has working scrapers, a classification engine, and 3 months of pool accumulation, CurateVIP has 3 more months of depth. The CCTF classifications are not reproducible without the full taxonomy, worked examples, and institutional knowledge encoded in this system — making the pool itself proprietary, not just the pipeline that built it.
H1 Live Intelligence Pipeline — Technical Architecture New — June 30

This section is the investor-facing technical brief. It answers in one read: what exactly happens between a member tapping "TABLE" and receiving three curated venue cards — and why that pipeline cannot be replicated by a competitor who simply calls the same AI APIs.

The Core Claim

CurateVIP does not ask Claude "what are the best restaurants in Seattle." It feeds Claude a structured block of live credential intelligence — fetched seconds before curation — alongside a proprietary seed library of manually confirmed venues and a member-specific speed profile. The AI's job is not to recall; it is to judge, filter, and match. That distinction is the entire moat.

Member Time Value — What This Replaces New — June 30

What takes a traveler 2.5–3 hours of manual research across 14 browser tabs, CurateVIP returns in 30 seconds.

What the member would have to do themselves
To replicate one CurateVIP TABLE curation manually, a thorough traveler would need to work through five stages — each one slower than it looks on paper: (1) Navigate to each of 14 authoritative sources (guide.michelin.com, jamesbeard.org, forbestravelguide.com, eater.com, robbreport.com, winespectator.com, foodandwine.com, cntraveler.com, worlds50best.com, and more) — ~14 minutes just in tab management and navigation. (2) Search and read each site for the specific city and find the relevant awards or list section — ~3–4 min per site × 14 sites = 42–56 minutes. (3) Compile and cross-reference all results into a usable list — identifying which venues appear across multiple sources, which awards are recent vs. old, which are venue-level vs. chef-level — this step is deceptively slow. A thorough job takes 45–60 minutes, not 15. Most travelers give up and go with whatever felt most familiar. (4) Match to personal taste — now you have a list of credentialed venues and no idea which one is actually your vibe. You have to open each restaurant's website, scroll Instagram, read Yelp and Google reviews, look at interior photos, try to feel whether the energy of the room is what you want that night. This is the most time-consuming step and the one travelers consistently underestimate. Conservatively 60+ minutes — many people spend 2–3 hours here alone. (5) Verify credentials — check that awards belong to the current venue and not a chef who has since moved on. Most travelers skip this step entirely and occasionally get burned by a recommendation that was true 3 years ago. Conservative total: 2.5–3 hours per destination.
What CurateVIP delivers instead
All 14 sources checked in parallel in 30 seconds. Results extracted, cross-referenced, and filtered against the member's speed tier, the quality floor, chain disqualifiers, and credential attribution rules. The taste-matching step — the one that costs most travelers an hour or more — is replaced entirely by the Speed Tier profile built during onboarding. The member already told us how they experience spaces, what they notice first, whether they want to hide away or be seen. CurateVIP matches venues to that profile automatically. Three curated venue cards, 30 seconds after tapping Curate.
The number that matters
~360× faster than a thorough manual research session. And the manual version still does not include speed-tier matching, credential attribution verification, chain disqualification, environment classification, or post-filter guards. CurateVIP does not just compress research time — it performs research steps the member cannot practically do themselves, and eliminates the taste-matching step entirely through the onboarding profile.
Marketing use Approved copy
"We check 14 authoritative sources in 30 seconds and hand you the three venues that match exactly how you dine or travel." / "What used to take 3 hours of research across 14 tabs. Now takes 30 seconds." / "The research your travel advisor would take a week to compile — delivered in the time it takes to read this sentence." / "You've spent hours on this before. Scrolling photos, reading reviews, trying to feel whether a room matches your mood. We built CurateVIP so you never have to do that again."
Phase 1 — Live Credential Intelligence

Fires on every cache miss. Results cached 7 days per market + category — a single API cost amortized across hundreds of curations.

Step 1 — Brave Search queries
The system fires parallel queries via Brave Search API across authoritative sources — 14 queries for TABLE (Michelin Guide + guide.michelin.com direct, James Beard Foundation + jamesbeard.org direct, World's 50 Best Restaurants, Robb Report, Wine Spectator, Food & Wine, Condé Nast Traveler / Travel + Leisure, Forbes Five Star + forbestravelguide.com direct, Eater + eater.com direct, top-10 sweep), 9 queries for STAY (Forbes Five Star, Condé Nast Traveler, Travel + Leisure, Leading Hotels of the World, Small Luxury Hotels, Preferred Hotels, Relais & Châteaux, Mr & Mrs Smith, Design Hotels), and 5 queries for SOCIAL. All queries run in Promise.all() — the full sweep completes in parallel, not sequentially.
Step 2 — Haiku extraction
Raw search snippets are passed to Claude Haiku with a structured extraction prompt. Haiku returns [{ name, credentials[] }] — venue names mapped to credential signals. Haiku does not rank or curate; it only extracts. Cost: ~$0.0003 per run. Haiku receives a CRITICAL rule at extraction time: chef awards follow venues, not chefs. A James Beard Award earned at a prior employer is context only — it does not become a credential for the chef's current restaurant.
Step 3 — Signal block assembly
formatSignalsBlock() in websearch.js assembles the structured extraction output into a text block formatted for Claude Sonnet. The block lists each credentialed venue and its signals. It also states explicitly: credentials are DISCOVERY SIGNALS, not admission tickets. They tell Sonnet which venues have passed external quality checks — Sonnet still applies the full CCTF protocol to decide whether they belong in this member's curation.
Output
The signal block, plus a count of credentialed venues found (credentialedVenueCount), is returned to server.js and injected into the Sonnet prompt. The member-facing spinner shows the sources being checked in real time — 14 sources for TABLE, 9 for STAY, spread across 25 seconds (~1.8s each) — so members see the work happening, not a loading spinner.
Phase 2 — Personalized Curation

Cache-first. On a hit, Phase 2 costs $0.00 and returns in milliseconds. On a miss, Sonnet runs once and the result is cached asynchronously.

What Sonnet Receives
Input 1 — Live credential block
The signal block from Phase 1 is prepended to the Sonnet prompt. Sonnet sees which venues the live web currently recognizes as credentialed in this market and category — e.g. * Canlis: James Beard Award winner | Robb Report Best. This is live data, not training memory.
Input 2 — Seed calibration
The proprietary seed database (seed.js) contains every venue manually researched, evaluated against the quality floor, classified by CCTF environment, and confirmed. Seed data tells Claude what ultra-luxury looks like in each specific market — a calibration layer, not an allowlist. Blocked venues are excluded from the calibration prompt entirely so Claude never considers them as candidates.
Input 3 — Member speed profile
The member's Speed Tier (Couture / Provision / Shadow / Vanguard / etc.) is passed as a named profile with its full characteristic description and disqualifiers. Sonnet matches venue character to member profile — a Provision member receives food-first quiet venues; a Vanguard member receives scene-driven properties. A credentialed venue that is the wrong tier for the member is not recommended.
Input 4 — Quality standard
Sonnet receives the quality floor structured in two credential tiers. PRIMARY credentials — standalone qualifiers: Forbes Five Star, Michelin Key, AAA Five Diamond, and flagship ultra-luxury brand operators (Aman, Four Seasons, Ritz-Carlton, Rosewood, Peninsula, Mandarin Oriental, St. Regis, Park Hyatt select, Belmond, Oetker Collection). Any one of these is sufficient on its own. SECONDARY credentials — sufficient only with price confirmation: Relais & Château, Preferred Hotels Legend, Leading Hotels of the World, Small Luxury Hotels of the World, Condé Nast Gold List, editorial coverage as a named destination. These require confirmed $500+/night rack rate in peak season AND no disqualifying signals — membership alone is not sufficient. The price test: Before including any STAY venue, Sonnet must confirm: does this property command $500+/night at rack rate in peak season? If not, and it lacks a primary credential, it is excluded. “When in doubt, leave it out” is explicit in the prompt. Disqualifiers: properties at the $250–$400/night tier regardless of design quality, LHW or SLH members where membership alone is the only credential, venues described with “better than expected” or “hidden gem” language — CurateVIP venues are acknowledged institutions, not discoveries.
Input 5 — Brand tier framework
The prompt uses a three-tier brand framework. Tier 1 — Hard disqualifiers (no property-level exception, ever): Hyatt Regency, Grand Hyatt, Marriott (all tiers), Sheraton, Westin, Hilton, DoubleTree, Renaissance, Omni, Loews, Embassy Suites, Crowne Plaza, Holiday Inn. These are mass-market or upper-midscale by design — no renovation, location, or award changes their tier positioning. Tier 2 — Scrutinize harder (genuine variation; property-level evaluation required): Thompson Hotels, Andaz, W Hotels (select), Autograph Collection (select), Kimpton (select), 1 Hotels (select). These brands span a wide range. A specific property within a Tier 2 brand can qualify — but must clear at least two property-specific signals beyond brand membership: confirmed $500+/night rack rate, specific editorial coverage about this property (not the brand), architectural or historic significance, or an independently credentialed amenity at that specific location. Brand reputation is a starting point, not a credential. Tier 3 — Presumptively qualified (brand IS the credential at flagship tier): Aman, Four Seasons, Ritz-Carlton, Rosewood, Peninsula, Mandarin Oriental, St. Regis, Park Hyatt (select), Belmond, Oetker Collection, Alila, Six Senses, Auberge Resorts. One of these flags is sufficient on its own.
Input 6 — Environment classification rules
Sonnet receives the full CCTF environment taxonomy with named worked examples: what makes a Vanguard (the hotel IS the scene), an Estate (historic heritage is the primary identity), a Sanctuary (privacy and restoration are the draw), an Atelier (human-designed architecture is the reason). For TABLE: Provision vs Couture disambiguation rules with the Canlis example. Environment is classified by PRIMARY IDENTITY — a design hotel with a pool scene is Vanguard, not Atelier, because the scene is what guests are actually buying.
How Sonnet Evaluates Each Venue
Credential interpretation — 3 mandatory tests
Every venue surfaced by the credential block must pass three tests before inclusion. (1) Attribution test: Is this credential for THIS venue, or did the chef earn it at a previous restaurant? A James Beard winner who now runs a casual neighborhood spot — the award belongs to where they earned it. The current venue has no credential. (2) Full experience test: Does the venue deliver ultra-luxury end to end? Physical setting, neighborhood positioning, price tier ($150+ per person minimum for TABLE), service model, and the room itself must all qualify. A talented chef cooking in a former video store in a working-class neighborhood = interesting meal, wrong venue. The food can be transcendent and the venue still fails. (3) Member trust test: Would a discerning member who has handed you their trust feel this recommendation respected their expectations? If any doubt — leave it out.
Discovery mandate
Before finalizing, Sonnet must sweep the full geography (every neighborhood in scope, not just the main luxury corridor) and the full reference stack (local award bodies, Relais & Châteaux members, luxury travel media specific to that market). A venue in a less-obvious neighborhood is always preferred over a mediocre one in the most visible zone. This mandate is what surfaces venues that default AI behavior misses.
Quality over count
Sonnet returns up to 6 candidates for the frontend to randomly select 3 from — giving members fresh results each visit. If the market genuinely has fewer qualifying venues at this caliber for this speed tier, Sonnet returns fewer and provides an honest editorial note. A short honest list beats a padded one. This principle is explicitly enforced in the prompt.
Server-Side Post-Filter Guards (run after Sonnet)
Guard 0 — Signal Guard
A Haiku AI validation pass — the only post-filter guard that makes an AI call. After Sonnet returns its candidate list and the geo + tier guards run, each candidate venue name is sent to Haiku alongside the full raw Brave Search result set. Haiku checks whether the venue appears anywhere in the live results and returns one of three states: found (passes), not_found (rejected unless seed-confirmed), uncertain (always passes — conservatism prevents false negatives). Venues with confirmed: true in seed.js bypass this guard. Runs only when raw search results are in memory (cache miss on quality_signals). On cache hit: skipped. This is the guard that catches the Hotel 1000 class of error: a venue surfaced from training knowledge alone, with no live web signal, no primary credential, and no seed entry. Logged as [signal-guard] in Railway. Cost: ~$0.001–0.002/run. Latency: +500ms–1s on cache-miss path only.
Guard 1 — Seed-block filter
Removes any venue marked blocked: true in seed.js. These are venues confirmed too casual, wrong tier, or otherwise inappropriate regardless of what Sonnet returns. Logged as [seed-block] in Railway. Each blocked entry includes documentation of why — encoding institutional knowledge that prevents the system from repeating the same error. Example 1: Tomo Seattle — blocked permanently regardless of chef pedigree (James Beard attribution error case study). Example 2: Hotel 1000 Seattle — blocked after being surfaced by training knowledge and passed through the old quality gate via LHW membership alone. Documented: 120 rooms, $300–$450/night, no Forbes Five Star / Michelin Key / AAA Five Diamond. Its own character description (“zero scene, better than the address suggests”) is disqualifying language for CurateVIP.
Guard 2 — Environment-block filter
Removes venues that are valid on the platform generally but blocked for the specific environment requested. Controlled by environment_blocked: ['Verandah'] on a seed entry. Example: Canlis is valid for Provision/Couture but blocked for Verandah — it is an indoor glass-wall building, not an open-air environment. Logged as [env-block].
Guard 3 — Surrounding filter
Removes venues marked surrounding: true in seed.js when the member has not toggled "Include Surrounding Areas." These venues exist in the seed and Sonnet knows about them, but they do not appear until the member opts in. Logged as [surrounding-block].
Final output
Up to 3 venue cards shown to the member (randomly selected from Sonnet's candidates) + 1 Wild Card from an adjacent speed tier. Fewer cards returned if fewer qualify — never padded. Every venue shown has cleared: geo guard → tier guard → Signal Guard → seed-block → env-block → surrounding-block. Six independent checks between Sonnet's output and the member's screen.
What a Competitor Would Need to Replicate This

Brave Search API access: commodity. Any developer can get this in 10 minutes.

Claude API access: commodity. Any developer can get this in 10 minutes.

The CCTF vocabulary and Speed Tier taxonomy: not replicable without the same iteration history. Each of the 11 Speed Tier names encodes precise definitions, disqualifiers, and worked examples developed over multiple cycles. A competitor can copy the names; they cannot copy what the names mean in the context of a curation decision.

The seed database: not replicable without years of manual research. Every entry was evaluated, classified, and confirmed. Blocked entries encode hard-won decisions — Tomo Seattle (chef attribution error), Hotel 1000 Seattle (LHW-alone gate failure) — that prevent the specific class of errors that make AI curation untrustworthy. Each blocked entry documents why it was blocked, creating an institutional knowledge base that compounds with time. A competitor starting today gets generic LLM responses. CurateVIP's AI gets market-calibrated responses anchored to confirmed classifications.

The brand tier framework: The distinction between hard disqualifiers (Marriott, Hilton — no exceptions), scrutinize-harder brands (Thompson, Andaz — property-level evaluation required), and presumptively qualified operators (Aman, Four Seasons — brand is the credential) was developed through live curation testing, not desk research. The specific assignment of brands to tiers and the two-signal requirement for Tier 2 brands represent accumulated curation judgment that cannot be reconstructed without running the system against real markets.

The discovery source hierarchy: The architectural decision to make live Brave Search signals the primary discovery source — with training knowledge as supplement of last resort — prevents training-memory-only recommendations from passing quality gates. A competitor who copies the API calls without the prompt architecture gets the same class of errors CurateVIP had before this layer was built. The hierarchy requires both the signal pipeline and the curation prompt working in concert.

The attribution rules and worked-example library: the James Beard / Canlis / Tomo pattern is documented, seeded into the extraction prompt, the signal block formatter, and the Sonnet curation prompt. A competitor would need to independently discover and document every category of misattribution error. CurateVIP already has them — and adds new ones as edge cases emerge.

The Signal Guard: a second Haiku validation pass that runs after Sonnet, checking each proposed venue against raw Brave Search results before the result reaches the user. The three-state response design (found / not_found / uncertain), the seed-confirmed bypass, the cache-hit skip, and the non-fatal failure mode are all non-obvious design decisions. A competitor who copies the Brave Search queries and Sonnet prompt but omits the Signal Guard gets the same training-knowledge-surfacing errors CurateVIP eliminated. The guard adds ~$0.002/run and 500ms on the cache-miss path — an invisible cost for a significant trust guarantee.

The three-layer post-filter chain: each filter encodes classification decisions that took months to surface. Environment blocking (Canlis ≠ Verandah) requires knowing the venue, knowing the environment definition, and deciding to encode the block at the seed level. A competitor cannot guess these entries; they can only discover them by watching the system make errors, which requires having members who notice and report them.

The defensible summary for an investor: The APIs are commodity. The intelligence layered on top of them — seed data, classification vocabulary, attribution rules, post-filter chain, member profile matching — is not. It compounds with every new market, every new blocked venue, every new edge case discovered and encoded. A competitor who launches tomorrow starts with the same APIs and zero of the institutional knowledge. That gap widens, not narrows, with time.

Pipeline Cost Structure
Phase 1 (cache miss)
Brave Search API: ~$0.001–0.003 per run. Claude Haiku extraction: ~$0.0003 per run. Amortized across 7 days of curations per market/category.
Phase 2 (cache miss)
Claude Sonnet: ~$0.004–0.007 per run. Amortized across all curations served from cache for that market + intent + environment combination.
Cached curation
$0.00 AI cost. Infrastructure costs only. The majority of member curations in an active market are served from cache.
Per-member economics
A member who curates 10 times a week in the same market generates, on average, less than $0.01/week in AI API cost once the cache is warm. The economics improve with member density in each market.
H2 Speed Engine — Background Discovery Architecture New — July 2026

The Speed Engine is the autonomous background pipeline that discovers and pre-ranks qualifying venues across all active markets. It is distinct from the member-facing pipeline in H1 — it runs asynchronously on a cron schedule, builds the pool of classified venues that H1 draws from, and is what allows curation results to be served from pre-ranked pools at sub-100ms latency rather than from real-time AI inference on every member request.

The Core Claim

CurateVIP does not surface venues at curation time by asking Claude what's good in this city. Before any member taps CURATE, four autonomous scrapers have already collected every qualifying hotel from Michelin, Lartisien, Forbes, and Brave Search. A discovery bridge has classified each one by CCTF environment and quality-gated them. A precompute engine has ranked them into pools. The member receives a pre-ranked result. The AI at curation time matches, narrates, and personalizes — it does not discover. Discovery already happened.

The 4-Scraper Architecture
Michelin (Puppeteer DOM)
Renders Michelin Guide hotel pages. Selectors: .card__menu-content, .michelin-award. Extracts: name, Michelin Key, guest score, member privileges. Not a Brave Search query — actual DOM parsing of Michelin's rendered listing pages. Writes to michelin_hotels.
Lartisien (Puppeteer + pagination)
Renders Lartisien city pages, walks ?page=N pagination until exhausted. City-keyword filter prevents cross-market card contamination. Coverage: Scottsdale, Los Angeles, Santa Barbara. Writes to lartisien_hotels.
Forbes (direct JSON API)
Single fetch of award-winners.json returns 2,400+ properties. No browser. Structured data: property name, city, rating tier. All 5 markets covered in one request. Writes to forbes_hotels.
Broad Search (Brave API)
6 queries per market targeting AAA Five Diamond, Relais & Châteaux, LHW, SLH, CN Gold List, T+L World's Best. 30 queries total across 5 markets. Title parsing extracts hotel names by stripping suffix patterns. Writes to broad_search_hotels.
Scraper market coverage
Michelin and Forbes cover all 5 markets. Lartisien covers Scottsdale, Los Angeles, Santa Barbara only — no Seattle or Maui listings exist on their site. Broad Search covers all 5 markets (30 queries per run). Seattle and Maui use 3 scrapers; the other 3 markets get all 4.
Broad Search name-extraction robustness
The Brave Search title field is noisy — results often return article titles rather than hotel names. The extractHotelName() function in broadSearchScraper.js applies two layers of defence: (1) strip patterns that remove em-dash subtitles and geographic suffixes (“in City, ST 2026”) from otherwise clean titles; (2) generic title guards that reject extracted strings matching article-opener patterns (the best, review of, here are, here’s, why/how/what/inside/discover/explore, etc.), ending in punctuation, ending with a year, or exceeding 8 words. If no clean hotel name can be extracted, the result is skipped entirely. This makes the broad_search_hotels table reliable as a discovery signal even though the underlying Brave API data is unstructured.
Cron schedule
Sunday 2:00 AM UTC — all 4 scrapers run (0 2 * * 0). Sunday 4:00 AM UTC — precompute for all markets (0 4 * * 0). Two Railway Cron services, same backend repo, configured with INTERNAL_CRON_SECRET env var. The pipeline is self-sustaining: each Sunday it discovers new venues, scores them, classifies them, and rebuilds pools — with no manual intervention required.
Discovery Bridge — What Makes It Defensible
3-pass architecture
Each scraper table is a separate pass through the bridge. Within each pass: dedup check (prevents re-evaluating already-seeded or already-queued venues) → Brave Search enrichment (description, location context, surrounding signals) → cross-reference all other scraper tables (multi-source convergence is a quality signal) → Claude Haiku CCTF classification → quality gate decision → upsert to pending_venues.
Haiku as classifier, not curator
Haiku's role in the Speed Engine is classification, not curation. It receives structured signals about a venue and returns: (1) the CCTF environment tier (Atelier, Sanctuary, Estate, Vanguard) and (2) quality_pass: true or false. It does not select venues for members — that is Sonnet's job at curation time with the member's speed profile. Haiku decides whether a venue clears the quality floor and what its environment is. Cost: ~$0.0003 per venue classified.
Accumulated institutional knowledge
Every venue that enters pending_venues carries its classification decision, quality score, signal breakdown, and discovery source. Every venue manually rejected carries the reason. This creates an institutional memory of what the quality floor looks like in each market — a judgment library that a competitor cannot reconstruct by running the same APIs, because the CCTF taxonomy governing the classifications is not available from any API.
Precomputed Pools — What They Enable

The precomputed pool is the infrastructure that makes CurateVIP feel instant. A member who curates Sanctuary hotels in Seattle is not waiting for the system to discover, evaluate, and rank hotels in real time. The pool was built before they arrived. Their curation is a retrieval + personalization, not a discovery. This is what separates a product from a demo.

What competitors experience without this
A competitor who builds an AI curation product without a precompute layer asks Claude "what are good Sanctuary hotels in Seattle?" at curation time, every time. They get training-knowledge responses with no live validation, no quality scoring, no CCTF classification, and latency proportional to the inference call. As their user base grows, their costs scale linearly with curations. CurateVIP's cost per curation trends toward zero as pool hits grow. The architecture is fundamentally more scalable and more defensible.
Pipeline Cost Structure
Full pipeline run (per market)
Brave Search queries (broad scraper): ~$0.002 per market. Haiku classification (new venues only): ~$0.0003/venue × new venues found. Precompute (no AI cost): infrastructure only.
Per-curation cost (pool hit)
$0.00 AI cost for discovery. Haiku personalization (if needed): ~$0.0003. Sonnet FEEL/WHY generation: ~$0.004–0.006 (cached permanently per venue). A warm pool amortizes all Speed Engine costs across every curation served from it.
Economics vs. real-time discovery
Real-time discovery model: every curation requires fresh discovery + classification + ranking, ~$0.01–0.05/run, scales with curation volume. CurateVIP pool model: discovery cost is fixed per pipeline run, amortized across unlimited curations. As member density per market grows, per-curation economics improve monotonically.
I Version History — Deliberate Evolution Record

A methodology that evolved deliberately has more legal and commercial weight than one that appeared fully formed. This version history demonstrates that the CCTF Engine is a living system, iterated with intention. For IP counsel: the dates below establish a timeline of development and first use.

v1.0
May 2026
Initial CCTF Engine: two-axis classification (member Speed Tier × venue Environment). Three intent categories (STAY, TABLE, SOCIAL). Initial Speed Tier vocabulary established. Quality floor defined. Seed data for Scottsdale and Seattle. AI curation pipeline using Claude Sonnet.
v1.1
May 2026
Multi-environment Wild Card system added. Adjacency mapping hardcoded. Dual-environment seed entries introduced. KOAST (Maui) identified as first triple-environment wild card candidate (Provision × Verandah × Couture).
v1.2
May–June 2026
Surrounding areas architecture introduced. Per-market labels. Server-side surrounding filter added as third post-filter in the three-filter chain (seed-block → env-block → surrounding-block). Scottsdale, Seattle, Maui surrounding areas seeded.
v1.3
June 2026
Quality-over-count principle formalized. contextMessage system added: AI returns an honest editorial note when it cannot find 3 venues with full confidence, rather than padding the list. "1 exceptional venue + honest contextMessage is always better than 3 mediocre venues with no message." Quality floor documentation expanded with named disqualifiers (TripAdvisor, Five Star Alliance, AAA Four Diamond).
v1.4
June 2026
environment_blocked field added to seed schema. Verandah definition hardened: "the table itself is outside, under the sky, in open air" — eliminates glass-wall edge cases. Canlis and Goldfinch Tavern added to environment_blocked: ['Verandah']. Discovery Mandate formalized: geographic sweep + reference sweep required before any curation. Maui TABLE deep-dive surfaced nyloS, The Restaurant at Hotel Wailea, and Nobu Maui — all missed by default AI behavior without the mandate.
v1.5
June 30, 2026
Beta market paring to 4 active markets (Scottsdale, Seattle, Maui, Santa Barbara). Verandah hidden from TABLE speed selector for beta. Vanguard hidden from STAY for beta. Auto-re-curation on surrounding toggle change. Admin documentation migrated to curatevip.app with SHA-256 authentication. IP methodology specification drafted (this document).
v1.7
June 30, 2026
New Section H1 — Live Intelligence Pipeline — Technical Architecture: investor-facing brief covering the complete two-phase pipeline (Phase 1: Brave Search 22 parallel queries → Haiku extraction → signal block assembly; Phase 2: Sonnet curation with 4 input layers + 3 post-filter guards). Competitive replication analysis and pipeline cost structure documented. New moat item added to Section H: Live Credential Intelligence Layer with full competitive analysis. Section 15 AI-First Architecture updated: old two-layer model (training + seed) replaced with accurate three-layer model (live credential intelligence + seed calibration + Claude judgment). New quote: "Live credential intelligence is the signal. Seed data is the calibration. Claude's judgment is the engine." Section J Trade Secret list expanded: items 11 (Live Credential Intelligence Layer) and 12 (credential attribution rule system) added.
v1.8
June 30, 2026
Quality floor restructured — PRIMARY vs SECONDARY credential tiers. Primary credentials (Forbes Five Star, Michelin Key, AAA Five Diamond, flagship brand operators) are standalone qualifiers. Secondary credentials (LHW, SLH, Relais & Châteaux, Preferred Hotels Legend, Condé Nast Gold List) now require confirmed $500+/night rack rate — membership alone is insufficient. $500+/night price test formalized as an explicit pre-inclusion check. Hotel 1000 Seattle added to permanently excluded list: LHW member, no primary credential, $300–$450/night, described as “zero scene, better than the address suggests” — disqualifying for CurateVIP.

Discovery architecture restructured. Previously, training knowledge was the explicit primary discovery source. Now: Brave Search DISCOVERY SIGNALS are primary. A venue not in seed.js must appear in live signals to be included unless it holds a primary credential. Training knowledge is a supplement of last resort — not the default engine. REFERENCE SWEEP reframed: interprets and supplements live signals, does not replace them.

Brand tier framework introduced (discussion stage). Three tiers: (1) Hard disqualifiers — Marriott, Hilton, Hyatt Regency — no property exceptions. (2) Scrutinize-harder brands — Thompson, Andaz, W Hotels (select) — genuine portfolio variation; requires two property-specific positive signals to qualify. (3) Presumptively qualified — Aman, Four Seasons, Ritz-Carlton, Rosewood — brand is the credential. Framework replaces the “(most)” qualifier pattern that created exploitable loopholes.
v1.9
June 30, 2026
Signal Guard added — Guard 0 in the post-filter chain. A second Haiku validation pass runs after Sonnet returns candidates and geo/tier guards run, before the mechanical seed-block / env-block / surrounding-block guards. Haiku receives each proposed venue name alongside the full raw Brave Search result set and returns a three-state signal: found (passes), not_found (rejected unless seed-confirmed), uncertain (always passes). Venues with confirmed:true in seed.js bypass the guard. Runs only on quality_signals cache misses — skipped on cache hits. Cost ~$0.001–0.002/run. Latency +500ms on cache-miss path only. Logged as [signal-guard] in Railway. This guard closes the last architectural gap: venues surfaced by training knowledge alone, with no live web presence, no primary credential, and no seed entry. The Hotel 1000 class of error is now caught at Guard 0 before it can reach Guards 1–3. websearch.js: validateVenuesAgainstSignals() added and exported. server.js: signal guard integrated after tierPicks, before venueResults build.
v1.6
June 30, 2026
Live credential source spinner added: sequential display of all sources checked (TABLE: 8, STAY: 9, SOCIAL: 5), spread across ~25 seconds using Math.floor(25000 / msgCount). Status SSE event added — backend sends credentialedVenueCount after Brave/Haiku extraction so frontend can display "Found X verified venues · Curating just for you…". "Paired X matches just for you" message added before venue checkmark sequence. Credential Attribution Rule formalized and enforced at three layers (Haiku prompt, formatSignalsBlock guidance, server.js CREDENTIAL INTERPRETATION section): chef awards from prior employers do not transfer to current restaurant. Tomo Seattle added to seed.js with blocked: true — canonical example of chef-pedigree misattribution. Social tab hidden for Phase 1 with "Coming Soon" badge (opacity 0.4, disabled, non-clickable) — single-line re-enable when ready. Admin credentials table created in Supabase (SHA-256 hashed, username/password_hash schema) with /api/admin-auth and /api/admin-set-password endpoints on Railway backend.
v2.0
July 2026
Speed Engine — Autonomous Discovery Pipeline launched. Four scrapers introduced: Michelin v7 (Puppeteer DOM, .card__menu-content + .michelin-award, writes to michelin_hotels), Lartisien v3 (Puppeteer + ?page=N pagination, city-keyword filtering, writes to lartisien_hotels), Forbes (direct award-winners.json API, no browser, writes to forbes_hotels), Broad Search (6 Brave Search queries × 5 markets, writes to broad_search_hotels). Quality scoring engine: 0–100 point scale, 13 weighted signals plus source-bucket convergence bonus, stored in venue_quality_scores. Discovery Bridge: 3 sequential passes, each: dedup → Brave Search enrichment → cross-reference all scraper tables → Claude Haiku classifies (CCTF environment + quality_pass) → upsert to pending_venues. Quality gate: quality_pass true → status 'approved' (live immediately); quality_pass false → status 'pending' (admin review queue). Precompute engine: ranks seed + approved venues by quality score × intent × environment → precomputed_venue_pools. Full error handling audit across 9 backend files (55d3b93): 25+ gaps closed; throw on data-corrupting failures (delete+upsert race), warn+continue on signal-absent failures, CRITICAL log when scrape_log unreachable. Pipeline endpoints: /internal/run-scrapers (full), /internal/run-discovery (bridge only), /internal/precompute-all-markets (precompute only). New sections in IP methodology: §H moat item and §H2 Speed Engine Architecture.
J Confidentiality & Trade Secret Designation

TRADE SECRET NOTICE. The methodology, taxonomy, decision protocol, classification rules, worked examples, seed data architecture, wild card logic, and version history contained in this document constitute trade secrets of RMK Group LLC, DBA CURATEvip, protected under the Defend Trade Secrets Act (18 U.S.C. § 1836 et seq.) and applicable state law.

Reasonable measures taken
This document is stored behind password-authenticated access. The password is hashed (SHA-256) and stored in a private database. Access is limited to the founder, authorized legal counsel, and qualified investors under executed NDA and IP-assignment agreements. No portion of this methodology is published, open-sourced, or disclosed in marketing materials.
What is protected
(1) The Speed Tier vocabulary and definitions. (2) The classification decision protocol. (3) The quality floor criteria and named disqualifiers. (4) The two-axis matching methodology. (5) The wild card adjacency logic. (6) The seed data and its classification assignments. (7) The worked-example library. (8) The surrounding areas architecture. (9) The three-filter post-processing chain. (10) The AI prompt engineering implementing the above. (11) The Live Credential Intelligence Layer: the specific Brave Search query set, the Haiku extraction prompt and attribution rules, and the formatSignalsBlock() signal assembly architecture. (12) The credential attribution rule system: the documented categories of misattribution error, the three-layer enforcement architecture (Haiku prompt → signal formatter → Sonnet curation prompt), and the canonical worked examples (Canlis / Tomo Seattle). (13) The discovery source hierarchy: Brave Search live signals as primary, seed calibration as approved reference, training knowledge as supplement of last resort. The requirement that a venue not in seed.js must appear in live signals (absent a primary credential) is a non-obvious architectural decision that prevents training-memory-only recommendations. (14) The brand tier framework: the three-tier classification of hospitality brands (hard disqualifiers / scrutinize-harder / presumptively qualified) and the two-signal requirement for Tier 2 brands, developed through live curation testing and edge-case discovery. (15) The Signal Guard: a post-Sonnet Haiku validation pass that cross-references each proposed venue against raw Brave Search results. The three-state response design (found / not_found / uncertain), seed-confirmed bypass logic, cache-hit skip behavior, and non-fatal failure mode constitute a distinct and non-obvious system. The guard eliminates the class of errors where AI training knowledge surfaces a venue with no live web verification — a problem that is invisible until a specific misclassification reaches a member.
(16) Speed Engine pipeline
The four-scraper configuration (Michelin DOM selectors, Lartisien pagination strategy, Forbes JSON endpoint, Broad Search award-query set), the 13-signal quality scoring formula and its exact weights, the three-pass discovery bridge logic, and the precomputed pool schema. The accumulated pool data — weeks of quality-scored venue records across all markets — is a trade secret asset independent of the code that generated it.
(17) Scraper name-extraction logic
The extractHotelName() function in broadSearchScraper.js: the specific pattern library for stripping article titles from Brave Search page titles (em-dash subtitle strip, geographic suffix strip, 8 generic article-opener guards, 8-word count heuristic). Derived through iterative live-data testing; not derivable from API documentation.
(18) Two-model AI architecture
The specific division of labor between Claude Sonnet (curation, FEEL/WHY editorial) and Claude Haiku (credential extraction, CCTF classification, Signal Guard, photo vision check), including the prompt design for each role. The non-obvious reasoning for which decisions are made by which model at which pipeline stage constitutes a distinct engineering judgment that cannot be reconstructed without the decision history.
(19) Booking architecture
The decision to route fulfilment through a branded White Label with the partner as merchant of record — capturing commission and a fully branded, curated booking experience while keeping PCI scope, Seller of Travel registration, and chargeback liability off CurateVIP — is a deliberate structural choice reached through direct regulatory analysis. The venue-to-LiteAPI-ID mapping, the 27/10 White-Label/Expedia routing split, the deep-link-plus-inventory-guard design that prevents members from reaching generic hotel search, and the injected-theme integrity monitor are proprietary integration decisions not derivable from any vendor documentation.
(20) TABLE dual-credential discovery
The two-family restaurant discovery architecture: the specific prestige query set (Michelin all-tiers including “Selected,” Beard winner/finalist/semifinalist, Wine Spectator, La Liste, World’s 50 Best, national and per-market critic institutions) and the scene query set (Eater Heatmap, Infatuation Hit List, Resy demand coverage, scene vocabulary, chef-pedigree detection). The insight that “cool” is a parallel credential system with its own publications; the 270-day scene-decay window with weekly re-confirmation as the freshness mechanism; the two-source scene gate as the noise filter; the tiered scoring weights and the scene cap that lets heat surface venues within an environment pool without outranking starred institutions; and the Haiku snippet-extraction method for list-article sources where title parsing is impossible. Developed through direct market analysis (Catch / Toca Madera class venues); not derivable from any single source’s documentation.
(21) Fable 5 learning loop
The three-part discipline that lets the classification AI improve from ground truth without retraining, and stay on the right model as the field moves: (a) the quality-bar correction loop — detecting disagreement (not mere occurrence) between the AI's approve/deny recommendation and the human's actual decision, generating a distilled lesson via a lightweight model, and injecting the most recent disagreements directly into the next classification prompt, live, with no redeployment; (b) the engagement-tracking architecture — treating a member's Book Now / Reserve tap (and Check Availability) as a positive real-world signal, plus true booking completion via LiteAPI/Nuitee webhook, deliberately held out of the scoring formula until sufficient history exists to weight it responsibly rather than let early noise distort standings; and (c) the model-currency discipline — verifying against Anthropic's current published documentation, before adopting or holding a model for this specific decision, that it is genuinely the frontier tier and not just the newest name. Running this one judgment call — the single decision in the pipeline that reaches a member directly — on the frontier model, and re-verifying that choice as new models ship rather than treating it as set-and-forget, is itself a considered architectural choice specific to CurateVIP’s risk profile as a trust-based curation product.
What is not protected
The names of individual venues (publicly known). The fact that CURATE uses AI (disclosed in marketing). The general categories (STAY, TABLE, SOCIAL). The existence of a speed profile system (disclosed in member onboarding). These are the surface; the methodology is what lies beneath.
Disclosure protocol
Before sharing any portion of this document with any third party (investors, potential acquirers, contractors, legal counsel), obtain an executed NDA with IP-assignment clause and log the disclosure with date, recipient, and scope. Treat any sharing of the classification decision protocol or worked examples with the same care as sharing source code.
Patent potential
The two-axis classification methodology, the surrounding areas expansion architecture, and the multi-environment wild card detection system may contain patentable elements. This determination requires review by a qualified IP attorney. A provisional patent application should be evaluated — it is inexpensive, preserves a priority date, and allows "patent pending" to be claimed during any deal process. Do not over-invest here; trade secret is the primary protection and is more certain. But the provisional is worth the conversation.

Document prepared: July 9, 2026. Last updated: July 19, 2026 (v2.4 — Fable 5 learning loop expanded to a three-part discipline: quality-bar corrections + engagement tracking + model-currency verification; v2.3 — Fable 5 learning loop: quality-bar corrections + engagement tracking; v2.2 — TABLE dual-credential discovery engine; v2.1 — booking architecture / White Label fulfilment; v2.0 — Speed Engine architecture). Owner: Rick Bouffard, RMK Group LLC. Status: Active trade secret. Review annually or upon any material change to the methodology. Consult IP counsel before any M&A or licensing discussion that would require disclosure of this material.