Skip to content

salvage(swarm): hourly scanner, event journal, space weather, scan severity - #111

Merged
THOClabs merged 1 commit into
mainfrom
salvage/swarm-capabilities
Aug 7, 2026
Merged

salvage(swarm): hourly scanner, event journal, space weather, scan severity#111
THOClabs merged 1 commit into
mainfrom
salvage/swarm-capabilities

Conversation

@THOClabs

@THOClabs THOClabs commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Summary

Recovers the four unmerged capabilities identified by docs/BRANCH_CLEANUP.md before the 86-branch purge deletes their only copies, adapted to current main (post-#108/#109 NEO client API):

Capability Source branch Files Tests
Hourly event scanner feat/neo-hourly-scanner hourly_scanner.py 34
Event journal (SQLite) nightwatch/neo-tracking-and-event-journal event_journal.py 36
Space weather (NOAA SWPC) feat/neo-space-weather-hourly-scan space_weather.py 34
Scan severity + CNEOS sign fix feat/hourly-event-scanner scan_severity.py, fireball_client.py 38

Key adaptations

  • Scanner rewired from swarm-era neo_client to main's close_approach_client (field renames) with a rank-preserving threat map: JPL WATCH/ALERT (<2 LD, PHA, <1 LD) → scanner CLOSE/ALERT (the alerting tiers).
  • All salvaged modules converted datetime.utcnow() → timezone-aware UTC (same class of bug fix(neo_feed): missing-distance false ALERT + UTC feed window #109 fixed in neo_feed_client).
  • fireball_client._parse_fireballs: CNEOS returns unsigned lat/lon + lat-dir/lon-dir — southern/western events were previously mislocated; now signed correctly.
  • space_weather._parse_solar_wind logs a warning when the feed is partial so an outage can't silently report a quiet sun.
  • generate_prayer_of_approach + NEO count in status prayer (additive lexicon salvage).

Test plan

  • 142 new unit tests pass locally; meteor_tracking suite fully green.
  • Pre-existing local failures in onstepx/camera suites are environment-only (missing astropy/pyserial) and untouched by this diff — CI is authoritative.

Part 1/Step 1 of the v0.1.1 main-only consolidation.

🤖 Generated with Claude Code


Note

Medium Risk
New background scanning, external NASA/NOAA dependencies, and SQLite persistence expand operational surface; the CNEOS coordinate fix materially affects alert geography but is a targeted parser change.

Overview
Salvages four NIGHTWATCH capabilities into meteor_tracking: an always-on hourly scanner (CNEOS fireballs + JPL close approaches + shower calendar), a SQLite event journal with Hopi-ring classification and hourly/daily Lexicon summaries, a NOAA SWPC space weather client, and scan severity helpers for prioritizing alerts.

The package exports journal types and lazy loaders for the scanner, space weather, and severity. Lexicon adds generate_prayer_of_approach and NEO approach counts on status prayers. The scanner maps close_approach_client.ThreatLevel to scanner alert tiers (CLOSE/ALERT drive has_alerts) and uses timezone-aware UTC in scan loops.

fireball_client now applies CNEOS lat-dir / lon-dir so southern/western events get correct signed coordinates (fixes mislocated fireballs). space_weather warns when solar-wind feeds are partial so quiet defaults cannot mask an outage.

Large unit test coverage is added for journal, scanner, severity, and space weather (~140 tests).

Reviewed by Cursor Bugbot for commit 58c54a0. Bugbot is set up for automated code reviews on this repo. Configure here.

…verity

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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 7 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

self._last_scan = datetime.fromisoformat(state["last_scan"])
self._known_event_ids = set(state.get("known_event_ids", []))
except (json.JSONDecodeError, KeyError) as e:
logger.warning(f"Could not load scanner state: {e}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scanner state never reloads

High Severity

The HourlyEventScanner's _load_state method is never called, so _known_event_ids and _scan_count reset on restart. This causes previously seen fireballs and NEO approaches to be re-alerted.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

},
threat_level="INFO",
)
shower_events.append(shower_event)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shower events repeat every scan

Medium Severity

Meteor shower events (active and upcoming) are not deduplicated against _known_event_ids during each scan. This inflates the events_found count and causes repeated shower entries in the scan history and prayer output.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

SELECT * FROM sky_events
WHERE timestamp >= ? AND timestamp < ?
ORDER BY timestamp
""", (start.isoformat(), end.isoformat())).fetchall()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Journal timestamps compare inconsistently

Medium Severity

EventJournal stores each event’s timestamp.isoformat() as-is while create_hourly_entry, get_recent_events, and default create_daily_summary query with timezone-aware UTC bounds (+00:00). Naive timestamps from CNEOS, CAD, or tests compare as strings against aware bounds and can fall outside ranges—hourly and daily rollups may omit valid events.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

fireball: Fireball,
home_lat: float = 38.9,
home_lon: float = -117.4,
bright_threshold: float = -8.0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default home coords disagree

Medium Severity

New scan_severity helpers default home to 38.9, -117.4, while EventJournal and HourlyEventScanner use Nevada 39.5, -117.0. Callers using defaults get different distance zones and fireball proximity severity than the journal and scanner for the same event.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

lines = []
hour_str = self.hour_start.strftime("%Y-%m-%d %H:00")
lines.append(f"nightwatch-journal. varek-hour: {hour_str}")
lines.append(f"home-wit: {self.site_name} ({self.site_lat:.1f}N {abs(self.site_lon):.1f}W)")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prayer output assumes west longitude

Low Severity

HourlyEntry.to_prayer and daily summary text format longitude as {abs(site_lon):.1f}W regardless of sign. A site with eastern longitude is mislabeled west in journal prayers.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

event.ring = classify_ring(
self.home_lat, self.home_lon,
event.latitude, event.longitude
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ring never auto-classified from coords

High Severity

record_event only recomputes ring when event.ring is None, but SkyEvent requires a non-optional EventRing, so typical events keep a placeholder like GLOBAL even when coordinates imply ZENITH or nearer rings. Hourly prayers and ring summaries can mislabel proximity.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

row = conn.execute(
"SELECT prayer FROM hourly_entries WHERE hour_start = ?",
(hour_start.isoformat(),)
).fetchone()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hourly prayer query ignores site

Low Severity

get_hourly_prayer selects by hour_start only, while hourly_entries has a unique key on (hour_start, site_name). Multiple sites in one database can return the wrong hour’s prayer for the current journal instance.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 58c54a0. Configure here.

@THOClabs
THOClabs merged commit 10a5495 into main Aug 7, 2026
10 checks passed
@THOClabs
THOClabs deleted the salvage/swarm-capabilities branch August 7, 2026 04:16
THOClabs added a commit that referenced this pull request Aug 7, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant