ADR-053 — Fleet imagery: hero, anatomy SVG, mission patch, crew portrait sourcing
Status · Accepted (retrospective; shipped v0.6.0) Date · 2026-05-15 Closes · RFC-016 OQ-3, OQ-8, OQ-13, OQ-18 TA anchor · §components/fleet/imagery · §constraints/provenance Related ADRs · ADR-035 (diagram authoring pipeline), ADR-046 (agency-first imagery), ADR-047 (provenance manifests + license stewardship), ADR-051 (outbound learn-link stewardship)
Context
Every fleet entry needs four kinds of imagery:
- Hero photo — one card-grid thumbnail per entry (137 entries).
- ANATOMY SVG — hand-authored cutaway/exploded diagram (~35 entries shipped at v0.6; rest no-op the tab).
- Mission patch — per notable flight (3–6 flights × ~30 crewed-spacecraft entries ≈ 120 patches).
- Crew portrait — per crew member on each notable flight (~400 portraits at full coverage).
The naive path — pull whatever Google Images returns — produces three predictable failures: (a) artist's impressions get mistaken for photographs; (b) non-US programs end up represented by Western-press renderings instead of Roscosmos / CNSA / JAXA / ISRO releases; (c) crew portraits skew toward famous astronauts while flight-engineer mission specialists go missing entirely. ADR-046 established agency-first sourcing for the rest of the corpus; this ADR applies the same discipline to the four asset classes above and adds the SVG authoring rule from ADR-035 to the anatomy diagrams.
Decision
Hero photo sourcing (closes OQ-8)
Source priority (same as ADR-046, restated here so curators have it in one place):
- Operating agency's published archive — NASA Image and Video Library, ESA, Roscosmos, CNSA, JAXA Digital Archives, ISRO, KARI, MBRSC, CSA, ASI. Each entry's
country/agencyfields drive the lookup. - Wikimedia Commons — only when the agency archive is unavailable or doesn't publish the era's imagery (mid-century Soviet, etc.). Must be a CC-BY / CC-BY-SA / PD-Gov / PD-Soviet license.
airandspacehistory.com— first-party permission granted for restricted Soviet-era imagery (closes OQ-18). Cited assource: "airandspacehistory.com"insource-logos.json; per-image waiver tracked inlicense-waivers.jsonper ADR-047.
Banned sources:
- Artist's impressions of vehicles that exist or existed (per ADR-046; an
artistic-impression: trueflag exists inlicense-waivers.jsonfor planned-only entries likestarship-hls,dream-chaser, where no flown vehicle exists yet). - Render mockups from third-party publishers (no
wired.com, nospace.com). - Anything without a license file row in
static/data/image-provenance.json(fail-closed per ADR-047).
Path convention: static/images/fleet-galleries/<id>/01.jpg (hero), 02.jpg–NN.jpg (gallery). Manifest at static/data/fleet-galleries.json lists the slot order + caption per image.
Anatomy SVG (closes OQ-13)
Each fleet entry that ships an ANATOMY tab carries a single SVG at static/diagrams/fleet/<id>.svg. Hand-authored per the ADR-035 rule: source committed (the SVG file is the source), no AI generation, palette matches the Orrery canonical colour scheme (/science palette: deep navy background, gold + silver accents, magenta highlights, mono labels).
Tiered rollout (closes OQ-13):
- F.1 — Marquee entries (~20 SVGs): Saturn V, Apollo CSM Block II, Apollo LM, Soyuz-MS, Falcon 9, Crew Dragon, Space Shuttle Orbiter, ISS, Tiangong, Hubble, JWST, Curiosity, Perseverance, Voyager 1/2, Cassini, Viking 1, Lunokhod 1, Chang'e 5, Chandrayaan-3 Vikram.
- F.2 — Family complements (~15 SVGs): other Soyuz generations, Mercury, Gemini, Skylab, Saturn IB, Atlas V, Long March 5, Ariane 5, Sokol-KV-2, A7L, etc.
- F.3 / F.4 — Long tail: ship as content authoring continues post-v0.6.
ANATOMY tab no-ops gracefully when an entry has no SVG yet (closes RFC-016 OQ-4): the tab is hidden, the panel shrinks, no broken-image placeholder ever renders. At v0.6.0 the corpus has ~35 SVGs committed; ~100 entries no-op the tab.
Validation: scripts/validate-diagrams.ts checks that every entry referencing anatomy_svg: true has the file on disk and the file is parseable XML; missing SVG fails the build.
Mission patch sourcing (closes OQ-3)
Mission patches are first-party agency assets (NASA, Roscosmos, JAXA, ESA, CNSA, ISRO publish their own). Path convention: static/images/missions/<mission_id>-patch.png. Manifest row in image-provenance.json per ADR-047 — same fail-closed pipeline as hero photos.
Where the operating agency doesn't publish a patch (most uncrewed missions; some early Soviet flights), the entry's flights[i].patch_path is omitted; the panel renders the flight without a patch.
Wikimedia Commons is acceptable when it carries the agency's official patch under a free license (frequently does — patches are designed to be widely reproduced).
Crew portrait sourcing (closes OQ-3)
Source priority for crew portraits:
- Official agency portrait (NASA "official" astronaut headshots; equivalent ESA / Roscosmos / CNSA / JAXA / ISRO releases). Path:
static/images/crew/<surname>-<initial>.jpg. Always preferred — these are explicitly licensed for editorial use. - Wikimedia Commons when no agency portrait exists at modern resolution (most early Soviet cosmonauts; some 1960s NASA mercury/gemini astronauts).
- In-flight crew photos as a last resort, cropped to a portrait aspect ratio. Provenance row records the crop in
notes.
No crew portrait fallback: when no licensed portrait exists, the crew member renders as a name + role without an image. The panel does not display a silhouette placeholder — empty space is more honest than a generic avatar that implies "this person exists but we couldn't find them".
scripts/audit-fleet-heroes.ts + scripts/fix-fleet-heroes.ts were the bulk-audit tools used in v0.6 Phase F to flag low-quality heroes and substitute agency-archive equivalents; their output lives in docs/provenance/fleet-hero-audit.md and the Wikipedia-API filename derivation pattern they used is the canonical example for future audit passes.
Build-time integrity
All four image classes route through the same fail-closed validation locked by ADR-047:
fetch-assets → build-image-provenance → validate-dataEvery image referenced from a fleet entry (hero_path, gallery[*].path, flights[i].patch_path, flights[i].crew[j].portrait_path) must have a corresponding row in static/data/image-provenance.json with a valid license and a file present on disk. Missing rows or missing files fail the build with a structured diff.
Asset size cap: 8 MiB per file (locked by scripts/validate-data.ts post-ADR-047). Aggregate watch via the asset-size CI guard.
Rationale
- Operator-first sourcing is the same discipline the rest of the corpus follows (ADR-046, ADR-051). Inconsistency between fleet and the surrounding routes would be a user-visible quality regression.
- No artist's impressions for flown vehicles preserves the editorial honesty that distinguishes Orrery from media surveys; planned-only vehicles carry the
artistic-impression: trueflag in their license waiver so the rendering is explicit. - Hand-authored ANATOMY SVGs are the headline original contribution per PRD-012. They are the reason a curator visits
/fleetinstead of Wikipedia. The tiered rollout (F.1 marquee first) gets the highest-traffic 20 entries to depth before paying the long-tail authoring cost. - No-op gracefully on missing SVGs / portraits keeps editorial honesty: the absence of an image is itself information.
- Build-time integrity is non-negotiable per ADR-047 — fleet does not get a discount on the provenance rule that governs the rest of the corpus.
Alternatives considered
- Stock photography APIs for hero images (rejected) — license drift, no agency provenance, biases the corpus toward Western-press aesthetic.
- AI-generated anatomy diagrams (rejected by ADR-035) — not reproducible, no auditable source, breaks the curated-knowledge promise.
- Silhouette placeholders for missing crew portraits (rejected) — implies a generic person where the truth is "we don't have a portrait yet"; replaces information with noise.
- Embed images base64-encoded in JSON (rejected) — kills HTTP caching, bloats every fetch, makes provenance audit harder.
Consequences
Positive
- Every fleet image has a provenance row, a license, and a source agency.
- ANATOMY tab carries hand-authored depth on the 20 entries that anchor the page.
- Failure entries (Challenger, Columbia, Apollo 1, N1) get the same imagery rigour as flown entries — including the crew portraits that turn them from data points into people.
- Asset pipeline reuses ADR-046/047 infrastructure unchanged; no new manifest, no new validator.
Negative
- ~100 entries no-op the ANATOMY tab at v0.6 ship; long-tail authoring is ongoing.
- Crew-portrait coverage is incomplete for some 1960s Soviet flights where the agency archive doesn't publish digitised photos at modern resolution — those crew members render as name-only.
- airandspacehistory.com permission is per-image (no blanket licence); each use needs a waiver row.
Implementation notes
- Hero gallery directory:
static/images/fleet-galleries/<id>/{01..NN}.jpg. - Anatomy SVG:
static/diagrams/fleet/<id>.svg. Author with the/sciencepalette; ship sources as the committed file. - Mission patches:
static/images/missions/<mission_id>-patch.png. - Crew portraits:
static/images/crew/<surname>-<initial>.jpg. Naming convention is loose ("aldrin-b.jpg", "tereshkova-v.jpg"); theportrait_pathfield is the authoritative reference. - Audit tooling:
scripts/audit-fleet-heroes.ts(read-only),scripts/fix-fleet-heroes.ts(substitution). Run after major fleet content changes; output todocs/provenance/fleet-hero-audit.md. - License waivers (planned-only vehicles, airandspacehistory.com images):
static/data/license-waivers.json, schema instatic/data/schemas/license-waivers.schema.json.
Related
- ADR-035 — Diagram authoring pipeline: hand-drawn SVG, sources committed.
- ADR-046 — Agency-first build-time imagery sourcing.
- ADR-047 — Provenance manifests + license stewardship.
- ADR-051 — Outbound learn-link stewardship.
- ADR-052 — Fleet schema + bidirectional cross-reference contract.
- ADR-054 — Fleet i18n strategy.
- RFC-016 — Spaceflight Fleet · architecture, schema, and dataset boundaries.
- PRD-012 — Spaceflight Fleet product spec.