feat: calibration/ corpus + scenarii regresie FSM

- calibration/frames/: 16 PNG-uri ground-truth numite {ts}_{color}.png,
  copiate din logs/fires (izolate de samples/ și logs/fires/ care se pot goli)
- calibration/calibration_labels.json: mutat din samples/, curățat de entries
  cu fișiere inexistente, extins la acoperire completă 7 culori → 16/16 PASS
- calibration/scenarios.json: 8 secvențe FSM (BUY/SELL full cycle, phase_skip,
  catchup, post-fire suppression) pe frame-uri reale
- tests/test_scenarios_regression.py: parametrizat pe scenarios.json, asertează
  color+state+reason+trigger+alerts+scheduler prin pipeline-ul
  Detector → _handle_tick
- docs: README + CLAUDE reflectă noua structură, incidentul 2026-04-20/21
  (pixel saturat UNKNOWN → FSM blocat în PRIMED → polling continuu) +
  troubleshooting pentru trigger UNKNOWN

Pytest: 184 → 192 passed (+8 scenarii regresie).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-21 08:32:11 +03:00
parent bed79fcc35
commit 9e8cbafbd4
24 changed files with 578 additions and 78 deletions

View File

@@ -9,13 +9,23 @@ pip install -e ".[windows]" # Windows: live capture
pip install -e ".[dev]" # Linux/macOS: dev + tests (WSL: create venv first)
atm calibrate # Tk wizard
atm debug --delay 5 # one-shot capture + detect
atm validate-calibration samples/calibration_labels.json # offline color gate
atm validate-calibration calibration/calibration_labels.json # offline color gate
atm run --start-at 16:30 --stop-at 23:00 # live session
atm run --tz America/New_York --oh-start 09:30 --oh-stop 16:00 # NYSE window override
atm dryrun samples # corpus gate
pytest -q # 184 tests
pytest -q # 192 tests (184 core + 8 scenarii regresie)
pytest tests/test_scenarios_regression.py -v # FSM pe imagini reale
```
## Calibration corpus
`calibration/` — persistent, auto-suficient, safe to keep când `samples/` și `logs/fires/` se golesc. Conține:
- `frames/` — PNG-uri `{ts}_{color}.png` (ground truth în nume)
- `calibration_labels.json` — gate offline pentru `atm validate-calibration`
- `scenarios.json` — secvențe FSM pentru `tests/test_scenarios_regression.py`
Când adaugi un frame: copiezi din `logs/fires/` → redenumești `{ts}_{color}.png` → adaugi entry în JSON. Validare după orice recalibrare.
## Telegram commands (live)
`/ss` `/status` `/pause` `/resume` `/resume force` `/3` (interval min) `/stop`
@@ -31,6 +41,15 @@ pytest -q # 184 tests
`[options.alerts] fire_on_phase_skip = true` (default) — ARMED→light_* direct (dark_* missed) still emits a `⚠️ PHASE SKIP` alert using FSM lockout to suppress spam.
## Palette gotcha (2026-04-21 recalibration)
TradeStation M2D indicators paint the four bright colors at near-pure saturation:
turquoise `(0,253,253)`, yellow `(253,253,0)`, light_green `(0,255,0)`, light_red `(255,0,0)`.
If Tk-wizard calibration samples a slightly desaturated pixel, classifier returns `UNKNOWN`
(distance > tolerance=60) → FSM never sees trigger → stuck in PRIMED → scheduler polls
forever. Always run `atm validate-calibration calibration/calibration_labels.json` after
recalibrating. Current active config: `configs/2026-04-21-recalib.toml`.
## Skill routing
When the user's request matches an available skill, ALWAYS invoke it using the Skill