Three-tier discovery: pg-orrery-catalog in PATH, sibling dev
checkout, or original build_catalog.py + curl. Indexes use
IF NOT EXISTS for idempotent re-runs.
Bug: inner_consistent used sma_low for footprint calculation, but
ground footprint grows with altitude. High-SMA bins (GTO, HEO)
need sma_high to compute the maximum footprint — using sma_low
caused 453 false negatives at high-latitude observers (Tromsoe).
Fix: use sma_high (not sma_low) in L1 inclination pruning.
Added regression test: GTO-debris (inc 5 deg, e=0.73) at Tromsoe
must return identical results from seqscan and index scan.
Benchmark on 65,886-object catalog (full Space-Track including
decayed): 80-92% pruning, zero false negatives across 7 query
patterns. SP-GiST beats seqscan for high-latitude observers.
Space-Track USSPACECOM catalog: 29,784 objects from full GP query.
Benchmark shows SP-GiST index reaches parity with seqscan at 30k:
- Delta: +1.6ms (14k) -> +0.9ms (20k) -> +0.0ms (30k)
- Planner voluntarily chooses Index Only Scan at this scale
- Zero heap fetches (all data served from index pages)
- 75.9% candidate pruning on 2h/10deg query
Archive includes TLEs from Space-Track, TLE API, and SatNOGS.
New docs:
- guides/pass-prediction.mdx: two-stage workflow (SP-GiST filter
then SGP4 propagation), query window comparison tabs, GiST/SP-GiST
coexistence example
- reference/operators-gist.mdx: &? operator signature and description,
observer_window type reference, SP-GiST operator class docs with
eccentricity/HEO limitation aside
Benchmarks on 14,376 CelesTrak active satellites:
- SP-GiST index: 2,344 kB, builds in 19 ms
- GiST index: 2,904 kB, builds in 45 ms
- Consistency: 0 false negatives, 0 false positives
- At 14k catalog size, seqscan (~6 ms) still beats index scan (~8 ms)
due to low page count; cross-over expected at ~100k objects