Note di Matteo


#dev


Leggo cose buone su RWX, nuova piattaforma di CI/CD pensata per velocizzare i processi nell'era dell'AI engineering, con parallelizzazione automatica, esecuzione delle pipeline prima del commit e altre ottimizzazioni.

#480 /
30 aprile 2026
/
11:20
/ #dev

Imagine if this is as good as AI gets. If this is where it stops, you'd still have models that can almost code a web browser, almost code a compiler—and can even present a pretty cool demo if allowed to take a few shortcuts. You'd still get models that can kinda-sorta simulate worlds and write kinda-sorta engaging stories. You'd still get self-driving cars that almost work, except when they don't. You get AI that can make you like 90% of a thing!

90% is a lot. Will you care about the last 10%?

I'm terrified that you won't.

I'm terrified of the good enough to ship—and I'm terrified of nobody else caring. I'm less afraid of AI agents writing apps that they will never experience than I am of the AI herders who won't care enough to actually learn what they ship. And I sure as hell am afraid of the people who will experience the slop and will be fine with it.

[...]

I'm terrified that our craft will die, and nobody will even care to mourn it.

Dima Konev, software engineer, in (AI) Slop Terrifies Me.

#461 /
21 aprile 2026
/
12:21
/ #ai#dev

Tokenmaxxing

It feels to me that a good part of the industry is using token count numbers similarly to how the lines-of-code-produced metric was used years ago. There was a time when the number of lines written daily or monthly was an important metric in programmer productivity, until it became clear that it’s a terrible thing to focus on. A lines-of-code metric can easily be gamed by writing boilerplate or throwaway code. Also, the best developers are not necessarily those who write the most code; they’re the ones who solve hard problems for the business quickly and reliably with – or without – code!

Similarly, the number of tokens a dev generates can easily be gamed, and if this metric is measured then devs will indeed game it. But doing so generates a massive accompanying AI bill!

Gergely Orosz in The Pulse: ‘Tokenmaxxing’ as a weird new trend.

#456 /
18 aprile 2026
/
11:12
/ #ai#dev

I tre tipi di software engineer secondo The Pragmatic Engineer:

  • Builders: those who care about quality, good architecture, following good coding practices, and who talk about the craft of software engineering, etc.

  • Shippers: those who primarily focus on outcomes for a product, features, testing, and experimenting with users. A fair number of leaders, managers, and engineers who were more hands-off with coding before AI tools are in this category, as are product engineers.

  • Coasters: engineers who are not considered particularly good or great engineers, but they get the work done. They often do this without much taste or concern for quality, and seem to be mostly coasting along and doing what they’re told.

Con l'AI, queste categorie restano ma con diversi livelli di entusiasmo e pro/contro. Il resto nell'articolo.

#450 /
16 aprile 2026
/
14:18
/ #dev#ai

DNSimple spiega come gestiscono le repository GitHub con Terraform. Quando iniziano a diventare centinaia, gestirle manualmente genera inconsistenze:

  • Repositories had different settings, even when they should have been identical
  • Labels for issue triage varied from repository to repository, making cross-project tracking difficult
  • Some repositories had issue templates, while others didn't
  • Permission management was manual and error-prone
  • Security features like vulnerability alerts weren't consistently enabled
  • Pull request templates were copy-pasted (when they existed at all)

Dopo un tentativo con Repocop, per automatizzare il setup, hanno deciso di usare Terraform con aggiornamento delle configurazioni tramite Pull Request e Terraform Cloud.

#305 /
23 gennaio 2026
/
14:46
/ #dev#github

2FA for developers

Ho aggiunto il supporto all'autenticazione a due fattori su DMARCwise e ho fatto fatica a trovare informazioni su best practice attorno alla 2FA con OTP, per cui segno quello che ho scoperto qui.

Intanto, l'algoritmo si chiama Time-based One-Time Password (TOTP) e permette di generare un codice di N cifre ogni T secondi partendo da un secret. Non tutte le app "authenticator" supportano tutte le configurazioni, per cui la più comune è:

  • Codici di 6 cifre.
  • Intervallo di tempo T di 30 secondi.
  • Algoritmo HMAC-SHA1.

Il secret nella maggior parte dei casi è di 20 byte (160 bit) e viene codificato in Base32 (es. CVEBO7GKWLFDRBJRPPTOZ7I6VEPDIGIT). Va generato diverso per ogni utente.

Per la verifica del TOTP la RFC consiglia di usare una tolleranza (drift window) di +/- un intervallo di tempo T (quindi vale sia il codice precedente che quello successivo).

Il secret andrebbe cifrato prima di essere inserito nel database. Nel mio caso ho scelto AES-256 GCM. Nel db vanno quindi salvati il secret cifrato (Base64) più il nonce e il tag AES.

Per la validazione dei codici ho usato la libreria Otp.NET per .NET/C#. Per AES ho usato l'implementazione nativa di .NET.

Per la configurazione iniziale del secondo fattore, all'utente vanno forniti il secret e i vari parametri menzionati sopra (o anche no, dato che quelli indicati qui sopra sono di solito il default), oppure un QR code che contiene un URI con questo formato (inizialmente definito da Google ma ora standard de facto):

otpauth://totp/{label}:{accountName}?secret={secret}&issuer={issuer}";

I parametri vanno URL encoded. La prima etichetta viene mostrata nella UI dell'applicazione authenticator di turno (Google Authenticator, Ente Auth, ecc.) assieme al nome dell'account, mentre l'issuer dovrebbe essere a uso interno.

Il codice QR lo genero server-side in SVG con ZXing.QrCode e lo ritorno nella risposta JSON delle API. Probabilmente si può fare anche client-side, ma avevo già generato QR in C# in un altro progetto per cui ho riciclato il codice.

Per confermare l'abilitazione della 2FA l'utente deve inserire un primo codice TOTP generato dall'app authenticator. C'è la possibilità che l'utente abbandoni il processo a metà, per cui ci vuole un cleanup delle configurazioni che non sono ancora state abilitate dopo 24/48 ore.

Andrebbero poi generati e forniti dei codici di backup/recupero. Nel mio caso sono 10 codici di 8 caratteri presi dall'alfabeto ABCDEFGHJKLMNPQRSTUVWXYZ23456789 (es. BVEZ-MMWP). Sono hashati con Argon2id, come le password, e salvati in una tabella del db. Di conseguenza nel momento della verifica del backup code bisogna verificarli tutti uno a uno per trovare se c'è un match, e poi segnare il codice individuato come già usato.

Come si implementa la verifica del secondo fattore in fase di login? Il login restituisce un token di tipo TwoFactorPending e il frontend fa redirect alla pagina di verifica. Questo token temporaneo permette di usare solo l'endpoint di verifica 2FA. Se il codice inserito dall'utente è corretto viene invalidato il token temporaneo (che ha comunque scadenza breve, es. 5 minuti) e ne viene creato uno nuovo "standard".

La disattivazione del secondo fattore deve richiedere la password dell'utente, mentre la rigenerazione dei codici di backup deve richiedere un codice TOTP valido (per verificare che l'utente sia effettivamente ancora in possesso del secondo fattore).

Bonus: il 95% del codice è stato scritto da Claude Code e dall'inizio alla fine ci abbiamo impiegato circa 3 giorni (progettazione, implementazione di 6 endpoint backend, integration test e tutta la UI con SvelteKit).

#291 /
16 gennaio 2026
/
20:25
/ #dev#security

certs.email

Ho pubblicato certs.email: un mini-servizio per essere notificati all'avvicinamento della scadenza dei certificati SSL/TLS dei propri domini.

È gratis e open source e in realtà mi serve prevalentemente per avere un dominio in più che invia email, per poter testare meglio DMARCwise.

#290 /
15 gennaio 2026
/
17:32
/ #dev#security

Segmentation fault in una build TypeScript mi giunge nuova:

EDIT: era colpa di una libreria con binding Rust, il che ha ancora meno senso in realtà.

#264 /
26 dicembre 2025
/
18:05
/ #dev

Nuovo mini progetto work in progress:

#262 /
24 dicembre 2025
/
15:28
/ #dev

Un sito ben fatto, Logging Sucks, per spiegare due concetti di logging nelle applicazioni:

  • Structured logging, cioè spezzare il messaggio testuale nelle sue componenti in modo che siano filtrabili (ogni log line è un oggetto JSON, in pratica).
  • Wide events, cioè avere una singola log line per ciascun evento nel senso più ampio possibile. Ad esempio una richiesta HTTP produce un log che contiene tutte le info di contesto su ciò che è successo durante l'elaborazione, al posto di avere le informazioni sparse tra più righe di log.

Molto d'accordo sul primo (anche se preferisco una forma ibrida con messaggio formattato + variabili scorporate), meno sul secondo. Righe di log separate con un id di correlazione lo troverei più comodo (a meno di logging su scale enormi che finora non mi sono capitate).

#254 /
22 dicembre 2025
/
13:27
/ #dev

Postmortem di Railway, la creazione di un indice PostgreSQL ha tirato giù tutto:

A routine change to this Postgres database introduced a new column with an index to a table containing approximately 1 billion records. This table is critical in our backend API’s infrastructure, used by nearly all API operations.

The index creation did not use Postgres’ CONCURRENTLY option, causing an exclusive lock on the entire table. During the lock period, all queries against the database were queued behind the index operation. [...] Manual intervention attempts to terminate the index creation failed.

Le misure:

We’re going to introduce several changes to prevent errors of this class from happening again:

  • In CI, we will enforce CONCURRENTLY usage for all index creation operations, blocking non-compliant pull requests before merge.
  • PgBouncer connection pool limits will be adjusted to prevent overwhelming the underlying Postgres instance's capacity.
  • Database user connection limits will be configured to guarantee administrative access during incidents, ensuring maintenance operations remain possible under all conditions.
#228 /
14 dicembre 2025
/
10:58
/ #database#dev#cloud



Ottimizzazioni di un'altra era nell'app Facebook:

In 2012 we took this wild ride at mobile infra at Facebook when trying to reduce the several-seconds long load time for “Newsfeed”. A few people worked on different approaches. Something we quickly realized was that setting up a connection with TCP and TLS was incredibly slow on mobile networks at the time. The fix was to have just one, keep it alive and multiplex. Shaved a whole second off. But it was still slow. Several people were convince that us sending JSON was the problem, so two different teams started to work on compact binary encoding. After a lot of experimentation what actually worked out best was to send JSON with ordered fields and a compile-time generated parser. Turns out both our iOS and Android app would do something silly like: 1) read all JSON data from server into a buffer, 2) decode that buffer with a generic JSON decoder into lists & dicts, 3) traverse those structures and build the final struct/class tree. Oh and another neat thing we eventually did—when the network connection needed to be setup—was to send an optimistic UDP packet to the server saying “get started fetching data for the following query”; once the real connection was established, TLS handshake completed and user session authenticated, the response was already ready to be sent back.

#198 /
3 dicembre 2025
/
23:39
/ #dev#reti


Review your own git pull requests

When you create a pull request in GitHub, click on the Files changed tab, and scroll through the diff. Anywhere you’ve done something new that’s not already explained by in-code comments, add a comment in the GUI about what you did and why.

  • Often, it’s stuff that’s not important enough for in-code commentary, but is useful for the reviewer to know.
  • Sometimes, it’s stuff that should actually be documented in the code, and this is a good time to go back and add it.
  • Every now and then, you’ll notice a bug in your own code because you’re reading it with fresh eyes, in a different format than your text editor.

It’s a simple behavior change that adds maybe 5 or 10 minutes to the time it takes to setup a PR, but it’s saved me so many headaches, and makes life for whoever reviews your PR a lot easier, too!

(Chris Ferdinandi)

#161 /
17 novembre 2025
/
22:56
/ #dev#git

TIL con un file .git-blame-ignore-revs si possono ignorare determinati commit dall'output "blame" su GitHub (o con git blame --ignore-revs-file .git-blame-ignore-revs), utile quando si fanno refactoring o si modifica la formattazione ma non la funzionalità.

(fonte, esempio)

#151 /
15 novembre 2025
/
16:16
/ #dev#git


Google sta riscrivendo pezzi di Android che prima erano in C++ in Rust, con notevoli risultati dal punto di vista della sicurezza:

With roughly 5 million lines of Rust in the Android platform and one potential memory safety vulnerability found (and fixed pre-release), our estimated vulnerability density for Rust is 0.2 vuln per 1 million lines (MLOC).

Our historical data for C and C++ shows a density of closer to 1,000 memory safety vulnerabilities per MLOC. Our Rust code is currently tracking at a density orders of magnitude lower: a more than 1000x reduction.

#147 /
14 novembre 2025
/
10:02
/ #google#android#dev

Pagina 1 di 3 Successiva →