ADR-090 — Flight-map grand hero: a whole-mission scientific diagram per capstone/milestone
Status · Accepted · 2026-08-31 · Operator-directed (Physics Lab v0.9) · builds on ADR-087 (systems layer) + ADR-088/089 (entry) · adds the whole-mission grand hero to the capstone/milestone goals and unblocks the per-goal flight-map subsystem
Context
Each Lab goal is a ladder of per-formula cards, and each card renders one figure "hero" (FigureRenderer → the canvas heroes). That answers "how does this one step work?" but nothing answered "what is the whole flight, end to end?" — the question a capstone is really about. A learner finishing the Apollo round-trip saw six good step figures but never one picture tying launch, trans-lunar injection, descent, ascent, trans-earth injection and entry into a single mission.
The operator asked for a data-driven scientific diagram of the whole flight — explicitly not a stylised poster — in the reference language of the NASA Apollo flight-plan chart and Nik Schulz's "Destination Moon": a trajectory annotated with every event, its real MET/Δv, and the spacecraft configuration at each phase; and to make it contextual with the rest of the Lab (blueprint teal, honesty line) and a showcase of how the flight works and why each phase matters.
Decision
Add a goal-level grand hero — one wide canvas per capstone/milestone goal, above the notebook's step cards — rendered by a new reusable component and fed by a data module:
src/lib/lab/FlightMapCanvas.svelte— renders aFlightMap: a schematic trajectory (cubic béziers) over the Lab's blueprint background, bodies (with optional orbit rings and a planetary limb mode for ascent profiles), numbered event stations withMET · physicsannotations (gold for burns), and a filmstrip of per-phase spacecraft-configuration line-icons.src/lib/lab/flight-maps.ts— theFlightMapdescriptors, one per goal. The physically computable speeds/Δv are derived here from the same kernel the lessons use (visVivaKms,circularVelocityKms,escapeVelocityKms), so the map never disagrees with the cards. Non-computable values (historical MET, mid-course/ascent burn Δv) come from the flight record and are labelled as such on each map's honesty line.Notebook.svelteshowsgetFlightMap(goal.id)at the top of a goal's notebook when one exists.
Shipped maps: apollo-round-trip, get-to-mars, leave-the-solar-system, plan-a-mission, reach-orbit (limb/ascent-profile mode), reach-the-moon.
Honesty boundaries (the load-bearing part)
- Geometry is schematic, and says so. Distances are compressed for legibility (a true-scale Earth–Moon or Sun–Neptune map is unreadable). Every map's honesty line states "schematic … not to scale" and names which numbers ARE computed.
- Numbers are honest. Computable speeds/Δv come from the kernel; record values are named as record values. No faked physics.
- Canvas copy is English, matching every existing Lab hero (
EntrySteeringCanvaset al.) — the hardcoded-copy convention. Only the connection-panel link labels (DOM text) are i18n'd ×14.
Also in this change (same Lab-polish pass)
- Three per-step heroes that were blank or generic curves now have bespoke canvases + figure kinds (
spec.ts):launch-window→ synodic phase-angle dial;gravity-assist→ velocity-triangle deflection;assist-chain→ cumulative-Δv staircase. - Fleet-asset links added to the spaceflight goals that lacked them (Saturn V / CSM / Apollo 13 on the Moon goals; Mars Odyssey / Atlas V on get-to-Mars; Viking 1 on land-on-Mars; Voyager 1/2 on leave-the-solar-system), translated ×14.
Alternatives considered
- A stylised poster (screen-print, big display type). Prototyped and rejected by the operator — wanted a scientific diagram, not marketing art. The poster palette also clashed with the Lab.
- A porkchop/axed plot for the whole mission. Rejected: a single mission spans 10 min to years and 10⁴ km to 10⁹ km; no single axis pair reads. The trajectory-with-annotations form is the standard for a reason.
- True-scale geometry. Rejected: illegible. Schematic + an explicit honesty line is the honest compromise.
Consequences
- New goal-level surface;
Notebookgains one optional block. No change to the card/figure contract. - Adding a map for a new goal is data-only (
flight-maps.ts) unless it needs a new config icon or the limb mode. The filmstrip icon set is a small closed union (IconKind). - Follow-ups: maps for the remaining milestones if wanted; wiring the annotations to live per-notebook input changes (today they read the kernel at module load with the lesson's canonical inputs).