Everything above as machine-readable JSON: what is sourced, what is guessed, what still has to be checked, and what nobody has looked at yet.
{
"trip": "alpstein",
"name": "Alpstein",
"where": "Appenzell, Switzerland",
"task": "Finish planning this trip. Fill every entry in `unresearched` with sourced figures in the same shape.",
"assumptions": {
"travellers": 2,
"rooms": 1,
"dinner_for": 2
},
"fx": {
"base": "EUR",
"rates": {
"EUR": 1,
"CHF": 1.0681
},
"checked": "2026-08-24",
"note": "Reference rates, updated by hand. Do not call a currency service."
},
"readiness_percent": 88,
"planning_state": "Ready to book",
"claims": [
{
"field": "travel.duration",
"status": "estimate",
"value": [
8,
9
],
"unit": "hours by car from Antwerp",
"basis": "Roughly 700 km of motorway, before fuel, food and traffic stops. An estimate, not a routing result.",
"checked": "2026-08-25"
},
{
"field": "cost.room.mountain",
"status": "fact",
"value": [
230,
250
],
"currency": "CHF",
"unit": "Mountain room, one night",
"multiplier": 1,
"source": "https://bollenwees.ch/zimmer-matratzenlager/",
"checked": "2026-08-25"
},
{
"field": "room.choice",
"status": "our_choice",
"value": "The “Bollenwees” double room for two, breakfast included: CHF 115 per person midweek, CHF 125 Friday to Sunday."
},
{
"field": "verify",
"status": "must_verify",
"note": "Bollenwees private-room availability — most listed 2026 weekends reported sold out."
},
{
"field": "verify",
"status": "must_verify",
"note": "Brülisau parking takes coins, Parkingpay, Easypark or TWINT — not cards."
},
{
"field": "verify",
"status": "must_verify",
"note": "Trail and weather status on the day; agree a turnaround before starting."
}
],
"unresearched": [
"cost.room.valley",
"cost.dinner",
"cost.fuel"
],
"blocks_total_cost": true,
"cost_total_rule": "A whole-trip total is published only when every cost component is sourced. Never a partial total, never 'from', never an estimated total.",
"itinerary": [
{
"day": 1,
"label": "Friday",
"title": "The long drive south",
"activities": [
{
"label": "Drive Antwerp → Appenzell",
"hours": 8,
"status": "estimate"
}
]
},
{
"day": 2,
"label": "Saturday",
"title": "Up to the lake",
"activities": [
{
"label": "Drive to Brülisau and park",
"hours": 0.5,
"status": "estimate"
},
{
"label": "Walk in to Bollenwees via Sämtisersee",
"hours": 2,
"status": "fact",
"source": "https://www.appenzell.ch/en/alpstein/hiking/hiking-tour-suggestions.html"
}
]
},
{
"day": 3,
"label": "Sunday",
"title": "Down to the same car",
"activities": [
{
"label": "Walk back to the same car",
"hours": 2,
"status": "estimate"
},
{
"label": "Drive back to Appenzell",
"hours": 0.5,
"status": "estimate"
}
]
},
{
"day": 4,
"label": "Monday",
"title": "Home, unhurried",
"activities": [
{
"label": "Drive Appenzell → Antwerp",
"hours": 8,
"status": "estimate"
}
]
}
],
"itinerary_mode": "days",
"open_questions": [
"Dinner at Bollenwees has no published price.",
"The valley hotel quotes only through its own booking system.",
"Dates wait on a Bollenwees private-room confirmation."
],
"itinerary_contract": "Every trip page uses this shape. Timings are rough and may be wrong unless calendar_event is true, which identifies the one activity fixed by trip.calendar. Fill day -> activities[] -> {label, hours, status, calendar_event?}, or say why a day is empty. hours may be a number, a [min,max] range, or null when no figure is published - never invent one. status is fact (sourced timing), estimate (reasoned) or unresolved (something must be decided or booked first). Do not invent waking, breakfast or transfer time, and do not compute how full a day is - just list what we want to do and roughly how long it takes.",
"discovery_query": "Berggasthaus Bollenwees Fählensee Alpstein overnight review"
}