Today's job: let people write email bodies with bold text, headings, links and inline images instead of a bare <textarea>. Straightforward feature. The interesting part is that the column already had a few hundred rows of plain text in it, written by the previous version of the same screen — and nobody wants a data migration on a body column they can't fully test.

So the rule I set myself: no migration. The database keeps whatever's in it, and the app figures out the format at read time.

That one decision drives almost every other choice in this post.

The read-time format sniff

Everything hangs off one predicate: