Recover NASA NEO close-approach + feed clients (salvage from March swarm) - #108
Conversation
Salvages the one piece of genuinely-unmerged work buried in the March 2026 branch swarm (~60 near-duplicate AI-generated branches for this feature, none merged): the NASA/JPL CNEOS Close Approach Data client and the NASA NEO Feed API client, for pre-entry near-Earth-object awareness at the Nevada site. - close_approach_client.py (372 lines): CADClient, CloseApproach, ThreatLevel, diameter-from-H estimation, approach-prayer formatting, fetch_upcoming_approaches. - neo_feed_client.py (186 lines): NEOFeedClient over the NASA NEO Feed API. - Wired into the package via lazy loaders (get_close_approach_client / get_neo_feed_client), matching the existing aiohttp-lazy-import pattern. - 63 salvaged tests; meteor_tracking suite 86 passed. Self-contained (stdlib + aiohttp, already a declared dep) — no dependency on the since-refactored meteor_service, so it drops onto current main cleanly. Recovered onto current main rather than merging any of the 45-commits-behind swarm branches, which are near-duplicates and would conflict. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SKZMQ755R7q38SKqJsCQsg
…nal->|None, import order) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SKZMQ755R7q38SKqJsCQsg
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f09165b. Configure here.
| miss_distance = ca.get('miss_distance', {}) | ||
| dist_au = float(miss_distance.get('astronomical', 0)) | ||
| dist_km = float(miss_distance.get('kilometers', 0)) | ||
| dist_ld = dist_au / LD_TO_AU if dist_au else 0 |
There was a problem hiding this comment.
Missing distance defaults to alert
High Severity
When miss_distance.astronomical is absent, parsing uses 0 for distance_au and distance_ld, so CloseApproach.threat_level can classify the object as ALERT despite unknown or non-zero kilometer data.
Reviewed by Cursor Bugbot for commit f09165b. Configure here.
| if start_date is None: | ||
| start_date = date.today() | ||
| if end_date is None: | ||
| end_date = start_date + timedelta(days=7) |
There was a problem hiding this comment.
NEO feed uses local date
Medium Severity
Default start_date uses date.today() (local calendar date) while the CAD client and other NEO timing use UTC, so the implicit feed window can shift by a day relative to close-approach queries near timezone boundaries.
Reviewed by Cursor Bugbot for commit f09165b. Configure here.
Explains the 87-branch pileup (a March 2026 NEO/hourly-scan swarm of ~59 near- duplicate AI branches + 15 already-squash-merged-this-session + 12 old reviews + legacy master) and classifies every branch. All are safe to delete; the NEO core was salvaged to main (#108/#109). Flags three distinct un-salvaged features (hourly scanner, event journal, space-weather client) as salvage candidates before the swarm is deleted. scripts/delete_stale_branches.sh is turnkey (remote deletion is blocked from the automation sandbox, so it's run locally). Claude-Session: https://claude.ai/code/session_01SKZMQ755R7q38SKqJsCQsg Co-authored-by: Claude <noreply@anthropic.com>
…verity (#111) Recovers the four capabilities flagged by docs/BRANCH_CLEANUP.md before the swarm branches are deleted, adapted to the post-#108/#109 API on main: - hourly_scanner.py (from feat/neo-hourly-scanner): autonomous hourly scan of CNEOS fireballs, JPL CAD close approaches, and shower calendar. Adapted to close_approach_client (field renames), rank-preserving THREAT_LEVEL_MAP (JPL WATCH/ALERT -> scanner CLOSE/ALERT), timezone-aware UTC. - event_journal.py (from nightwatch/neo-tracking-and-event-journal): SQLite sky-event journal with Hopi-ring classification; timezone-aware UTC. - space_weather.py (from feat/neo-space-weather-hourly-scan): NOAA SWPC Kp, solar wind, alerts; UTC-aware parsing + warning when the feed is partial so outages cannot masquerade as quiet conditions. - scan_severity.py (from feat/hourly-event-scanner): severity classification with tests. - fireball_client.py: CNEOS lat-dir/lon-dir sign fix (coords are unsigned in the API; S/W must negate) from feat/hourly-event-scanner. - lexicon_prayers.py: generate_prayer_of_approach + status prayer NEO count (from the event-journal branch). - __init__.py: eager event_journal/lexicon exports; lazy loaders for hourly scanner, space weather, scan severity. 142 new unit tests, all passing. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
#112) Preserves the durable content of three open-PR branches before the v0.1.1 branch purge closes them: - .claude/agents/ (7 review subagents) + .claude/commands/full-review.md from PR #93's branch — repo-state-independent review tooling; the stale July review reports on that branch are intentionally NOT taken. - docs/design/ Claude Design frontend prompt pack (3 files) from PR #92's branch — targets the v0.2 frontend; NEO data-model sections predate #108/#109 and need a refresh before use (noted in its provenance table). - docs/audits/ archive of AUDIT_LANDSCAPE.md + REVIEW_RECONCILIATION.md from PR #90's branch, with HISTORICAL SNAPSHOT headers — findings were fixed by #94-#110; preserved as engineering history. Its STALE_BRANCH_TRIAGE.md is dropped (superseded by #110). Part 1/Step 2 of the v0.1.1 main-only consolidation. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ry tests (#114) Recovered from the legacy master branch before its deletion: a purely additive spiral search-route generator (Waypoint, SearchRoute, generate_spiral_route, destination_point, initial_bearing) for hopi_circles, plus the comprehensive test suites for hopi_circles and trajectory (the only content of master's 8 unique commits not already superseded by #108/#109/#111). All tests pass against current main. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>


Summary
Recovers the one piece of genuinely-unmerged work from the March 2026 branch swarm (~60 near-duplicate AI-generated branches for this feature, none of which ever merged): NASA near-Earth-object tracking clients for pre-entry awareness at the Nevada site. Brought onto current
mainas clean standalone additions rather than merging any 45-commits-behind swarm branch.What's included
services/meteor_tracking/close_approach_client.py(372 lines) — NASA/JPL CNEOS Close Approach Data client:CADClient,CloseApproach,ThreatLevel,estimate_diameter_from_h,generate_approach_prayer,fetch_upcoming_approaches.services/meteor_tracking/neo_feed_client.py(186 lines) — NASA NEO Feed API client (NEOFeedClient).__init__.pylazy loadersget_close_approach_client()/get_neo_feed_client(), matching the existing aiohttp-lazy-import pattern.tests/unit/test_neo_client.py,tests/unit/test_neo_feed_client.py(1,245 lines).Why this way
The feature spawned ~60 near-duplicate branches (NEO client × 29, hourly scanner × 10, event journal × 9, space-weather × 2, …), all 45 commits behind
main. Merging them would be conflict chaos. These two clients are the coherent, self-contained core (stdlib +aiohttp, already a declared dependency; no dependency on the since-refactoredmeteor_service), so they drop onto currentmaincleanly.Testing
pytest tests/unit/test_neo_client.py tests/unit/test_neo_feed_client.py→ 63 passedpytest tests/unit/test_meteor_tracking.py(regression) + NEO → 86 passedNotes
The broader swarm ideas not included here (hourly scanner, event journal, space-weather client) can be salvaged in follow-ups if wanted; they're more entangled with the old
meteor_service. This PR recovers the crown-jewel NEO capability; the remaining swarm branches are slated for deletion as stale duplicates.🤖 Generated with Claude Code
Generated by Claude Code
Note
Low Risk
Additive library code and tests with no changes to auth, persistence, or existing meteor service behavior; external HTTP to public NASA APIs only.
Overview
Adds pre-entry near-Earth object awareness to NIGHTWATCH meteor tracking, complementing existing post-entry fireball APIs.
A new JPL CNEOS Close Approach Data client (
CADClient) fetches upcoming passes, maps them to a sharedCloseApproachmodel withThreatLevel(routine → alert), diameter estimates from H magnitude, and Lexicon-stylegenerate_approach_prayeroutput. A second NASA NeoWs feed client (NEOFeedClient) reuses the same types and supplies officialis_potentially_hazardous_asteroidflags where CAD only uses a heuristic.Package entry points follow the existing pattern: lazy
get_close_approach_client()andget_neo_feed_client()inservices/meteor_tracking/__init__.py(aiohttp loaded only when called). Unit coverage is intest_neo_client.pyandtest_neo_feed_client.py; nothing in this diff wires the clients intometeor_serviceor a scheduler yet.Reviewed by Cursor Bugbot for commit f09165b. Bugbot is set up for automated code reviews on this repo. Configure here.