## ADDED Requirements ### Requirement: PlanetConfig shape The system SHALL export a `PlanetConfig` type containing name, mass, radius, polar radius, surface gravity, rotation period, axial tilt, optional atmosphere, satellites, optional orbital elements, and optional texture manifest. #### Scenario: Validate PlanetConfig schema - **WHEN** a `PlanetConfig` with all required fields is constructed via Zod parse - **THEN** validation succeeds - **AND** when mass is omitted, validation throws `ValidationError` ### Requirement: AtmosphereConfig shape The system SHALL export an `AtmosphereConfig` type with surface pressure, scale height, Rayleigh coefficient, Mie coefficient, and extinction per air mass. #### Scenario: Validate atmosphere - **WHEN** an `AtmosphereConfig` with valid positive values is parsed - **THEN** validation succeeds - **AND** `atmosphericDensity(0)` on a `PlanetSurface` using this config returns surface pressure-derived density ### Requirement: SatelliteConfig shape The system SHALL export a `SatelliteConfig` type with name, mass, radius, orbital radius, orbital period, inclination, eccentricity, and albedo. #### Scenario: Satellite definition - **WHEN** a `SatelliteConfig` for a moon is parsed with `mass > 0` and `orbitalRadius > 0` - **THEN** validation succeeds ### Requirement: PlanetSurface geometry delegation The system SHALL implement `PlanetSurface` whose `distance`, `bearing`, `destination`, and `pointInPolygon` methods delegate to `@suaveplan/geo` functions using the planet's ellipsoid. #### Scenario: PlanetSurface uses correct ellipsoid - **WHEN** a `PlanetSurface` is constructed with a planet having `radius = 3396200` and `polarRadius = 3376200` (Mars-like) - **THEN** `distance` between two surface points matches the great-circle distance on that ellipsoid, not WGS84 ### Requirement: Atmospheric density The system SHALL compute atmospheric density at a given altitude from `AtmosphereConfig` using the scale-height exponential model. #### Scenario: Density halves at scale height - **WHEN** `atmosphericDensity(scaleHeight)` is called on a planet with `scaleHeight = 8500` - **THEN** the result equals half the surface density ### Requirement: Air mass The system SHALL compute air mass for a given altitude angle using the Kasten–Young formula. #### Scenario: Zenith air mass - **WHEN** `airMass(90)` is called - **THEN** the result is approximately `1.0` - **AND** `airMass(0)` returns a value significantly greater than `1.0` ### Requirement: No bundled planet data The system SHALL NOT bundle any pre-defined planet configuration. #### Scenario: Inspect geo-planet exports - **WHEN** all exports from `@suaveplan/geo-planet` are enumerated - **THEN** no `EARTH`, `MARS`, or pre-built `PlanetConfig` constant exists