chore(release): bump to v1.6.0 — mirror (dual-send) docs

Version bump across series3_watcher.py / tray / settings dialog / installer.iss.
CHANGELOG + README document the optional best-effort mirror server
(MIRROR_API_URL / MIRROR_SFM_URL / MIRROR_SFM_STATE_FILE, default off).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-25 05:54:20 +00:00
parent 92ebbd6537
commit e6e4c94f19
6 changed files with 53 additions and 6 deletions
+23 -2
View File
@@ -1,4 +1,4 @@
# Series 3 Watcher v1.5.0
# Series 3 Watcher v1.6.0
Monitors Instantel **Series 3 (Minimate)** call-in activity on a Blastware server. Runs as a **system tray app** that starts automatically on login, reports heartbeats to terra-view, and self-updates from Gitea.
@@ -124,6 +124,27 @@ Combine both for a fully controlled rollout: seed-state to skip the deep archive
---
## Mirror (Dual-Send) — v1.6.0+
The watcher can post every heartbeat and event to a **second ("mirror") server** in addition to the primary — useful for keeping a standby box (e.g. the office NAS) as a continuous replica during a server migration, so the eventual cutover is a non-event. **Default off.**
The mirror rides along with the primary — there is no separate enable flag:
- **Heartbeat mirror** is active when `API_ENABLED = true` **and** `MIRROR_API_URL` is set. After the primary heartbeat POST, the same payload is fired at the mirror.
- **Event mirror** is active when `SFM_FORWARD_ENABLED = true` **and** `MIRROR_SFM_URL` is set. Events are re-forwarded to the mirror using a **separate** sha256 state file (`MIRROR_SFM_STATE_FILE`, blank → `<log dir>/sfm_forwarded_mirror.json`).
**The mirror can never delay or fail the primary.** The heartbeat mirror is fully wrapped and bounded by the API timeout. The event mirror runs a quick reachability probe (~3 s) first and skips the pass if the mirror server is down — skipped events stay pending in the mirror state and deliver when it returns, so nothing is lost. All mirror exceptions are swallowed-and-logged; the primary path stays exactly as reliable as before.
| Key | Description |
|-----|-------------|
| `MIRROR_API_URL` | Second heartbeat base URL, e.g. `http://10.0.0.x:8001` (blank = off) |
| `MIRROR_SFM_URL` | Second SFM base URL, e.g. `http://10.0.0.x:8200` (blank = off) |
| `MIRROR_SFM_STATE_FILE` | Path to the mirror's sha256 state file. Blank → `<log dir>/sfm_forwarded_mirror.json` |
**Seeding for a migration.** To re-deliver only the gap since a one-time replica snapshot, copy the primary state file to the mirror state file and drop entries whose `forwarded_at` is after the snapshot. SFM-side dedup covers any overlap. See [`docs/mirror-dual-send-design.md`](docs/mirror-dual-send-design.md).
---
## Tray Icon
| Colour | Meaning |
@@ -167,7 +188,7 @@ where the corresponding server-side work lives.
## Versioning
Follows **Semantic Versioning**. Current release: **v1.5.0**.
Follows **Semantic Versioning**. Current release: **v1.6.0**.
See `CHANGELOG.md` for full history.
---