NATAL_DISCOVERY_API - TheDaniel166/moira GitHub Wiki
Natal discovery evidence packets
Three POST /v1/natal-discovery/ routes compose existing engine products for the
free natal page. They do not add astrology algorithms or modify their defaults.
All responses are structured transport data; consumer interfaces must render
domain labels, units, values and explanations rather than dump these objects.
Accepted request and source
Each route accepts dt (a timezone-aware ISO instant), longitudes (only the
selected planets Sun through Pluto, finite degrees in [0, 360)), zodiac
(Tropical or Sidereal), ayanamsa_system, and time_unknown. Sidereal requires
a named system in Ayanamsa.ALL; Tropical forbids a supplied ayanamsa. Nonzero
sub-microsecond digits are rejected. Numerically equivalent trailing fractional
zeros are admitted. Birth-time uncertainty remains an explicit boolean.
The source receipt preserves the original instant string and separately exposes
the normalized UTC datetime at Python microsecond resolution and the resolved
UT1 Julian Day. longitude_basis identifies caller-supplied accepted geometry.
The website's unknown-time convention supplies a nominal noon reference;
reference_kind=noon_reference names that convention, not a recorded birth time.
No route fills omitted selected subjects from defaults.
/dispositors
Delegates to calculate_dispositorship with its admitted default
DispositorshipComputationPolicy: classic-seven subjects, traditional domicile
rulers, self-domicile final stops, terminal cycles and visible unsupported
subjects. Modern dignity co-rulership is a different doctrine and is not admitted
as a dispositorship option here. Selected Uranus, Neptune and Pluto are reported
as out of scope, not assigned invented chains.
Returned links name their source subject, source sign and sign ruler. The packet
distinguishes final_dispositor, terminal_cycle, missing_selected_ruler and
out_of_scope. Several final sinks are preserved as several sinks. A missing
selected ruler is named without inventing its placement. Zero-degree placements,
empty results and cycles remain meaningful values.
/shape
Delegates to classify_chart_shape only when every one of the ten Jones planets
is selected. Otherwise insufficient_selection returns the missing bodies and
supplied positions without a classification. Nodes, angles and added bodies are
outside the request contract.
Authority and branch policy remain in moira/chart_shape.py: Marc Edmund Jones,
Essentials of Astrological Analysis (1960), chapters 1 and 2; the authorized
Sabian Publishing Society text; Moira's declared priority order and borderline
Splash residual. There is no new confidence score.
The full-chart circular gap list uses the engine's existing gap helpers. A
Bucket's returned occupied arc and largest gap describe its nine-planet Bowl
core with the singleton handle removed. metrics_scope=nine_planet_bowl_core
preserves this distinction from the separately returned ten-planet gap list.
Other classifications use metrics_scope=all_ten.
/lunar-context
Unknown-time and missing-luminary requests return explicit uncalculated statuses, with no phase, events, contacts or source-consistency claim. No nominal-noon syzygy is advertised as definitely prenatal.
For a recorded time, the packet first witnesses every supplied selected planet
against Moira.chart(dt, bodies=selected, include_nodes=False), geocentric
apparent ecliptic geometry. Sidereal uses the named true-mode ayanamsa at the
resolved UT1 instant. A circular discrepancy greater than 1e-6 degree rejects
the packet. This tolerance admits decimal serialization and microsecond input;
it is not an external-accuracy claim. The accepted caller values remain the
returned natal values after this independent witness.
The forward Sun-to-Moon ecliptic angle and existing synodic_phase_state retain
their declared convention. Coarse state labels use 45-degree quadrant boundaries;
waxing is the directed angle below 180 degrees, waning the other half-cycle.
They are distinct from the physical Sun–Moon–Earth angle and physical illuminated
fraction calculated by phase_angle and illuminated_fraction. Every lunar
ephemeris product is bound with use_reader_override(engine._reader) to the
startup-owned kernel reader. No ecliptic illumination approximation is used.
last_new_moon and last_full_moon find the strictly preceding geocentric
conjunction and opposition. The latest is marked as prenatal syzygy. Returned
event longitudes use the requested zodiac and event-specific true-mode ayanamsa.
Event Julian Days are UT1; UTC display strings use the engine's admitted inverse
UT1-to-civil-UTC conversion, including its historical proxy policy.
Each event Moon longitude is compared with the selected natal planets through
aspects_between(tier=0, orb_factor=1): the existing five major aspect definitions
and default orbs. Contacts preserve target angle, actual separation, deviation
and applied orb ceiling. No speeds or applying/separating claims are fabricated.
The policy is independent of the natal wheel's aspect display settings.
Verification scope
tests/server/test_server_natal_discovery.py covers direct request admission,
selected-only chains, cycles and multiple sinks, missing ruler stops, Bucket
metric scope, partial selection, unknown time, source timestamp preservation,
real-kernel Tropical/Sidereal lunar composition and strict preceding selection at
a solved event. These are transport, policy and geometric invariant checks;
they do not independently revalidate the existing substrate against an external
astronomical authority.