Travel notebook

How it works

How the notebook works

One page, a small server, two phones and an assistant that touches nothing without approval. Here is every piece, as it is built.

Overview

The notebook is a single HTML page: day cards, map, tools and documents. A server hands it out behind a password with the current data of the plan, and relays live what the two phones do.

Calls to the assistant and web reads that check a fact leave from the server, never from the phone.

Architecture of the notebook Two phones talk to the server over HTTPS and receive a live event stream. The server keeps the plan and its versions, the shared state, the conversations and the encrypted vault. It alone calls the AI provider and reads official sites. Phone 1page and send queue Phone 2page and send queue HTTPS · SSE stream Server plan and versions · shared state conversations · encrypted vault from the server AI providerthe travellers’ key Official sitesread to check
The phones only talk to the server for the plan and the state; the server alone calls the AI provider and reads official pages.

The plan

Everything about the trip lives in twenty data lists written in the page itself. The server keeps the current version, swaps those lists in when it serves the page, and caches the rendered page for each version. Photos are served separately and loaded on demand.

ListContents
citiesCities: coordinates, hotels, Airbnb, places, recommended and avoided districts
daysDays: where you sleep, cities, transport, steps to tick, notes
photosAttractions: name in French and Japanese, image search, official site
dayAttrAttractions of each day
cityAttrAttractions of each city
wikiWikipedia articles for places without a photo
luggageMovesLuggage transfers: cities, days, delivery to the hotel or to a depot
luggageGuideLuggage guide: principles, the bag you keep, sources
bookings“To book”: what, by when, how, link
overviewOverview: categories, passes, festivals, sources
dayRoutesRoutes of each day, to open in the apps
PHRASESPhrases to show, in Japanese and romaji
PACKINGPacking list
CAL_EVENTSAppointments to export to the calendar
APPSApps to install
UBERCities where Uber works
PREP“Before leaving”: formalities, deadlines, one box per traveller
CARDS“To show”: Japanese cards, waybill, place and map
MESSAGESPrepared e-mails, never sent by the site
FIELDSFields of “My details”

Every value has a type the engine knows: plain text, HTML limited to a few tags, a web address, a value from a closed list, or a number. A value that does not match is refused before it enters the plan.

On the phone

  • Live mode — the default: during the trip the page opens on the current day, on Japan time. The day card gathers daylight, luggage, a 16-day forecast, “Now”, the routes of the day, steps to tick, photos, places with “Take me there”, lodging, spending and notes.
  • Full mode — adds the route map, the Luggage, To book and Photos tabs, search across the whole plan, sources and festivals.
  • Guide — illustrated steps to install the useful apps, open the page and add it to the home screen.
  • Tools — yen to francs converter, phrases to show, trip spending, packing list, calendar export as .ics, settings.
  • Documents — before leaving, to show, messages to send, my details, tickets.

The app buttons are plain universal web links: on the phone they open the app when it is installed, and the website otherwise.

Syncing

Ticking a step, writing a note or choosing a place to stay changes the shared state. The phone turns that change into an operation: adding to or removing from a list (ticked steps, packing, preparations), or a new value (note, lodging, “My details”).

  1. Operations are grouped over a few hundred milliseconds, kept in a queue on the phone, then sent to the server.
  2. The server validates them, applies them in one block and moves the state version forward.
  3. It pushes the change to the other phone on a live event stream (Server-Sent Events).
  4. The other phone updates the box or the note on screen, without reloading the page.

With no network the queue stays on the phone and retries every five seconds until the connection is back. On each reconnection the phone reads back what changed since its own state version. An operation already received is never applied twice.

When the plan itself changes

A change to the plan, rather than to the state, creates a new version. Both phones reload the page keeping the open view; if you are typing or the assistant is open, a “Plan updated · Reload” banner waits for your move.

The assistant

The assistant runs on the travellers’ API key, entered in Tools › Settings: Anthropic, OpenAI, DeepSeek or any OpenAI-compatible server. The key is encrypted on the server, and the phone only ever sees its last four characters.

Each turn of the conversation runs on the server: it finishes even if the phone locks, and both phones see the same conversation, one per day.

Life of a proposal 1. Question : asked from either phone. 2. Reading : get_day, get_city, search_plan…. 3. Checking : official pages read by the server. 4. Proposal : checked patches, nothing written yet. 5. Apply : or Dismiss: you decide. 6. New version : both phones reload the plan. 7. Undo : inverse patches, another new version. 1Questionasked from either phone2Readingget_day, get_city, search_plan…3Checkingofficial pages read by the server4Proposalchecked patches, nothing written yet5Applyor Dismiss: you decide6New versionboth phones reload the plan7Undoinverse patches, another new version
A proposal only touches the plan when a traveller applies it; every step after that stays reversible.

The tools

The assistant never receives the whole plan at once: it reads what it needs, and every line it reads starts with the exact place it comes from.

ToolRole
get_dayReads a whole day: steps, routes, attractions, related bookings, shared state.
get_cityReads a city: hotels, Airbnb, places, districts, chosen lodging.
get_sectionReads a section: luggage, bookings, overview, preparations, cards, messages.
search_planSearches a word across the whole plan, with the exact place of each hit.
propose_changesRecords a proposal checked by the engine, without applying it.
fetch_urlReads a web page or a PDF from the server, behind the anti-SSRF guard.
search_webWeb search, for providers without one of their own (Anthropic uses its built-in search).
get_weatherOpen-Meteo forecast for a city and a date within 16 days.
set_stateTicks a step, records spending or a place to stay, on an explicit request only.
load_guideReads a practical guide from the repository (luggage, onsen, manners, phrases, everyday life).
find_nearbyConvenience stores and post offices near a point, with the sending rules of each chain.
list_documentsLists the tickets in the vault (metadata).
read_documentReads the text of a PDF, only if it is marked readable by the assistant.
load_skillLoads a detailed playbook.

The vault tools only exist on the hosted notebook. Web pages that are read are marked untrusted: what they contain stays data, never an instruction.

The playbooks

The assistant has 12 short playbooks; it loads the detail of the one it needs with load_skill.

  • verifier-un-fait
    Check an opening time, a price or a rule on an official source, then date and source the result.
  • modifier-une-journee
    Change a step, a time, a leg or a note without breaking the day.
  • ajouter-un-lieu
    Add an attraction, a restaurant or a shop everywhere it must appear.
  • logement
    Hotels, Airbnb, recommended and avoided districts, chosen lodging.
  • reservations
    The “To book” list, the passes and the calendar appointments.
  • valises
    Luggage, takkyūbin transfers and depot pick-ups.
  • preparatifs
    Formalities and errands before leaving, deadlines and official links.
  • documents-et-cartes
    Japanese cards to show, prepared e-mails, fields to fill, tickets on file.
  • phrases-utiles
    Phrases to show, grouped by situation, in polite Japanese with Hepburn romaji.
  • etat-et-depenses
    Ticking, recording spending or lodging, on a clear request only.
  • sources-et-festivals
    Kept sources, festivals, illuminations and the categories of the overview.
  • style
    Writing and typography rules for every string written into the plan.

The checks

A proposal is a list of patches. Each patch points at a precise place in the plan with a JSON pointer (for example /days/1/plan/2), carries the current value it expects, the reason for the change and an official source.

The engine checks the path, the type of the value, the schema, the style rules (no emoji, no exclamation mark, French typography, short steps) and the links between lists. At the moment of applying, everything is checked again against the current version: if the plan moved in between, the card goes stale and nothing is written.

Never applied automatically. The plan only changes when a traveller presses Apply. The assistant may only tick a step, record spending or save a place to stay, and only on an explicit request; those changes are logged.

Versions and undo

Applying a proposal, undoing it or restoring an older version always creates a new version: nothing is rewritten. The server keeps the last hundred, with their author, their summary and the patches applied.

  • Undo — the server applies the inverse patches, and refuses if the value has changed since.
  • Restore — (Tools › Settings › Plan versions): a copy of an older version as a new version.
  • Ticks follow — inserting or removing a step renumbers the ticked boxes in the same version.

Documents and cards

  • Before leaving — formalities and errands, deadlines with a countdown, one box per traveller when each of you must do it.
  • To show — cards in large Japanese type for the reception desk, the ticket counter, the taxi or the luggage depot, with the waybill, the address to copy and the map of the place.
  • Messages to send — prepared e-mails, to copy or to open in the Mail app. The site never sends anything.
  • My details — names, numbers and addresses filled in by the travellers, kept in the shared state and never in the plan. The assistant does not read them.
  • Tickets and documents — a vault encrypted with AES-256-GCM on the server (PDF, JPEG, PNG, WebP or HEIC, type checked from the file contents, 15 MB per file). Documents marked “offline” are copied onto the phone.
Screenshot: a card to show a taxi driver, in large Japanese type, with the French translation underneath
A card to show, on the fictional demo trip: large Japanese type first, the translation underneath, the address and the map below.

The maps on the cards to show are made of 地理院タイル tiles from the Geospatial Information Authority of Japan (国土地理院), with their attribution under each map.

Offline

  • The service worker keeps a copy of the page, the photos and the maps already seen: with no network the notebook still opens, with an “Offline” banner.
  • Changes made offline wait in the queue and leave when the network returns.
  • A complete HTML copy, photos and maps embedded (about 6 MB), can be downloaded from the settings for a computer.

Security

  • Access — one shared password of at least 12 characters, compared against a scrypt hash; a growing delay per IP address after each failure, and a general block after a run of failures.
  • Session — a random token in a cookie marked HttpOnly, Secure and SameSite=Lax, valid for 60 rolling days; every session can be closed at once.
  • Requests — origin checked on every write, request size bounded.
  • Page — a strict content security policy (CSP), inline scripts allowed by SHA-256 hash, connections limited to the named services.
  • Keys and documents — encrypted with AES-256-GCM; API keys never travel back to the phone.
  • Web reads — an anti-SSRF guard on every page read for the assistant (public hosts only, IP address checked after DNS resolution, redirects re-checked, size and time bounded).
  • Data — atomic writes, patches validated against the schema, no code from the model is ever run.
  • Robots — a noindex header on every response.

Hosting

The Node.js server runs in a container on a small server in Switzerland, behind a Caddy proxy that handles HTTPS. The data lives in a volume backed up every night, encrypted. Every code update passes the automated test suite before it is deployed.

What the demo simulates

The public demo shows the real notebook, on a five-day fictional trip between Kyōto, Himeji, Miyajima and Hiroshima.

Same as the real notebook

  • The page and the code of the phones
  • Live syncing between the two phones
  • The change engine, the versions, Apply and Undo
  • The cards to show and their maps

Simulated or switched off

  • The assistant follows scripts written in advance: no key, no network call, no page read
  • Each visitor gets their own sandbox, wiped after 20 minutes without activity and after 90 minutes at the latest
  • The ticket vault, accounts, the API key and the offline copy are switched off
  • The maps are loaded straight from the servers of 国土地理院

Start the demo