PRD-020 · Launches Calendar — upcoming + historic global launches on /missions
Status · Accepted (v0.7 ship — closed by RFC-023) Date · 2026-05-19 Owner · Marko Closes into · RFC-023 Slice gate · v0.7 (lands during current dev cycle alongside hotspots work)
Why this is a PRD. Today
/missionssurfaces only the 37 hand-curated catalogue entries. There is no global view of what's launching next or what has launched across the broader spaceflight register. This PRD adds that surface: a banner + dedicated/missions/launchesroute covering both upcoming and historic launches, importance-tiered, hand-overridable, mobile-first. The architectural commitment that makes this worth a PRD is the data-sourcing posture — same agency-first discipline already locked by ADR-046 (imagery) and ADR-051 (LEARN links): primary sources direct (NASA / ESA / JAXA / SpaceX / Roscosmos / ISRO / CNSA + GCAT for historic), aggregators (Launch Library 2) only to fill gaps. We're not building a UI for someone else's database.
§why
Orrery's mission catalogue is editorial: 37 hand-picked missions that map to our 3D scenes, /fly trajectories, /moon and /mars markers. Deliberately narrow.
What it doesn't tell the user:
- "What's launching this week?" — the single most common question a casual visitor asks.
- "How many Falcon 9 flights so far in 2026?" — slice across the broader register.
- "Show me every Soviet R-7 launch in the 60s." — historic exploration that frames the catalogue.
The architectural risk to manage. A naïve implementation pipes Launch Library 2 (LL2) into the UI and calls it done. LL2 is the de-facto public aggregator (~350 upcoming + historic back to 1957). It's permissively licensed and fits a build-time snapshot. But: LL2 is itself a downstream aggregator (it sources from Jonathan McDowell's GCAT + Gunter's Space Page). Building Orrery's launches surface as a thin UI over LL2 would make us a downstream-of-a-downstream — fragile coupling, no editorial differentiation, and "Orrery is a fancy UI for thespacedevs" is exactly the brand outcome we don't want.
The discipline that already keeps Orrery editorially first-party is locked in two ADRs:
- ADR-046 (agency-first imagery). NASA / ESA / JAXA / agency portals are tried first; Wikimedia + NASA Images API are the fallback library.
- ADR-051 (agency-first LEARN links). Operator's own page must be the first intro link; aggregators second; Wikipedia never alone.
PRD-020 extends the same pattern to launch data:
- Primary sources (agency-direct): NASA media schedule + press calendar, ESA operations / press, JAXA press calendar, SpaceX upcoming-launches page, Roscosmos / CNSA / ISRO press feeds. Manual where APIs don't exist (most of them).
- Historic primary source: Jonathan McDowell's GCAT (
planet4589.org/space/gcat) — the actual canonical register that LL2 itself draws from. Released under CC-BY, requires citation. We pull GCAT directly, cite McDowell on the calendar page itself +/library+/credits, and bypass LL2 entirely for historic data. - Aggregator augmentation (gap-fill only): LL2 covers small commercial / CubeSat / rideshare launches where direct agency sourcing isn't realistic. Used only where the agency-first chain returns nothing. Always cited.
- Editorial layer: featured launches get an Orrery-authored one-sentence context, pulling the calendar closer to the hand-curated catalogue's voice.
Same architectural posture as the rest of the corpus: language-neutral base data + locale overlays, agency-first attribution chain, fail-closed validation, build-time fetch (ADR-016).
§audiences
| Audience | Why this helps them |
|---|---|
| Casual learner / first-time visitor | "What's launching this week?" answered on the /missions banner. Lands on a featured launch with rocket, agency, payload, 3D scene if we have one. |
| STEM student | Slice the historic register: Falcon 9 cumulative count, Saturn V flight history, Soviet R-7 lineage, Long March family per year. Teaching surface. |
| Space enthusiast | Track the upcoming queue with editorial filtering. "Featured" tier = the launches worth watching. Curated overrides catch the heuristic's misses. |
| Educator / journalist | Cite the calendar with confidence — every row traces to a primary-source provenance chain (agency-direct OR GCAT OR aggregator-of-last-resort), all visible on hover/long-press. |
§what's already shipped (readiness inventory)
| Capability | Status | Source |
|---|---|---|
/missions catalogue grid (37 hand-curated entries) | shipped | PRD-004 |
static/data/missions/index.json manifest (build-time, language-neutral + locale overlays) | shipped | ADR-006, ADR-017 |
static/data/fleet/launcher/* — 23 launch vehicles | shipped | PRD-012, ADR-052 |
| Agency-first image + link provenance pattern, fail-closed validation | shipped | ADR-046, ADR-047, ADR-051 |
Build-time fetch scripts under scripts/fetch-*.ts + cache layout | shipped | ADR-016 |
wave23/ translation toolchain for new UI string sets | shipped | ADR-033 |
| Per-route readiness signals | shipped | ADR-056 |
Public /credits (image + text provenance) + /library (outbound link inventory) | shipped | ADR-047, ADR-051 |
Gaps PRD-020 fills:
- No external-launch-register surface plugged into the corpus.
- No multi-source data pipeline with priority ordering (the imagery + link patterns are agency-first; launches will be too).
- No importance-tiering pattern (the closest precedent — PRD-018 image curation — is heading toward auto-tier + override; PRD-020 lands that model in parallel).
§goal
Ship a launches surface on /missions:
- A banner strip on
/missionsabove the catalogue grid showing the next ~3 featured upcoming launches with live-ish T-0 countdown. - A dedicated
/missions/launchesroute with hybrid UI: horizontal month strip (jump-to-month) + vertical timeline list (chronological detail). Two modes: UPCOMING + HISTORIC. - An importance-tiering layer — deterministic heuristic + per-launch curated override file (committed, diff-friendly).
- A multi-source data pipeline that resolves each launch from the highest-available-priority source, records the full provenance chain per entry, validates fail-closed.
- Cross-integration hooks — fleet launcher pages get "next flight" + "recent flights" widgets reading the same manifests.
- First-class attribution — GCAT citation surfaced on the calendar page itself, in
/credits, and in/librarynext to existing citations. CC-BY compliance is a ship-gate, not a follow-up.
v0.1 ship gate = banner + dedicated route + heuristic + override + multi-source pipeline (agency-direct + GCAT + LL2-fallback) + fleet "next flight" widget + i18n + attribution surfaces complete.
v0.2 = mission-catalog backlinks + i18n overlays for high-frequency LL2/agency strings.
v0.3 = post-launch outcome enrichment loop + Orrery-editorial one-sentence overlays on T1 featured launches.
§user stories
US-1 — "What's launching this week?" on /missions. Casual visitor lands on /missions. Above the catalogue grid: NEXT LAUNCH · Falcon 9 · Starlink Group 10-31 · T-0 in 2d 4h · Cape Canaveral. Tappable → opens the calendar at that entry.
US-2 — Browse upcoming launches as a calendar. /missions/launches. Top: month strip (MAY · JUN · JUL · …) with per-month counts. Tap → timeline scrolls. Timeline rows show T-0 countdown, vehicle, payload, agency flag, tier chip (FEATURED gold / nothing / ROUTINE greyed), webcast-live icon. Each row's source-chip on hover/long-press shows the full provenance chain (e.g. "NASA media schedule → confirmed via LL2").
US-3 — Browse historic launches. Toggle UPCOMING → HISTORIC. Default: last 30 days. Filters: year range (1957 → today), agency, vehicle family, orbital destination, outcome. Every historic row traces to GCAT with optional secondary sources noted. McDowell citation visible at page footer.
US-4 — Featured tier surfaces editorial picks. Crewed launches, beyond-LEO / interplanetary / lunar missions, first-flights of new vehicles, and any launch in the curated launches-curation.json featured list get a gold chip + appear in the /missions banner rotation. Routine LEO comsat constellation batches do not. Marko can manually promote or demote any launch.
US-5 — "Next Falcon 9 flight" on the fleet launcher page. /fleet/launcher/falcon-9 shows a NEXT FLIGHT widget (T-0 + payload + pad) + RECENT FLIGHTS (last ~5 from historic manifest). Cross-link to /missions/launches?vehicle=falcon-9.
US-6 — Offline shell holds the calendar. First page load fetches the static manifest. Subsequent loads (offline shell via @vite-pwa) still render. T-0 counters reflect the last build's snapshot with a "last refreshed Xh ago" stamp visible.
US-7 — Attribution is visible, not buried. McDowell / GCAT citation surfaces in THREE places: (a) at the bottom of the calendar page itself in a small CITATIONS strip; (b) on /credits next to existing image-provenance sections; (c) on /library next to existing outbound link citations. Each calendar row also exposes a per-row provenance chip on hover/long-press. CC-BY compliance is enforced by validate-data.ts (fail-closed if the citation strings disappear).
US-8 — Editor curation loop (auto + override). Marko reviews a fresh fetch. Promotes a launch → adds its canonical ID to launches-curation.json featured list with a one-line note. Demotes → demoted list. Curation file committed; next build picks up the override.
US-9 — Multi-source provenance is transparent. A featured Artemis II launch row shows: PRIMARY: nasa.gov/artemis-2 → CONFIRMED-VIA: GCAT → AUGMENTED-WITH: LL2 (image + webcast link). Each link in the chain is clickable. The pipeline records this chain; the UI surfaces it on hover/long-press; /credits lists every primary source actively in use.
US-10 — i18n: UI chrome translated, raw data English-only v0.1. UI chrome (FEATURED / UPCOMING / HISTORIC / "T-0 in 2d 4h" / month names / orbital category labels / agency type labels / status labels) via Paraglide. Source-data strings (mission names, payload descriptions, rocket variant names) stay English for v0.1 — overlays land in v0.2 for recurring high-value strings.
§must-have requirements
| ID | Requirement |
|---|---|
| M1 | Multi-source data architecture, agency-first. A LaunchSource provider interface (mirrors VisionProvider from RFC-022) with explicit priority order: (1) Agency-direct providers — NasaSource, EsaSource, JaxaSource, SpaceXSource, RoscosmosSource, IsroSource, CnsaSource. Many of these are scraping- or manual-curation-shaped (no clean JSON APIs); pipeline accepts that. (2) GCAT direct (GcatSource) — Jonathan McDowell's canonical historic register at planet4589.org/space/gcat, downloaded as TSV/text catalogs, parsed locally. Primary source for ALL historic data. (3) Launch Library 2 fallback (LL2Source) — https://ll.thespacedevs.com/2.3.0/, anonymous tier (15 req/hour). Used ONLY when (1) + (2) return nothing for an upcoming launch entry (typical case: small commercial / rideshare / CubeSat). |
| M2 | Build-time fetch only per ADR-016. New script scripts/fetch-launches.ts orchestrates the providers in priority order. Each provider writes its raw responses to .launches-cache/<provider>/... (gitignored). A merge step consolidates into static/data/launches.json (upcoming) + static/data/launches-historic.json (everything ≤ today) with full provenance_chain per entry. |
| M3 | Two-manifest layout. launches.json holds future launches only (~350 entries). launches-historic.json is the full register paged by decade (1957–1970 / 1971–1980 / … / 2021–2026) for git friendliness — RFC-023 to finalise paging granularity. |
| M4 | Importance tier algorithm — heuristic + curated override. T1 (FEATURED) = crewed OR beyond-LEO (interplanetary / lunar / cislunar / L1/L2 / heliocentric / Mars / Moon / Venus / Jupiter / Saturn) OR first-flight of a vehicle. T2 (NOTABLE) = first flight from a new pad, first reusable-stage milestone, agency-debut. T3 (STANDARD) = everything else. T4 (ROUTINE) = LEO comsat constellation batches (Starlink / OneWeb / Kuiper / Qianfan), GTO comsat, run-of-the-mill resupply. Override file static/data/launches-curation.json (committed, hand-edited) holds featured + demoted lists by launch ID. Pipeline applies overrides AFTER heuristic. |
| M5 | Launch manifest schema (per entry). Required fields: id (Orrery-internal stable slug, e.g. 2026-05-26-falcon9-starlink-10-31), net (ISO 8601), net_precision, window_start, window_end, status, name, mission_name, mission_type, orbit_abbrev, orbit_name, agency_id, agency_name, agency_type, country, rocket_config_name, rocket_family, orrery_launcher_ref (fleet launcher id if mapped, else null), pad_name, pad_location, image_url, image_credit, tier (T1–T4), tier_reason, provenance_chain (array of { source, source_url, fetched_at, role } where role ∈ { "primary", "confirmed-via", "augmented-with", "fallback-primary" }), editorial_note (optional, Orrery-authored one-sentence context for T1 featured), fetched_at. |
| M6 | Curation file schema. static/data/launches-curation.json (committed): { "version": 1, "featured": [{ "launch_id": "…", "reason": "…", "editorial_note": "…", "added_by": "marko", "added_at": "…" }, …], "demoted": [{ "launch_id": "…", "reason": "…", … }, …] }. The editorial_note field flows through to the manifest entry (M5) so curated featured launches can carry an Orrery-authored one-sentence framing. |
| M7 | /missions banner. New top-of-route component LaunchesBanner.svelte. Shows next 1–3 T1 launches by net ascending. Mobile: single-card swipe. Desktop: 3-card row. Each card: T-0 countdown, vehicle, payload, agency flag, tier chip, editorial note if present. Tap → /missions/launches?id=<launch-id>. |
| M8 | /missions/launches route. New route. Layout: filter strip + horizontal month strip + vertical timeline list. UPCOMING / HISTORIC toggle. Filters: agency, vehicle family, orbital destination, outcome (historic only), year range, tier (FEATURED ONLY ↔ ALL). Deep-link friendly URL state via the existing untrack() pattern. |
| M9 | Mobile-first. Designed at 375 px. Banner: single-card swipe → 3-card row at ≥ 768 px. Calendar: timeline + horizontal-scroll month strip on mobile; sidebar filter drawer on filter-button tap. Touch targets ≥ 44×44 px. |
| M10 | Cross-integration: fleet launcher pages. Each /fleet/launcher/<id> gains NEXT FLIGHT + RECENT FLIGHTS sections. Reads launches manifests filtered by orrery_launcher_ref === <id>. Requires ll2-rocket-mapping.json → rename to launches-rocket-mapping.json (since not LL2-specific): a manual map from rocket_family strings to fleet launcher ids covering our 23 launchers. Unmapped vehicles surface in the calendar with orrery_launcher_ref: null — they appear; they just don't backlink. |
| M11 | Refresh cadence per source. GH Actions cron workflow .github/workflows/refresh-launches.yml: (a) GCAT — pulled weekly (its data update cadence is roughly monthly per the release header); pinned to a specific GCAT release version with explicit git diff of the manifest committed. (b) LL2 augmentation — every 6 hours (only fetches launches not already resolved by agency-direct or GCAT). (c) Agency-direct providers — manual/operator-triggered for v0.1 (a marko bot schedule of weekly review of nasa.gov / esa.int / jaxa.jp / spacex.com / etc. for the upcoming-launches windows). v0.2 graduates the most reliable agency sources (e.g. NASA RSS feeds) to automated cadence. T-0 counters stamp fetched_at per provider; a "last refreshed Xh ago" stamp shows the freshest of the chain. |
| M12 | Cache + idempotency. Each provider's raw responses cached at .launches-cache/<provider>/.... Merge step idempotent: running twice with no source changes produces a byte-identical manifest. GCAT cache invalidated by GCAT release-version bump. LL2 cache by ETag. Agency-direct providers by content hash of the scraped page. |
| M13 | Validation (fail-closed). validate-data.ts gains new checks: launches.json + launches-historic.json validate against ajv schemas. Every entry must have provenance_chain with at least one { role: "primary" } OR { role: "fallback-primary" } entry. Schema malformation = fail. Missing primary provenance = fail. The CITATION strings (GCAT McDowell citation; LL2 attribution where used; any agency citation explicitly required) must be present in static/data/text-sources.json or static/data/source-logos.json per ADR-047 — fail-closed if absent. CC-BY compliance lives at this validation gate, not in operator memory. |
| M14 | Attribution surfacing — three places, ship-gate (NOT follow-up). (a) On the calendar page itself (/missions/launches): a CITATIONS strip at the page footer naming Jonathan McDowell / GCAT (CC-BY) + any other primary sources actively used in the current manifest. Links to planet4589.org/space/gcat + agency sources. (b) On /credits: a new LAUNCH DATA section with the McDowell citation, GCAT release version pinned in the build, the per-source provenance summary (counts of entries by primary source). (c) On /library: GCAT + each agency-direct source + LL2 added as outbound-link entries with proper provenance per ADR-051 (native-language priority where applicable, rel="noopener noreferrer external"). |
| M15 | i18n. UI chrome via Paraglide. Source-data strings (mission/payload/vehicle variants) English-only v0.1. Wave23 catalog/maps/apply-translations cycle picks up the new chrome strings. Citation strings themselves stay English (canonical academic-citation form is language-neutral). |
| M16 | No client storage. Per ADR-018 + ADR-057. All filter state URL-encoded. |
| M17 | Mission-catalog backlink (v0.1 best-effort, false-positive-NOT-OK). When a launch matches one of our 37 catalogue missions (agency + vehicle + launch date ± 2 days + best-effort mission name token overlap), surface "→ Open in Orrery" → existing mission detail. False-negatives OK; false-positives must not happen. v0.2 adds a manual orrery_mission_ref lookup for heuristic misses. |
| M18 | Status-aware UI. Map source-provided status into four visual states: SCHEDULED (greys countdown if TBD), GO (countdown live), IN-FLIGHT (live banner), OUTCOME (success/failure/partial badge). Failure rows show source-provided fail reason text with attribution. |
| M19 | Performance budget. launches.json ≤ 250 KB gzipped. launches-historic.json paged per decade, each ≤ 1 MB gzipped, lazy-loaded by year-range filter. First-paint bundle impact at /missions/launches: ≤ 300 KB additional over /missions. |
| M20 | Webcast-live signal. Where source data provides a live-webcast URL (agency stream first, LL2 fallback), surface a LIVE indicator + "watch" link. No embedded video v0.1. |
| M21 | GCAT integration mechanics. GCAT publishes catalogs as fixed-width text + TSV. scripts/gcat-source.ts downloads the Orbital Launch Log TSV (the derived catalog of orbital launches + payloads), parses the column-described format per the GCAT documentation, normalises to the M5 schema. GCAT release version (e.g. "1.8.0") + data-update date are recorded in the manifest header AND committed to text-sources.json for the citation. A GCAT major-version bump (1.x → 2.x) requires a manual review pass before promotion (potential schema change). |
§should-have requirements
| ID | Requirement |
|---|---|
| S1 | "Notify me" placeholder UI on featured launches (mailto: link with pre-filled subject; real notification system out of scope). |
| S2 | iCal export per launch (client-side .ics from manifest). |
| S3 | Spotlight one historic launch on-this-day in the /missions banner when upcoming queue is thin (≤ 1 T1 in next 48 h). |
| S4 | Filter chip presets ("This week" / "Crewed only" / "Beyond LEO" / "First flights"). |
| S5 | "Heatmap" historic-mode visualisation: year × agency grid of launch counts, tappable. |
| S6 | Per-source toggle on /credits (show only entries whose primary source is NASA, ESA, JAXA, GCAT, LL2, …) — surfaces the multi-source posture concretely. |
§will-not-have (v0.1)
- Embedded video webcasts. Link out only.
- Real push notifications. Mailto placeholder.
- Editorial mission writeups for every LL2/agency-sourced launch. That's what the 37-mission hand-curated catalogue is for. Featured launches optionally carry a one-sentence
editorial_note(M6); the rest surface raw source fields. - i18n overlays for source-data strings. v0.1 keeps these English.
- Auto-detection of new vehicle families. Unmapped vehicles surface with
orrery_launcher_ref: null; operator catches via audit report, edits the mapping file. - Roscosmos / CNSA / ISRO full agency-direct integration. v0.1 falls back to GCAT (historic) + LL2 (upcoming) for these; agency-direct providers added incrementally in v0.2+.
- Capacitor mobile native notification. Defer to PRD-015 / RFC-018.
- Outcome-write-back to LL2 / GCAT. Downstream consumer only.
§success-criteria
Editorial:
- ≥ 95 % of T1 (FEATURED) launches in the next 90 days are launches Marko + 1 reviewer agree should be featured.
- 0 false-positive mission-catalog backlinks (M17).
- Every calendar row's
provenance_chaincontains at least oneprimaryorfallback-primaryentry. No silent LL2-only rows for launches an agency directly covers. - McDowell / GCAT citation visible on
/missions/launches,/credits, AND/library— verified by a Playwright spec that reads each route + asserts the citation string.
Technical: 5. npm run fetch:launches cache-cold completes in ≤ 8 minutes (GCAT TSV parse + agency-direct sweep + LL2 fill). 6. Build-cron refresh workflow stable: 4 consecutive runs land without manual intervention. 7. First-paint bundle impact on /missions/launches ≤ 300 KB additional over /missions. 8. validate-data.ts enforces existing fail-closed gates AND the new launch + curation + citation schemas. 9. Mobile-first works at 375 px without horizontal overflow + all touch targets ≥ 44 px. 10. Offline shell loads the calendar from the last manifest.
Operational: 11. Curation loop: editing launches-curation.json + re-running the pipeline applies the override within one build cycle. 12. Adding a new agency-direct provider takes one new <Agency>Source.ts file implementing the LaunchSource interface + one entry in the providers config + an attribution line in text-sources.json. 13. GCAT release-version bump is a one-file change in the build config + a re-run.
§dependencies
- ADR-016 (build-time asset resolution) — strictly respected: zero runtime fetches from the deployed app.
- ADR-046 (agency-first imagery) — same priority discipline now applied to launch data. PRD-020 cites this ADR as precedent.
- ADR-047 (provenance + license stewardship) — every primary source registered in
text-sources.json; CC-BY compliance enforced byvalidate-data.ts. - ADR-051 (LEARN links — agency-first, native-language priority) —
/libraryintegration follows this exact pattern. - ADR-052 / ADR-053 (fleet schema + imagery) —
orrery_launcher_refjoins from launches into fleet entries. No symmetric-link enforcement (a launcher having upcoming/recent flights is a query result, not stored cross-ref). - ADR-017 / ADR-033 (i18n) — new UI string set via
wave23/. - ADR-018 (mobile-first) — bottom-sheet filter drawer on mobile.
- ADR-056 (e2e readiness signals) —
/missions/launchesexposesdata-route-readyonce manifest is rendered. - ADR-057 (no client storage) — all filter state URL-encoded.
§resolved decisions
Resolved 2026-05-19 in scoping conversation with Marko.
- Surface placement — RESOLVED: Banner on
/missions+ dedicated/missions/launchesroute. Two-tier surfacing. - Data sourcing model — RESOLVED: Agency-first multi-source pipeline, LL2 as augmentation only. Direct sources: NASA / ESA / JAXA / SpaceX / Roscosmos / ISRO / CNSA (manual/scraping/RSS depending on what each agency exposes) + GCAT direct as the historic primary (the same source LL2 itself uses, bypassing LL2 in the historic chain entirely). LL2 fills upcoming-launch gaps the agency layer can't reach (small commercial, CubeSat, rideshare). Mirrors ADR-046 (agency-first imagery) and ADR-051 (agency-first LEARN links).
- Historic register included — RESOLVED: YES, via GCAT direct.
- Importance tiering — RESOLVED: Heuristic + curated override (
launches-curation.json). Same auto + override pattern PRD-018's image-curation is moving toward. - Calendar UI — RESOLVED: Hybrid timeline + month strip. Mobile-first at 375 px.
- Cross-integration scope (v0.1) — RESOLVED: Fleet launcher pages get "next flight" + "recent flights" widgets. Mission-catalogue backlinks best-effort.
- Refresh model — RESOLVED: Per-source cadence. GCAT weekly (its update cadence is ~monthly); LL2 augmentation every 6 h; agency-direct manual v0.1 → graduating to automated where APIs/RSS support it in v0.2.
- Attribution — RESOLVED: McDowell / GCAT citation surfaces on the calendar page itself,
/credits, AND/library. CC-BY compliance is a ship-gate, enforced byvalidate-data.ts; not a follow-up. Each calendar row exposes a per-row provenance chip showing the chain. - Editorial overlay — RESOLVED: T1 featured launches optionally carry an Orrery-authored one-sentence
editorial_noteflowed through from the curation file. Pulls the calendar closer to the hand-curated catalogue's editorial voice without forcing an Orrery write-up on every routine commercial launch. - i18n strategy — RESOLVED: UI chrome via Paraglide, source-data English-only v0.1.
§open questions
- Realistic agency-direct provider list for v0.1. Which agencies do we attempt direct integration with in the first slice? Recommend: NASA (RSS + KSC media schedule) + SpaceX (their upcoming-launches page) + ESA (press calendar) for v0.1; JAXA + Roscosmos + ISRO + CNSA fall back to GCAT (historic) + LL2 (upcoming) v0.1, with agency-direct added incrementally. RFC-023 to lock the v0.1 list.
- GCAT data shape vs. our schema. GCAT's Orbital Launch Log is the closest match. Verify at implementation time that the column set covers our M5 required fields without significant transformation. Likely yes (LL2 maps from GCAT for these fields already), but confirm.
- GCAT release-version pinning. Lock to a specific release (e.g. 1.8.0) per build. Bumping is operator-triggered, with a manual review pass on the schema diff. Avoids silent regressions if a future GCAT release adds/removes columns.
- Historic manifest paging granularity. Per-decade (~7 files, ~1 MB each) vs. per-year (~70 files, ~100 KB each). Per-decade probably wins. RFC-023.
launches-rocket-mapping.jsonseed. Manual mapping for our 23 fleet launchers + provision for "per-config vs per-family" matches. Recommend per-family default with optional per-config exception list.- Agency-direct provider implementation cost. Most agencies don't expose JSON APIs — providers will be HTML scraping or RSS parsing. Each provider is ~½–1 day of engineering + ongoing brittleness when an agency reshuffles their press page. Worth it because it's the ONLY thing that prevents the "we're a UI for LL2" outcome. RFC-023 to lock the per-provider implementation pattern + the brittleness-tolerance posture (degrade-gracefully to LL2 + log a warning when an agency scraper breaks).
- PRD-018 alignment. Marko has asked PRD-018's image-curation to adopt the same heuristic + override pattern as
launches-curation.json. Captured as a follow-up task on this scoping session. - Failure-data tone. GCAT records fatalities (Soyuz 1, Challenger, Columbia, etc.) factually. v0.1 surfaces the GCAT text verbatim with attribution. Revisit case-by-case if any specific row feels off-tone.
- Build-cron commit author + commit message conventions. GH Actions bot identity + diff format. RFC-023.
- Editorial-note bandwidth. How many
editorial_notestrings does Marko realistically maintain per quarter? Probably ≤ 10 for the FEATURED rotation. Manageable. Worth confirming so the field doesn't become a thing that's "supposed to be filled in" but never is.
PRD-020 · Orrery · Launches Calendar · Drafted 2026-05-19 · Closes-into-RFC-023