Product principles
These exist to end arguments quickly. When two reasonable options are on the table, the one that sits better with these principles wins, and the discussion stops there.
1. The crag is the context, not the app
The user is at a place. Everything should be reachable from "where I am" in one or two taps: this crag, this sector, this route. A navigation structure that makes sense in an org chart and not on a hillside is the wrong structure.
In practice: the crag list is the home tab. Search is in the navigation bar, not behind a button. Sectors are ordered by the order you walk past them, not alphabetically.
2. Offline is not a degraded mode
If a feature is unavailable without signal, it is not finished. The correct behaviour with no network is the same behaviour, with a quiet indicator that sync is pending.
In practice: screens read SQLite. There is no loading spinner on the crag list. "Sync failed" is never an error dialog — it is a line on the Profile screen.
3. Never guess on the user's behalf about safety
Grades, access restrictions, gear notes, approaches and descents are safety information. Where we are unsure, we say so. We do not interpolate, we do not round, and we never present an estimate with the confidence of a fact.
Note what that does and does not forbid. A route always shows the grade it was published in, and that never changes. But it may show an approximate conversion beside it — marked as approximate, given as a range where the mapping is genuinely uncertain, and refused entirely between disciplines that have nothing to compare (ADR-0010). The principle is not "never estimate". It is "never let an estimate look like a measurement".
Approach and descent are on that list deliberately. On a single-pitch crag, a wrong walk-in costs twenty minutes. On a multi-pitch or alpine route it is the most dangerous thing in the record — more days go wrong on the way down than on the way up, and an abseil description that is out by one station, or that assumes a rope length you are not carrying, is not a documentation defect. It is an epic.
In practice: grades display in the system they were published in. A route with no recorded protection notes says nothing rather than "trad, standard rack". Access restrictions are shown prominently and dated. A descent states what it requires — rope length, number of abseils, whether the stations are bolted — or states that we do not know.
4. Native beats consistent-across-platforms
We are building for iOS. The right button is the one iOS users expect, not the one that would also work on Android.
In practice: native tabs, SF Symbols, system share sheet, context menus on long-press, the real large-title navigation bar with its scroll behaviour. See iOS native feel.
5. The record should match what happened
Climbing is done with people. A logbook that records a solo activity is recording it wrong.
In practice: ascents carry partners — both tagged users and free-text names for people who are not on Crag Topo. Style is a first-class field, because "I did it" and "I did it onsight" are different claims.
6. Fast beats complete
A screen that shows nine of the ten fields instantly is better than one that shows all ten after 400ms. The tenth field can arrive.
In practice: blurhash placeholders on topo photos. Route lists render from SQLite before any sync starts. Images stream in.
7. Curated data, contributed corrections
We are responsible for what the app says a route is graded. Users can propose corrections and log their own opinion of a grade; those feed a consensus we review, they do not overwrite the guidebook.
In practice: Ascent.suggestedGrade and suggestedStars exist on the ascent record from day
one, even though the consensus feature that uses them is much later. The data is cheap to collect
and impossible to backfill.
8. The feed and the guidebook are separate systems
There is a feed (ADR-0009), and there is a wall down the middle of it. Engagement — reactions, comments, follows, views — has no input into guidebook data, and safety information is never ranked by popularity.
This principle exists because the pressure to breach it will be constant and will always sound reasonable. "Show the most-liked topo first" is a sensible-sounding sentence and a bad idea: a topo is chosen for how well it shows the lines, not for how good it looks.
In practice: grade and quality consensus comes from logged ascent opinions and nothing else. Access warnings and condition reports appear because they are relevant to where you are, never because they are popular. Nobody has to open the feed to use the guidebook.
When principles conflict
They will. Principle 6 (fast) and principle 3 (never guess) collided over exactly this: whether to show a converted grade at all, and whether it could stand in for the published one. ADR-0010 settled it — a conversion may appear beside the published grade, never instead of it, not even for the moment it takes the real one to load.
That is the pattern. When two principles collide, write it up as an ADR rather than deciding it in a code review.