errore Deribit in envelope su get_positions -> [] -> il libro legge flat e compra sopra la posizione #19

Open
opened 2026-09-27 13:12:09 +00:00 by Adriano · 0 comments
Owner

Revisione 2026-09-27 (goldrake): rilievo Opus 5.5, verifica avversariale fable. Sola lettura, nessun codice toccato.

Rilievo D3 [bug-critico]

FILE: TB:src/gateway/deribit.py:197-201,307-310,327-340 + TB:src/live/deribit.py:291-297 + TB:src/live/shadow.py:76-89
COSA: un errore sui soli endpoint PRIVATI (auth, scope rifiutato da _verifica_scope, 10028 rate-limit privato, 13021) diventa «posizione flat» senza eccezione: positions() fa grezza.get("result") or [], position_usd non trova lo strumento e torna 0.0, _positions segnala pos_error SOLO su eccezione.
SCENARIO: ticker pubblico ok -> online=True (shadow.py:218 guarda solo il mark BTC); account_summary -> equity None -> sizing su paper capital $2.000 (eq_fallback, «NON blocca» in book_execute:223); positions -> [] -> pos 0.0, pos_error None. L'ombra NON salta (book_ombra.py:88) e registra BUY ~$300/$200 contro posizioni vere $814/$758: e' la stessa riga falsa del 15/09 (#16) per un'altra via. Dopo la promozione il libro compra sopra le posizioni esistenti (cap da watermark ~$2.290/asset, non morde). open_orders() idem -> [] -> ensure_disaster_sl crede il bracket assente e ne piazza un secondo. Stessa forma in cerbero-mcp (_request riga 148/173 + get_positions or []), quindi latente anche nel libro vivo PG.
PROVA: VERIFICATO: lettura delle righe citate; _verifica_scope solleva AuthError dentro _autentica, che richiesta (riga 200) converte in {"result": None, "error": ...}. PRESUNTO: mai accaduto nell'ombra (1 sola riga paper capital in 335, quella del 15/09 con online=false).
PROPOSTA: nel gateway, positions/open_orders sollevano GatewayError se grezza porta "error" (una lista vuota deve voler dire solo «nessuna posizione»); in book_ombra saltare anche su eq_fallback a online. Test: gateway con risposta {"error":{"code":13009}} -> pos_error valorizzato -> riga saltato.

Verifica fable D3 VERDETTO: CONFERMATO

GRAVITA': critico
PERCHE': TB src/gateway/deribit.py:196-201 (richiesta: AuthError -> {"result": None, "error"}) e :215-223 (qualunque envelope Deribit senza result -> stesso dict, nessuna eccezione; _leggi_risposta :455-462 solleva SOLO su HTTP>=500/non-JSON — Deribit risponde gli errori applicativi con HTTP 400 + JSON); positions() :307-310 grezza.get("result") or [] -> lista vuota; src/live/deribit.py position_usd -> 0.0; shadow.py _positions valorizza pos_error SOLO su eccezione (identico in PG e TB: diff shadow.py = 9 righe, nessuna su positions/online). Stessa forma in cerbero-mcp client.py:142-146,161-173 ({"result": None, "error": msg}) + :371-373 (raw.get("result") or []) + _parse_deribit_response :17-32 (solleva solo su 5xx/non-JSON) -> in PG un 10028/13xxx non-auth sulla sola get_positions diventa "flat" e il gate pos_error NON scatta. In PG con account_summary ok: equity fidata 4583, cap 2291, pos letta 0 -> BUY di tutto il target ($813 BTC / $756 ETH) SOPRA la posizione esistente, poi vendita al giro dopo quando la lettura torna. In TB: riga d'ombra falsa (come #16 per un'altra via). Nessun test copre una risposta {"error":{...}} su get_positions.
CORREZIONE: ok (positions/open_orders/account_summary sollevano se grezza porta "error"; in cerbero-mcp get_positions dovrebbe propagare l'errore come HTTP 502 — oggi risponde 200 [], quindi PG va protetto o lato cerbero o distinguendo lato PG una lista vuota con direction assente... non distinguibile: la correzione VERA sta nel gateway).

Revisione 2026-09-27 (goldrake): rilievo Opus 5.5, verifica avversariale fable. Sola lettura, nessun codice toccato. ### Rilievo D3 [bug-critico] FILE: TB:src/gateway/deribit.py:197-201,307-310,327-340 + TB:src/live/deribit.py:291-297 + TB:src/live/shadow.py:76-89 COSA: un errore sui soli endpoint PRIVATI (auth, scope rifiutato da `_verifica_scope`, 10028 rate-limit privato, 13021) diventa «posizione flat» senza eccezione: positions() fa `grezza.get("result") or []`, position_usd non trova lo strumento e torna 0.0, `_positions` segnala pos_error SOLO su eccezione. SCENARIO: ticker pubblico ok -> online=True (shadow.py:218 guarda solo il mark BTC); account_summary -> equity None -> sizing su paper capital $2.000 (eq_fallback, «NON blocca» in book_execute:223); positions -> [] -> pos 0.0, pos_error None. L'ombra NON salta (book_ombra.py:88) e registra BUY ~$300/$200 contro posizioni vere $814/$758: e' la stessa riga falsa del 15/09 (#16) per un'altra via. Dopo la promozione il libro compra sopra le posizioni esistenti (cap da watermark ~$2.290/asset, non morde). open_orders() idem -> [] -> ensure_disaster_sl crede il bracket assente e ne piazza un secondo. Stessa forma in cerbero-mcp (_request riga 148/173 + get_positions `or []`), quindi latente anche nel libro vivo PG. PROVA: VERIFICATO: lettura delle righe citate; `_verifica_scope` solleva AuthError dentro `_autentica`, che `richiesta` (riga 200) converte in `{"result": None, "error": ...}`. PRESUNTO: mai accaduto nell'ombra (1 sola riga paper capital in 335, quella del 15/09 con online=false). PROPOSTA: nel gateway, positions/open_orders sollevano GatewayError se `grezza` porta "error" (una lista vuota deve voler dire solo «nessuna posizione»); in book_ombra saltare anche su `eq_fallback` a online. Test: gateway con risposta `{"error":{"code":13009}}` -> pos_error valorizzato -> riga `saltato`. ### Verifica fable D3 VERDETTO: CONFERMATO GRAVITA': critico PERCHE': TB src/gateway/deribit.py:196-201 (`richiesta`: AuthError -> `{"result": None, "error"}`) e :215-223 (qualunque envelope Deribit senza `result` -> stesso dict, nessuna eccezione; `_leggi_risposta` :455-462 solleva SOLO su HTTP>=500/non-JSON — Deribit risponde gli errori applicativi con HTTP 400 + JSON); `positions()` :307-310 `grezza.get("result") or []` -> lista vuota; src/live/deribit.py position_usd -> 0.0; shadow.py `_positions` valorizza pos_error SOLO su eccezione (identico in PG e TB: diff shadow.py = 9 righe, nessuna su positions/online). Stessa forma in cerbero-mcp client.py:142-146,161-173 (`{"result": None, "error": msg}`) + :371-373 (`raw.get("result") or []`) + `_parse_deribit_response` :17-32 (solleva solo su 5xx/non-JSON) -> in PG un 10028/13xxx non-auth sulla sola get_positions diventa "flat" e il gate pos_error NON scatta. In PG con account_summary ok: equity fidata 4583, cap 2291, pos letta 0 -> BUY di tutto il target ($813 BTC / $756 ETH) SOPRA la posizione esistente, poi vendita al giro dopo quando la lettura torna. In TB: riga d'ombra falsa (come #16 per un'altra via). Nessun test copre una risposta `{"error":{...}}` su get_positions. CORREZIONE: ok (positions/open_orders/account_summary sollevano se `grezza` porta "error"; in cerbero-mcp get_positions dovrebbe propagare l'errore come HTTP 502 — oggi risponde 200 `[]`, quindi PG va protetto o lato cerbero o distinguendo lato PG una lista vuota con `direction` assente... non distinguibile: la correzione VERA sta nel gateway).
Adriano added the bug label 2026-09-27 13:12:09 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Adriano/PythagorasGoal#19