#!/usr/bin/env python3 """Sorveglianza giornaliera della CHIAVE DI SCALA del libro (SPEC-scale-key §6.4). uv run python scripts/live/scale_watch.py # osserva e stampa, invia se ALLARME uv run python scripts/live/scale_watch.py --secco # osserva e stampa, NON invia nulla uv run python scripts/live/scale_watch.py --quiet # una riga sola (per il cron) Tre domande, tre azioni diverse, tre stati (OK / ALLARME / NON MISURABILE). Non impedisce la modifica: la rende visibile entro 24 ore e attribuibile. """ from __future__ import annotations import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[2])) from src.live.notifier import notify # noqa: E402 from src.live.scale_watch import ALLARME, OK, run_once # noqa: E402 def _sender(testo: str): try: notify(testo) return True, "telegram" except Exception as e: # P3: si registra dove lo si ingoia return False, f"{type(e).__name__}: {e}" def main() -> None: secco = "--secco" in sys.argv quiet = "--quiet" in sys.argv rep = run_once(sender=None if secco else _sender) icona = {OK: "✅", ALLARME: "🚨"}.get(rep["stato"], "⚠️") if quiet: fb = rep["fallback"] q = f"{100*fb['quota']:.2f}%" if "quota" in fb else "n/d" print(f" scale_watch: {icona} {rep['stato']} · scala {rep['scala_dichiarata']:.2f}x · " f"fallback {q} · {rep['invio']}") return print("=" * 88) print(f" SCALE WATCH — la chiave di scala del libro {icona} {rep['stato']}") print("=" * 88) print(f" scala dichiarata : {rep['scala_dichiarata']:.2f}x " f"(scaletta {rep['ladder']}, tetto {rep['tetto']:.2f}x — costanti di CODICE)") for nome, d in rep["domande"].items(): print(f"\n {nome} [{d['stato']}] {d['motivo']}") if d.get("azione") and d["azione"] != "nessuna": print(f" → azione: {d['azione']}") fb = rep["fallback"] if fb.get("stato") == "NON MISURABILE": print(f"\n fallback [{fb['stato']}] {fb.get('motivo')}") else: print(f"\n fallback [{fb['stato']}] equity illeggibile in {fb['fallback_veri']}/{fb['giri']} " f"giri ({100*fb['quota']:.2f}%, soglia {100*fb['soglia']:.0f}%) — " f"{fb['paper']} giri pre-finanziamento esclusi, li' il libro non invia affatto") print(f"\n lettore di produzione [{rep['lettore']['stato']}] {rep['lettore']['motivo'][:150]}") print(f"\n invio: {rep['invio']}") USO = """uso: scale_watch.py [--quiet] [--secco] uv run python scripts/live/scale_watch.py # osserva e stampa, invia se ALLARME uv run python scripts/live/scale_watch.py --secco # osserva e stampa, NON invia nulla uv run python scripts/live/scale_watch.py --quiet # una riga sola (per il cron) Dettaglio nel docstring in testa al file.""" if __name__ == "__main__": from src.live.cli import valida valida("scale_watch.py", USO, flag=("--quiet", "--secco"), con_valore=()) main()