Skip to main content

Decisions we owe

The roadmap describes a much larger product than the one the decision log currently supports. This page is the gap between the two: the questions that have to be answered before the work behind them can start.

:::info This page holds questions, not answers

Per CLAUDE.md and the decision log, an architectural decision is confirmed with @mattmoran56 first, and only then written as an ADR. Nothing here has been decided. Where an option is marked as a recommendation, that is a recommendation and not a position — it exists so the conversation starts somewhere other than a blank page.

When one of these is answered it leaves this page, becomes an ADR, and the roadmap row that depended on it stops saying "needs a decision". The feed question left this page that way: ADR-0009. :::


The order they need answering in

Not all of these are equally urgent.

Number 1 is on the critical path for almost everything. Number 6 is next, because phase 2 is early on the roadmap and it is a schema change that gets more expensive with every route in the database. Numbers 7, 8, 9 and 11 are unblocked and could be answered this week.


1. Identity — superseding ADR-0007

Blocks: roadmap phases 6, 7, 8, 9, 12. Effectively the whole second half of the product.

ADR-0007 deferred accounts and gave the device a local identity. That reasoning holds for a guidebook you read. It does not hold for a guidebook that credits authors, tracks who maintains what, follows people, or pays anyone.

What the decision has to cover:

  • Provider. Sign in with Apple only (cheapest, best on iOS, no password surface, but it ties the account to an Apple ID and complicates Android later) versus Apple plus email, versus a managed provider.
  • Migration. There are already device-local identities. Existing ticks have to survive being claimed by a real account, offline, without duplicating.
  • How strong. Attaching money to an identity raises the bar: account recovery, a verified email, and a path to KYC for anyone taking payouts.
  • Anonymity. Whether a contributor can be credited under a handle rather than a legal name, and how that interacts with being paid.

Cost of getting it wrong: identity is the hardest thing to change after launch, because every other record points at it.


2. Contribution licence

Blocks: phase 7 (publishing contributions at all), phase 8 (paying for them), phase 9 (sharing them off-platform).

When somebody traces a line, writes a description, or uploads a photo, what rights do they grant and what do they keep? This is the decision that everything about community content sits on, and it must be settled before the first contribution exists, because a licence cannot be applied retrospectively to content people have already submitted.

The options run from a copyleft licence (CC-BY-SA — open, community-friendly, and probably incompatible with selling the result) through permissive (CC-BY) to a contributor grant that keeps the content open for attribution but licenses commercial use to Crag Topo.

Two things to decide alongside it: whether a contributor can withdraw their content, and what happens to their attribution if they leave.

Cost of getting it wrong: you cannot pay people for content you have no right to sell, and you cannot retrofit a licence onto contributions already made under a different one.


3. Revenue model

Blocks: phase 8 entirely.

Subscription, per-crag purchase, licensed premium packs alongside free community content, or some combination. The choice determines what the community is incentivised to document.

ModelConsequence for contribution
SubscriptionEvery crag earns from a shared pool. Obscure crags earn something. Simple to explain
Per-crag purchasePopular crags earn well, obscure ones earn nothing — which is the coverage a book already has
Premium licensed packsPublisher content alongside free community content. Two-tier quality perception is the risk

Recommendation to react to: subscription with a pooled royalty, because it is the only one of the three that pays anything at all for documenting a quarry nobody has heard of — which is the coverage a book cannot produce and this app can.


4. How contributors are paid

Blocks: phase 8. Depends on 1, 2 and 3.

Once there is money and there are identities, four sub-questions:

  • What counts as use. Downloads, route views, ticks logged, or session time. Whatever is chosen becomes what people optimise for.
  • The split. Author versus maintainer versus moderator, and whether the author's share decays over time as the maintainer does the ongoing work.
  • Conditionality. Whether a maintainer share is contingent on responsiveness — proposals answered, access and conditions kept current — and what the threshold is.
  • Anti-gaming. Money attracts invented crags, inflated route counts, and sockpuppet verification. A crag earning nothing until a second climber has been there is the obvious floor; it is probably not sufficient on its own.

And the compliance floor beneath all of it: payouts, KYC, tax reporting, minimum thresholds and which countries are supported at launch.


5. Trust and moderation model

Blocks: phase 7.

Who can change what, and what merges without a human looking at it. The proposal on the roadmap is four roles and a hard rule that safety-critical fields — grade, gear notes, access status, bolt condition, descent and approach — never auto-merge regardless of reputation.

Open within that: how a maintainer is appointed and removed, what "inactive" means for crag adoption, how disputes between two maintainers of adjacent crags resolve, and whether an immediate safety banner can be posted by anyone or needs any threshold at all.

Cost of getting it wrong: this is one of two on this page where the failure mode is somebody getting hurt rather than somebody being annoyed. The other is number 6.


6. The multi-pitch and alpine data model

Blocks: roadmap phase 2, which is early and deliberately so. This is the most urgent decision after identity, because it is a schema change and schema changes get more expensive with every route in the database.

Today a route has one grade, one line, one photo, and a walk-in measured in minutes. Phase 2 needs all four of those to become something larger, and each one is a separate call:

  • Grades become a set. An alpine route carries an overall grade (PD/AD/D/TD/ED) and a rock grade and possibly ice, mixed and aid grades, none of which convert into the others (ADR-0010). What is still open is the storage shape: a child table or a JSON column, and a rule for which grade in the set grade_band derives from, since that integer is what filtering uses.

    The same question, in a smaller form, decides how UK trad grades hold their adjectival and technical halves — parsed on read from "E2 5c", or stored as separate columns with the display string derived. Answering it once for both is the cheap version; answering it twice is how they drift apart.

  • Pitches become records. Number, grade, length, belay, gear. And then: does route_lines key on a pitch, or stay keyed on a route?

  • Descent becomes shared. One gully or abseil line serves twenty routes, so it wants to be its own record rather than a field. That complicates attribution — who maintains a descent? — and the offline download bundle, because a route's download now pulls a record that is not under its crag.

  • Approach becomes structured, superseding or extending crags.parking and approach_minutes.

  • Facts acquire an age. A condition report needs a date and a staleness rule. Does the app compute staleness from the date, or does a report carry an explicit validity window? Alpine and gritstone decay at very different rates.

All of these are new syncable tables, so they inherit the ADR-0004 conventions — client-generatable ids, soft delete, (updated_at, id) — and each one grows the crag download.

Cost of getting it wrong: the same as number 5. A descent record that cannot express "two 60 m ropes, four abseils, stations bolted but the third one is worn" is a record that will eventually be read in the dark by somebody who needed it to.


7. The route tag vocabulary

Blocks: the tags and pills in phase 1, and the tag consensus in phase 7.

The decision is not the list of tags — that is editorial and can grow. It is the three things a growing list cannot fix later:

  • Controlled vocabulary versus free text. Free tags fragment into "runout", "run-out" and "bold" inside a week, and a fragmented tag cannot be filtered, counted, translated or voted on. Recommended without much hesitation: a controlled vocabulary in packages/shared, versioned like any other enum.
  • Whether a tag is editorial, voted, or both. "Slab" is a fact and belongs to whoever wrote the route up. "Polished" is an opinion that a hundred people can answer better than one editor. If both exist, they need to be visibly different kinds of claim rather than the same pill.
  • Whether safety tags are a separate class. "Loose rock" and "crimpy" are not the same sort of statement, and rendering them identically flattens a distinction principle 3 exists to protect. Separate class, separate visual weight, sorted first — and never carried by an icon alone, because a glyph for "loose rock" is not self-evident and is invisible to a screen reader.

Everything else — which tags, what the icons look like, how many fit on a card — is a design question and does not need an ADR.


8. Tab structure

Blocks: phase 3. Unblocked and cheap to answer.

The roadmap proposes Nearby, Map, Plan, Logbook, Feed, with Profile moving to the navigation bar and no dedicated Crag tab. That is five, which is the iOS maximum before the system starts hiding things in "More".

The question is whether that is the right five — in particular whether Plan and Logbook are distinct enough to be separate tabs rather than two segments of one, which would free a slot.


9. Image storage and delivery

Blocks: phase 1. Already flagged on the roadmap; still unanswered.

R2 bucket layout, which transform service, which sizes are generated, how originals are retained, and what the per-crag download actually contains. Contributed photos make this bigger than it looks — user uploads need moderation, EXIF stripping, and a deletion path.


10. Storage tiers and eviction

Blocks: phase 4.

The three-tier model — pinned, cached, metadata — and its eviction rules are cross-cutting to sync, which makes them ADR territory rather than a code-review decision. Specifically: where tier state lives, whether it syncs across a user's devices, and what the default budget is on a 128 GB phone.


11. Offline map tiles

Blocks: phase 1 (approach) and phase 3 (map tab). Already flagged; still unanswered.

Tile source, licensing for offline caching — several providers forbid it outright — download size per crag area, and the styling. This one is mostly a licensing question wearing a technical hat.


12. Sharing, redistribution and quiet crags

Blocks: the sharing half of phase 9. Depends on 2.

Rendering a contributor's topo into an image and posting it to Instagram is redistribution to a third party, under that third party's own very broad licence terms. A contributor who is happy for Crag Topo to use their photo may be considerably less happy about Meta acquiring a sublicence to it, and the contribution licence has to say which it is before the share button exists.

Alongside that:

  • How attribution survives. A credit in the corner of an image can be cropped off. Whether that matters, and what the minimum is.
  • Somebody else's photo. Sharing a card built from a topo you did not take — covered by the licence, or does it need per-share consent?
  • Quiet crags. Some venues stay unpublicised by agreement with a landowner or a local club, and a share sheet is an extremely efficient way to break that. Who marks a crag as location-suppressed — the maintainer, a moderator, or an access flag — and does suppression apply to the whole app or only to what leaves it?

13. External references and UKC

Blocks: phase 12.

Adding externalRefs to crags and routes is small and additive. The decisions around it are not: what the legal and relationship position with UKC is, whether import happens through the user's own data export or something else, and how confident a cross-database route match has to be before it is applied silently rather than shown for confirmation.

Worth saying plainly: the right first move here is a conversation with UKC, not a scraper.


14. 3D asset pipeline

Blocks: phase 11. Not urgent, but it constrains phase 6's capture flow, which is much sooner.

Model format, where reconstruction runs, level-of-detail tiers, and the size budget for anything that might go into an offline download. The reason it is on this page now rather than later: if the guided capture flow in phase 6 does not record the right things, every photo taken before the pipeline exists is unusable for it.