Mountains
An agent researches and designs the route. Deterministic code measures it, draws it, and cuts the files I carry. No number on a map here was guessed by a language model.
Sheet data
Area
Colorado Front Range
Routes planned
11
Route miles
163.4
Vertical gain
60,992 ft
GPX on file
67
Track points
83,977
Tools
8 / 1,027 LOC
Elev. datum
USGS EPQS
Profile Mt of the Holy Cross, 5-day loopLength 45.39 miGain 11,398 ftRange 8,470–14,015 ftSource gpx_measure.py
01
The problem
Planning a big off-trail day above 12,000 ft is two jobs. One is judgment: reading scattered beta and deciding where the line goes. The other is bookkeeping: producing numbers you can trust and files you can navigate by when there is no signal.
Nothing about a route like the Parnassus tundra loop exists in one place. The line comes out of a guidebook chapter, one blogger's GPS track, a trip-report thread from 2023 arguing about a gully, OpenStreetMap way geometry that may or may not be tagged correctly, and a premium AllTrails export. Those sources disagree, and they disagree in ways that matter.
They disagree about elevation. On the Jones Pass loop, the guidebook put Mount Machebeuf near 12,805 ft and the OpenStreetMap tag said something else. That is not a debate you settle by reading more prose. You settle it by taking the maximum elevation of a track that crossed the summit.
They disagree about gain, and often the disagreement is an artifact of measurement rather than terrain. Elevation gain is not a property of a route. It is a property of a route and a smoothing threshold. Measured twice from one walked track, same file, the answer moves 579 ft. A number quoted without its threshold is not a number, and comparing a raw measurement against a published, smoothed one produces a plan that is wrong by an entire subpeak.
And the output of planning is not a paragraph. It is files. A course cut in the direction I will actually walk, so the watch's climb screen shows the climb ahead of me instead of behind me. A waypoints layer with the summits named. A self-contained map card that opens with no internet.
Get the file format wrong and the day fails at the trailhead. The watch truncates imports past roughly 2,000 points. An export with two track elements concatenated end to end invents an elevation cliff at the seam. These are not interesting problems, but they are the ones that decide whether the plan survives contact with the mountain, so they belong in code that runs every time rather than in a checklist someone remembers.
One file, two thresholds · gpx_measure.py
Threshold
Dist
Gain
Delta
30 ft, default. Approximates AllTrails smoothing
11.55 mi
4,392 ft
base
10 ft, raw. Counts GPS noise
11.55 mi
4,971 ft
+13.2%
Jones Pass tundra loop, walked 2 Aug 2026. Identical geometry, identical distance, 579 ft of disagreement about how hard the day was.
02
Architecture
The whole design is one boundary. The model is allowed to decide where the route goes. It is not allowed to decide how long it is. Judgment crosses that line as a structured spec; facts come back as computed output.
Left of the lineModel judgment
Read and reconcile the beta: guidebook, trip reports, GPS tracks, road-condition evidence.
Decide the line. Which ridge, which direction, where to leave the trail, which descent is not a gully that has already been vetoed.
Name the waypoints and place them on coordinates that come from data, not from memory.
Choose which variants are worth building so they can be compared.
Emit a route spec: an ordered list of legs plus named waypoints. Legs are typed, not drawn.
the boundary
Right of the lineDeterministic code
Resolve way legs against real OpenStreetMap geometry by way id, oriented to run away from where you already are.
Resolve crest legs by sampling USGS point elevations at lateral offsets perpendicular to the line and keeping the high side, so the track follows the spine.
Sample every point's elevation from the USGS elevation query service. The model never types an elevation.
Measure: summed haversine for distance, threshold-filtered accumulation for gain, one shared implementation.
Render the topo map, the elevation profile, the interactive map, and the offline card. Write the GPX and cut the watch courses.
→ route spec (JSON): legs, waypoints, labels
geometry, measured miles and feet, artifacts ←
Why the split is drawn here
A language model is good at the part of this that is genuinely hard: knowing that one blogger's GPS numbers are trustworthy and a forum estimate is not, noticing that a proposed descent is the same gully three separate sources call loose, holding a guidebook chapter and an OSM tag next to each other and recognising they contradict.
It is bad at arithmetic over 300 coordinate pairs, and worse, it is confidently bad. So the spec it emits contains no distances and no elevations. It contains way ids, coordinate pairs, leg types, and labels. Every quantity on the finished plan is produced by code that can be re-run.
The practical test: delete every rendered artifact for a trip, re-run the build from the spec, and the numbers come back identical. When I did that for the Jones loop while assembling this page, the freshly built line measured 10.63 mi and 4,214 ft, matching the committed GPX to the digit.
Measurement has exactly one implementation
Distance is summed haversine. Gain is accumulated with a 30 ft threshold, and critically, a descent must also clear the threshold before it resets the reference elevation. Skip that and noise ratchets the baseline downward and inflates the total. That rule is implemented the same way in the measurement tool, the course cutter, and the visualiser, so a number never changes depending on which tool happened to print it.
Correctness guardrails
AVerified beta before buildingOff-trail lines require a real source first: a book page, a trip report, a GPS track. Terrain data can check a line. It cannot invent one.
BDescents follow terrain, not interpolationDown-legs are crest legs that follow spines and drainages. A straight interpolation across a face reads as an unnatural line on a topo and gets caught immediately.
CEvery number carries its tierWalked GPX beats an AllTrails export beats a marked route beats OSM geometry beats a built estimate. The tier is stated, and tiers are never mixed inside one total.
DKnown bias is stated, not hiddenBuilt lines under-read distance because they cut switchbacks. The expectation is 10 to 25 percent. Measured against the walked track, the Jones line came in 8 percent short.
ESimplify without losing the measurementCourse simplification is Douglas-Peucker, not every-Nth decimation, so switchbacks survive and the distance survives with them. Because Douglas-Peucker only measures horizontal deviation, it is skipped entirely on sparse ridge lines where it would happily delete points carrying real elevation change.
FPresent tradeoffs, do not decideVariants are built and measured side by side with honest numbers. The system does not pick; it makes the comparison legible.
03
One route through the pipeline
The Parnassus, Woods and Machebeuf tundra loop out of Herman Gulch, from route spec to files on the watch. This is a walkthrough of a real pipeline run captured on 11 Aug 2026, not a live capture. Every terminal block below is verbatim output from running the tools on real trip data. Nothing on this page executes in your browser.
01
The route spec
spec.json
The agent's entire output for this trip. Eight ordered legs and five named waypoints. Two leg types appear here: way follows a real OpenStreetMap trail by id, and crest follows a ridge between two coordinates. Note what is absent: no distances, no elevations, no gain.
trips/jones-tundra-loop/spec.jsonexcerpt
{"name": "Parnassus - Woods - Machebeuf tundra loop (book favorite)",
"osm": "osm_three.json", "start": [39.7024, -105.8543],
"legs": [
{ "type": "way", "id": 816685530,
"label": "Watrous Gulch trail (lower)" },
{ "type": "way", "id": 816685529,
"label": "Watrous Gulch trail (upper)" },
{ "type": "crest", "to": [39.71999, -105.82251], "steps": 22,
"label": "West slopes to Mount Parnassus 13,579" },
{ "type": "crest", "to": [39.73045, -105.83984], "steps": 20,
"label": "Parnassus to Woods Mountain 12,940" },
/* ... Woods to Machebeuf, then the west spine down ... */
{ "type": "way", "id": 59861793,
"clip": [[39.72465, -105.87732], [39.7228, -105.8879]],
"label": "Jones Pass Trail south to the Herman Gulch junction" },
{ "type": "way", "id": 59861792,
"label": "Herman Gulch Trail back to the car" }
],
"wpts": [["Herman Gulch TH", [39.7024, -105.8543], "Trail Head"],
["Mount Parnassus 13,579", [39.71999, -105.82251], "Summit"],
["Mount Machebeuf 12,251", [39.72119, -105.85696], "Summit"]]
}
The clip on that second-to-last leg is the interesting bit of judgment: the Jones Pass Trail is one long OSM way, and only the stretch between two coordinates belongs to this route. The agent decides which stretch. The code finds the nearest vertices and slices it.
02
Resolve the legs, sample the terrain
build_traverse.py
Trail legs are pulled from cached Overpass geometry by way id. Crest legs are walked in 20 or so steps; at each step the tool samples five candidate points across a 480 m span perpendicular to the direction of travel and keeps the highest, which is what makes the line follow the spine instead of cutting across the bowl. Every retained point then gets a real USGS elevation.
captured 11 Aug 2026verbatim
python3 tools/build_traverse.py jones/spec.json
sampling USGS elevations...
leg mi gain ft
Watrous Gulch trail (lower) 1.21 814
Watrous Gulch trail (upper) 0.92 782
West slopes to Mount Parnassus 13,579 1.25 1,590
Parnassus to Woods Mountain 12,940 1.32 455
Woods to Mount Machebeuf 12,251 1.27 451
Down the west spine from Machebeuf to the Jones Pass Trail 1.32 56
Jones Pass Trail south to the Herman Gulch junction 0.60 32
Herman Gulch Trail back to the car 2.75 0
TOTAL 10.63 4,179
ROUTE TOTAL 10.63 mi / 4,193 ft low 10,299 high 13,559 ft
saved jones_tundra_loop.gpx (316 pts)
The leg subtotals add to 4,179 ft but the whole-route figure is 4,193 ft. That is not a bug and it is not rounding. Gain accumulated per leg resets the threshold reference at every leg boundary; accumulated across the joined line it does not. The tool prints both rather than silently picking one.
03
Measure the built line
gpx_measure.py
The measurement tool is deliberately dependency-free stdlib, because it is the thing everything else is checked against. It re-reads the written GPX from disk rather than trusting what the builder reported.
captured 11 Aug 2026verbatim
python3 tools/gpx_measure.py jones/jones_tundra_loop.gpx
File: jones/jones_tundra_loop.gpx (316 points)
TOTAL distance: 10.63 miTOTAL elev gain: 4,214 ft (threshold 30 ft)
Elev range: 10,300 - 13,559 ft
WAYPOINTS (5) — use these, don't invent camps:
- Herman Gulch TH (39.702400, -105.854300)
- Mount Parnassus 13,579 (39.719990, -105.822510)
- Woods Mountain 12,940 (39.730450, -105.839840)
- Mount Machebeuf 12,251 (39.721190, -105.856960)
- Meet Jones Pass Trail 11,960 (39.724650, -105.877320)
4,214 ft here against 4,193 ft from the builder: the written GPX is the simplified line, and re-measuring it is the number that ships. The tool re-prints the waypoints because a downstream step will cut courses at them, and inventing a camp or a junction that is not in the file is a failure mode worth designing against.
04
Check it against ground truth
gpx_measure.py
This loop has since been walked, which makes it the one case where the built line can be graded. The walked track is the top tier of the provenance hierarchy: a real GPS recording of a person actually on the ground.
captured 11 Aug 2026verbatim
python3 tools/gpx_measure.py raw/colorado/Jones_Tundra_Loop_walked_20260802.gpx
File: Jones_Tundra_Loop_walked_20260802.gpx (7266 points)
TOTAL distance: 11.55 miTOTAL elev gain: 4,392 ft (threshold 30 ft)
Elev range: 10,300 - 13,636 ft
python3 tools/gpx_measure.py raw/colorado/Jones_Tundra_Loop_walked_20260802.gpx --gain-threshold 10
File: Jones_Tundra_Loop_walked_20260802.gpx (7266 points)
TOTAL distance: 11.55 mi
TOTAL elev gain: 4,971 ft (threshold 10 ft)
Elev range: 10,300 - 13,636 ft
Built line graded against the walked track
Source
Points
Distance
Gain (30 ft)
High
Built from spec, OSM + USGS ●
316
10.63 mi
4,214 ft
13,559 ft
Walked GPS track ●
7,266
11.55 mi
4,392 ft
13,636 ft
Built line error
−8.0%
−4.1%
−77 ft
Both errors point the same direction and both are explainable. The built line is short because a 316-point line cuts switchbacks that a 7,266-point recording captures. It reads low on the summit because the built line touches the coordinate given for Parnassus while the recorded track wandered over the actual high point. That is exactly the 10 to 25 percent under-read the system is documented to expect, landing at the optimistic end because most of this loop is on trail.
Plate 01gpx_topo_png.py · USGS The National MapThe 8 percent, drawn. Red is the built line, blue is the track that was actually walked, on the same sheet. The gap is legible: red takes corners the recorded track curves around, and it holds a straighter line down the Herman Gulch trail. Rendering the error is how you find out whether it is switchback loss or a genuinely wrong route.
05
Draw the profile
leg_profile.py
The builder writes a legs JSON alongside the GPX, so the profile can be coloured per leg with each leg's own measured distance and gain in the legend. The summits are placed by proximity to the track rather than by index, so they land on the line.
Plate 02leg_profile.pyWhere the work is. Half the day's gain arrives in the 1.25 mi off-trail push to Parnassus. Everything after Machebeuf is a 4.7 mi walk-off with 88 ft of gain in it. That shape is the argument for walking this loop in this direction.
06
Render it on real topo
gpx_topo_png.py
Zoom level is chosen so the image lands near the requested pixel budget, then the tiles are stitched, cropped to padded bounds, and the route, waypoints, legend and an imperial scale bar are drawn on top. The basemap is the USGS topo series, so the contour labels are already in feet and nothing needs converting.
Plate 03gpx_topo_png.py · 80 tiles at zoom 15The correctness check that needs no code. A built line that crosses contours at an implausible angle, or runs a descent straight down a face, is obvious on this sheet in about two seconds. This render exists so a person can veto the geometry before anything reaches a watch.
07
Cut the files I carry
gpx_course.py · gpx_garmin.py
Two different destinations with two different formats. Courses go to the watch and are what unlock the climb and distance-remaining screens, so they get cut at named waypoints, in travel order, simplified with Douglas-Peucker under the import point cap. The waypoints layer is a separate file with symbol icons assigned from the names.
captured 11 Aug 2026verbatim
python3 tools/gpx_course.py jones/jones_tundra_loop.gpx \
--split "Mount Parnassus,Mount Machebeuf" \
--names "Leg 1 Herman Gulch to Parnassus,Leg 2 Parnassus to Machebeuf,Leg 3 Machebeuf to the car" \
--tol 0 --outdir jones/courses
course mi gain ft pts (raw mi)
Leg 1 Herman Gulch to Parnassus 3.38 3200 159 (3.38)
Leg 2 Parnassus to Machebeuf 2.59 906 40 (2.59)
Leg 3 Machebeuf to the car 4.67 88 114 (4.67)
python3 tools/gpx_garmin.py jones/jones_tundra_loop.gpx --out jones/Jones_Garmin.gpxsaved jones/Jones_Garmin.gpx (5 waypoints, 1 tracks)
The simplified and raw distances match to the hundredth on all three legs, which is the point of that last column. It is a regression check printed on every run: if simplification ever starts eating switchbacks, the two numbers separate and you see it immediately rather than discovering it on the mountain.
Three legs, 10.64 mi, and the gain lands where the profile said it would. The remaining artifacts for a trip come off the same GPX: an interactive topo map, and a self-contained HTML card with the map and stats embedded so it opens with no signal.
04
Plates
Output from other trips in the same repository. Every image here was written by one of the eight tools; none were touched by hand afterwards.
Plate 04gpx_topo_png.py · trips/bard-silver-plumeBard Peak from the 7:30 Mine trail, Silver Plume. 12.11 mi and 5,239 ft as measured, climbing 4,450 ft from the town to the summit. The full variant carries on over Robeson and Engelmann for 15.93 mi and 7,535 ft.
Plate 05gpx_topo_png.py · trips/parnassus-4packWatrous Gulch four-pack. 13.58 mi, 6,703 ft, four summits over 13,000 ft. The numbered markers are the order of travel, which matters when the descent is a different drainage from the approach.
Plate 06gpx_visualize.py · trips/bard-creek-tripleLaw Firm traverse, reversed. 15.18 mi and 5,881 ft, up Silver Plume and out over Bard, Robeson and Engelmann to a 7-mile walk-off with no regain. The two-panel output pairs the plan view with the profile so a direction decision can be made from one image.
Plate 07gpx_visualize.py · trips/holy-crossMount of the Holy Cross, five days. 45.39 mi and 11,398 ft split into five day courses, cut at the camps that exist in the waypoints file. Day 2 carries the summit and 4,246 ft of it, with the pack left at a junction.
Plate 08leg_profile.py · trips/parnassus-4packProvenance printed on the artifact. Read the subtitle: ridge from a GPS track, trail from OSM, connectors sampled from USGS. Three source tiers in one route, labelled on the image itself, so the plan cannot be separated from where its numbers came from.
Plate 09gpx_visualize.py · trips/mosquito-ridgeMosquito Range, six summits. 11.89 mi and 5,617 ft that never drops below 12,046 ft. The sawtooth is the whole planning problem in one picture: the mileage is modest and the re-ascent is not.
05
Scale
Counts taken from the repository while this page was written, not from memory.
11routes planned
163.4route miles
60,992feet of gain
67GPX files
83,977track points
8tools, 1,027 LOC
18rendered maps & profiles
7offline map cards
The 67 GPX files split into 29 raw source exports filed by region and untouched, 37 built or cut route files across the 11 trips, and one fixture. Every distance and gain figure in the table below was produced by running gpx_measure.py over the trip's primary route file while assembling this page.
Measured route inventory · threshold 30 ft · gpx_measure.py
Trip
Distance
Gain
Low
High
Tier
Holy Cross, 5-day loop
45.39 mi
11,398 ft
8,470
14,015
built
James quiet-side ridge loop
17.22 mi
3,367 ft
9,211
12,151
built
Bard, Robeson, Engelmann from Silver Plume
15.93 mi
7,535 ft
9,171
13,650
built
Law Firm traverse, reversed
15.18 mi
5,881 ft
8,990
13,623
built
Watrous Gulch four-pack
13.58 mi
6,703 ft
10,300
13,637
built
Guyot and Bald from Georgia Pass
11.97 mi
6,738 ft
11,118
13,688
built
Mosquito Range, six summits
11.89 mi
5,617 ft
12,046
14,041
built
Huron Peak via Lulu Gulch
11.24 mi
4,244 ft
10,351
14,012
gpx
Jones Pass tundra loop
10.63 mi
4,214 ft
10,300
13,559
built
Bancroft, Parry and Eva from Loch Lomond
6.63 mi
4,291 ft
11,190
13,356
built
Hassell Lake carry and paddle
3.73 mi
1,004 ft
10,612
11,391
built
11 routes
163.39 mi
60,992 ft
8,470
14,041
What I would build next
The system has one honest weakness and it is the crest builder. It samples five lateral offsets per step and takes the high one, which reliably finds the spine but cannot see a cliff band. That is why the human topo check in step 06 is load-bearing rather than decorative, and why verified beta is required before anything gets built.
The fix is not a better prompt. It is more data on the right side of the boundary: a slope-angle raster sampled along each candidate offset so the builder can reject a step that requires descending 45 degrees, and a wider lateral fan on descent legs where the consequence of picking the wrong rib is largest.
The second gap is that only one of these eleven routes has been walked, so there is exactly one data point grading the built lines. Every trip that gets walked adds a row to that comparison, and the under-read figure stops being a documented expectation and becomes a measured correction factor with a distribution behind it.
Both of those are the same shape of change: move a judgment call across the boundary into code, and only once there is data to make it deterministic.