Skip to content

PRD-012 — Spaceflight Fleet ​

Orrery · Product Requirements · v0.1 · May 2026

Status: Accepted (v0.6 ship — /fleet; RFC-016 closed via ADR-052 / ADR-053 / ADR-054) Sources: PRD-009 (Mission Catalog) for the card-grid template; PRD-010 / PRD-011 (ISS / Tiangong Explorers) for detail-panel + provenance reuse; existing rockets.json + missions.json + iss-* / tiangong-* datasets as primary data sources to cross-reference. Audiences: curious learner, STEM student, space enthusiast (PA §audiences) Promises: real mission data fully attributed, educational at every level (PA §promises) Principles: physics first, attribution is design (PA §principles) Why this is a PRD: Orrery already tells the story of what was done (Mission Catalog) and what was built in a few specific places (ISS / Tiangong Explorers). It does not yet tell the story of the machines themselves — the rockets that put crews in orbit, the rovers driving on Mars, the observatories mapping the universe, the retired stations whose legacy enabled today's flights. A Saturn V card next to a Falcon 9 card next to a Space Shuttle card — a direct ladder from Vostok 1 to Crew Dragon, from Lunokhod-1 to Perseverance — gives users a hardware-first path through 70 years of spaceflight that complements the mission-first path. Every entry has a builder, a maiden flight, and a list of the missions it enabled.

A student arrives at /fleet. The grid loads: ~110 cards across categories — launchers, crewed spacecraft, cargo spacecraft, stations, rovers, landers, orbiters, observatories. They filter to crewed spacecraft and see Vostok, Voskhod, Mercury, Gemini, Apollo CSM, Soyuz 7K-OK, Soyuz T, Soyuz TM, Soyuz TMA, Soyuz MS, Buran, Space Shuttle Orbiter, Shenzhou, Crew Dragon, Starliner, New Shepard, Orion, Gaganyaan — a single row that compresses six decades of human spaceflight engineering, with each Soyuz generation distinguishable. They filter to STATUS=FAILED and see Mars 2, Schiaparelli, Beresheet, Hakuto-R, Vikram CY-2, N1, Hitomi — the redemption-arc layer of the story, paired with their successors. They click Vostok 1. The panel opens: the spacecraft schematic (ANATOMY tab reusing the spacecraft-anatomy work), notable-flight patches, Yuri Gagarin's portrait, a link to Vostok 1's full mission entry under /missions, and three tiers of links (intro / core / deep). They click Saturn V next. Same panel shape: anatomy, specs, the 13 Apollo mission cards it launched, builder + agency + retirement. The hardware lineage becomes legible.


§why ​

The Mission Catalog answers "what missions have been flown?" The ISS / Tiangong Explorers answer "how is this station put together?" Neither answers the broader question: "what hardware exists, and how is it related to what came before it?"

A Vostok-to-Crew-Dragon thread is a story Orrery can tell uniquely well, because:

  • We already have the primitives. rockets.json (13 launchers), missions.json (37 missions, each with a launch_vehicle field), iss-modules + iss-visitors + tiangong-* (~30 station components), earth-objects (orbital satellites including observatories), moon-sites (lunar rovers + landers). A new aggregate fleet.json becomes the connective tissue: one canonical entry per piece of hardware, with cross-references to the existing data.
  • The detail panel already exists. ANATOMY tab from the visiting-spacecraft schematics work in May 2026 generalises directly: rockets, rovers, observatories all want a labelled-subsystem schematic.
  • The card grid pattern is solved. /missions (PRD-009) is the proven template — filter chips, lazy-loaded cards, deep-link ?id=.... Reuse the structure.

The shape of the page promises: every machine that ever flew has a story, and Orrery shows you which other Orrery pages know more about it.

Why now ​

The visiting-spacecraft anatomy diagrams shipped in May 2026 (Crew Dragon, Soyuz, Cygnus, Starliner, HTV-X, Progress, Cargo Dragon, Shenzhou, Tianzhou) created the visual + interaction template. A fleet page is the logical next step — taking that schematic treatment from "9 station visitors" to "every crewed spacecraft + every launcher + every rover + every observatory ever flown."


§audiences ​

Same primary audiences as PRD-009 / PRD-010 / PRD-011:

  • Curious learner — wants to see Saturn V and Falcon 9 side by side, click into either, and follow the lineage. Scrollable filterable grid is the right primitive.
  • STEM student — wants the specs (height, mass, thrust, payload-to-LEO, manufacturer, first/last flight). Detail panel's OVERVIEW tab grid covers this.
  • Space enthusiast — wants the cross-references. Every Saturn V card reveals "missions launched: Apollo 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, Skylab" with each item linking to the mission detail. Every Crew Dragon card reveals "first flight: Demo-2, then Crew-1, Crew-2..." Closes the loop with the Mission Catalog.

§promises ​

  • Every entry attributed. Builder + agency + country + first flight (and retirement, if applicable). Imagery sourced via the existing pipeline (ADR-046 / ADR-047) with three priority tiers:
    1. airandspacehistory.com — Marko's own museum-photography collection from Russia, USA, UK, France, Germany, Netherlands museums (Smithsonian / Cosmonautics Museum / Science Museum London / Le Bourget / Speyer / Aviodrome / etc). Photos are first-party originals of actual hardware, often with composition unavailable elsewhere. Each photo's gallery row carries credit: "© airandspacehistory.com" + a deep link back to the photo's page on airandspacehistory.com. Acts as both unique value-add (museum-grade hardware photography, not stock press kits) and natural cross-promotion.
    2. Agency-first (per ADR-046) — NASA Image Library / ESA Photo Library / JAXA Library / Roscosmos / CMSA archives.
    3. Wikimedia Commons fallback — for entries without first-party or agency coverage.
  • Every entry cross-linked. When a piece of hardware is referenced elsewhere in the app — a launcher referenced in a mission's launch_vehicle, an ISS module attached to a station — the Fleet card surfaces those references. Bidirectional: the linked mission's panel can hint "see also: Saturn V" in a future iteration.
  • Mission badges and crew portraits where applicable. Crewed-spacecraft entries include the mission patches of every flight (Apollo 11 patch, STS-1, Demo-2, etc.) and crew portraits sourced from agency archives. Adds a human dimension to the hardware story. (Per Marko's V1 decision: in scope, not deferred.)

§principles ​

  • Physics first. Spec grid in OVERVIEW is the truth: real heights, masses, thrusts, payloads. Round numbers only when official specs themselves are rounded.
  • Attribution is design. Builder line + country + agency badge is the first thing the user sees on every card, not a footer afterthought.
  • Mobile-first. Same /missions mobile-first card grid translates directly. Detail panel uses the existing mobile bottom-sheet / desktop right-drawer pattern.

§scope ​

V1 — per-generation curated set (~110 entries) ​

Per Marko's locked decisions:

  • One entry per generation/variant (not per family) — Soyuz 7K-OK / T / TM / TMA / MS each get their own entry; Long March 2F / 5 / 5B / 7 each separate.
  • ~110 entries, expanded from initial ~50 estimate to honour the per-generation rule and "every machine, every outcome" framing.
  • Failure / partial-success entries included — N1, Buran, Schiaparelli, Beresheet, Hakuto-R, Vikram CY-2, Mars 2, Hitomi, etc. Failure drives the next generation; the page reads as the full story, not just the wins.

Categories and target counts ​

CategoryV1 countExamples
launcher~22Atlas LV-3B, Titan II, R-7/Vostok, Saturn IB, Saturn V, N1, Soyuz-U, Space Shuttle stack, Proton-M, Ariane 5, Soyuz-FG, Atlas V, Long March 2F, H-IIA, Falcon 9 Block 5, Energia, Long March 5/5B, Falcon Heavy, LVM3, SLS Block 1, Long March 7, H3, Ariane 6
crewed-spacecraft~18Vostok, Voskhod, Mercury, Gemini, Soyuz 7K-OK, Apollo CSM Block II, Apollo LM, Soyuz T, Space Shuttle Orbiter, Buran, Soyuz TM, Soyuz TMA, Shenzhou, Soyuz MS, Crew Dragon, Starliner, New Shepard, Orion, Gaganyaan (planned)
cargo-spacecraft~11Progress 7K-TG, Progress M, Cargo Dragon v1, HTV, Cygnus Standard, ATV, Progress MS, Cygnus Enhanced, Cargo Dragon 2, HTV-X, Tianzhou
station~9Salyut 1, Skylab, Salyut 6, Salyut 7, Mir, ISS, Tiangong-1, Tiangong-2, Tiangong
rover~12Lunokhod-1, LRV (Apollo), Lunokhod-2, Sojourner, Spirit, Opportunity, Curiosity, Yutu, Perseverance, Yutu-2, Zhurong, Pragyan
lander~19Luna 9, Surveyor 3, Venera 7-class, Mars 2, Mars 3, Viking 1, Luna 16-class sample return, Mars Polar Lander, Phoenix, Chang'e-3, Chang'e-4, Schiaparelli, InSight, Beresheet, Chang'e-5, Vikram CY-2, Hakuto-R program, SLIM, Vikram CY-3, IM-1 Odysseus
orbiter~14Mariner 4, Mariner 9, Pioneer 10, Voyager 1, Voyager 2, Galileo, Magellan, Phobos 2, Cassini, Mars Express, MRO, Rosetta, Hayabusa2, Juno, Mangalyaan, Chang'e-2, DART, OSIRIS-REx
observatory~11Hubble, Compton GRO, XMM-Newton, Chandra, Spitzer, Kepler, Gaia, Hitomi, TESS, Spektr-RG, JWST, Euclid

(Bold = added in the per-generation + failure-inclusion expansion vs. the original ~50.)

Country distribution ​

Country / agencyCount
USA (NASA + commercial)~47
USSR / Russia~27
China (CNSA / CMSA)~12
ESA (multi-country European)~10
Japan (JAXA + ispace)~7
India (ISRO)~6
Israel1
International (ISS)1

(Sum > category total because Hubble + JWST + BepiColombo are jointly attributed US+ESA.)

= ~110 entries. Dataset is curated, not exhaustive — the long tail stays out. V2 expansion is intentional.

Out of scope (V1) ​

  • The full long tail of every variant (each Mariner numbered separately, every Surveyor 1–7 split, every Long March sub-variant). Per-generation rule already adds significant breadth; below-the-line entries defer to V2.
  • Orrery-side mission badge / crew photo gallery for non-crewed missions (no badges on rovers).
  • Working-satellite long tail — GPS, GLONASS, Starlink, communication satellites stay in earth-objects.json only; they don't get fleet entries unless they're observatories or otherwise iconic (Hubble / JWST / Chandra do, since they have hardware-story value beyond "is in LEO").
  • Pure vaporware (no public spec sheets, no announced launch window). PLANNED status entries like Gaganyaan and SLS Block 2 require a published agency reference + named launch window.
  • Full SVG coverage for V1 — V1 ships ~30–40 SVGs (the marquee tier per Phase F.2). V1.5 fills the next 30; V2 reaches full ~110 coverage. ANATOMY tab no-ops gracefully on entries without an SVG yet.

§what-it-must-do ​

Page surface ​

  • Top-level nav slot: EXPLORE → MISSIONS → PLAN → FLY → EARTH → MOON → MARS → ISS → TIANGONG → FLEET → SCIENCE. Inserted between TIANGONG and SCIENCE so the inventory-style screens (ISS / Tiangong / Fleet) cluster together with SCIENCE as the educational tail.
  • /fleet route loads a card grid (mirror of /missions).
  • Filter chips: CATEGORY (the 8 above), AGENCY (NASA / Roscosmos / ESA / JAXA / CNSA / ISRO / SpaceX / Northrop Grumman / Boeing / Blue Origin / ispace / multi), EPOCH (named historic epochs — see §epochs below; replaces the date-range ERA chip with story-shaped buckets), STATUS (FLOWN / ACTIVE / RETIRED / FAILED / PLANNED).
  • Epoch timeline strip above the card grid: a horizontal scrub bar from 1957 → present + planned, labelled with the 8 named epochs. Click an epoch band to filter; hover/tap reveals the entry count for that epoch. Today indicator (vertical line) marks "now". Mobile collapses to a compact horizontal swipe carousel.
  • Sort options: chronological descending (default — newest first by first flight, surfaces current/active hardware at the top), chronological ascending (oldest first), alphabetical, by category.
  • Deep-link ?id=saturn-v opens the detail panel pre-selected.
  • ?view=list low-fidelity fallback like /iss and /tiangong.

Card design ​

Mirrors /missions cards but tuned for hardware:

  • Hero photo (full-bleed top, 16:9 or 4:3)
  • Name (display font, large)
  • Category chip + agency badge
  • Era chip (1960s, 1970s, etc.)
  • First flight year + status
  • One-line "first of" / "best known for" tagline (e.g., "First crewed orbital flight" for Vostok)
  • Click → opens detail panel

§epochs — named historic spans for filtering + timeline UX ​

Replaces the original 5-bucket date-range ERA chip with 8 named epochs that map to actual milestones rather than arbitrary decade-ish chunks. Each epoch is both a chip filter and a band on the timeline strip. Ranges intentionally overlap where two strands ran concurrently (Shuttle program straddles First-Stations and ISS-Assembly epochs).

EpochYearsTheme~Entries
First Steps1957–1961Sputnik, first satellites, R-7, first crewed orbital~6
Space Race1961–1969Mercury, Vostok, Voskhod, Gemini, Apollo prep, lunar build-up, Mariner 4~12
Lunar Era1969–1972Apollo lunar landings, Lunokhod, Soviet N1 failures, LRV~8
First Stations1973–1986Skylab, Salyut 1–7, Apollo-Soyuz, Voyager grand tour, Vikings~16
Shuttle & Mir1981–1998Shuttle program, Mir, Buran/Energia, Galileo, Magellan, Hubble~22
ISS Assembly1998–2011ISS construction, Shuttle retirement, Mars Spirit/Opportunity, Cassini~14
Commercial Era2011–presentCrew Dragon, Falcon, Tiangong, JWST, Perseverance, Hayabusa2, commercial lunar~30
Lunar Return2024+Artemis, Starship, Gaganyaan, IM-class, planned lunar missions~6

EPOCH chip values are these 8 names. Timeline strip UI renders horizontal bands keyed to these names, with the entry count visible per band on hover/tap. The strip has a fixed-width axis (1957 → 2030+) and clicking a band selects + filters that epoch's hardware. Today-indicator shows where we are relative to the spans.

Cross-route linking — fleet ↔ everything ​

Locked decision: the fleet page becomes the canonical hardware reference for the rest of the app. Mission entries, surface-map markers, and orbital-object panels all link into fleet entries; fleet entries link back to the contexts they appear in.

Schema additions ​

FileNew fieldPurposeExample
static/data/missions/{dest}/{id}.jsonfleet_refs: [{ id, role }]Map mission → its launcher + spacecraft + payload fleet entries[{id: "saturn-v", role: "launcher"}, {id: "apollo-csm-block-ii", role: "spacecraft"}, {id: "apollo-lm", role: "spacecraft"}]
static/data/moon-sites.jsonfleet_refs: [...]Lunar landing site → hardware that landed thereApollo 11 site → [{id: "apollo-csm-block-ii"}, {id: "apollo-lm"}, {id: "lrv-apollo"}] (LRV only on later Apollos)
static/data/mars-sites.jsonfleet_refs: [...]Mars landing site → rover/landerMSL site → [{id: "curiosity"}]
static/data/earth-objects.jsonfleet_refs: [...]LEO satellite/observatory → fleet entryHubble → [{id: "hubble"}]
static/data/fleet/{cat}/{id}.jsonlinked_sites: [...]Reverse pointer to surface markers / orbitsCuriosity → [{type: "mars", site_id: "msl"}]

Detail panel rendering ​

  • /missions panel (existing) gains a "Hardware" row in OVERVIEW that lists fleet_refs as clickable chips: [Saturn V →] [Apollo CSM Block II →] [Apollo LM →].
  • /moon and /mars site panels gain a "Hardware" section listing fleet_refs chips.
  • /earth object panel gains "See in Fleet: [Hubble →]" CTA.
  • /fleet entry panel OVERVIEW tab renders linked_sites reverse pointers: e.g., Curiosity entry shows "Operating site: [Gale Crater on /mars →]".
  • MISSIONS tab on fleet panel already covered: cross-links to /missions are already locked.

Build-time validation ​

scripts/validate-data.ts extended to assert symmetric integrity:

  1. Every fleet_refs[*].id resolves to a real entry in fleet/index.json.
  2. Every fleet entry's linked_sites[*] resolves to a real moon-site / mars-site / earth-object.
  3. Bidirectional check: if a mission has fleet_refs: [{id: "saturn-v", role: "launcher"}], then Saturn V's linked_missions array MUST include that mission (catches drift).
  4. Build fails closed if any fleet_id reference dangles.

This makes fleet the single source of truth for hardware metadata, and every other route becomes a per-context view that pivots to fleet for the canonical record. Reads as one cohesive product rather than parallel datasets that happen to mention the same machines.

Detail panel tabs ​

Built as new component FleetEntryPanel.svelte (copied from StationModulePanel.svelte per RFC-016 OQ-4 lock — keeps station-specific concerns out, generalises to a unified EntityDetailPanel.svelte in v0.7+):

  1. OVERVIEW — specs grid (height / mass / thrust / payload / first flight / last flight / manufacturer / status), editorial paragraph, "best known for" highlight. For station entries with explorer routes (ISS, Tiangong), prominent "Open ISS Explorer →" CTA at the top of the OVERVIEW tab deep-links to /iss or /tiangong.
  2. GALLERY — same per-entry gallery infrastructure as /missions and /iss. Targets ≥4 photos per entry.
  3. ANATOMY — labelled-subsystem schematic in the canonical /science chapter style (white-on-dark, monospace labels, viewBox 400×320, teal accent leader lines). Hand-authored per fleet entry — every one of the ~110 entries gets its own SVG, contributed as original artwork in the same Orrery house style as the 9 station-visitor anatomy diagrams shipped May 2026. Existing 9 (Crew Dragon / Soyuz MS / Cygnus / Starliner / HTV-X / Progress MS / Cargo Dragon / Shenzhou / Tianzhou) are reused as-is at /diagrams/spacecraft/{id}.svg. Authoring is tiered (see Phase F in §rfc-link / Issue #59) so V1 ships with high-priority coverage and the long tail completes through V1.5 / V2. Tab gracefully no-ops when an SVG hasn't yet been authored for an entry.
  4. CREW — (crewed-spacecraft only) 3-6 notable flights per entry, hand-curated (first flight, last flight, 1–4 historic ones). Each flight shows mission patch + crew portraits. Cross-link to the relevant /missions entry per flight. (Notable-flights curated rather than every-flight paginated, to bound editorial scope.)
  5. MISSIONS — list of cross-referenced mission entries from missions.json (linked_missions: [...] field, curated per fleet entry). Build-time validator cross-checks bidirectionally: every mission's new launch_vehicle_id field must appear in its launcher's linked_missions. Each mini-card clickable → /missions?id=....
  6. LEARN — link tiers (intro / core / deep) sourced via the existing link-provenance pipeline (ADR-051). For non-US entries, operator's native-language page first (Roscosmos Russian, CMSA Chinese, JAXA Japanese, ISRO).

Data shape (per entry) ​

json
{
  "id": "saturn-v",
  "name": "Saturn V",
  "category": "launcher",
  "agency": "NASA",
  "country": "United States",
  "manufacturer": "Boeing / North American / Douglas",
  "first_flight": "1967-11-09",
  "last_flight": "1973-05-14",
  "status": "RETIRED",
  "era": "1960s",
  "best_known_for": "Sent humans to the Moon",
  "specs": {
    "height_m": 110.6,
    "mass_kg": 2970000,
    "thrust_n": 35100000,
    "payload_to_leo_kg": 140000,
    "stages": 3
  },
  "linked_missions": ["apollo11", "apollo12", "apollo13", "apollo14", "apollo15", "apollo16", "apollo17"],
  "credit": "NASA Apollo Program imagery archive (PD-NASA)",
  "links": [
    { "l": "Wikipedia · Saturn V", "u": "...", "t": "intro" },
    { "l": "NASA · Saturn V Reference", "u": "...", "t": "core" },
    { "l": "Apollo by the Numbers (NTRS)", "u": "...", "t": "deep" }
  ]
}

Locale overlays at static/data/i18n/{locale}/fleet/{id}.json carry editorial copy:

json
{
  "name": "Saturn V",
  "tagline": "First of: human-rated heavy-lift launcher",
  "description": "The 36-storey rocket that put 24 humans on a translunar trajectory and 12 of them on the lunar surface...",
  "best_known_for": "Apollo lunar program · 13 successful launches · zero crew losses on ascent"
}

§what-it-must-not-do ​

  • Not a replacement for /missions. The Mission Catalog remains the primary "what was done" surface; Fleet is the "what was used" complement. Cards on Fleet link to mission detail, they do not duplicate the mission narrative.
  • Not a duplicate of /iss or /tiangong. Stations on the Fleet page link out to the dedicated explorer routes when relevant.
  • Not a parts catalogue. We do not list every variant ("Falcon 9 Block 5 Reusable Booster" vs. "Falcon 9 Block 5 Heavy"). One entry per recognisable hardware family.

§metrics ​

(Soft V1 acceptance signals; to track post-launch.)

  • ≥80% of visitors who open a Fleet card visit at least one cross-linked mission via the MISSIONS tab.
  • Filter usage: ≥40% of grid sessions apply at least one filter chip (suggests the filter axes match user mental models).
  • Category spread: at least 10 different cards opened per session on average (suggests the grid layout invites browsing, not just launcher-hunting).
  • ≤5 mission badges render unattributed (license-vetting failure mode).

See RFC-016 — Spaceflight Fleet · architecture, schema, and dataset boundaries for the technical resolution: schema design, cross-reference strategy, mission-badge / crew-portrait sourcing, anatomy SVG authoring tiers, and phasing.

ADRs spawned by RFC-016 (proposed):

  • ADR-052 — Fleet schema + bidirectional cross-reference contract: fleet/index.json + per-entry files; linked_missions / linked_sites curated explicitly; new fleet_refs field on missions / moon-sites / mars-sites / earth-objects; bidirectional drift validation at build.
  • ADR-053 — Mission badge + crew portrait sourcing via Wikimedia Commons + agency archives. Per-image provenance via existing pipeline (ADR-046 / ADR-047). Graceful no-op on missing imagery.
  • ADR-054 — Fleet i18n: en-US + es at V1 launch (~110 entries × 2 locales = 220 overlay files); remaining 12 locales via existing ADR-033 auto-translate pipeline in v0.6.x slice.

Implementation tracker: Issue #59 with 11 phases (A through K — added Phase K for cross-route bidirectional linking on /missions / /moon / /mars / /earth panels).


PRD-012 · /fleet · May 2026 · Update when scope or principles change

Orrery — architecture documentation · MIT · No tracking