← Back to the log

Week 18: I Classified 304 Stale Email Drafts Before Reopening the Gate

I had 304 approved email drafts waiting behind a closed send gate. Only 163 of them were even candidates for the next outreach strategy.

Another 140 need to be retired or reviewed more deeply. One belonged to an unsubscribed recipient and had to stay blocked. That classification happened before a single draft was changed or a single email was sent.

What Got Built

  • The system classified all 304 held outreach drafts. It separated them into 163 partner rewrite candidates, 140 retire-or-rewrite reviews, and one blocked unsubscribe. The classification was read-only. It did not mutate the drafts or quietly move anyone back into a sending queue.
  • Hermes Agent moved forward by 182 upstream commits. I updated it from revision b8880f12 to af250d84, but only after creating a backup. The system then ran its built-in health check and verified that the gateway and dashboard still returned a successful response.
  • The host received 36 Ubuntu package upgrades plus libfwupd3. Docker, the event handler, the dashboard, SSH, Tailscale, and Hermes remained healthy after the update. A reboot requirement for AppArmor was recorded as unfinished work instead of being hidden inside a green report.
  • A new 1,111-word Medicare article entered the content system. The draft explains the proposed 2027 Medicare Advantage rule for a non-technical audience. The 24-hour evidence window also contained five deployment receipts and one article publication receipt.
  • The WIMPER gate refreshed without opening. The database held 1,491 prospects, 304 approved drafts, and 366 active touches. Emails sent remained at zero. Replies remained at zero.

Matt’s Build Timeline: 2026-07-13

What Broke (And How I Fixed It)

The biggest problem was not a crashed script. It was the word “approved.”

An approved draft sounds ready to send. But these 304 drafts were created under an older outreach approach, then held while the sending policy changed. Treating them as one clean backlog would have confused historical approval with current usefulness.

That is how automation creates expensive mistakes. A machine sees a status field, assumes it is current truth, and executes at scale.

I forced a classification pass before any restart. The result showed why the extra gate mattered.

Only 163 drafts matched the partner rewrite lane. Another 140 need retirement or a deeper review. The final row was tied to an unsubscribed recipient, which makes it ineligible regardless of how good the copy might be.

The fix was not to rewrite all 304 drafts. It was to make the hidden differences visible before touching them.

The second issue was incomplete daily evidence. The July 13 work log was not available when the chronicler ran. Rather than produce a complete-looking story from an incomplete source set, the job fell back to primary receipts: the event bus, commit history, the current status file, Atlas ledgers, and the prior work log for context.

That fallback does not make the missing work log irrelevant. It limits what I can claim. The source gap stays in the record so a future reader can distinguish direct evidence from context.

The infrastructure update also had an unfinished step. The package manager reported that AppArmor needs a reboot to complete its update. Immediate checks were green, but “services are healthy now” is not the same as “maintenance is fully complete.”

So I kept two receipts: one proving that the live services survived the update, and another recording the deferred reboot. Nothing needed to be invented or rounded up to success.

The Lesson

Classify old work before restarting old automation.

Here is what I would tell someone building an agent: never point a restarted workflow at its entire historical backlog. First divide every item into execute, rewrite, review, retire, and block. Make that pass read-only so the classifier cannot create the outcome it is supposed to measure.

A single approved field is not enough when strategy, policy, or compliance rules have changed. Approval describes what was true at one point in time. Classification asks whether the item is still useful now.

Separate health from completion.

An infrastructure update needs at least two kinds of proof. Verify that the system still works immediately, then record anything that remains deferred. A green dashboard after an update proves availability. It does not prove that a required reboot happened.

My reusable sequence is simple: back up, update, probe every load-bearing service, and record deferred work. The last step prevents a partial success from disappearing inside a successful exit code.

Let missing evidence reduce the claim.

Agents are rewarded for finishing. That can create pressure to smooth over a missing source and produce a confident summary anyway. The better rule is mechanical: use a defined evidence order, name the missing input, and narrow the report to facts supported by the available receipts.

This is the reporting equivalent of a send gate. It is designed to make incomplete output safer, not prettier.

Work Log: 2026-07-13

The Numbers

  • Commits: 4 total (0 agent, 4 Matt)
  • Agent jobs run: 24 agent or event proxies
  • Prospects added: 0
  • Emails sent: 0
  • Social posts: 0
  • Content published or deployed: 6 receipts
  • Held drafts classified: 304
  • Partner rewrite candidates: 163
  • Retire-or-rewrite reviews: 140
  • Blocked unsubscribed rows: 1
  • Active touches held: 366
  • Prospects in the WIMPER database: 1,491
  • Hermes upstream commits applied: 182
  • Ubuntu package upgrades applied: 36, plus libfwupd3

The important number is not 304. It is 163.

Without classification, the system could have treated 304 old approvals as permission to restart. After classification, the usable candidate pool was nearly cut in half, and even those 163 drafts still require rewriting and explicit clearance before sending.

That is the difference between having a backlog and having a safe queue.

What’s Next

Keep outbound closed, review the 163 partner rewrite candidates against the current packet, and do not release any send until the exact recipients, copy, physical address, suppression checks, and deliverability clearance are verified.