TLDR: Some destructive-but-bounded operations are legitimately "traced-only" — not because you were lazy, but because that's the honest shipping posture. The key is: bound the blast radius, wire in observability, and write the gap down.

The Setup

I was wrapping a big audit remediation pass on a webinar project-management tool I built for an ecommerce business.

Twenty-two findings. Twenty-one closed with tests or live verification.

Then there was C10.

Purge read notifications older than 30 days.

It's a DELETE. Runs automatically. And I had no clean way to unit-test it or trigger it live in any reasonable window.

The Question Nobody Asks Out Loud

"Should I test this before shipping it?"

GREAT question. The honest answer is: sometimes "no" is the right call — if you're deliberate about it.

Here's what I had to weigh. The blast radius on C10 is actually pretty contained:

  • Only read notifications get purged (a user actively dismissed them)
  • Only rows older than 30 days (not anything recent or unread)
  • If it misfires, a user loses old dismissed notifications — annoying, not catastrophic

That's bounded. That's recoverable. That's a different risk profile than, say, a cascading delete on a core table.

So I didn't chase coverage I couldn't meaningfully get.

What I Did Instead

I shipped it traced-only — meaning I wired in enough observability that the system would scream if something broke, and I accepted the first real mark-all-read click as live verification.

That's not the same as shipping blind.

Same remediation pass, I made a bunch of silent failures loud:

  • Bell error dot fires on 500GET /api/notifications returning an error used to silently show nothing. Now it returns 500 so the little red dot fires. You see it broke.
  • Cmd-K palette surfaces fetch failures — the search palette used to fail silently too. Now errors surface in the UI.
  • RLS rejections on position writes — Supabase row-level security (the database access policy layer) rejections used to vanish. Now they bubble up.
  • Two deliberately-degrading reads logged — there are two spots in the app that intentionally degrade gracefully under load. I left the degradation in place and added logs so I know when they trigger.

The point: observability is the safety net for the thing you couldn't test.

The Step That Actually Matters

The commit I'm most proud of from that batch isn't feat(notifications): purge read notifications older than 30 days.

It's this one: docs: flag retention purge as traced-only in HANDOFF.

I wrote it down. Explicitly. In the handoff doc. "C10 is traced-only — the one destructive change with no live/unit coverage. Bounded blast radius. First real mark-all-read click proves it."

That's the difference between a hidden gap and a known accepted risk.

Hidden gaps are how things blow up quietly. Known risks with bounded blast radii and observability wired in? That's just shipping like an adult.

Why This Matters to Me

I used to think every destructive change needed a test before it could ship. I'd hold up features trying to manufacture test scenarios that were clunky at best, meaningless at worst.

What I've landed on: the question isn't "do I have test coverage?" It's "do I have visibility?" And for some operations — bounded, recoverable, hard to stage — the right answer is observability + honest documentation, not a fake test that doesn't actually prove anything.

The first real user click is real data. Sometimes you let that be the test… and you know it when it fires.