Your captures, and where they live
Field captures — the photos, videos, audio notes and waypoints you record on a ride — have always had two homes: the phone that took them and the server they sync to. Since June, the Library has been smart enough to stream a capture from the server when its local copy is gone, so deleting data to free space no longer dead-ends a session. But you still couldn't say what you actually meant: "keep this, just not on my phone", or "I don't want to see this in my library any more — but don't destroy it".
Today the session view grows three storage actions that say exactly that.
Remove from device
A synced session's local copies can now be dropped in one tap. The session stays in your list, the track stays on the map, and every capture keeps playing — streamed from the server with the same viewers, just marked "Streaming from server". This is the space-freeing move: media is by far the heaviest thing the app stores. The action only appears once the session is fully synced, so it can never throw away the only copy of anything.
Download for offline
The inverse. A session that lives only on the server — because you removed it, or because it was recorded on another device — can be re-materialized locally: every capture row and every media file comes back to the phone, and the session works with no connection again. Sessions the server knew but the phone had completely forgotten are rebuilt from the registry, wired back up so future streaming and syncing keep working.
Delete from library
This one needed a new server verb, and the verb had to be soft. The session
registry only knew two things: list a session, or cascade-delete it together
with its GRASS layers. Neither is "remove this from my listing". So the
registry gained a hidden flag — a PATCH that hides a session from the
listing while leaving the layers, the attribute tables, and the media
untouched on the server. Deleting from the library hides the registry entry,
soft-deletes the Library cards (the catalogue has had a trash with restore for
months), and wipes the local copy. A permanent delete remains what it always
was: a separate, explicit act.
The subtle part is discovery. When the registry returns an empty list, the app
falls back to scanning the environment's raw track_* layers — a deliberate
escape hatch for sessions published before the registry existed. But a hidden
session's layers are still there, so the scan would cheerfully resurrect
everything you just deleted. The listing now reports how many sessions it
hid, and the fallback scan only runs when the registry is genuinely empty —
not when it's merely quiet on purpose.
One more lesson from the reroute
post applied here before the bug could
exist: a background re-publish overwrites a session's whole registry entry
with whatever the phone sends — and the phone never sends hidden. The
register route now preserves the flag across upserts, and a route-level test
pins it: sync more samples all you like, a deleted session stays deleted.
All of it lands with route-level server tests against the real HTTP boundary, and the mobile pieces ride the next phone build.
