RFC-004 — Mission URL sharing: serialisation, back-button behaviour
Status · Decided TA anchor · §components/router · §components/fly-screen · §components/missions-screen Closed by · ADR-024 (2026-04-29) Why this is an RFC · The fly and missions screens support URL-encoded state. What exactly is encoded, what happens on back navigation, and what's out of scope for v1 are open questions with real trade-offs.
The question
Two screens support URL params:
/fly?mission=curiosity— loads a specific mission arc/missions?dest=MARS— opens library with filter applied
Open questions: what state is encoded, how does back-button work, what stays out of scope for v1?
Use cases
- "FLY THIS MISSION" in mission library navigates to
/fly?mission=curiosity - Shared link opens directly to a specific mission's arc
- User presses back from fly screen — returns to missions with filter intact
/missions?dest=MARS&status=ACTIVEopens with both filters applied
Goals
- Shared links work without session state
- Back button feels natural
- Params are human-readable in the URL
- Forward-compatible — adding params doesn't break old links
Constraints
From ADR-013: History API routing via SvelteKit. Params in the query string of the URL (/fly?mission=id). URLSearchParams handles parsing; $page.url.searchParams exposes them in Svelte components.
Proposed approach
Encoded state:
- Fly screen:
?mission=[id]— mission ID. Absent = default ORRERY-1 scenario. - Missions screen:
?dest=[MARS|MOON]and?status=[ACTIVE|FLOWN|PLANNED]. Combinable:?dest=MARS&status=ACTIVE. - Nothing else encoded in v1 (porkchop range, camera angle, simulation time all reset on navigation).
Back button: router.navigate() pushes to hash history. Back/forward works naturally within session.
Link generation: "FLY THIS MISSION" calls router.navigate('fly', { mission: id }) → /fly?mission=id.
Alternatives considered
Encode simulation time in fly URL (?mission=curiosity&met=180) — allows sharing a moment in the trajectory. Adds initialisation complexity (fast-forward to encoded time). Deferred to v2.
Encode porkchop range in plan URL — useful for sharing a launch window analysis. Deferred to v2.
No URL params — breaks the "share this mission" use case. Rejected.
Trade-offs
v1 encodes mission ID and library filters only. Camera, simulation time, and porkchop configuration are not shared. This is an explicit scope decision.
Open questions
- Should
?mission=invalid-idfall back to ORRERY-1 or show an error state? - Should filter combinations be bookmarkable beyond the two proposed params?
- Should
/fly?mission=curiosity&met=180be supported for deep-linking to a mission moment?
Closing evidence
/fly?mission=curiosity loads Curiosity's arc. /missions?dest=MARS opens Mars filter. Back button returns to previous filtered state. Available at Slice 4 gate.
How this closes
One ADR: URL encoding contract for mission and filter params.