fix: opposite_rearm/rearm alerts + /resume unified + canary-pause UX guards

Trei găuri observate în sesiunea 2026-04-21:

A. _handle_tick nu avea branch pentru reason=opposite_rearm (PRIMED_* ↔
   ARMED_opus) sau reason=rearm (PRIMED_* → ARMED_* aceeași direcție). La
   17:45 yellow a trecut FSM-ul PRIMED_BUY→ARMED_SELL corect, dar zero alert
   pe Telegram. Adaugă helper _emit_arm_alert (DRY cu branch-ul arm existent)
   și două branch-uri noi cu kind=opposite_rearm / kind=rearm.

B. Canary drift se curăța doar cu /resume force — user ușor confundă
   /set_interval cu „relansare" și rămâne în drift-pause (cazul 18:09 azi).
   /resume acum curăță user_paused + canary.resume() într-o singură comandă.
   /resume force rămâne alias acceptat (muscle memory legacy).

C. Heartbeat-ul afișa „activ ARMED_SELL" deși detecția era oprită de 3 ore
   (state FSM înghețat). Extract _build_heartbeat_alert care arată
   „⚠️ pauzat (drift)" + „[drift-pause]" când canary.is_paused.

Guard-uri pentru comenzi când canary e paused:
- /set_interval: refuzat cu warn „Trimite /resume"
- /ss: screenshot trimis + body-ul include „⚠️ DETECȚIE OPRITĂ"

11 teste noi (1 critical regression pentru bug-ul A observat azi), plus
actualizarea test-ului /resume existent care aserta vechiul comportament.
Total: 235 passed + 8 scenarii regresie.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-21 22:23:20 +03:00
parent a796e91e90
commit 66ffa4bb9a
4 changed files with 420 additions and 41 deletions

View File

@@ -29,10 +29,11 @@ Când adaugi un frame: copiezi din `logs/fires/` → redenumești `{ts}_{color}.
## Telegram commands (live)
`/ss` `/status` `/pause` `/resume` `/resume force` `/3` (interval min) `/stop`
`/ss` `/status` `/pause` `/resume` `/3` (interval min) `/stop`
- `/resume` clears only user pause; Canary drift requires `/resume force`.
- Drift-pause now emits a single Telegram alert (was silent pre-refactor — root cause of the 2026-04-17 hang).
- `/resume` clears BOTH user pause and canary drift-pause in one shot (`/resume force` still accepted as legacy alias).
- Drift-pause emits a single Telegram alert on transition. While paused, `/set_interval` is refused and `/ss` captions warn that detection is off.
- Heartbeat shows `⚠️ pauzat (drift)` instead of `activ` while canary is paused.
## Operating-hours config