Files
suaveplan/openspec/archive/2026-05-05-enterprise-universe-family/specs/solar-system/spec.md
2026-05-27 23:29:53 +01:00

111 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## ADDED Requirements
### Requirement: SolarProvider implementation
The system SHALL export `createSolarSystemProvider` returning a `SolarProvider` that computes real solar system body positions.
#### Scenario: Sun altitude at noon
- **WHEN** `getBody("Sun", observer, time)` is called for an observer at latitude `0` at local noon
- **THEN** the returned `altitude` is approximately `90` minus the absolute declination offset
### Requirement: Astronomy.js engine injection
The system SHALL accept an injectable `AstronomyEngine` in `createSolarSystemProvider`, defaulting to astronomy.js.
#### Scenario: Deterministic engine injection
- **WHEN** a deterministic mock `AstronomyEngine` is injected
- **THEN** `getBodies` returns exactly the mocked positions
### Requirement: Keplerian propagator for custom planets
The system SHALL propagate positions for planets with `OrbitalConfig` using a Keplerian solver from epoch.
#### Scenario: Custom planet position
- **WHEN** a `PlanetConfig` with valid `OrbitalConfig` is used as observer's planet or target body
- **THEN** `getBodies` includes the custom planet with a propagated heliocentric position
### Requirement: Angular diameter computation
The system SHALL compute `angularDiameterArcmin` as `2 * arctan(radius / distance) * (180/π * 60)`.
#### Scenario: Sun angular diameter
- **WHEN** `getBody("Sun", ...)` is called
- **THEN** `angularDiameterArcmin` is approximately `32` arcminutes
### Requirement: Apparent magnitude for real bodies
The system SHALL compute `apparentMagnitude` for real bodies using phase angle and distance via astronomy.js.
#### Scenario: Venus magnitude range
- **WHEN** `getBody("Venus", ...)` is called at multiple times
- **THEN** `apparentMagnitude` varies between approximately `-4.9` and `-3.8`
### Requirement: Sunrise and sunset computation
The system SHALL compute sunrise and sunset dates in UTC for a given observer and calendar date.
#### Scenario: Equator sunrise consistency
- **WHEN** `getSunrise` and `getSunset` are called for an equatorial observer on an equinox date
- **THEN** sunrise is approximately 12 hours before sunset
### Requirement: Season computation
The system SHALL export `getSeason` defaulting to Earth but accepting any `PlanetConfig` with `axialTilt` and `OrbitalConfig`.
#### Scenario: Northern hemisphere season
- **WHEN** `getSeason(new Date("2026-06-21"), EARTH)` is called
- **THEN** the result is `summer`
### Requirement: Equinox and solstice prediction
The system SHALL export `getNextEquinox` and `getNextSolstice` for any configured planet.
#### Scenario: Next equinox after a date
- **WHEN** `getNextEquinox(new Date("2026-01-01"), EARTH)` is called
- **THEN** the result is a `Date` in March 2026
### Requirement: Lunar phase
The system SHALL export `getLunarPhase` returning phase (0–1), illumination percentage, and name for Earth/Moon.
#### Scenario: Full moon phase
- **WHEN** `getLunarPhase(fullMoonDate)` is called
- **THEN** `phase` is approximately `0.5`
- **AND** `illumination` is approximately `100%`
### Requirement: Eclipse prediction
The system SHALL export `predictEclipse` for solar and lunar eclipses on Earth.
#### Scenario: Known eclipse
- **WHEN** `predictEclipse(new Date("2026-01-01"), "solar")` is called
- **THEN** the returned `EclipseEvent` has a date after the input and a `totality` value
### Requirement: Constellation lookup
The system SHALL export `getConstellation` mapping RA/Dec to IAU constellation name.
#### Scenario: Orion lookup
- **WHEN** `getConstellation(raOrion, decOrion)` is called with Orion's centre coordinates
- **THEN** the result equals `"Orion"`
### Requirement: Atmosphere extinction for surface observers
The system SHALL apply atmospheric extinction to apparent magnitudes when the observer has an atmosphere.
#### Scenario: Horizon extinction
- **WHEN** `getBody("Sun", surfaceObserver, time)` is called with the Sun near the horizon
- **THEN** `apparentMagnitude` is dimmer than the vacuum value