sei sorveglianti registrano i giri e stanno in monitor_health (Fixes #16)
src/live/giri.registra_giro: una riga jsonl {ts ms, campi} dopo una misura completata,
mai un'eccezione. edge_watch, fee_watch, scale_watch, vrp_f_watch, venue_news (cron_daily)
e venue_watch (cron_book, orario) scrivono data/<dir>/runs.jsonl; niente riga senza misura.
monitor_health: sei MonitorSpec (30h i giornalieri, 3h venue_watch), open_labeled=False.
Stessa riparazione di cc01 (#10, #12), generalizzata. Primo giro notturno: NUOVO, non allerta.
Test: incrocio P1 percorso/RUNS, misura -> una riga, non-misura -> nessuna. Suite: 1098 passed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
"""registra_giro — il giro che un sorvegliante ha misurato, come riga jsonl (2026-09-21, #16).
|
||||
|
||||
PERCHE' ESISTE. `cc01_regime_watch` e' morto 14 notti di fila (#10) senza che nessuno lo vedesse,
|
||||
perche' non scriveva niente da sorvegliare: `monitor_health` guarda solo le serie che i monitor
|
||||
scrivono, e un monitor silenzioso non e' distinguibile da uno che dice "tutto ok". La riparazione
|
||||
di cc01 (`data/cc01_regime/runs.jsonl`, commit 31f5915) e' il modello: qui si generalizza a ogni
|
||||
sorvegliante, cosi' un monitor fermo diventa FERMO in `monitor_health`, non invisibile.
|
||||
|
||||
Un registro che fallisce non deve cambiare l'esito del sorvegliante che lo scrive: `registra_giro`
|
||||
non solleva mai, e su errore lo dice su stderr e ritorna False.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def registra_giro(path: Path, **campi) -> bool:
|
||||
"""Appende `{"ts": <ms epoch>, **campi}` a `path` (jsonl, una riga). Crea la cartella se manca.
|
||||
|
||||
Ritorna True se la riga e' stata scritta, False su OSError (disco pieno, permessi, percorso
|
||||
invalido...) dopo aver scritto il motivo su stderr. Non solleva mai: la misura del
|
||||
sorvegliante e' gia' fatta, e un registro che fallisce non deve buttarla via.
|
||||
"""
|
||||
riga = {"ts": int(time.time() * 1000), **campi}
|
||||
try:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with path.open("a", encoding="utf-8") as fh:
|
||||
fh.write(json.dumps(riga, default=str) + "\n")
|
||||
return True
|
||||
except OSError as e:
|
||||
print(f"registra_giro: non scrivo {path}: {type(e).__name__}: {e}", file=sys.stderr)
|
||||
return False
|
||||
@@ -105,6 +105,29 @@ MONITORS: tuple[MonitorSpec, ...] = (
|
||||
MonitorSpec("cc01_regime_watch", "cc01_regime", "runs.jsonl", 24.0, max_age_h=30.0,
|
||||
gate="trigger di regime CC01: WARN>=10% / ALERT>=15% funding 30g (riapre il dossier)",
|
||||
open_labeled=False),
|
||||
# I sei sorveglianti che generalizzano la riparazione di cc01 (#16): ognuno registra il
|
||||
# proprio giro in `data/<dir>/runs.jsonl` (src.live.giri.registra_giro), timbri di
|
||||
# ESECUZIONE come cc01 -> open_labeled=False. cron_daily.sh (GIORNALIERO) per i primi
|
||||
# cinque: max_age 30h = un giro mancato + margine.
|
||||
MonitorSpec("edge_watch", "edge_watch", "runs.jsonl", 24.0, max_age_h=30.0,
|
||||
gate="kill del libro live (Sharpe 36m < -0,5 / protezione TP01)",
|
||||
open_labeled=False),
|
||||
MonitorSpec("fee_watch", "fee_watch", "runs.jsonl", 24.0, max_age_h=30.0,
|
||||
gate="regola fee §3 decisa in anticipo",
|
||||
open_labeled=False),
|
||||
MonitorSpec("scale_watch", "scale_watch", "runs.jsonl", 24.0, max_age_h=30.0,
|
||||
gate="GATE SCALA-01 criterio A2",
|
||||
open_labeled=False),
|
||||
MonitorSpec("vrp_f_watch", "vrp_f_watch", "runs.jsonl", 24.0, max_age_h=30.0,
|
||||
gate="criteri (a)(b) §5.18",
|
||||
open_labeled=False),
|
||||
MonitorSpec("venue_news", "venue_news", "runs.jsonl", 24.0, max_age_h=30.0,
|
||||
gate="annunci Deribit, debito 8",
|
||||
open_labeled=False),
|
||||
# cron_book.sh: gira OGNI ORA accanto al libro vivo. max_age 3h = due giri persi.
|
||||
MonitorSpec("venue_watch", "venue_watch", "runs.jsonl", 1.0, max_age_h=3.0,
|
||||
gate="tripwire di venue orario",
|
||||
open_labeled=False),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user