Aggiunto il quarto livello della pagina, tenuto separato dagli altri tre:
numeri -> misurati dal feed e dal DB
Lettura -> regole deterministiche, ognuna col suo id
Analisi -> questo: prosa di un modello, che puo' sbagliare
Nota -> l'operatore
NON scrive dentro `nota`, che era la richiesta letterale: quel campo e'
dell'operatore, ed e' cio' che a rileggere il giornale fra sei mesi permette
di sapere chi ha scritto cosa. L'agente ha `analisi`, marcato col modello,
con l'ora e con l'esito del controllo sui numeri.
Gira via `claude -p` (verificato con env -i che risponda nell'ambiente nudo
di cron), una chiamata al giorno sul giorno CHIUSO, tolte le tool.
Tre guardie, una per ogni modo in cui una prosa generata rovina un registro:
- NUMERO INVENTATO: numeri_non_supportati() estrae ogni cifra dall'analisi e
verifica che compaia in cio' che il modello ha ricevuto. Oltre tre numeri
liberi l'analisi e' RIFIUTATA e la pagina resta senza. E' un controllo
debole per costruzione, e lo dichiara: prende l'invenzione, non il
ragionamento sbagliato.
- COMMENTO DI SE': senza_analisi() toglie dalla pagina la sezione dell'agente
prima di dargliela. Al primo giro reale il modello aveva letto la propria
uscita precedente e prodotto un paragrafo sull'avviso che si era preso il
giorno prima — un ciclo di retroazione che in poche settimane avrebbe
riempito il giornale di meta-commento, e che nessun controllo automatico
puo' distinguere da prosa valida.
- ANALISI DI IERI SPACCIATA PER OGGI: se il modello non risponde, la pagina
resta VUOTA e il perche' viene registrato (stato + motivo). Il silenzio non
diventa continuita'.
Corretto anche un falso positivo mio: il tripwire validava sulla sola pagina
mentre il prompt include anche il blocco storico, quindi bocciava un'equity
vera. Una guardia piu' stretta del contratto produce allarmi che si impara a
ignorare.
Ogni guardia ha un test in entrambe le direzioni. 695 test passano.
Strategia, pesi, config INVARIATI. Nessun ordine.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
I trade erano salvati, ma non allineati col tempo: book_execute.py scriveva
ts_utc = pd.Timestamp(r['last_data']), cioe' la data della BARRA DI SEGNALE.
19 righe su 19 a 00:00:00, e un trade (ETH 0.04 @ 1869.74) registrato SEI
GIORNI prima di essere eseguito — fill vero 2026-07-14T14:00, scritto 08/07.
L'ora vera esisteva solo in logs/cron_book.log, che e' gitignored, fuori dal
backup e ruotabile: la cronologia reale del libro live viveva in un file che
una rotazione avrebbe cancellato senza che nessuno se ne accorgesse.
- src/live/tradesdb.py: parser del cron log (ora vera + contesto del segnale),
FIFO con fee pro-quota, riconciliazione a tre fonti, sqlite in data/live/
(dentro il perimetro del backup). Le tre fonti si INCROCIANO e non si
sovrascrivono: reconcile() riporta le divergenze e non ripara niente da solo.
Il venue e' autorevole ma TRONCA (1 trade su BTC, 0 su ETH): dichiarato.
- scripts/live/trades_db.py: --sync (idempotente, in cron_book ogni ora),
--report, --reconcile.
- src/live/journal.py + scripts/live/journal.py: una voce al giorno in
docs/journal/YYYY-MM-DD.md — mercato (ritorni, RV30, TSMOM sugli orizzonti
di produzione, DVOL con eta'), libro (TP01/SKH01, target, posizione, leva),
P&L (equity del venue come autorita', scomposizione locale), salute.
NIENTE narrativa automatica: il campo `nota` e' l'unico posto per il testo
libero ed e' dell'operatore, mai riscritto da un ricalcolo.
- book_execute.py: ts_utc = ora vera del fill, bar_ts = barra. Test di
regressione sulla sorgente: se qualcuno rimette last_data, il test lo dice.
- 62 voci di giornale ricostruite dall'arming a oggi.
Tre difetti trovati dai test mentre scrivevo, non a occhio: il renderer cadeva
in KeyError se mancava il blocco mercato (un giornale che non si scrive non e'
un giornale); "24 giri attesi" su un giorno IN CORSO produceva un allarme a
ogni esecuzione; e libro e P&L leggevano due istanti diversi, quindi la stessa
pagina mostrava due equity.
Strategia, pesi, config INVARIATI. Nessun ordine. 659 test passano.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>