# 2026-09-02 — Un flag sconosciuto non è l'azione di default *Scritto fra le 15:45Z e le 16:05Z. Il difetto è stato misurato, non ipotizzato: la revisione del codice di questa sessione ha eseguito `trades_db.py --help` come sonda di tempi e lo ha visto sincronizzare il DB.* ## 1. Il difetto Nessuno dei 18 script di `scripts/live/` usava argparse. Leggevano gli argomenti così: ```python if "--reconcile" in args: ... elif "--report" in args: ... else: sync() # <- qui finiva QUALUNQUE cosa non riconosciuta ``` Un flag sbagliato non era un errore: era il ramo finale. Costo osservato e costi possibili: | script | `--help` faceva | gravità | |---|---|---| | `trades_db.py` | `sync()`: riscriveva `meta.ultimo_sync` | osservato oggi, danno nullo | | `journal.py` | scriveva la pagina di oggi e una riga nel DB | non osservato, ma scrive | | `analista.py` | spendeva una chiamata al modello e mandava un Telegram | non osservato, ma spende | ## 2. La riparazione, e perché non è argparse `src/live/cli.valida(nome, uso, flag=..., con_valore=...)`, chiamata come **prima istruzione** di ogni blocco `__main__` — prima di `connect()`, prima del sync, prima della rete. - `--help` / `-h` → stampa l'uso, esce **0**; - flag non dichiarato, o valore mancante, o posizionale → stderr con **cosa** e **cosa si poteva** (P4), esce **2** (errore d'uso, distinto dall'1 con cui gli script segnalano un esito negativo); - tutto il resto invariato. **Argparse no.** Cambierebbe messaggi d'errore, codici d'uscita e il comportamento di `--help` su 18 script che il cron già invoca: romperebbe ciò che gira per riparare ciò che non gira mai. Qui serviva l'opposto — lasciare intatti i flag esistenti e rifiutare solo l'ignoto. ## 3. Il test guarda entrambe le metà del contratto `tests/test_cli_flag.py`, 30 test: - **l'elenco degli script si deriva dalla cartella** (P1): uno script nuovo che legge `sys.argv` a mano e non chiama `valida` fa fallire il test, non passa inosservato perché nessuno ha aggiornato una lista; - `valida` dev'essere la **prima istruzione** di `__main__` (uscire dopo l'effetto non è uscire); - l'uso deve **nominare** i flag che lo script accetta; - **i flag che il cron usa davvero devono restare accettati** (P15/P16, letti dai `cron_*.sh`): una guardia che ferma il libro di bordo la notte stessa sarebbe peggio del difetto; - end-to-end sui tre script che scrivono: `--help` esce 0 e **non tocca `trades.db`**; un flag ignoto esce 2 e non lo tocca (M15: il caso che ha causato il difetto, non un caso vicino). Verificato a mano anche il contrario: `monitor_health.py --quiet`, `trades_db.py --sync --quiet` e `book_execute.py` in dry-run escono 0 come prima. ## 4. Il resto della sessione **Indice USDE orario** (debito §5.15, primo passo). Il classificatore dei movimenti di capitale confronta due letture di equity a un'ora di distanza e il suo bound guarda solo BTC/ETH, mentre il 31% dell'equity è USDE: un depeg sarebbe scorporato come un prelievo. `usde_watch` registra l'indice una volta al giorno — troppo rado. Ora `balance_watch` (orario, sola lettura) lo registra a ogni campione, `None` con la ragione se non leggibile, mai 1,0. Il cablaggio nel bound viene quando la serie ha storia: prima serve il dato, poi la regola. **Pulizia lasciata dalla revisione.** `tests/helpers.carica_script` sostituisce la dodicesima copia del caricatore `importlib` (15 in giro, con nomi di modulo diversi per lo stesso file e differenze silenziose su `sys.modules`); il fill di prova si scrive con `upsert_fills` invece che con un `INSERT` a mano che lasciava `verified` NULL, una forma che la produzione non produce; le asserzioni sul testo del report non sono più ancorate al padding; `movimenti_capitale` accetta le righe già lette, così il report non fa due SELECT sulla stessa tabella a un'ora del cron — due letture ai due lati di una scrittura descriverebbero due istanti diversi. ## 5. Cosa NON ho fatto - I loader `importlib` dei test sulla **ricerca** (moduli in `scripts/research/`) restano come sono: sono a livello di modulo, con radici diverse, e toccarli non ripara niente. - Il bound USDE nel classificatore: manca la storia, non il codice.