usde_watch e fee_watch salvano lo stato prima dell'invio: un Telegram fallito non viene piu' ripetuto #29
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Revisione 2026-09-27 (goldrake): rilievo Opus 5.5, verifica avversariale fable. Sola lettura, nessun codice toccato.
Rilievo B2 [bug]
FILE: pg:scripts/live/usde_watch.py:287-320
COSA: il marcatore "gia' detto" di DEPEG_WARN / QUOTA_OVER / BLIND e' la condizione del record precedente, non l'esito di notify(): un invio fallito consuma la transizione (la lezione §5.2 applicata in cuscino_watch non e' applicata qui).
SCENARIO: giorno 1 indice 0.985 (DEPEG_WARN nuova), Telegram in errore -> notify False, ignorato; record scritto con px 0.985. Giorno 2 ancora 0.985: att_prev contiene DEPEG_WARN -> nessun invio. Il depeg resta non detto finche' non sparisce e ricompare. Idem QUOTA_OVER e BLIND. Il cron e' giornaliero: la perdita e' di 24h per tentativo.
PROVA: VERIFICATO: lettura — nessuno dei notify() alle righe 296-319 ha il valore di ritorno registrato; il record e' scritto a riga 288 prima degli invii; condizioni() dipende solo da px/quota/stato.
PROPOSTA: come cuscino_watch: scrivere il record DOPO gli invii con
allertati=[...]effettivamente partiti, e innuovesottrarre solo le condizioni del prev che risultano allertate.Verifica fable B2 VERDETTO: CONFERMATO
GRAVITA': medio
PERCHE':
scripts/live/usde_watch.py:288-289scrive il record PRIMA degli invii; 296-319: nessunnotify()ha il ritorno letto;condizioni()(166) dipende solo da px/quota/stato ->att_prevdel giro dopo contiene la condizione anche se l'invio e' fallito. Il record non ha campoallertati.CORREZIONE: ok (schema di cuscino_watch: record dopo gli invii con
allertati,nuove = att_now - {c in att_prev se allertata}).Rilievo B8 [bug]
FILE: pg:scripts/live/fee_watch.py:248-253
COSA: il cambio di fee viene consumato anche se Telegram fallisce: notify() ignorato, save_state() salva i nuovi valori subito dopo.
SCENARIO: Deribit porta il taker da 5 a 8 bps (livello NOTA), invio fallito -> il giro dopo prev == cur, changes vuoto, livello NOTA non allerta: il cambio non sara' mai detto. (AZIONE >10 bps invece si ripete.)
PROVA: VERIFICATO: lettura righe 248-253; stesso schema che §5.2 ha riparato in venue_watch/scale_watch/cuscino_watch.
PROPOSTA:
ok = notify(...); salvare lo stato solo se ok (o se non c'erano cambi).Verifica fable B8 VERDETTO: CONFERMATO
GRAVITA': medio
PERCHE':
scripts/live/fee_watch.py:248-253:notify(...)senza lettura del ritorno, poisave_state(r["current"])incondizionato -> un cambio NOTA con invio fallito non viene piu' detto (il giro dopochangese' vuoto). AZIONE si ripete perche'level=="AZIONE"e' ricalcolato ogni giro.CORREZIONE: ok.
ANALISI (passo 1, Opus) — unita' U3, ramo lavoro/goldrake-u3, repo gitea:Adriano/PythagorasGoal
RIF: #26 (B1), #29 (B2, B8), #31 (B7), #35 (solo B3, B4)
FILE: scripts/live/usde_convert.py, scripts/live/usde_watch.py, scripts/live/fee_watch.py, src/live/venue_watch.py, scripts/live/venue_watch.py, tests/
a) funzione
cancella_residui(c) -> list[str]: legge gli ordini aperti sullo spot U.SPOT (USDE_USDC) e cancella SOLO quelli con label che inizia per "usde-quota-". Per sapere come chiedere gli ordini aperti di uno spot leggi (SOLA LETTURA) /opt/docker/cerbero-mcp/src/cerbero_mcp/exchanges/deribit/tools.py e client.py (get_open_orders: parametri accettati; cancel_order: {"order_id"}). Se la lettura fallisce -> solleva (non si ordina al buio).b) in main() con --esegui: chiamare cancella_residui PRIMA del ciclo (stampare quanti) e, nel ciclo, dopo ogni ordine con filled < amt cancellare quell'order_id (
c._post("/mcp-deribit/tools/cancel_order", {"order_id": ...})), registrarlo nel record (cancellato: true/errore). Se la cancel fallisce: stampa, registra e FERMA il ciclo (break) — mai un secondo ordine con un residuo vivo.c) il record finale e l'exit code non cambiano significato.
allertati= condizioni il cui invio e' riuscito;nuove = att_now - {c in att_prev se c in prev.get("allertati", att_prev)}— compatibilita': un record vecchio senzaallertativale come tutto allertato. fee_watch: save_state solo se l'invio (quando serviva) e' riuscito.TEST (tests/test_usde_u3.py ecc., client finto, nessuna rete, time.sleep patchato):
Suite completa:
cd <worktree> && /opt/docker/PythagorasGoal/.venv/bin/python -m pytest -q -p no:cacheprovider(baseline 1098 passed, 3 skipped).NON TOCCARE: src/live/usde.py (formula del cuscino: e' #28, altra unita'), cuscino_watch.py (salvo leggerlo), config/live.json, /opt/docker/cerbero-mcp (sola lettura), /opt/docker/PythagorasGoal. Nessuna rete, nessun ordine, nessun Telegram (notify va mockato nei test).
ESITO: fatto sul ramo, non in produzione
RIF: gitea:Adriano/PythagorasGoal#29
COSA: correzione su lavoro/goldrake (pushato), analisi Opus, codice Sonnet, controllo finale Opus
FILE: commit
4725839dda5d41PROVA: /home/adriano/lavoro/PythagorasGoal pytest -q → 1166 passed, 3 skipped
MANCA: merge su main — richiede ok esplicito di Adriano (libro vivo). Chiusura con --soluzione dopo il merge.
PROSSIMO: ok di Adriano → merge lavoro/goldrake su main → git pull in /opt/docker/PythagorasGoal
Soluzione
usde_watch: record 'allertati' scritto dopo gli invii; fee_watch: save_state solo se l'invio e' riuscito.
COMMIT:
4725839dda5d41, su main dal 27/09/2026 (merge con ok di Adriano). Produzione aggiornata.