[{"data":1,"prerenderedAt":2279},["ShallowReactive",2],{"docs-pages-it":3,"doc-it-changelog-sdk-ruby":310},[4,9,15,20,25,30,35,41,52,60,69,77,85,93,97,106,110,118,123,128,133,139,144,149,154,159,164,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,261,266,270,275,280,285,290,295,300,305],{"path":5,"title":6,"description":7,"order":8,"group":8,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fpermissions","Chi può fare cosa","[object Object]",null,{"path":10,"title":11,"description":12,"order":13,"group":14,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Finstallation","Installazione","Installa CloseYourIt sul tuo server con un solo comando.",1,"start",{"path":16,"title":17,"description":18,"order":19,"group":14,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fsettings","Impostazioni","Ogni impostazione del file .env, a cosa serve e quali non vanno mai cambiate.",2,{"path":21,"title":22,"description":23,"order":24,"group":14,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fdatabase","Database","Cos'è il database, cosa contiene, quanto restano i dati e quanto spazio occupa.",3,{"path":26,"title":27,"description":28,"order":29,"group":14,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fupdates-and-backups","Aggiornamenti e backup","Aggiorna a una versione nuova, fai e ripristina il backup del database, controlla l'installazione.",4,{"path":31,"title":32,"description":33,"order":34,"group":14,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Ftroubleshooting","Risolvere i problemi","Cosa controllare quando installazione, certificato, email o dati in arrivo non funzionano.",5,{"path":36,"title":37,"description":38,"order":39,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fconnect-your-apps","Collega le tue app","Tutti gli strumenti che mandano dati a CloseYourIt, e cosa raccoglie ognuno.",6,"connect",{"path":42,"title":43,"description":44,"order":45,"group":8,"parent":46,"package":47,"note":48,"collects":49,"status":8},"\u002Fdocs\u002Fsdk-ruby","Ruby \u002F Rails","La gemma closeyourit-ruby manda errori, log, query lente e metriche dei job da un'app Rails.",7,"connect-your-apps","closeyourit-ruby","Errori, log, query e metodi lenti, job in background.",{"errors":50,"logs":50,"performance":50,"visits":51,"servers":51},"full","none",{"path":53,"title":54,"description":55,"order":56,"group":8,"parent":46,"package":57,"note":58,"collects":59,"status":8},"\u002Fdocs\u002Fsdk-javascript","JavaScript","Il pacchetto @bussolabs\u002Fcloseyourit-js funziona nel browser e su Node 20.16 o più recente.",8,"@bussolabs\u002Fcloseyourit-js","Browser e Node, adattatori framework e query database dalla 0.13.0.",{"errors":50,"logs":50,"performance":50,"visits":50,"servers":51},{"path":61,"title":62,"description":63,"order":64,"group":8,"parent":46,"package":65,"note":66,"collects":67,"status":8},"\u002Fdocs\u002Fsdk-dart","Dart \u002F Flutter","Il pacchetto closeyourit cattura gli errori delle app Flutter, anche quando il telefono è senza rete.",9,"closeyourit","Errori, log e metriche pubblici dalla 0.9.3.",{"errors":50,"logs":68,"performance":68,"visits":51,"servers":51},"partial",{"path":70,"title":71,"description":72,"order":73,"group":8,"parent":46,"package":65,"note":74,"collects":75,"status":76},"\u002Fdocs\u002Fsdk-python","Python","Il pacchetto closeyourit manda errori, log e metriche da applicazioni Python lato server.",10,"Lato server. SQLAlchemy; query Django e FastAPI\u002FStarlette dalla 0.4.0.",{"errors":50,"logs":50,"performance":68,"visits":51,"servers":51},"pre_alpha",{"path":78,"title":79,"description":80,"order":81,"group":8,"parent":46,"package":82,"note":83,"collects":84,"status":8},"\u002Fdocs\u002Fsdk-sentry","SDK Sentry","Invia errori con un SDK Sentry compatibile; sessioni e crash hanno profili separati.",11,"Sentry SDK","Errori compatibili; sessioni e crash richiedono il profilo verificato.",{"errors":50,"logs":51,"performance":51,"visits":51,"servers":51},{"path":86,"title":87,"description":88,"order":89,"group":8,"parent":46,"package":90,"note":91,"collects":92,"status":8},"\u002Fdocs\u002Fagent-server","Agent per server","Un piccolo programma sul server che manda lo stato della macchina ogni 60 secondi.",12,"closeyourit-agent","CPU, memoria, dischi, rete, container e servizi.",{"errors":51,"logs":68,"performance":51,"visits":51,"servers":50},{"path":94,"title":95,"description":96,"order":89,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fnuxt","Vue e Nuxt","Collega gli errori del browser Nuxt e del server Nitro senza esporre un token segreto.",{"path":98,"title":99,"description":100,"order":101,"group":8,"parent":46,"package":102,"note":103,"collects":104,"status":105},"\u002Fdocs\u002Fagent-kubernetes","Kubernetes","Un osservatore in sola lettura del cluster: una copia sola per cluster.",13,"closeyourit-kube","Macchine, app ed eventi di errore del cluster.",{"errors":51,"logs":51,"performance":51,"visits":51,"servers":50},"coming",{"path":107,"title":108,"description":109,"order":101,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fopentelemetry","OpenTelemetry","Invia tracce, metriche e log dei server attraverso il ricevitore OTLP facoltativo.",{"path":111,"title":112,"description":113,"order":114,"group":8,"parent":46,"package":115,"note":116,"collects":117,"status":8},"\u002Fdocs\u002Fcli","CLI cyi","Il comando closeyourit, in breve cyi: gestisci progetti, errori e ticket dal terminale.",14,"@bussolabs\u002Fcloseyourit-cli","Non raccoglie dati: comanda CloseYourIt dal terminale.",{"errors":51,"logs":51,"performance":51,"visits":51,"servers":51},{"path":119,"title":120,"description":121,"order":122,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fhttp-api","API HTTP","Manda errori, log, metriche e visite con semplici richieste HTTP, senza un SDK.",15,{"path":124,"title":125,"description":126,"order":127,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fgithub-app","GitHub","Collega i repository GitHub a ticket e rilasci con una GitHub App tua.",16,{"path":129,"title":130,"description":131,"order":132,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fingest-gateway","Gateway di ingest","Tieni al sicuro errori, log e metriche in arrivo quando l'app è lenta o sta ripartendo.",17,{"path":134,"title":135,"description":136,"order":137,"group":138,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fai","AI","Accendi assistente, analisi, dettatura e ricerca intelligente con una chiave CloseYourIt AI o con il tuo provider.",18,"automation",{"path":140,"title":141,"description":142,"order":143,"group":138,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fautomator","Automator","Fai lavorare i ticket in automatico su una tua macchina Linux, con Claude Code, Codex o tutti e due.",19,{"path":145,"title":146,"description":147,"order":148,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fstack-coverage","Framework e copertura degli stack","Scegli un SDK pubblicato o verifica i limiti di un’integrazione provata localmente.",20,{"path":150,"title":151,"description":152,"order":153,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fmonitoring","Tracce, misure e sessioni","Esplora i nuovi segnali, confronta le versioni e ricostruisci le posizioni originali degli errori.",21,{"path":155,"title":156,"description":157,"order":158,"group":40,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fnode-database","Database Node","Monitora query lente e ripetute con pg, mysql2, Drizzle e Prisma PostgreSQL.",22,{"path":160,"title":161,"description":162,"order":163,"group":138,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fclaude-code","Claude Code","CloseYourIt dentro Claude Code, in una colonna accanto alla conversazione con produzione e i tuoi ticket aperti.",23,{"path":165,"title":166,"description":167,"order":168,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Ftickets","Ticket e idee","Apri e segui i ticket sulla bacheca, raccoglili in milestone, fai domande e trasforma le idee votate in lavoro.",30,"use",{"path":171,"title":172,"description":173,"order":174,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Ferrors","Errori","Come gli errori delle tue app diventano righe uniche, e come risolverli, ignorarli, fonderli o trasformarli in ticket.",31,{"path":176,"title":177,"description":178,"order":179,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fperformance","Performance","Trova le query e i metodi lenti, leggi i problemi riconosciuti da soli e ricevi un avviso quando ne compare uno.",32,{"path":181,"title":182,"description":183,"order":184,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Flogs","Log","Cerca i messaggi delle tue app, segui una richiesta dall'inizio alla fine e collega un messaggio a un errore o a un ticket.",33,{"path":186,"title":187,"description":188,"order":189,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fsecrets","Segreti","Password, chiavi e file riservati in un posto solo, per progetto e ambiente, letti dall'app senza un .env sul disco.",34,{"path":191,"title":192,"description":193,"order":194,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fservers","Server","Lo stato delle tue macchine in una pagina, con lo storico e gli avvisi quando qualcosa si rompe o si sta riempiendo.",35,{"path":196,"title":197,"description":198,"order":199,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fuptime","Uptime","Controlla che i tuoi siti rispondano, tiene il conto dei guasti e li mostra ai clienti su una pagina di stato.",36,{"path":201,"title":202,"description":203,"order":204,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fcrons","Lavori programmati","Accorgersi quando un lavoro che deve partire da solo smette di partire, o parte e finisce male.",37,{"path":206,"title":207,"description":208,"order":209,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Falerts","Avvisi","Le regole che fanno nascere un avviso, il centro notifiche e dove ognuno sceglie di riceverli.",38,{"path":211,"title":212,"description":213,"order":214,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fhelpdesk","Assistenza","Chi visita il sito di un progetto scrive al team con il bottone «Serve aiuto?», e la richiesta arriva nel progetto giusto.",39,{"path":216,"title":217,"description":218,"order":219,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fanalytics","Statistiche del sito","Quante persone visitano il sito, cosa guardano e da dove arrivano, senza cookie.",40,{"path":221,"title":222,"description":223,"order":224,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Freplays","Session replay","Registra la navigazione di chi usa il sito e la riguardi come un video, anche accanto a un errore.",41,{"path":226,"title":227,"description":228,"order":229,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Freleases","Release","Le versioni che girano in ogni ambiente, legate ai tag di GitHub, e gli errori che tornano dopo una correzione.",42,{"path":231,"title":232,"description":233,"order":234,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fvulnerabilities","Vulnerabilità","I problemi di sicurezza noti nelle librerie dei tuoi progetti e i linguaggi che non ricevono più correzioni.",43,{"path":236,"title":237,"description":238,"order":239,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fseo","SEO","CloseYourIt visita i tuoi siti come un motore di ricerca e ti dice cosa impedisce alle pagine di essere trovate.",44,{"path":241,"title":242,"description":243,"order":244,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fknowledge","Knowledge base","Scrivi note, decisioni e guide dei progetti, ritrovale per significato e fai domande con le fonti.",45,{"path":246,"title":247,"description":248,"order":249,"group":169,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fagents","Agenti AI","Quali ticket prendono gli agenti, cosa ti consegnano, dove decidi tu e come si misura ogni macchina.",46,{"path":251,"title":252,"description":253,"order":254,"group":14,"parent":8,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog","Versioni","Ogni sistema di CloseYourIt con la sua ultima versione, e le note di ogni rilascio.",50,{"path":256,"title":257,"description":258,"order":259,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-app","App","Tutte le versioni stabili di App, dalla più recente.",51,"changelog",{"path":262,"title":263,"description":264,"order":265,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-cli","Riga di comando (cyi)","Tutte le versioni stabili di Riga di comando (cyi), dalla più recente.",52,{"path":267,"title":141,"description":268,"order":269,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-automator","Tutte le versioni stabili di Automator, dalla più recente.",53,{"path":271,"title":272,"description":273,"order":274,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-agent-server","Agente per server","Tutte le versioni stabili di Agente per server, dalla più recente.",54,{"path":276,"title":277,"description":278,"order":279,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-agent-kubernetes","Agente Kubernetes","Tutte le versioni stabili di Agente Kubernetes, dalla più recente.",55,{"path":281,"title":282,"description":283,"order":284,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-sdk-javascript","SDK JavaScript","Tutte le versioni stabili di SDK JavaScript, dalla più recente.",56,{"path":286,"title":287,"description":288,"order":289,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-sdk-ruby","SDK Ruby","Tutte le versioni stabili di SDK Ruby, dalla più recente.",57,{"path":291,"title":292,"description":293,"order":294,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-sdk-python","SDK Python","Tutte le versioni stabili di SDK Python, dalla più recente.",58,{"path":296,"title":297,"description":298,"order":299,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-sdk-dart","SDK Dart","Tutte le versioni stabili di SDK Dart, dalla più recente.",59,{"path":301,"title":302,"description":303,"order":304,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-skills","Skill per assistenti AI","Tutte le versioni stabili di Skill per assistenti AI, dalla più recente.",60,{"path":306,"title":307,"description":308,"order":309,"group":8,"parent":260,"package":8,"note":8,"collects":8,"status":8},"\u002Fdocs\u002Fchangelog-site","Sito e documentazione","Tutte le versioni stabili di Sito e documentazione, dalla più recente.",61,{"id":311,"title":287,"body":312,"collects":8,"description":288,"extension":2273,"group":8,"meta":2274,"navigation":2275,"note":8,"order":289,"package":8,"parent":260,"path":286,"seo":2276,"status":8,"stem":2277,"__hash__":2278},"docs_it\u002Fdocs\u002Fchangelog-sdk-ruby.md",{"type":313,"value":314,"toc":2247},"minimark",[315,320,327,337,341,345,385,389,394,412,416,424,428,432,440,444,449,457,461,469,473,477,489,493,519,523,527,549,553,557,575,579,583,594,598,602,610,614,618,660,665,737,741,745,797,801,875,879,883,1125,1129,1323,1328,1436,1440,1444,1503,1507,1511,1547,1551,1713,1717,1721,1752,1756,1760,1820,1824,1828,1883,1887,1926,1930,1934,1985,1989,1993,2117,2121,2135,2139,2143,2151,2155,2159,2219,2223,2238,2242],[316,317,319],"h2",{"id":318},"_0121-2026-10-07","0.12.1 · 2026-10-07",[321,322,323],"p",{},[324,325,326],"strong",{},"Corretto",[328,329,330],"ul",{},[331,332,333,336],"li",{},[324,334,335],{},"La 0.12.0 non è arrivata su RubyGems."," Questa versione contiene le stesse modifiche.",[316,338,340],{"id":339},"_0120-2026-10-07","0.12.0 · 2026-10-07",[321,342,343],{},[324,344,326],{},[328,346,347,361,371],{},[331,348,349,357,358,360],{},[324,350,351,352,356],{},"Il body della richiesta resta a casa senza ",[353,354,355],"code",{},"send_pii","."," Con la privacy spenta i parametri dei form non vengono più allegati agli errori, come promesso dalla documentazione. Chi li vuole attiva ",[353,359,355],{},". (CYRB-28)",[331,362,363,366,367,370],{},[324,364,365],{},"I filtri di Rails valgono anche per la gemma."," Le chiavi dichiarate in ",[353,368,369],{},"config.filter_parameters"," dell'app vengono redatte in errori, tag e metriche senza ripeterle nella configurazione. (CYRB-28)",[331,372,373,376,377,380,381,384],{},[324,374,375],{},"Argomenti dei metodi lenti redatti."," Con ",[353,378,379],{},"capture_method_arguments"," anche gli argomenti posizionali passano dallo scrubber dei messaggi (credenziali e ",[353,382,383],{},"scrub_message_patterns","). (CYRB-28)",[316,386,388],{"id":387},"_0110-2026-10-04","0.11.0 · 2026-10-04",[321,390,391],{},[324,392,393],{},"Aggiunto",[328,395,396,402],{},[331,397,398,401],{},[324,399,400],{},"Contesto dei tentativi di lavoro."," ActiveJob e Sidekiq inviano il contesto job v1 con durata, attesa e ritardo programmato separati. Tempi o esiti non osservabili restano sconosciuti. (CYRA-972)",[331,403,404,407,408,411],{},[324,405,406],{},"Log del ciclo di vita dei job."," L'opzione ",[353,409,410],{},"job_lifecycle_logs",", spenta per default, registra gli esiti osservati senza argomenti o risultati e senza duplicare ActiveJob dentro Sidekiq. (CYRA-972)",[321,413,414],{},[324,415,326],{},[328,417,418],{},[331,419,420,423],{},[324,421,422],{},"SQL protetto anche con stringhe dollar-quoted."," I valori PostgreSQL racchiusi fra delimitatori dollar-quoted vengono redatti prima dell'invio della telemetria.",[316,425,427],{"id":426},"_0102-2026-10-01","0.10.2 · 2026-10-01",[321,429,430],{},[324,431,326],{},[328,433,434],{},[331,435,436,439],{},[324,437,438],{},"Pubblicazione riparata."," La 0.10.1 non è arrivata su RubyGems: questa versione contiene le stesse modifiche.",[316,441,443],{"id":442},"_0101-2026-10-01","0.10.1 · 2026-10-01",[321,445,446],{},[324,447,448],{},"Modificato",[328,450,451],{},[331,452,453,456],{},[324,454,455],{},"Le query dell'app costano meno."," Il punto del codice da cui parte una query si calcola solo per quelle lente o da analizzare, non più per ogni query. (CYRB-26)",[321,458,459],{},[324,460,326],{},[328,462,463],{},[331,464,465,468],{},[324,466,467],{},"L'attesa in coda dei lavori non conta più i rinvii voluti."," Un lavoro rimandato apposta, o ritentato dopo un errore, risultava in ritardo anche se partiva puntuale. Ora l'attesa si misura dall'ora prevista di partenza. (CYRB-27)",[316,470,472],{"id":471},"_0100-2026-09-14","0.10.0 · 2026-09-14",[321,474,475],{},[324,476,393],{},[328,478,479],{},[331,480,481,484,485,488],{},[324,482,483],{},"Si sceglie quanto attendere alla chiusura."," Nuova opzione ",[353,486,487],{},"shutdown_timeout",": dice quanto tempo dare all'invio degli eventi rimasti prima di chiudere. (CYRB-24)",[321,490,491],{},[324,492,326],{},[328,494,495,501,507,513],{},[331,496,497,500],{},[324,498,499],{},"Alla chiusura del programma gli eventi in coda non si perdono più in silenzio."," L'attesa era troppo corta e l'ultimo gruppo spariva, dato per consegnato. Ora l'attesa basta a completare l'invio e ciò che resta indietro viene contato. (CYRB-24)",[331,502,503,506],{},[324,504,505],{},"Un messaggio malformato non porta più via gli altri."," In un gruppo di voci di registro viene scartata solo quella che dà problemi: le altre partono. (CYRB-24)",[331,508,509,512],{},[324,510,511],{},"La misurazione dei tempi non fa più fallire il metodo dell'applicazione."," Un guasto interno alla misurazione tornava a chi aveva chiamato il metodo. Ora viene registrato e assorbito. (CYRB-24)",[331,514,515,518],{},[324,516,517],{},"I controlli automatici tornano a girare su ogni proposta di modifica."," Le verifiche erano ferme e le modifiche passavano senza prova. Ora ogni proposta viene controllata prima di essere unita. (CITM-8)",[316,520,522],{"id":521},"_094-2026-09-07","0.9.4 · 2026-09-07",[321,524,525],{},[324,526,326],{},[328,528,529,539],{},[331,530,531,534,535,538],{},[324,532,533],{},"La credenziale nel testo di un messaggio non parte più in chiaro"," (CYRB-23). Un\n",[353,536,537],{},"Authorization: Bearer …"," finito in un errore o in un log ora è redatto di serie, senza\nconfigurazione: restano leggibili chiave e schema, sparisce il valore.",[331,540,541,544,545,548],{},[324,542,543],{},"Il token non segue più un redirect su un'altra porta"," (CYRB-22). Un redirect che teneva lo stesso\nnome host ma cambiava porta riceveva ancora il ",[353,546,547],{},"Bearer",": sullo stesso server è un servizio diverso.\nOra l'invio richiede stesso host, stessa porta e schema non degradato.",[316,550,552],{"id":551},"_093-2026-09-03","0.9.3 · 2026-09-03",[321,554,555],{},[324,556,448],{},[328,558,559],{},[331,560,561,564,565,574],{},[324,562,563],{},"Il README dice dove finisce la gemma e dove iniziano gli altri SDK"," (CYRB-21). Non lascia più\nintendere di fare le stesse cose di JavaScript, Dart e Python: dice cosa esiste solo qui e rimanda\nalla tabella unica di cosa c'è dove\n(",[566,567,571],"a",{"href":568,"rel":569},"https:\u002F\u002Fgithub.com\u002Fbussolabs\u002Fcloseyourit-docs\u002Fblob\u002Fmain\u002Fcompatibility\u002Fsdk-feature-parity.md",[570],"nofollow",[353,572,573],{},"sdk-feature-parity.md",").",[316,576,578],{"id":577},"_092-2026-08-31","0.9.2 · 2026-08-31",[321,580,581],{},[324,582,326],{},[328,584,585],{},[331,586,587,593],{},[324,588,589,592],{},[353,590,591],{},"CloseYourIt.used"," è davvero chiamabile."," Il punto d'ingresso della telemetria d'uso era\nfinito per sbaglio fra i metodi interni; e due rami senza prova tenevano il rilascio sotto la\nsoglia di copertura. La 0.9.1 esiste come etichetta ma non è mai stata pubblicata.",[316,595,597],{"id":596},"_091-2026-08-31","0.9.1 · 2026-08-31",[321,599,600],{},[324,601,326],{},[328,603,604],{},[331,605,606,609],{},[324,607,608],{},"Il rilascio non si ferma più su se stesso."," Il controllo che confronta l'etichetta del rilascio\ncol numero dentro la libreria aveva quel numero scritto a mano nei propri test: ogni aggiornamento\nli faceva diventare rossi. Ora lo leggono dalla libreria. La 0.9.0 esiste come etichetta ma non è\nmai stata pubblicata: si è fermata qui.",[316,611,613],{"id":612},"_090-2026-08-31","0.9.0 · 2026-08-31",[321,615,616],{},[324,617,393],{},[328,619,620],{},[331,621,622,625,626,629,630,633,634,637,638,641,642,645,646,649,650,653,654,657,658,356],{},[324,623,624],{},"Telemetria d'uso (CYSK-29)",": la gemma dichiara quali rotte (",[353,627,628],{},"Controller#action",", mai l'URL),\njob e chiavi custom (",[353,631,632],{},"CloseYourIt.used(\"chiave\")",") vengono davvero eseguiti — un flush ogni 5\nminuti per processo verso ",[353,635,636],{},"\u002Fapi\u002Fv1\u002Fprojects\u002F:id\u002Fusages",". I conteggi sono indicativi, solo\n",[353,639,640],{},"last_seen_at"," è portante; oltre ",[353,643,644],{},"usage_max_symbols"," (2000) il flush dichiara ",[353,647,648],{},"truncated",", che\nlato scanner squalifica il kind. Nessun dato utente nel payload per costruzione. Interruttori:\n",[353,651,652],{},"usage_enabled"," (default ON), ",[353,655,656],{},"usage_flush_interval",", ",[353,659,644],{},[321,661,662],{},[324,663,664],{},"Sicurezza",[328,666,667,688],{},[331,668,669,672,673,676,677,680,681,684,685,687],{},[324,670,671],{},"Non si pubblica più una versione col nome di un'altra",": prima di toccare RubyGems il rilascio\nconfronta il numero scritto sull'etichetta con quello scritto dentro la libreria, e li pretende\nidentici lettera per lettera. Finora non li guardava nessuno: ",[353,674,675],{},"rake release"," pubblicava il numero\ndel gemspec qualunque cosa dicesse l'etichetta, e quando poi bundler cercava fra i tag quello che\naveva appena pubblicato non lo trovava — così se lo creava da solo. Nasceva un rilascio che nessuna\npersona aveva deciso, e il giro finiva verde. Adesso si ferma prima, e scrive quali sono i due\nnumeri che non tornano. Il confronto è fra stringhe di proposito: per le regole delle versioni Ruby\n",[353,678,679],{},"0.8"," e ",[353,682,683],{},"0.8.0"," sono lo stesso numero, ma chi legge l'annuncio di una ",[353,686,679],{}," cercherebbe su RubyGems\nuna versione che non esisterà mai.",[331,689,690,693,694,697,698,657,701,704,705,708,709,712,713,716,717,720,721,724,725,728,729,732,733,736],{},[324,691,692],{},"Hardening della supply chain CI"," (CYRB-16): le action di terze parti (",[353,695,696],{},"actions\u002Fcheckout",",\n",[353,699,700],{},"ruby\u002Fsetup-ruby",[353,702,703],{},"rubygems\u002Frelease-gem",") sono ora fissate al ",[324,706,707],{},"commit SHA"," con il tag versione a\ncommento, non più a un tag mobile che l'owner può ripuntare a un commit arbitrario; i workflow\ndichiarano permessi ",[324,710,711],{},"least-privilege"," (",[353,714,715],{},"contents: read"," di default, ",[353,718,719],{},"write"," + ",[353,722,723],{},"id-token"," solo nel\njob che pubblica); Dependabot presidia gemme di sviluppo e action tenendo i ",[324,726,727],{},"major come PR\nseparate",". Nessun impatto sul runtime della gemma (",[353,730,731],{},"concurrent-ruby"," invariato): cambia solo come la\nCI si costruisce. Un nuovo spec \"meta\" (",[353,734,735],{},"ci_hardening_spec",") impedisce di reintrodurre un riferimento\nmutabile o un token troppo ampio.",[316,738,740],{"id":739},"_080-2026-08-01","0.8.0 · 2026-08-01",[321,742,743],{},[324,744,393],{},[328,746,747],{},[331,748,749,752,753,756,757,712,762,765,766,769,770,773,774,776,777,780,781,784,785,788,789,792,793,796],{},[324,750,751],{},"Propagazione del trace context W3C"," (CYRB-15): opt-in (",[353,754,755],{},"propagate_trace_context",", default OFF) per\ncorrelare le richieste Ruby e le chiamate in uscita con lo standard\n",[566,758,761],{"href":759,"rel":760},"https:\u002F\u002Fwww.w3.org\u002FTR\u002Ftrace-context\u002F",[570],"W3C Trace Context",[353,763,764],{},"traceparent","\u002F",[353,767,768],{},"tracestate","), senza formato\nproprietario. In ",[324,771,772],{},"ingresso"," un ",[353,775,764],{}," valido diventa il ",[353,778,779],{},"trace_id"," degli eventi CloseYourIt, così\nerrore e metrica della richiesta si allineano alla traccia distribuita; un header malformato viene ignorato\ne si genera un root. In ",[324,782,783],{},"uscita"," gli header sono iniettati ",[324,786,787],{},"solo"," verso gli host di\n",[353,790,791],{},"trace_propagation_allowlist"," (default vuoto = nessuna destinazione), mai verso l'endpoint CloseYourIt né\nverso host esterni; un redirect verso un host non elencato non riceve nulla. ",[353,794,795],{},"baggage"," non viene mai emesso.",[321,798,799],{},[324,800,326],{},[328,802,803],{},[331,804,805,808,809,812,813,816,817,820,821,765,824,827,828,831,832,836,837,840,841,844,845,847,848,850,851,853,854,857,858,860,861,816,864,867,868,871,872,874],{},[324,806,807],{},"Un errore ritentato non è più segnalato una volta per tentativo"," (CYRB-19): l'",[353,810,811],{},"around_perform"," che\ncattura gli errori dei job gira ",[324,814,815],{},"dentro"," ",[353,818,819],{},"perform_now",", mentre ",[353,822,823],{},"retry_on",[353,825,826],{},"discard_on"," (rescue_from)\nsono valutati ",[324,829,830],{},"fuori",", dopo i callback — così ogni tentativo veniva segnalato come errore non gestito\n(e ogni tentativo solleva una nuova istanza, quindi la deduplica per-istanza non interviene). Un errore\npasseggero che si risolveva al secondo tentativo ne generava comunque due, gonfiando conteggi, allarmi e\ncorsa verso i limiti (sul campo: 2.033 eventi ",[833,834,835],"em",{},"rate limited",", il 74,7% erano ripetizioni di retry). Su\nActiveJob ",[324,838,839],{},"7.1+"," la segnalazione passa ad ",[353,842,843],{},"after_discard",", invocato da Rails al fallimento definitivo,\nmai sui tentativi che ",[353,846,823],{}," ritenta: un ",[353,849,823],{}," riuscito non produce errori, un ",[353,852,823],{},"\nesaurito produce ",[324,855,856],{},"una sola"," occorrenza — con i breadcrumb e i tag raccolti durante l'esecuzione\npreservati nel report. Sulle versioni prive di ",[353,859,843],{}," resta il comportamento precedente (fallback\nlegacy). Due conseguenze da conoscere: gli errori intercettati da un ",[353,862,863],{},"rescue_from",[324,865,866],{},"custom"," non sono più\nsegnalati (sono gestiti dall'app: prima li marcavamo impropriamente come non gestiti); i retry a livello\ndi ",[324,869,870],{},"adapter"," (es. Sidekiq) senza ",[353,873,823],{}," risollevano l'errore non gestito e restano quindi segnalati\na ogni esecuzione, come prima.",[316,876,878],{"id":877},"_070-2026-07-30","0.7.0 · 2026-07-30",[321,880,881],{},[324,882,393],{},[328,884,885,952,1001,1009,1050,1072],{},[331,886,887,890,891,894,895,898,899,902,903,906,907,910,911,914,915,657,918,657,920,923,924,680,927,712,929,765,932,935,936,939,940,943,944,947,948,951],{},[324,888,889],{},"Metriche dei background job"," (CYRB-14): ",[353,892,893],{},"slow_job"," (durata del ",[353,896,897],{},"perform"," oltre soglia) e\n",[353,900,901],{},"job_queue_latency"," (attesa enqueue→esecuzione oltre soglia) per ActiveJob e Sidekiq, come metriche\n",[353,904,905],{},"performance_issue",". Ogni metrica porta ",[353,908,909],{},"label"," (nome della classe del job — ",[324,912,913],{},"mai"," gli argomenti),\n",[353,916,917],{},"queue",[353,919,870],{},[353,921,922],{},"attempt"," (i retry diventano visibili), ",[353,925,926],{},"release",[353,928,779],{},[353,930,931],{},"job_id",[353,933,934],{},"jid","),\ncosì log ed errore dello stesso job si correlano. Nuove opzioni ",[353,937,938],{},"monitor_jobs"," (ON di default:\nvedere i job lenti non deve richiedere strumentazione manuale in ogni app), ",[353,941,942],{},"slow_job_threshold_ms","\n(5000), ",[353,945,946],{},"job_queue_latency_threshold_ms"," (60000), ",[353,949,950],{},"jobs_sample_rate"," (1.0). Il middleware Sidekiq\nri-solleva sempre gli errori del job ospite: la telemetria è isolata.",[331,953,954,961,962,965,966,657,969,657,972,657,975,697,978,981,982,985,986,989,990,993,994,997,998,356],{},[324,955,956,957,960],{},"Hook diagnostico ",[353,958,959],{},"on_diagnostic"," + contatori estesi"," (CYRB-12): ",[353,963,964],{},"->(event, details)"," opt-in,\ninvocato a ogni tappa del ciclo di vita di un evento (",[353,967,968],{},":enqueue",[353,970,971],{},":send",[353,973,974],{},":drop",[353,976,977],{},":timeout",[353,979,980],{},":shutdown",") con dettagli privi di dati sensibili. È ",[324,983,984],{},"locale e non ricorsivo",": non invia\ntelemetria, quindi non può innescare un loop di auto-monitoraggio. Nuovo contatore ",[353,987,988],{},"timeout"," (come\nsotto-conteggio di ",[353,991,992],{},"failed",") e alias ",[353,995,996],{},"snapshot"," su ",[353,999,1000],{},"Stats",[331,1002,1003,1008],{},[324,1004,1005],{},[353,1006,1007],{},"CloseYourIt.after_fork"," (CYRB-11): hook per i worker dei server che precaricano l'app.",[331,1010,1011,1017,1018,1021,1022,1025,1026,1029,1030,1033,1034,1037,1038,1041,1042,1045,1046,1049],{},[324,1012,1013,1014],{},"Config ",[353,1015,1016],{},"excluded_log_patterns"," (default ",[353,1019,1020],{},"[]","): righe del broadcast ",[353,1023,1024],{},"Rails.logger"," da scartare in\nbase al ",[324,1027,1028],{},"testo",", per il rumore ripetuto che non è un'eccezione e che quindi ",[353,1031,1032],{},"excluded_exceptions","\nnon può coprire (es. ",[353,1035,1036],{},"\u002FSolidQueue-[\\d.]+ Error in thread\u002F","). I ",[353,1039,1040],{},"Regexp"," valgono come pattern, le\n",[353,1043,1044],{},"String"," come testo letterale (vengono escapate: chi scrive ",[353,1047,1048],{},"\"Error in thread (0.0ms)\""," non si\naspetta che parentesi e punto siano metacaratteri).",[331,1051,1052,1058,1059,720,1061,1063,1064,1067,1068,1071],{},[324,1053,1054,1055],{},"Predicato pubblico ",[353,1056,1057],{},"CloseYourIt.ignored_log_message?(text)",": risponde se una riga di log va\nscartata secondo ",[353,1060,1032],{},[353,1062,1016],{},". Reso pubblico per lo stesso motivo\ndi ",[353,1065,1066],{},"logs_active?"," — serve a un collaboratore (",[353,1069,1070],{},"LogBroadcast",") per non fare lavoro inutile.",[331,1073,1074,1079,1080,1083,1084,1087,1088,657,1091,657,1094,1097,1098,1101,1102,1105,1106,1108,1109,1112,1113,1116,1117,1120,1121,1124],{},[324,1075,1013,1076],{},[353,1077,1078],{},"excluded_query_patterns"," (CYRB-18): query da ",[324,1081,1082],{},"non"," misurare come rallentamento, match\nsul testo SQL. Default ",[324,1085,1086],{},"non vuoto",": ",[353,1089,1090],{},"solid_queue_",[353,1092,1093],{},"solid_cache_",[353,1095,1096],{},"solid_cable_",". Le tabelle di\nservizio del Solid stack sono infrastruttura del framework — una loro query lenta non si corregge\nleggendo il proprio repo, dice solo che il database è in contesa (cosa che le query dell'app\nraccontano già), e in compenso sommerge il segnale utile: su closeyourit-rails il 2026-07-30 erano\ncirca ",[324,1099,1100],{},"2.740 campioni su 4.400 (62%)",", tutti fra i 250 e i 655 ms. Chi vuole misurarle azzera la\nlista. ",[353,1103,1104],{},"\\b"," in testa a ogni pattern: una tabella dell'app che contenga ",[353,1107,917],{}," nel nome non sparisce\nper assonanza.",[1110,1111],"br",{},"Il filtro vale solo per la ",[324,1114,1115],{},"misura",", non per ",[353,1118,1119],{},"#breadcrumb"," né per ",[353,1122,1123],{},"#profile",": la cronologia «quali\nquery prima del crash» resta completa (nasconderne un pezzo la renderebbe bugiarda) e il profiling\nN+1 continua a vedere tutto, perché lì una tabella di servizio letta molte volte è essa stessa un\nsintomo. Un rallentamento va misurato se qualcuno può intervenire; una breadcrumb va tenuta se aiuta\na capire — due domande diverse.",[321,1126,1127],{},[324,1128,326],{},[328,1130,1131,1161,1190,1221,1249,1302],{},[331,1132,1133,1136,1137,1140,1141,1144,1145,1148,1149,1152,1153,1156,1157,1160],{},[324,1134,1135],{},"La gemma riparte nel processo figlio dopo un fork"," (CYRB-11): i server che precaricano l'app (Puma\ncluster, Sidekiq, Unicorn) inizializzano la gemma nel master e poi forkano. Il worker pool e il\n",[353,1138,1139],{},"TimerTask"," del buffer sono ",[324,1142,1143],{},"thread",", e i thread non sopravvivono al fork: nel figlio ",[353,1146,1147],{},"@client"," e\n",[353,1150,1151],{},"@log_buffer"," erano ereditati ma ",[324,1154,1155],{},"inerti",", e nessun evento partiva più. Ora il cambio di PID viene\nrilevato (lazy, al primo accesso) e le risorse ricreate nel processo corrente. I riferimenti\nereditati vengono abbandonati ",[324,1158,1159],{},"senza"," shutdown né drain: nessun join sui thread del padre, e\nnessun flush del suo buffer — rispedirebbe eventi che non sono di questo processo.",[331,1162,1163,1166,1167,1170,1171,1148,1173,1175,1176,1178,1179,1182,1183,1185,1186,1189],{},[324,1164,1165],{},"Re-inizializzare non perde più gli eventi in coda"," (CYRB-10): ",[353,1168,1169],{},"init"," azzerava ",[353,1172,1147],{},[353,1174,1151],{}," senza spegnerli, lasciando orfani il thread del worker pool e il ",[353,1177,1139],{},"; gli\neventi accodati venivano persi, o flushati fuori tempo con la ",[324,1180,1181],{},"vecchia"," credenziale. Ora ",[353,1184,1169],{},"\napplica al client precedente la semantica di fine-vita di ",[353,1187,1188],{},"#shutdown"," (flush del buffer → drain del\nworker con timeout) prima di sostituirlo. Idempotente.",[331,1191,1192,1195,1196,1199,1200,1202,1203,1209,1210,1213,1214,1217,1218,1220],{},[324,1193,1194],{},"La gemma si installa davvero su Ruby 4.0"," (CYRB-13): la CI la provava solo dentro il proprio\nbundle, dove le stdlib estratte e ",[353,1197,1198],{},"rack"," arrivano da altre gemme — un'app reale che installava solo\n",[353,1201,47],{}," su Ruby 4.0 ",[324,1204,1205,1206],{},"falliva il ",[353,1207,1208],{},"require",". Il gemspec ora dichiara ",[353,1211,1212],{},"logger"," (da Ruby\n4.0 non è più una default gem) e ",[353,1215,1216],{},"rack\u002Futils"," è caricato lazy dentro il middleware, così il require\ndella gemma non forza ",[353,1219,1198],{}," nelle app non-web.",[331,1222,1223,1226,1227,1230,1231,1234,1235,1237,1238,1241,1242,1245,1246,1248],{},[324,1224,1225],{},"Nessun batch di log perso in silenzio"," (CYRB-12): i log scartati da ",[353,1228,1229],{},"before_send"," incrementano\n",[353,1232,1233],{},"dropped"," ed emettono ",[353,1236,974],{}," come già faceva ",[353,1239,1240],{},"capture_event",", e un batch perso perché ",[353,1243,1244],{},"flush_logs","\nsolleva viene contabilizzato invece di svanire. ",[353,1247,980],{}," viene emesso una sola volta per sessione.",[331,1250,1251,1259,1260,1263,1264,1267,1268,1271,1272,1275,1276,1278,1279,1282,1283,1286,1287,1290,1291,1294,1295,1297,1298,1301],{},[324,1252,1253,1254,1256,1257],{},"Il broadcast di ",[353,1255,1024],{}," rispetta ",[353,1258,1032],{}," (CYRB-17): un'eccezione esclusa dal\ncanale ",[324,1261,1262],{},"errori"," rientrava da quello dei ",[324,1265,1266],{},"log",". Rails la registra comunque con ",[353,1269,1270],{},"logger.error",", e\n",[353,1273,1274],{},"LogBroadcast#add"," inoltrava la riga senza guardarne il testo — così il rumore che\n",[353,1277,1032],{}," aveva appena scartato ricompariva come log-entry. Misurato sul backend il\n2026-07-30: ",[324,1280,1281],{},"48.000 voci su 49.985"," nello stream cross-app, quasi tutte\n",[353,1284,1285],{},"ActionController::RoutingError"," da favicon mancanti e scansioni di bot, cioè una classe presente\nnelle esclusioni di ",[324,1288,1289],{},"default"," dalla prima riga della gemma. Il filtro guarda il testo (qui la\nclasse arriva come stringa dentro il messaggio, non come oggetto con ",[353,1292,1293],{},"ancestors",") e vive\nesclusivamente in ",[353,1296,1070],{},": un ",[353,1299,1300],{},"CloseYourIt.log"," scritto di proposito dallo sviluppatore non\nviene mai silenziato, perché chi lo scrive ha già deciso che vuole quella riga.",[331,1303,1304,1310,1311,1314,1315,1318,1319,1322],{},[324,1305,1306,1307],{},"Il filtro copre anche la forma lazy ",[353,1308,1309],{},"logger.error { ... }",": il testo viene valutato ",[324,1312,1313],{},"dopo"," lo\n",[353,1316,1317],{},"yield",". Guardando solo l'argomento posizionale (che in quella forma è ",[353,1320,1321],{},"nil",") ogni riga costruita\nlazy avrebbe scavalcato le esclusioni.",[321,1324,1325],{},[324,1326,1327],{},"Interno",[328,1329,1330,1362,1374,1391],{},[331,1331,1332,1335,1336,1339,1342,1343,1346,1347,1350,1351,1354,1355,1357,1358,1361],{},[324,1333,1334],{},"La CI verifica la gemma su una matrice Ruby con smoke install isolato"," (CYRB-13): minima ",[324,1337,1338],{},"esatta",[353,1340,1341],{},"4.0.0"," (prima ",[353,1344,1345],{},"\"4.0\""," installava l'ultima patch, lasciando la minima dichiarata non testata) più la\ncorrente derivata da ",[353,1348,1349],{},".ruby-version",", così la matrice non diverge dal runtime. Nuovo step che\ncostruisce la gemma e la installa in un ",[353,1352,1353],{},"GEM_HOME"," isolato verificando ",[353,1356,1208],{},", config no-op e API\npubblica; la release dipende da questo gate su ",[324,1359,1360],{},"tutte"," le versioni.",[331,1363,1364,1367,1368,1370,1371,356],{},[324,1365,1366],{},"Gate di branch coverage a 90"," (CYRB-13): la sola line coverage (97%) mascherava rami difensivi mai\nesercitati — guardie no-op da client disabilitato, path ",[353,1369,1321],{},", percorsi d'errore del transport.\nPortata da 84,5% a 90,7% e resa vincolante con ",[353,1372,1373],{},"COVERAGE_ENFORCE=1",[331,1375,1376,1377,1379,1380,1383,1384,997,1387,1390],{},"Chiusi due rami mai esercitati di ",[353,1378,1274],{}," (forma con block, messaggio assente): la branch\ncoverage torna sopra il gate (",[324,1381,1382],{},"90,05%","), che si era riabbassato a ",[324,1385,1386],{},"89,72%",[353,1388,1389],{},"main"," dopo\nCYRB-14.",[331,1392,1393,1087,1396,1399,1400,1403,1404,816,1406,1409,1410,1413,1414,1417,1418,1421,1422,1424,1425,1428,1429,1431,1432,1435],{},[324,1394,1395],{},"Uno spec di CYRB-14 passava solo dentro un git worktree",[353,1397,1398],{},"omette i campi nil"," faceva\n",[353,1401,1402],{},"config.release = nil",", ma il reader ",[353,1405,926],{},[324,1407,1408],{},"auto-rileva"," (tag, ENV di deploy, ",[353,1411,1412],{},"git rev-parse",").\n",[353,1415,1416],{},"git_revision"," si autoesclude quando ",[353,1419,1420],{},".git"," non è una directory — vero in un worktree, dove ",[353,1423,1420],{}," è\nun file, ",[324,1426,1427],{},"falso"," in un checkout normale come quello di ",[353,1430,696],{},": lì ",[353,1433,1434],{},"detect_release","\nrestituiva lo short SHA e lo spec cadeva. Ora stubba il reader, perché quello che vuole verificare è\nl'assenza della release, non il modo in cui viene rilevata. Trovato preparando questa release: la CI\nnon aveva mai girato su quei commit, mai pushati.",[316,1437,1439],{"id":1438},"_061-2026-07-11","0.6.1 · 2026-07-11",[321,1441,1442],{},[324,1443,326],{},[328,1445,1446],{},[331,1447,1448,1453,1454,1456,1457,765,1460,765,1463,765,1466,1469,1470,765,1473,1475,1476,1479,1480,1483,1484,1486,1487,1490,1491,1494,1495,1498,1499,1502],{},[324,1449,1450,1452],{},[353,1451,1434],{}," preferisce il tag semver allo short SHA"," (CYRB-9): l'auto-rilevamento della\n",[353,1455,926],{}," usava solo le fonti SHA (",[353,1458,1459],{},"KAMAL_VERSION",[353,1461,1462],{},"GIT_SHA",[353,1464,1465],{},"GIT_REVISION",[353,1467,1468],{},"SOURCE_VERSION","\u002F\n",[353,1471,1472],{},"HEROKU_SLUG_COMMIT",[353,1474,1412],{},"), quindi allegava agli eventi il commit hash (es. ",[353,1477,1478],{},"d3ce2af",")\ninvece del tag semver (es. ",[353,1481,1482],{},"v0.0.43","), creando release duplicate lato backend che non convergevano\ncon quelle registrate dalla CI (che usa il tag). Ora ",[353,1485,1434],{}," legge prima un tag semver da\n",[353,1488,1489],{},"APP_GIT_TAG"," poi ",[353,1492,1493],{},"GIT_TAG"," (accettato solo se non-blank e con forma ",[353,1496,1497],{},"vX.Y.Z"," + eventuale suffisso\nprerelease\u002Fbuild), con le fonti SHA come fallback invariato. Valori non-semver (",[353,1500,1501],{},"unknown",", vuoto,\nnomi di branch) vengono ignorati.",[316,1504,1506],{"id":1505},"_060-2026-07-10","0.6.0 · 2026-07-10",[321,1508,1509],{},[324,1510,393],{},[328,1512,1513],{},[331,1514,1515,1017,1520,1523,1524,1527,1528,1531,1532,1534,1535,1538,1539,1542,1543,1546],{},[324,1516,1013,1517],{},[353,1518,1519],{},"trap_signals",[353,1521,1522],{},"false",", opt-in): quando attiva, ",[353,1525,1526],{},"CloseYourIt.init"," intercetta\n",[353,1529,1530],{},"SIGTERM"," e lo converte in un exit pulito, così il flush di fine-vita gira anche al deploy (Kamal\ninvia ",[353,1533,1530],{},", che di default salta gli ",[353,1536,1537],{},"at_exit","). Opt-in perché sovrascrive un eventuale handler\n",[353,1540,1541],{},"TERM"," dell'app ospite. Esposto anche il metodo pubblico ",[353,1544,1545],{},"CloseYourIt.shutdown"," per drenare a mano.",[321,1548,1549],{},[324,1550,326],{},[328,1552,1553,1607,1636,1664,1682,1699],{},[331,1554,1555,1561,1562,1564,1565,1017,1568,1571,1572,657,1575,1578,1579,1584,1585,1588,1589,1591,1592,1594,1595,1597,1598,765,1600,1603,1604,1606],{},[324,1556,1557,1560],{},[353,1558,1559],{},"capture_rails_logs"," non inonda più lo stream col rumore del framework"," (CYRB-7): il broadcast di\n",[353,1563,1024],{}," usava ",[353,1566,1567],{},"logs_min_level",[353,1569,1570],{},":info",") come soglia → in produzione ad alto traffico\nogni riga info del framework (",[353,1573,1574],{},"Started GET",[353,1576,1577],{},"Rendered",", ...) veniva inoltrata, saturando lo stream.\nOra la soglia del broadcast è governata dalla nuova opzione ",[324,1580,1581],{},[353,1582,1583],{},"capture_rails_logs_min_level"," (default\n",[353,1586,1587],{},":warn",", distinta da ",[353,1590,1567],{},"): il rumore info del framework resta fuori di default, chi lo\nvuole abbassa esplicitamente la soglia (es. ",[353,1593,1570],{},"). ",[353,1596,1567],{}," continua a governare\n",[353,1599,1300],{},[353,1601,1602],{},".logger",". Il README già prometteva la soglia ",[353,1605,1587],{}," ma il codice non la applicava.",[331,1608,1609,1612,1613,712,1616,1619,1620,1623,1624,1626,1627,1630,1631,1633,1634,356],{},[324,1610,1611],{},"Flush di fine-vita affidabile (CYRB-5)",": allo shutdown del processo il buffer log ora ",[324,1614,1615],{},"drena\nanche il worker asincrono",[353,1617,1618],{},"@client.shutdown"," → ",[353,1621,1622],{},"wait_for_termination",") dopo il flush, non solo\naccoda l'ultimo batch. Prima l'",[353,1625,1537],{}," flushava il buffer nel worker pool ma non attendeva\nl'invio: i log sotto-batch (\u003C ",[353,1628,1629],{},"logs_batch_size",", timer non ancora scattato) restavano in coda e\nvenivano persi alla terminazione. Vedi anche la nuova config ",[353,1632,1519],{}," per il caso ",[353,1635,1530],{},[331,1637,1638,1641,1642,1645,1646,1649,1650,765,1653,765,1656,1659,1660,1663],{},[324,1639,1640],{},"Denylist Scrubber allineata alla PII del backend"," (CYRB-3): la ",[353,1643,1644],{},"DENYLIST"," dello Scrubber era più\nstretta del regex ",[353,1647,1648],{},"SENSITIVE_KEY"," del backend\u002FDart — i bind di query e metodi lenti su colonne\n",[353,1651,1652],{},"email",[353,1654,1655],{},"phone",[353,1657,1658],{},"dob"," (e affini) NON venivano redatti e finivano nel pannello \"Parametri\" della\nmetric-group, visibili a ogni viewer. Aggiunti i token ",[353,1661,1662],{},"email phone telephone mobile dob birth passport bearer session pin pan","; il match per sottostringa privilegia l'over-redaction\n(privacy-by-default).",[331,1665,1666,1674,1675,1678,1679,1681],{},[324,1667,1668,1671,1672],{},[353,1669,1670],{},"capture_message"," ora emette ",[353,1673,779],{}," (parità con ",[353,1676,1677],{},"capture_exception","): i messaggi diagnostici\nsi correlano ai log\u002Ferrori della stessa richiesta come gli eventi d'errore (prima il ",[353,1680,779],{}," era\nomesso e i messaggi restavano scollegati).",[331,1683,1684,1687,1688,1690,1691,1694,1695,1698],{},[324,1685,1686],{},"Sicurezza redirect",": il ",[353,1689,547],{}," (segreto d'ingest) non viene più ri-inviato dopo un redirect verso\nun host diverso, né su un downgrade ",[353,1692,1693],{},"https→http"," — solo stesso host (o variante ",[353,1696,1697],{},"www",") e schema non\ndegradato. Evita di consegnare il token a un endpoint non fidato.",[331,1700,1701,1704,1705,1708,1709,1712],{},[324,1702,1703],{},"DX diagnostica",": su risposta non-2xx il log include ora il codice d'errore ",[353,1706,1707],{},"R…"," e il messaggio\ndall'envelope del backend (es. ",[353,1710,1711],{},"HTTP 422 R422-INGEST-001: Evento malformato","), non solo lo status.",[316,1714,1716],{"id":1715},"_050-2026-07-08","0.5.0 · 2026-07-08",[321,1718,1719],{},[324,1720,393],{},[328,1722,1723],{},[331,1724,1725,1728,1729,1732,1733,1736,1737,1740,1741,1744,1745,765,1748,1751],{},[324,1726,1727],{},"Correlazione errore server ↔ session replay",": il middleware ",[353,1730,1731],{},"RequestContext"," legge il cookie\n",[353,1734,1735],{},"cyi_replay"," (id opaco scritto dal browser SDK) e lo mette su ",[353,1738,1739],{},"Scope#replay_session_id","; l'evento\nd'errore lo emette in ",[353,1742,1743],{},"contexts.replay.replay_id"," (stesso punto del percorso JS) → il backend lega\nil 500 al video della sessione. ",[353,1746,1747],{},"replay",[353,1749,1750],{},"replay_id"," non sono chiavi sensibili (sopravvivono allo\nScrubber). Nessuna nuova config.",[316,1753,1755],{"id":1754},"_040-2026-07-02","0.4.0 · 2026-07-02",[321,1757,1758],{},[324,1759,393],{},[328,1761,1762,1790],{},[331,1763,1764,1767,1768,765,1771,765,1774,1777,1778,1781,1782,1785,1786,1789],{},[324,1765,1766],{},"Context lines nei frame dello stacktrace",": ogni frame con file sorgente leggibile porta\n",[353,1769,1770],{},"pre_context",[353,1772,1773],{},"context_line",[353,1775,1776],{},"post_context"," (config ",[353,1779,1780],{},"context_lines",", default 3, ",[353,1783,1784],{},"0"," disattiva;\n",[353,1787,1788],{},"LineCache"," bounded e thread-safe). L'error show del backend renderizza già lo snippet.",[331,1791,1792,1799,1800,1803,1804,1807,1808,1811,1812,1815,1816,1819],{},[324,1793,1794,1795,1798],{},"Body della richiesta nell'evento (",[353,1796,1797],{},"request.data",")",": estratto LAZY solo quando l'errore accade\n(mai sul percorso felice) — preferisce i params già parsati da Rails\u002FRack, fallback rilettura\n",[353,1801,1802],{},"rack.input"," con rewind (JSON\u002Fform, cap 64 KB). Sanitizzato (upload → ",[353,1805,1806],{},"[FILE: …]",", oggetti →\n",[353,1809,1810],{},"[OBJECT: …]",", stringhe troncate a 1024) e scrubbato (denylist + ",[353,1813,1814],{},"filter_parameters","); il backend\nri-scruba difensivamente. Config ",[353,1817,1818],{},"capture_request_body"," (default true).",[316,1821,1823],{"id":1822},"_034-2026-06-29","0.3.4 · 2026-06-29",[321,1825,1826],{},[324,1827,393],{},[328,1829,1830],{},[331,1831,1832,1835,1836,1839,1840,1843,1844,1847,1848,1851,1852,1855,1856,1855,1859,1862,1863,1866,1867,1869,1870,1872,1873,1876,1877,1879,1880,356],{},[324,1833,1834],{},"Rilevamento performance issue lato client"," (opt-in ",[353,1837,1838],{},"detect_performance_issues",", default OFF):\n",[353,1841,1842],{},"Performance::RequestProfile"," accumula per-richiesta le query (per fingerprint + call-site, stile\nprosopite) e le chiamate HTTP esterne; ",[353,1845,1846],{},"Performance::Rollup"," emette verdetti ",[353,1849,1850],{},"n_plus_one"," \u002F\n",[353,1853,1854],{},"high_query_count"," \u002F ",[353,1857,1858],{},"slow_request",[353,1860,1861],{},"slow_external_http"," come ",[353,1864,1865],{},"PerformanceIssueEvent","\n(kind ",[353,1868,905],{},", con ",[353,1871,779],{},") verso ",[353,1874,1875],{},"\u002Fmetrics",". ",[353,1878,779],{}," aggiunto anche a\n",[353,1881,1882],{},"SlowQueryEvent",[321,1884,1885],{},[324,1886,326],{},[328,1888,1889],{},[331,1890,1891,1896,1897,1900,1901,1904,1905,1908,1909,1911,1912,1915,1916,1918,1919,1921,1922,1925],{},[324,1892,1893,1895],{},[353,1894,1559],{}," non agganciava il broadcast"," (i log dell'app non arrivavano a CloseYourIt):\nl'initializer del railtie ",[353,1898,1899],{},"closeyourit.capture_rails_logs"," girava ",[324,1902,1903],{},"prima"," di\n",[353,1906,1907],{},"config\u002Finitializers\u002Fcloseyourit.rb"," (dove ",[353,1910,1526],{}," imposta ",[353,1913,1914],{},"capture_rails_logs = true","),\nquindi leggeva il default ",[353,1917,1522],{}," e non agganciava mai il broadcast di ",[353,1920,1024],{},". Aggiunto\n",[353,1923,1924],{},"after: :load_config_initializers"," all'initializer.",[316,1927,1929],{"id":1928},"_033-2026-06-29","0.3.3 · 2026-06-29",[321,1931,1932],{},[324,1933,326],{},[328,1935,1936,1959,1975],{},[331,1937,1938,1944,1945,1948,1949,657,1952,697,1955,1958],{},[324,1939,1940,1941],{},"Scrubber — chiavi ",[353,1942,1943],{},"pass*",": la denylist ometteva ",[353,1946,1947],{},"pass"," bare (",[353,1950,1951],{},"pass_code",[353,1953,1954],{},"passkey",[353,1956,1957],{},"passphrase",") → allineata 1:1 al regex di backend\u002FDart (parità client-side, niente leak).",[331,1960,1961,1974],{},[324,1962,1963,1964,765,1967,765,1970,1973],{},"Scope — ",[353,1965,1966],{},"tags",[353,1968,1969],{},"extra",[353,1971,1972],{},"contexts"," scrubbati client-side"," prima dell'invio: il backend non li\nri-scrubbava sugli errori, quindi era l'unica difesa contro le chiavi sensibili in quei campi.",[331,1976,1977,1984],{},[324,1978,1979,1980,1983],{},"Log — chunking del batch a ",[353,1981,1982],{},"LOGS_MAX_BATCH"," (1000)",": un flush oltre il limite del server veniva\nrigettato in blocco (413) coi log persi; ora è spezzato in più POST sequenziali.",[316,1986,1988],{"id":1987},"_032-2026-06-29","0.3.2 · 2026-06-29",[321,1990,1991],{},[324,1992,393],{},[328,1994,1995,2099],{},[331,1996,1997,2000,2001,2004,2005],{},[324,1998,1999],{},"Log strutturati"," verso l'ingest ",[353,2002,2003],{},"\u002Flogs"," di CloseYourIt:\n",[328,2006,2007,2018,2037,2053,2073],{},[331,2008,2009,2012,2013,1619,2015,574],{},[353,2010,2011],{},"CloseYourIt.log(level, message, logger:, **attributes)"," — costruisce e bufferizza una voce di log\n(livello normalizzato ai valori canonici del backend; ",[353,2014,1587],{},[353,2016,2017],{},"warning",[331,2019,2020,2023,2024,657,2027,657,2030,2033,2034,2036],{},[353,2021,2022],{},"CloseYourIt.logger"," — oggetto Logger-compatibile (",[353,2025,2026],{},"debug\u002Finfo\u002Fwarn\u002Ferror\u002Ffatal",[353,2028,2029],{},"\u003C\u003C",[353,2031,2032],{},"add",") che\ninoltra a ",[353,2035,1300],{},". Usabile come logger esplicito dell'app, anche con attributes.",[331,2038,2039,2042,2043,2045,2046,2049,2050,2052],{},[324,2040,2041],{},"Batching"," in-memory thread-safe: flush a ",[353,2044,1629],{}," (default 50), a ",[353,2047,2048],{},"logs_flush_interval","\n(default 5s) o allo shutdown (",[353,2051,1537],{},"); invio come array, fire-and-forget.",[331,2054,2055,712,2060,2063,2064,1017,2066,2068,2069,2072],{},[324,2056,2057,2058],{},"Broadcast opt-in di ",[353,2059,1024],{},[353,2061,2062],{},"config.capture_rails_logs",", default OFF): re-inoltra i log\ndell'app ≥ ",[353,2065,1567],{},[353,2067,1570],{},"). Richiede ",[353,2070,2071],{},"BroadcastLogger"," (Rails 7.1+).",[331,2074,2075,2076,657,2079,657,2082,657,2084,697,2086,657,2088,2090,2091,2094,2095,2098],{},"Opzioni: ",[353,2077,2078],{},"logs_enabled",[353,2080,2081],{},"logs_sample_rate",[353,2083,1629],{},[353,2085,2048],{},[353,2087,1559],{},[353,2089,1567],{},". Gli ",[353,2092,2093],{},"attributes"," passano dallo ",[353,2096,2097],{},"Scrubber"," (denylist PII).",[331,2100,2101,2105,2106,2108,2109,2112,2113,2116],{},[324,2102,2103],{},[353,2104,779],{}," per richiesta (",[353,2107,1731],{},"): riusa il request id di Rails\u002FRack se presente,\naltrimenti lo genera. Attaccato sia a ",[353,2110,2111],{},"LogEvent"," sia a ",[353,2114,2115],{},"ErrorEvent"," → correlazione log↔errori.",[321,2118,2119],{},[324,2120,448],{},[328,2122,2123],{},[331,2124,2125,2126,1342,2129,2131,2132,2134],{},"Il logger diagnostico interno della gemma è ora ",[353,2127,2128],{},"CloseYourIt.internal_logger",[353,2130,2022],{},");\n",[353,2133,2022],{}," è riservato al logging applicativo strutturato.",[316,2136,2138],{"id":2137},"_031-2026-06-28","0.3.1 · 2026-06-28",[321,2140,2141],{},[324,2142,326],{},[328,2144,2145],{},[331,2146,2147,2150],{},[353,2148,2149],{},"Transport",": segue fino a 2 redirect su POST preservando metodo + body (es. apex → www), così\nl'evento non si perde in silenzio quando l'host canonico risponde 301.",[316,2152,2154],{"id":2153},"_030-2026-06-28","0.3.0 · 2026-06-28",[321,2156,2157],{},[324,2158,393],{},[328,2160,2161,2178,2195,2198,2212],{},[331,2162,2163,2166,2167,657,2170,657,2172,697,2175,2177],{},[353,2164,2165],{},"CloseYourIt.stats",": contatori diagnostici thread-safe (",[353,2168,2169],{},"enqueued",[353,2171,1233],{},[353,2173,2174],{},"sent",[353,2176,992],{},") per rendere visibili i fallimenti silenziosi del trasporto fire-and-forget.",[331,2179,2180,2181,2184,2185,657,2188,657,2191,2194],{},"Il trasporto ora logga a ",[353,2182,2183],{},"warn"," le risposte HTTP non-2xx (es. ",[353,2186,2187],{},"401",[353,2189,2190],{},"404",[353,2192,2193],{},"500","),\nprima ignorate silenziosamente.",[331,2196,2197],{},"Il background worker logga e conta gli eventi scartati quando la coda async è piena.",[331,2199,2200,2203,2204,2207,2208,2211],{},[353,2201,2202],{},"validate!"," avvisa se ",[353,2205,2206],{},"project_id"," non ha forma UUID o se ",[353,2209,2210],{},"endpoint_url"," è privo di host.",[331,2213,2214,2215,2218],{},"Scansione vulnerabilità delle dipendenze con ",[353,2216,2217],{},"bundler-audit"," nella CI.",[321,2220,2221],{},[324,2222,448],{},[328,2224,2225],{},[331,2226,2227,1087,2230,2233,2234,2237],{},[353,2228,2229],{},".rubocop.yml",[353,2231,2232],{},"TargetRubyVersion"," allineato a ",[353,2235,2236],{},"4.0"," (coerente con la gemspec).",[316,2239,2241],{"id":2240},"_020-2026-06-27","0.2.0 · 2026-06-27",[328,2243,2244],{},[331,2245,2246],{},"Baseline: client di telemetria (eccezioni, query\u002Fmetodi lenti, breadcrumbs, scope,\nsampling, scrubbing PII) con integrazione Rails\u002FSidekiq e trasporto fire-and-forget.",{"title":2248,"searchDepth":19,"depth":19,"links":2249},"",[2250,2251,2252,2253,2254,2255,2256,2257,2258,2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272],{"id":318,"depth":19,"text":319},{"id":339,"depth":19,"text":340},{"id":387,"depth":19,"text":388},{"id":426,"depth":19,"text":427},{"id":442,"depth":19,"text":443},{"id":471,"depth":19,"text":472},{"id":521,"depth":19,"text":522},{"id":551,"depth":19,"text":552},{"id":577,"depth":19,"text":578},{"id":596,"depth":19,"text":597},{"id":612,"depth":19,"text":613},{"id":739,"depth":19,"text":740},{"id":877,"depth":19,"text":878},{"id":1438,"depth":19,"text":1439},{"id":1505,"depth":19,"text":1506},{"id":1715,"depth":19,"text":1716},{"id":1754,"depth":19,"text":1755},{"id":1822,"depth":19,"text":1823},{"id":1928,"depth":19,"text":1929},{"id":1987,"depth":19,"text":1988},{"id":2137,"depth":19,"text":2138},{"id":2153,"depth":19,"text":2154},{"id":2240,"depth":19,"text":2241},"md",{},true,{"title":287,"description":288},"docs\u002Fchangelog-sdk-ruby","bNpf1j8xgC9dmYo-IBBTXLvePc9iLOwfP8y_cIYpw1Q",1791469655239]