Skip to content
thetrail

Engineering

The decisions we made early, and why they hold.

thetrail teaches a language along a real long-distance route. This page is the design document, and it answers one question: does the structure hold.

One

The engine is code. A trail is data.

The product teaches Spanish on the Camino Francés. Little of the machinery knows about Spanish, and little of it knows about the Camino. That separation is the first architectural decision, and everything else rests on it.

The engine holds what every trail shares: the walk mechanics, the component that speaks a line aloud, the audio and image pipelines, and the walker's progress. A trail is a package of data that the engine loads. A language pack rides along with it.

The engine and trail pack boundary Engine code on the left holds the walk mechanics, the speaking component, the audio and image pipelines, and the walker's progress. On the right, a trail pack holds route stages, encounter scripts, vocabulary, and manifests, and a language pack holds script, direction, and voices. The engine loads packs as declarations. The boundary between them is the design. CODE DATA The engine Trail-agnostic. Ships once. Walk mechanics and stage order Tap any line and hear it Audio and image pipelines The curator desk Progress, kept in the browser Route model: ordered stages with a declared finish THE BOUNDARY A trail pack Route stages and encounter scripts Vocabulary Audio and image manifests Culture notes Licensing and spoiler rules A language pack Script, text direction, calendar Voices and romanization rules loaded as declarations
Direction, script, and calendar are declarations in a pack. They never become branches in engine code. Adding a trail means writing a pack, and the engine stays as it is.

The circuit case, decided on day one

The Shikoku pilgrimage is a circle, and it ends where it began. A model cannot represent that walk if it runs from a start point to a different end point. Removing the assumption costs little now and a great deal later.

A route is therefore an ordered list of stages with a declared finish. A straight walk to Santiago satisfies that definition, and a circuit satisfies it too. We wrote the constraint into the model before anyone authored a trail against it.

Two

No generated content reaches a learner without human review.

That sentence is a policy, and the next tool always walks around a policy that lives only in tooling. The pipeline that produces content therefore carries the rule, and a founding requirement puts it in the Worker that serves content. The Worker enforces it once that requirement ships.

An author writes each asset as a prompt under a shared style preamble. Generation runs against that spec. An automated check then reads the result and knows which direction the subject should face. That check catches a class of error a person spots at once and a generic classifier misses. A curator looks at the asset last.

The content pipeline and where the person sits in it An authored prompt under a shared style preamble feeds generation. An automated direction-aware check follows. A curator then reviews. Approved content reaches a learner. Rejected work returns to the prompt for rewriting. Authored prompt style preamble Generation metered, capped Automated check direction-aware Curator review THE GATE Served to a learner rejected, rewritten, generated again EVERY ASSET TAKES THIS PATH
Every asset takes this path today, and the tools hold the gate. The founding requirement moves the gate into the Worker that serves the content, which makes the mandate a property of the code.

Audio, and verifying a language you cannot read

Recorded audio goes through a desk with a full round trip. Verification is the harder problem. A curator who reads no Spanish cannot confirm that a recording says what the script says.

A transcriber therefore hears each clip blind and sees no source text. The desk compares its transcript with the script, after the language pack's rules normalise both. Agreement counts as evidence. Disagreement holds the clip back, and a person decides it. The desk counts an empty transcript as a failure. This check runs ahead of curator review, and it stands in for none of it.

Three

Encounters recur. Nothing escalates.

A walker meets the same kinds of exchange again at a later stage. The recurrence is the teaching method, and familiarity deepens with the forms of the language. The product carries no plot to follow and no character to grow attached to, which we decided on purpose.

  • Every line has two paces. We recorded each one at a teaching pace and at a natural one, and a walker chooses which to hear. The pace governs how much a stage asks of the walker's ear.
  • The trailhead asks three questions. A walker says whether they are peregrina or peregrino, how much Spanish they have, and why they are walking. The forms they read and the voice they hear follow those answers for the rest of the road.
  • A wrong answer teaches. A wrong answer costs the walker nothing. The page says why the answer was wrong, and the character asks again.

The dialogue boundary

Every conversation stays inside its teaching purpose and stays nearly banal by design. Nothing escalates. No relationship forms, and none persists. Every choice a learner can make carries the same weight.

We write that boundary as the instructions our authors work against, and we will hand any live model the same instructions. A filter bolted on afterwards catches only the things somebody thought of first.

The commercial consequence is plain. A product that cannot turn strange is one a school, a parent, and a tourism board can all put in front of someone without reading every line first. That property makes a trail shippable in every culture.

Four

The founding requirements, and which of them run today.

Each of these arrived as somebody's retrofit on an earlier product. We write them down at the start for that reason. Two of them run today, and this page says which.

  • An unauthenticated write carries a hard cap. This runs today. The invitation form on this site sits behind a challenge and a honeypot, and the server refuses a request that arrives with an empty challenge.
  • A build ships only the files it names. This runs today. The pack's publish set is an enumerated allowlist, so a file nobody named reaches no visitor, and a test holds the list where it is.
  • Every route declares a gate. The public set becomes a closed allowlist that a test asserts, and any route that stays public carries a written reason.
  • A pack carries only its own content. A shipped bundle holds back content the learner has not reached, and a pack holds no other pack's licensed material. One guard covers licensing and spoiler control together.
  • Accounts arrive with consent. Progress persists today in the walker's own browser. Once accounts exist, progress persists for a signed-in learner, consent governs collection, and the product links its privacy policy from the first day it has one.

Five

The expensive part is the moat.

Authoring is the cost that decides whether this business works. We write every encounter, generate it against a spec, check it, and hand it to a reviewer who speaks the language. No version of this work gets cheap.

That cost is also the defence. Such a corpus takes far more than a weekend of scraping. It holds reviewed encounters, recorded audio, and checked images across sixty-six stages. The mandate that makes it slow is the mandate that makes it hard to copy.

The bottleneck is curator bandwidth, by design. The plan pays for reviewers and keeps the rule.