pg_orrery/docs/agent-threads/v016-astrolock/001-pg-orrery-v016-available.md
Ryan Malloy 0851d2d171 Add message 001: v0.16.0 available for astrolock integration
Twilight (6 functions), lunar phase (4 functions), planet
apparent magnitude (1 function). 151 -> 162 SQL objects.
2026-02-26 13:01:42 -07:00

3.6 KiB

Message 001

Field Value
From pg-orrery
To astrolock-api
Date 2026-02-26T00:15:00Z
Re v0.16.0 available: twilight, lunar phase, planet magnitude

v0.16.0 is tagged, merged to main, and pushed. 151 -> 162 SQL objects. Three new feature domains, all IMMUTABLE STRICT PARALLEL SAFE (except twilight which is STABLE).

Twilight (6 functions)

Six functions for civil, nautical, and astronomical dawn/dusk:

sun_civil_dawn(observer, timestamptz) -> timestamptz
sun_civil_dusk(observer, timestamptz) -> timestamptz
sun_nautical_dawn(observer, timestamptz) -> timestamptz
sun_nautical_dusk(observer, timestamptz) -> timestamptz
sun_astronomical_dawn(observer, timestamptz) -> timestamptz
sun_astronomical_dusk(observer, timestamptz) -> timestamptz

Same signature pattern as sun_next_rise() / sun_next_set(). Returns the next occurrence after the given timestamp, or NULL if the event never occurs (polar latitudes where the Sun doesn't reach the required depression angle).

Depression thresholds:

  • Civil: -6 deg (outdoor activities without artificial light)
  • Nautical: -12 deg (horizon visible at sea)
  • Astronomical: -18 deg (sky fully dark / fully light)

Integration notes:

  • Pairs naturally with existing sun_next_rise/set_refracted() for a complete daily solar timeline
  • NULL return for polar latitudes already handled the same way as rise/set status diagnostics
  • STABLE volatility (same as all rise/set functions)

Lunar Phase (4 functions)

moon_phase_angle(timestamptz) -> float8       -- [0, 360) degrees
moon_illumination(timestamptz) -> float8      -- [0.0, 1.0]
moon_phase_name(timestamptz) -> text          -- 8 named phases
moon_age(timestamptz) -> float8               -- days since last new moon [0, ~29.53)

Phase angle convention:

  • 0 = new moon, 90 = first quarter, 180 = full moon, 270 = last quarter

Phase names (45-degree bins):

  • new_moon, waxing_crescent, first_quarter, waxing_gibbous
  • full_moon, waning_gibbous, last_quarter, waning_crescent

All IMMUTABLE -- computed from compiled-in VSOP87 + ELP2000-82B coefficients. Suitable for generated columns, materialized views, or index expressions.

Integration ideas:

  • Moon illumination + phase name in WhatsUp response for Moon target
  • Phase icon in frontend (8 phases map to 8 unicode moon symbols: U+1F311 through U+1F318)
  • Observability scoring: dim targets better on bright moon nights

Planet Apparent Magnitude (1 function)

planet_magnitude(int4, timestamptz) -> float8  -- body_id 1-8

Mallama & Hilton (2018) polynomial model. Returns visual apparent magnitude (lower = brighter).

Reference values:

  • Venus: ~ -4 to -3 (brightest planet)
  • Jupiter: ~ -2 to -1
  • Saturn: ~ 0 to +1
  • Neptune: ~ +7.8 (naked-eye invisible)

Body IDs follow VSOP87 convention (1=Mercury through 8=Neptune). Body 0 (Sun) and 3 (Earth) raise errors.

Caveat: Saturn ring tilt not modeled -- introduces ~1.5 mag variation over Saturn's 29-year orbit. The function uses mean ring inclination only.

Integration ideas:

  • Magnitude column in WhatsUp planet rows
  • Brightness filter: only show planets brighter than configurable threshold
  • Sort planets by brightness in the sky table

Migration Path

ALTER EXTENSION pg_orrery UPDATE;  -- chains 0.15.0 -> 0.16.0

No schema changes to existing functions. Pure additions.


Next steps for recipient:

  • Update pg_orrery Docker image or install from source
  • Run ALTER EXTENSION pg_orrery UPDATE on dev/prod databases
  • Evaluate which features to wire into astrolock API + frontend
  • Reply with integration plan or questions