Our Email Gate Demanded a Hash That Could Never Exist

Our Email Gate Demanded a Hash That Could Never Exist

Posted by:

|

On:

|

The surprise in the pipeline

We built a gate in our production line that would accept or block business emails and internal updates based on one extractable ask, a binary send-or-block decision, and an evidence trail attached to the archived message.

An independent reviewer looked at the first version and passed it on form. We assumed it was safe.

Then a third checker ran it and found twelve logic faults. Twelve. Every single one got fixed the same day and the fixed version is what sits on the shelf now.

What failed — and how we watched it fail

First experiment. We put the gate in front of a batch of production drafts. The gate demanded an ask line on every message. Informational updates with no action required were blocked. Valid status notes never reached their recipients.

We replayed blocked messages. The ones meant only to inform had no ask line because there was nothing to ask. They were legitimate. The gate still refused them.

Second experiment. The gate required the writer to “verify” the ask by re-reading the draft. We let a writer run that check. The gate accepted the message. Later we tried a stricter check: give the verifier a copy with the ask line removed, and ask them to recover the ask from subject, opening and body only. The candidate failed. The earlier pass had been the writer grading its own line.

Third experiment. The evidence trail demanded a content hash. When we tried to verify the evidence from the archived message, the recomputed value never matched. Turns out the original design computed the hash over the entire message text including the evidence line that contains the hash itself — a paradox. No third party could ever recompute the same hash because the hash would change the input. It was obvious once we tried to recompute it: the archived file and the recorded hash couldn’t both be true.

The turning point came when the third checker said, “Try computing it from the message alone.” We did. It failed. The moment clicked. We could either accept an unverifiable claim or change the order of operations.

What we changed and why it fixed things

We changed three concrete behaviors in version 1.1.

1) The evidence hash is computed last, over everything except its own line. We archived a message, recomputed the hash from the archived content, and it matched. Third-party recomputation worked because the hash no longer mutated its own input.

2) Informational updates are allowed to carry an explicit “No action required” line that satisfies the gate. We replayed the earlier blocked batch after this change; the same status notes that had been blocked now passed. The gate recognized intentional no-ask messages instead of failing them.

3) Verification stopped being the writer re-reading their own draft. The gate now runs a read-back against a masked copy where the ask line is deleted. We forced several writers to recover the ask from the subject, opening and body alone. If the ask wasn’t recoverable, the gate blocks the send. That immediately removed our self-verification problem.

Those three changes closed the twelve faults the third checker found. We confirmed closure by re-running the same tests that had produced each fault; each test produced the expected pass. The fixed version moved to the shelf that day.

Why these fixes actually work

The hash fix restores external verifiability. If the evidence line is part of the hash input, verification becomes impossible because the proof alters what it proves. Computing the proof after excluding that line gives anyone with the archived message enough to check the claim.

The “No action required” line fixes a category error. A gate that assumes every message wants an action will force false negatives. Allowing an explicit no-action marker maps the check to the message’s intent instead of the writer’s omission.

Masked read-back removes the conflict of interest. A writer reading their own line will always confirm it; they can’t reliably be the sole check. Making the verification require recovery from other message fields turns the check into a test that can fail, which is the only kind of check that proves anything.

A fair counter-example

Someone suggested that a filled checklist appended to the message achieves the same assurance. We tried that. Writers completed a table from memory and appended it. The gate accepted the message. Later we audited the table against the archived content and found discrepancies. A self-filled table proved nothing. It was the classic illusion of control: a visible artifact that didn’t change the underlying verifiability. That myth led us to the masked copy and hash fixes instead.

One representative detail: during the masked read-back test, we removed the ask line and asked the writer to produce the ask from subject, opening and body only. Several failed. The gate blocked each of those. The blocked messages were previously accepted. That single step showed us both the vulnerability and the remedy in palpable terms.

The full runnable skill lives in our members’ library.

Questions we got

Why not just require a signer other than the writer?

That helps, but it’s brittle. We tried adding a second signer and the process slowed. The masked-copy check gives the same defect-detection without changing the workflow as drastically because it forces the message to stand on its own.

Won’t the “No action required” line be abused?

Maybe. We log and sample those messages. Abuse shows up quickly in audits when the body contradicts the “No action required” claim. The gate treats the line as a legitimate state, not a license to avoid accountability.

How do we know the twelve faults were actually fixed?

We reran the exact failure tests that produced each fault. For every failing case the third checker had recorded, the new behavior produced a pass or a justified block. An independent reviewer then spot-checked the fixes. All closures are recorded in the revision log.

Rule: never let the writer grade its own line; check a copy where the answer is missing.

Sources: internal testing notes and the version 1.1 skill file from our production line, dated 2026-07-24.


How we know

The factual claims in this article come from our verification store — each with a source type, a confidence label and a reference. The method is documented on How we know.

– The send gate’s first version blocked perfectly valid messages: purely informational types with a legitimate no-action-required had no ask line, and the gate demanded one anyway; version 1.1 lets those types carry an explicit ‘No action required’ line that satisfies the gate instead of failing it. | source: documented source | conf: verified | ref: EBZ skill-fabrikk 2026-07-24 + skillfil v1.1
– In the send gate’s first version, the same writer ‘verified’ the ask line it had just written by re-reading its own draft; version 1.1 requires a masked-copy read-back where the ask line is deleted and the ask must be recoverable from subject, opening and body alone, or the message blocks. | source: documented source | conf: verified | ref: EBZ skill-fabrikk 2026-07-24 + skillfil v1.1
– The first version of our email send gate demanded a hash over content that included the hash itself — a paradox that could never be verified by anyone; version 1.1 computes the evidence hash last, over everything except its own line, so a third party can recompute it from the archived message alone. | source: documented source | conf: verified | ref: EBZ skill-fabrikk 2026-07-24 + skillfil v1.1
– A mandatory third checker found 12 logic faults in the send gate’s first version after an independent reviewer had already passed it on form; every one was closed in version 1.1 on the same day, and the fixed version is what sits on the shelf. | source: documented source | conf: observed | ref: EBZ skill-fabrikk 2026-07-24 + skillfil v1.1
– Myth: a checklist appended to an email proves the email was checked. A table the writer fills in from memory proves nothing; our gate only counts checks that can actually fail — a read-back against a masked copy, and a hash anyone can recompute from the archived message. | source: documented source | conf: mythbuster | ref: EBZ skill-fabrikk 2026-07-24 + skillfil v1.1

Leave a Reply

Your email address will not be published. Required fields are marked *