A research toy for testing whether temporal signals — astrological, solar, seasonal, cyclical — carry measurable predictive value.
Every signal here starts life as a hypothesis, not a truth. Signals earn inclusion through measured performance or get dropped.
The headline object is the United States natal chart, mapped with real ephemeris math and explorable against documented history.
No astrological match is ever displayed without its denominator.
Ask what the sky was doing when COVID hit and a normal astrology tool says "Saturn conjunct Pluto, January 2020" and stops. This one says:
● HIT 2020-01-12 Capricorn → COVID-19 pandemic, Trump impeachment
○ miss 1947-08-11 Leo → no tier-1 event in window
○ miss 1851-10-09 Taurus → no tier-1 event in window
...
Coincided with an event ........ 4 of 8 (50%)
Base rate for ANY window ....... 43%
Lift ........................... 1.17× p = 0.47
→ Not distinguishable from chance.
The 1914 and 2020 conjunctions are memorable. The 1786, 1819, 1851 and 1947 ones are not, and that asymmetry lives in the observer, not the sky. A tool that surfaces only the hits is a confirmation-bias engine. Showing the full set is the entire justification for building this.
node cli.mjs baselineStart there. It reports how eventful US history is before any astrology enters the picture — the numbers every later result has to beat.
node cli.mjs compareThe four candidate US charts side by side. The most educational single output in the tool.
node cli.mjs baserate "Saturn conjunction Pluto"The headline claim, with its denominator attached.
| Command | Does |
|---|---|
baseline |
How often do arbitrary windows contain a major event? Read this first. |
compare |
All four US chart variants side by side |
chart [variant] |
One US natal chart (sibly, rudhyar, scorpio, dawn, or chart list) |
natal --date ... |
A personal chart — run bare to see arguments |
zodiac |
Tropical vs sidereal — and precisely what it does and doesn't change |
sky <date> |
Planetary positions and aspects on any date |
transits <date> |
Transits to the US chart |
baserate "<aspect>" |
Every occurrence + hit rate + base rate + caveats |
explore <event> |
The sky at a documented event |
events |
The event corpus |
Flags: --orbs tight|standard|wide|exact · --window <days> · --tier 1|2 · --start-only · --variant <name> · --houses whole|equal · --zodiac tropical|sidereal · --ayanamsa lahiri|fagan_bradley|krishnamurti|raman
Both are supported (--zodiac sidereal, four ayanamsa systems). The zodiac command exists to make one structural fact unmissable: sidereal is a rigid rotation of the whole frame, so aspects are identical in both systems — to floating-point precision. Saturn conjunct Pluto is conjunct in both, on the same dates, to the same arcsecond. The tropical/sidereal disagreement is real, but it's an argument about where to draw the sign boundaries, not about what the planets are doing — which is why every base-rate result in this tool is zodiac-agnostic. Two honest caveats the command also surfaces: the ayanamsa systems disagree with each other by up to 2.3°, and neither zodiac's equal 30° signs matches the wildly unequal actual constellations (Virgo spans ~44° of ecliptic, Scorpius ~7°, and Ophiuchus sits on the ecliptic without being a sign at all).
node test.mjs27 checks against published reference values. Run this after touching anything in src/.
| File | Job |
|---|---|
src/ephemeris.mjs |
body → geocentric ecliptic longitude, ecliptic of date |
src/chart.mjs |
natal charts, US presets, LMT handling. Birth data is always a parameter |
src/aspects.mjs |
aspect detection with configurable orb profiles |
src/transits.mjs |
transits, and findExactAspects — enumerate every occurrence in a range |
src/baserate.mjs |
the denominator engine |
src/events.json |
91 documented events, tiered and sourced |
EVENT_SELECTION_CRITERIA.md |
written before the corpus, to constrain it |
Ephemeris is astronomy-engine — pure JS, MIT, no native build step, accurate to ~1 arcminute, valid 1700–2200.
Ecliptic of date, not J2000. The tropical zodiac is anchored to the equinox of the moment. Precession runs ~50″/year, so J2000 coordinates would put every 1776 planet ~3.5° off — more than a third of a sign. The code uses Rotation_EQJ_ECT.
Multiple exact passes are one occurrence. Slow pairs often go exact three times over a year or two as they retrograde. That's one conjunction, not three; counting them separately would triple-count the famous ones (1914 was a triple passage, 2020 was single) and corrupt every rate.
The Sibly chart reproduces to within 3 arcminutes on all ten bodies, and the Ascendant lands on 12°21′ Sagittarius — the canonical published value to the arcminute. Saturn–Pluto conjunctions enumerate as 1786, 1819, 1851, 1883, 1914‑15, 1947, 1982, 2020, matching the historical record, with the 2020 exact date landing on January 12.
Two published Sibly values are wrong and this tool disagrees with them on purpose. Many printed Sibly charts mark Jupiter and Saturn retrograde on 1776‑07‑04. Both were direct, and you can check it without an ephemeris:
- Jupiter was conjunct the Sun. A body at solar conjunction is at its fastest direct motion — it cannot be retrograde.
- Saturn's retrograde loop centres on its opposition to the Sun. With Saturn in Libra, that falls with the Sun in Aries, around April. Saturn stationed direct ~June 16, three weeks before the Declaration.
The test suite locks both in.
There is no agreed United States chart. July 4 1776 is documented; the hour is not. Every candidate time yields a different Ascendant, and therefore a completely different set of houses.
compare shows exactly what's at stake:
sibly 17:10 LMT 12°21' Sagittarius
rudhyar 02:13 LMT 7°14' Gemini
scorpio 12:00 LMT 10°35' Libra
dawn 04:50 LMT 14°40' Cancer
Saturn 14°48' Libra spread 0.02° houses 11/5/1/4
Neptune 22°25' Virgo spread 0.01° houses 10/4/12/3
The planets agree to a hundredth of a degree. Every single one lands in a different house in all four columns. Any reading that leans on a house placement leans on an hour nobody recorded.
Phase 1 is honest exploration. Exploration, not evidence — the CLI prints that on every screen.
Phase 2 — the part that could actually produce an answer. Retrospective analysis cannot settle this no matter how the numbers land: the window length, orb profile, tier threshold and event list were all chosen by someone who could see the data. That's more than enough freedom to manufacture a finding from noise.
The test that would mean something is prospective and pre-registered:
- 20–30 forward-looking predictions derived from transits
- each with a resolution date and objective, pre-stated criteria
- locked before any outcome is known
- scored a year later against a chance baseline
Cheap to set up, immune to p-hacking, costs calendar time rather than attention.
This is a sealed sandbox. It does not read from, write to, or import anything belonging to any other project on this machine, and nothing it produces is a recommendation to act on. If it ever earns its way into a production system, that is a separate and deliberate later decision.
Built 2026‑07‑23, for shits and gigs, honestly.