## ADDED Requirements ### Requirement: ObserverPosition types The system SHALL export a discriminated union `ObserverPosition` with three variants: `surface` (planet + coord), `atmospheric` (planet + coord + altitude), and `space` (Vec3 + frame). #### Scenario: Surface observer construction - **WHEN** an `ObserverPosition` of type `surface` is constructed with a valid `PlanetConfig` and `SphericalCoord` - **THEN** the object validates successfully - **AND** the `PlanetConfig` is accessible inline without lookup ### Requirement: CoordinateFrame types and conversion The system SHALL export `CoordinateFrame` as a union of `heliocentric`, `galactic`, and `custom`, plus pure conversion functions `convertFrame`, `toHeliocentric`, and `toGalactic`. #### Scenario: Identity conversion - **WHEN** `convertFrame(vec, heliocentric, heliocentric)` is called - **THEN** the result equals the input vector ### Requirement: CelestialBody shape The system SHALL export a `CelestialBody` interface with name, type, altitude, azimuth, apparent magnitude, angular diameter, distance in AU, and heliocentric position. #### Scenario: Body validation - **WHEN** a `CelestialBody` object is constructed with all required fields - **THEN** Zod validation succeeds ### Requirement: CatalogStar and ObservedStar shapes The system SHALL export `CatalogStar` (catalog-space, no observer fields) and `ObservedStar` (extends `CatalogStar` with altitude, azimuth, and extincted magnitude). #### Scenario: Observed star construction - **WHEN** an `ObservedStar` is created from a `CatalogStar` with added `altitude`, `azimuth`, and `extinctedMagnitude` - **THEN** the object satisfies both the `CatalogStar` and `ObservedStar` contracts ### Requirement: SolarProvider interface The system SHALL export a `SolarProvider` interface with `getBodies`, `getBody`, `getSunrise`, and `getSunset`, all accepting `ObserverPosition`, `Date`, and optional `AbortSignal`. #### Scenario: SolarProvider cancellation - **WHEN** `getBodies` is called with an `AbortSignal` that is aborted before resolution - **THEN** the promise rejects with an abort error ### Requirement: StarProvider interface The system SHALL export a `StarProvider` interface with `getVisibleStars` (returns `ObservedStar[]`), `queryCone` (returns `CatalogStar[]`), and `getStar`. #### Scenario: StarProvider query - **WHEN** `getVisibleStars` is called with a surface observer and `StarQueryOptions` - **THEN** the returned array contains only `ObservedStar` entries with `altitude` and `azimuth` populated ### Requirement: TidalProvider interface The system SHALL export a `TidalProvider` interface with `predictHeight` and `getExtremes`, accepting `PlanetConfig`, `SphericalCoord`, `Date`, and optional `AbortSignal`. #### Scenario: Tidal prediction cancellation - **WHEN** `predictHeight` is called with an aborted signal - **THEN** the promise rejects with an abort error ### Requirement: WeatherState and WeatherProvider interface The system SHALL export `WeatherState` and `WeatherProvider` with a locked interface for future `@suaveplan/weather` integration. #### Scenario: WeatherProvider registration - **WHEN** a `WeatherProvider` is registered with `UniverseClient` - **THEN** `UniverseScene.weather` is populated after `getScene` ### Requirement: UniverseClient plugin registry The system SHALL provide `UniverseClient` with typed `register` methods for `solar`, `stars`, `tides`, and `weather` domains, returning `this` for chaining. #### Scenario: Register all providers - **WHEN** providers are registered for all four domains - **AND** `getScene` is called with valid observer and time - **THEN** the returned `UniverseScene` contains `bodies`, `stars`, `tides`, and `weather` ### Requirement: UniverseScene shape The system SHALL export `UniverseScene` with `bodies`, `stars`, optional `tides`, and optional `weather`. #### Scenario: Scene without optional providers - **WHEN** only `solar` and `stars` providers are registered - **AND** `getScene` is called - **THEN** the scene has `bodies` and `stars`, with `tides` and `weather` undefined ### Requirement: StarPacket BitSchema The system SHALL export a `StarPacket` BitSchema quantising RA, Dec, magnitude, altitude, azimuth, and spectral class into ~11 bytes per star. #### Scenario: Pack and unpack stars - **WHEN** an array of `ObservedStar` objects is packed via `packStars` - **AND** the buffer is unpacked via `unpackStars` with the correct count - **THEN** the unpacked array has the same length - **AND** each field is within the quantisation error tolerance of the original ### Requirement: CelestialBodyPacket BitSchema The system SHALL export a `CelestialBodyPacket` BitSchema quantising altitude, azimuth, angular diameter, apparent magnitude, and body type. #### Scenario: Pack and unpack bodies - **WHEN** an array of `CelestialBody` objects is packed via `packBodies` - **AND** the buffer is unpacked via `unpackBodies` with the correct count - **THEN** the unpacked array has the same length and matching fields within tolerance