Pre-baked offline cities (London, Barcelona, New York) + endpoint-stop fix
Tristan Leduc+1: Claude Opus 4.8 (1M context)
6881784
Keeps the "Off the Grid" badge while going multi-city: each extra city is baked
as a bounded walkable core (centre + radius) committed via Git LFS, so it routes
fully offline — no live OSM at request time.
- data/build_city.py + config.CITIES registry; data/cities/<slug>_{walk.graphml,
pois.parquet} for london/barcelona/newyork (+ cities_manifest.json).
- routing/area.py: resolve_area now picks Paris → a pre-baked city (both points
in its core) → (online only) on-demand fetch. In offline mode, anywhere else
is refused with an honest "WanderLust covers Paris, London, …" message.
- routing/geocode.py: offline name index now spans Paris + every pre-baked city,
with city-hint disambiguation ("…, London") so a landmark resolves to the
right city; suggest()/local_geocode() are city-aware.
- pipeline.py: drop candidate POIs within 80 m of the start/destination so an
endpoint (e.g. the square you start from) is never offered as a "discovery
stop" — it isn't a detour and read as …
Round-5 fix: relabel bakery_food_shop "food shop" (no false 'bakery' claim)
Tristan Leduc+1: Claude Fable 5
2577e90
Both round-5 reviewers converged on the SOLE remaining MAJOR: a wine shop
("Trois Fois Vin", OSM shop=wine → bakery_food_shop) was narrated "another
bakery along the way" — a false, verifiable label. The category bundles
bakery/patisserie/wine/cheese/deli, so render it "food shop" (always true).
Sole change to pretty_category.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adversarial round 3 (NOT-CONVERGED) found 3 MAJOR issues:
1. The discovery-cue affinity adjustments (zeroing "attraction" for "hidden
gems") were COMPUTED then DISCARDED — the pipeline scored with
effective_weights() while interp.weights was thrown away. Now the vibe
path uses interp's own affinity (blended with profile when present), so
"hidden gems" actually drops famous attractions.
2. OSM ref-code names ("PA_1570") surfaced as unfindable stops labelled "a
match". Added taxonomy.is_real_name(); such POIs now self-demote
(UNNAMED_SCORE_FACTOR) and render as "a <noun>".
3. "attraction" gloss ("famous landmark... worth seeing") embedded near
"tour/spots/photo", landing Hôtel de Ville on a coffee tour. Tightened to
"a major crowded tourist attraction or world-famous monument".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Route-fit fixes from adversarial review (span, glosses, attraction gate)
Tristan Leduc+1: Claude Fable 5
6c11e60
- MIN_AFFINITY_SPAN 0.18 -> 0.10: 0.18 neutralised real evocative vibes
("romantic", "beautiful", "brutalist" all span ~0.14-0.15) into an
identical generic grab-bag; gibberish spans 0.081, so 0.10 separates.
- Gloss keyword-bleed: drop "coffee roaster" from bakery gloss (was tying
cafe 1.00 / bakery 0.97 on "specialty coffee tour") and "quiet" from
worship gloss (was pulling churches into "quiet to read").
- classify(): admit a bare tourism=attraction only if notable
(wikidata/wikipedia/heritage) — drops commercial venues like escape
rooms that polluted monuments/worship/romantic routes (conf can't filter
them: an escape room has conf 1.0). Rebuilt parquet: 290 -> 58 attractions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Design system, live freshness, autocomplete, and clay-pin markers
Tristan Leduc+1: Claude Fable 5
b34c92a
UI/UX (from the design handoff):
- Clay-sticker theme, hero, framed Voyager map with warm grade, loading
state ("Scouting your wander…"), route-draw + staggered marker pop-in
- 14-piece clay-pin marker family (vendored SVGs) with color-by-meaning
mapping for all 17 categories, start/dest pins, legend in the family's
color language
- Start/Destination autocomplete over the local 30k POI-name index
- Force-light mode (design is light-only; Gradio dark vars made text
unreadable), per-event js fixed to pass inputs through
Freshness:
- Open-now awareness from OSM opening_hours (9,461 POIs): conservative
evaluator (abstains on exotic grammar, per-rule PH/SH handling),
plan-time demotion of closed places, night realism for unknown-hours
daytime categories, 🟢/🔴 itinerary badges
- Optional Google Places live-verify of final stops (GOOGLE_MAPS_API_KEY;
ToS-clean: per-request, never stored)
- Embedder switched to fastembed/ONNX (no torch in the request path;
warms in ~9s), bo…
Wanderlust: taste-aware Paris discovery routing
Tristan Leduc
f00d669
Build Small Hackathon submission - v1 complete
All P0 requirements + P1 features:
- OSM-based routing with detour budget control
- POI extraction with confidence scoring (30k places, 17 categories)
- Submodular orienteering solver with diversity optimization
- Vibe interpretation via sentence embeddings (bge-small)
- Grounded narration (0% hallucination gate) with optional Qwen3.5-9B
- Persistent taste profile (browser-based)
- Alternative routes (3 options)
- Custom UI (clay/sticker design with animations)
- Offline-first architecture (no runtime cloud APIs)
- Fully tested (42 tests passing)
Stack: OSM + networkx + scipy + Gradio 6 + HuggingFace
Ready for HF Space deployment.
See HACKATHON_DEPLOYMENT.md for push instructions.