clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

feat/atlas-next-horizon
atlas / docs / snapshots.md
snapshots.md 3.6K rendered
1# Scheduled city snapshots23> **Parked.** The workflow's steps are the shipped ones —4> `atlas crawl|tiles|compose|enrich` — but the ArcGIS/USGS crawler is not5> built: `atlas crawl -source list` offers `ign` alone, and6> `docs/generate.md` §3.2 says why. A run therefore fails at its first step,7> so this repository's scheduler is dispatch-only and the weekly cron is8> written down in `snapshots.yml` rather than armed. Everything after the9> crawl is the shipped path, walked over a city archive by the pipeline's own10> tests (`docs/generate.md` §8). One crawler registered as `arcgis-hub`11> unparks the whole thing, and nothing else here changes.1213A city's `.atlas` can build itself on a schedule: crawl the city's ArcGIS14hub, exit quietly when nothing changed, and publish a new versioned bundle15when something did.16The reusable workflow lives in this repository17(`.github/workflows/snapshot.yml`); this repository's own scheduler runs it18over the public proof cities. A city IT team runs the same workflow19in a repository of their own, so every employee works off the same enriched20`.atlas` at whatever cadence the team chooses.2122## What a run does23241. Crawls the city into the `fmg-archive` committed on the state branch.25 Captures are content-addressed: an unchanged city registers nothing.26 Beside the city's own hub, every crawl queries the USGS national27 hydrography services on `hydro.nationalmap.gov` for the city's window —28 watersheds, subwatersheds, named streams, waterbodies — so a runner29 with an egress allowlist needs that host beside the hub's.302. Composes the bundle. Its filename embeds the capture day and a content31 stamp over everything inside.323. Gates: if that exact filename is already a release asset, the run ends —33 "unchanged". The gate catches data changes, tool changes, and policy34 revisions alike, because the stamp covers them all.354. Otherwise commits the archive delta (durable, diffable history at any36 cadence — weekly, monthly, quarterly) and uploads the bundle to the37 rolling `snapshot-<city>` release. Every published version stays as an38 asset; `<city>-latest.atlas` always names the newest, so one URL serves39 the whole team.4041## Setting it up in your own repository4243One-time, in a (typically private) repository:4445```sh46git switch --orphan snapshots47git commit --allow-empty -m "snapshot state"48git push -u origin snapshots49git switch main50```5152The branch starts empty and fills up with the capture archive, one commit per53run that found something new.5455Then a workflow:5657```yaml58name: City snapshot59on:60 schedule:61 - cron: "0 6 * * 1" # weekly; monthly/quarterly are equally safe62 workflow_dispatch:63permissions:64 contents: write65jobs:66 snapshot:67 uses: FelineStateMachine/atlas/.github/workflows/snapshot.yml@main68 with:69 city: your-city-slug70```7172A city that should not be named in a public repository is carried by the73`atlas-ref` input: point it at a branch or fork of Atlas whose curation table74(`internal/generate/sources/arcgishub/cities.go`) names the city. There is no75side door — a table that can be extended by a file nobody reviews is not the76gate it is meant to be — so an uncurated city is refused rather than composed77wrong ([decision 16](decisions/0016-uncurated-captures-are-passed-over.md)).7879Employees fetch80`https://github.com/<org>/<repo>/releases/download/snapshot-<city>/<city>-latest.atlas`81and drop it into their Atlas bundles directory — or IT mirrors it onto a82share people copy from. (A bundle dropped in from outside appears at the next83launch: the registry scans at launch and rescans on import, never watches.)