Files
PythagorasGoal/docs/diary/2026-09-02c-flag-e-pulizia.md
T
Adriano Dal Pastro de83909db9 un flag sconosciuto non e' l'azione di default: guardia su 18 script, indice USDE orario, pulizia
MISURATO oggi durante la revisione: `trades_db.py --help` non stampava l'uso, cadeva in sync()
e riscriveva meta.ultimo_sync. Nessuno dei 18 script di scripts/live/ usava argparse: un flag
sbagliato era il ramo else. Su journal.py avrebbe scritto pagina e riga di DB, su analista.py
avrebbe speso una chiamata al modello e mandato un Telegram.

- src/live/cli.valida: prima istruzione di ogni __main__, prima di connect()/sync/rete.
  --help -> 0 con l'uso; flag ignoto, valore mancante o posizionale -> 2 con l'elenco dei
  previsti (P4). NIENTE argparse: cambierebbe messaggi, codici d'uscita e --help di script
  che il cron gia' chiama.
- 18 script cablati (i 3 che scrivono + 14 + cc01), flag invariati.
- tests/test_cli_flag.py (30): elenco DERIVATO dalla cartella (P1), valida come prima
  istruzione, uso che documenta i flag, e i flag che il CRON usa davvero restano accettati
  (P15/P16); end-to-end su --help e flag ignoto con trades.db non toccato (M15).
  Verificato a mano: monitor_health --quiet, trades_db --sync --quiet, book_execute dry-run.

Debito §5.15, primo passo: balance_watch (orario) registra `usde_usdc` a ogni campione — None
con la ragione se illeggibile, mai 1,0. Il cablaggio nel bound quando la serie ha storia.

Pulizia dalla revisione: tests/helpers.carica_script al posto della 15a copia del loader
importlib (5 file del libro live); il fill di prova via upsert_fills invece di un INSERT che
lasciava verified NULL; asserzioni non ancorate al padding; movimenti_capitale accetta le
righe gia' lette (una SELECT invece di due ai due lati di una scrittura del cron).

Test 910 verdi (+52). Diario 2026-09-02c.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
2026-09-02 15:49:40 +00:00

4.1 KiB

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ì:

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.