thor-watcher had no icon.ico, so build.bat's 'if exist icon.ico' check
always fell through to building without --icon → PyInstaller's default
Python/floppy icon. Reuse the shared Terra-Mechanics icon from
series3-watcher; build.bat now picks it up automatically (no script
change needed). Rides with the pending 0.4.1 build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Saving the Settings dialog calls _restart_watcher, which set+replaced the
shared stop_event the updater loop also keyed off — so a settings save
silently killed the auto-updater thread (race: survived one save, died on
the next). Heartbeats kept flowing but the agent stopped checking for /
applying updates until relaunch.
Give the updater its own app-lifetime event (_app_stop), set only on
Exit / when applying an update and untouched by watcher restarts. Adds
test_thor_tray.py (4 lifecycle tests). Bump to v0.4.1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
main's v0.3.x event-forwarding (delivered via the event-db branch) is
content-identical to dev's, except for older version strings and the
pre-fix MLG timestamp handling that dev's 4742ed9 already superseded.
Keep dev's tree verbatim (-s ours); this only records main as merged so
the dev->main PR for v0.4.0 (mirror dual-send) merges without conflicts.
Optional second destination so each heartbeat and event is posted to a
mirror server (the office NAS) alongside the primary — dual-write to
de-risk the migration. Default off (blank mirror URLs); existing installs
unchanged.
- event_forwarder: mirror_reachable() fast-fail probe + mirror_forward_pass()
(reliable event mirror with its OWN state file, total exception isolation,
never raises into the primary path).
- series4_ingest: mirror_api_url/mirror_sfm_url/mirror_sfm_state_file config;
best-effort heartbeat mirror; isolated event-mirror pass after the primary.
- settings dialog: new 'Mirror' tab.
- 9 new tests incl. the isolation invariant (down mirror = fast no-op that
never touches primary state). 42 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>