Recurrence horizon guard: warn when resolving years beyond the lookup tables (2035) #61

Closed
opened 2026-07-15 15:38:34 +00:00 by claude-bot · 1 comment
Contributor

From the 2026-07-15 review follow-ups. The hindu_lunar and some computed recurrence functions use pre-computed tables ending at 2035 (services/recurrence.py). Resolution outside the range raises ValueError, which the loaders catch and log — so from 2036 those events (Diwali, Lunar New Year, …) silently vanish from the calendar.

  • On startup / yearly generation, when a requested year exceeds any table's coverage, log a prominent warning and surface it as a UI header alert (the alert surface already exists)
  • List the affected events by name in the warning
  • Extend the tables while at it (cheap to add 2036–2045 now)
  • Document the horizon and how to extend it
From the 2026-07-15 review follow-ups. The `hindu_lunar` and some `computed` recurrence functions use pre-computed tables ending at 2035 (`services/recurrence.py`). Resolution outside the range raises `ValueError`, which the loaders catch and log — so from 2036 those events (Diwali, Lunar New Year, …) silently vanish from the calendar. - [ ] On startup / yearly generation, when a requested year exceeds any table's coverage, log a prominent warning and surface it as a UI header alert (the alert surface already exists) - [ ] List the affected events by name in the warning - [ ] Extend the tables while at it (cheap to add 2036–2045 now) - [ ] Document the horizon and how to extend it
claude-bot added this to the v1.1.0 milestone 2026-07-15 15:38:34 +00:00
Author
Contributor

Done in #113, except the table extension, which is split to #114.

  • On startup, when a requested year exceeds any table's coverage, log a prominent warning and surface it as a UI header alert — one aggregated warning replaces the per-event lines, plus GET /api/v1/recurrence-horizon and a banner in the app shell
  • List the affected events by name in the warning
  • Extend the tables while at it#114
  • Document the horizon and how to extend it — docs/troubleshooting.md, "Recurrence horizon"

Why the extension moved

This asked to extend 2036–2045 as "cheap to add now". It isn't, and the reason is worth having on record:

  • holidays stops at 2035 itselfcountry_holidays("IN", years=[2036]) warns "available only from 2001 to 2035" and returns nothing for Diwali; no Chinese New Year entries either. The obvious escape hatch has the same horizon.
  • astral has no solstice or equinox function — sunrise, sunset, golden hour, sun_declination, but nothing yielding an equinox instant.

So it needs an ephemeris library, a Chinese-calendar library, and a panchanga source for Diwali (tithi-based, not a plain lunar phase). Writing sixty dates by hand would have been silently wrong in a way far harder to notice than the events being absent — which is precisely what the guard now reports loudly. #114 carries the routes ranked by tractability, and the advice to validate any computation against the sixteen known years first.

table_horizon() is derived from the table data, so #114 will move it automatically once every table is extended — note it's the minimum across tables, so extending only some changes nothing.

Closing.

**Done in #113**, except the table extension, which is split to **#114**. - [x] On startup, when a requested year exceeds any table's coverage, log a prominent warning and surface it as a UI header alert — one aggregated warning replaces the per-event lines, plus `GET /api/v1/recurrence-horizon` and a banner in the app shell - [x] List the affected events by name in the warning - [ ] ~~Extend the tables while at it~~ → **#114** - [x] Document the horizon and how to extend it — `docs/troubleshooting.md`, "Recurrence horizon" ### Why the extension moved This asked to extend 2036–2045 as *"cheap to add now"*. It isn't, and the reason is worth having on record: - **`holidays` stops at 2035 itself** — `country_holidays("IN", years=[2036])` warns *"available only from 2001 to 2035"* and returns nothing for Diwali; no Chinese New Year entries either. The obvious escape hatch has the same horizon. - **`astral` has no solstice or equinox function** — sunrise, sunset, golden hour, `sun_declination`, but nothing yielding an equinox instant. So it needs an ephemeris library, a Chinese-calendar library, and a panchanga source for Diwali (tithi-based, not a plain lunar phase). Writing sixty dates by hand would have been silently wrong in a way far harder to notice than the events being absent — which is precisely what the guard now reports loudly. #114 carries the routes ranked by tractability, and the advice to validate any computation against the sixteen known years first. `table_horizon()` is derived from the table data, so #114 will move it automatically once every table is extended — note it's the **minimum** across tables, so extending only some changes nothing. Closing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Iris-WLED#61
No description provided.