# Generation as a service — how-to for venues

How an owner turns a place into a walkable tour in Hindsite. Written for the
people who run the site, not the people who write the code.

**PDF.** This document is Markdown in the repository (`docs/gaas-howto.md`). A
PDF build is not produced here: this environment has no `pandoc` /
`wkhtmltopdf` / WeasyPrint. Print or convert locally when you need a PDF —
`pandoc docs/gaas-howto.md -o docs/gaas-howto.pdf` once those tools are
installed.

---

## What you are building

Visitors download the **Hindsite** app once, open your tour by name, and walk
with narration, rooms and reconstructions on the phone — with no signal. You
keep editorial control: nothing reaches a visitor you have not approved.

Tour content updates through the **tour catalogue and bundle download**, not
through Expo over-the-air (OTA) JavaScript updates. Expo OTA is switched off
in the visitor app; a new walk ships as a new (or corrected) bundle the phone
fetches from your channel.

---

## 1. Destination language packs (at most five)

On **Languages** in the portal, name the packs your destination sells in —
for example `en-GB`, `de-DE`, `af-ZA`. A destination may have **at most five**.
A sixth distinct locale is refused.

Each pack is what a visitor picks on the phone and what names a narration
directory. You do not need every pack voiced on day one; you need to know which
languages the tour will eventually carry.

---

## 2. Places and buildings

A tour is a set of **places**:

| Kind | How a visitor finds it |
| --- | --- |
| **Stop** | Walk into a GPS radius outdoors |
| **Area** | Dwell in a larger outdoor zone |
| **Building** | Walk up to it outdoors (coordinates required) |
| **Room** | Tap or scan a doorway tag; may nest under a building |

Add places under the tour in the portal. Rooms name their parent building when
they sit inside one. Positions can come from a pasted Maps link.

---

## 3. Write the story in any language → English for GaaS → narration per pack

1. **Contribute** a story in whatever language you think in. The form does not
   ask for a locale.
2. On submit the portal **detects** the language and **pivots through English**
   (`en-GB`): the original words stay on the story; English is stored so
   curation and generation read one language without erasing what was written.
   The English prose is also written beside the photographs as
   `stories/{id}/en-GB.txt` in media storage — that object is what GaaS prompts
   from.
3. After review and (when generation is live) production, **narration is built
   per language pack** into `audio-packs/{locale}/…` — never baked into the
   video. Switching language on the phone does not re-download the pictures.

---

## 4. Periods and time targets

On destination settings, define **periods** — named spans such as “the diamond
years, 1908–1928”. Periods are editorial facts about the destination. When a
story or a generation request needs a time, the curator picks a period (or a
concrete year inside one). Periods may overlap; a story keeps the year it
resolved to even if a period is edited later.

---

## 5. Review → publish

1. **Review** every story. Approve or reject; nothing generated or contributed
   reaches a visitor unreviewed. Reconstructions keep a reconstruction badge.
2. On **Publish**, choose which narratives and language packs the bundle
   carries, then build. The tour already has a catalogue card from when you
   created it (`coming-soon`); Publish starts a build and **flips that card
   available immediately**. Wave C / Epic 12 owns settling Live from the
   finished build — the automatic flip is not a settle.
3. **Promote** moves tested bytes from the rehearsal channel to the public one
   by reference — it does not rebuild.

---

## What is live vs planned

| Piece | Status |
| --- | --- |
| Portal: destinations, tours, places, contribute, review, languages (≤5), periods | **Live** |
| Catalogue card on tour create (`coming-soon`); withdrawn on archive; **available** on Publish start | **Flips on start** — Wave C owns settle |
| Publish / promote UI and bundle channels | **Live** |
| English pivot on contribute (`stories/{id}/en-GB.txt` for GaaS) | **Live** |
| Cost guard on generation jobs | **Live** (domain) |
| Fal / Director generation from the laptop | **Live** for operators with keys |
| **Stills acceptance gate** — restored stills are reviewed before animation is bought | **Shipped** (gate, 30 August) — the job parks for review and the portal has a stills screen. The screen’s queue is not yet the library’s |
| **Worker loop** that claims queued jobs, runs Director → restore → motion → voice, and lands results in the review queue | **Shipped** (drain, 30 August) — an operator worker claims ten-clip batches and stops at the day’s spend ceiling. The portal does not yet enqueue a job that drain can run |
| Hero image required at tour create | **Decided** for the full #313 story; not yet required in the smallest wiring |

The drain shipped. Until the portal enqueues jobs that drain can run, “generation
as a service” for a venue still means: you describe the place and supply
photographs; an operator runs generation with the existing pipeline and keys;
results still enter the same review queue you already use.

---

## Where to go next

- Portal: [portal.hindsite.mobi](https://portal.hindsite.mobi/)
- Public “for venues” page: [hindsite.mobi/for-venues](https://hindsite.mobi/for-venues)
- Engineering detail: `plan.md` Parts 8 and 9, `docs/decisions.md`
