1
4 Comments

The fix for "we don't know what happened" depends on one thing: can you ask?

Yesterday's post got two replies that moved the problem forward more than the post itself did.

James (building UtilitySEO) pointed out the same ambiguity shows up in web crawling: a 403 might mean forbidden, or might mean a CDN edge challenged the request for not looking like a browser. Seventeen pages came back undecided in one scan — every single one turned out fine on a second look. His framing: "rare enough to handle manually, until it isn't" — Stripe webhooks, phone automation, and crawling all eventually hit enough volume that manual review of the ambiguous cases stops being an option.

octyn asked the question I didn't have a good answer to: for a Stripe webhook, you can query Stripe's API afterward and ask "what's the actual status of this charge," independent of whether your own handler crashed. Is there an equivalent for StareBrain — can I ask the phone carrier or the recipient's device "did this call/text actually complete"?

Honest answer: sometimes, sometimes not. SMS delivery receipts exist in some pipelines. Phone calls mostly don't have an equivalent I can reach in real time. Web crawling, per James, doesn't either — you can't ask a CDN "was that a real forbid or an edge challenge," you can only retry and look harder like a browser.

So the actual shape of the fix isn't one thing. It's two different problems wearing the same symptom:

A source of truth exists elsewhere, and you're just not querying it. Fixable with more integration work, no new state needed. This is James's crawling case (retry looking more like a browser) and probably some fraction of Stripe cases.
No source of truth exists, full stop. The ambiguity is real and permanent from your side. This is most of StareBrain's phone-call case today. The only honest move is flagging it for a human, not chasing an API that doesn't exist.

Yesterday's post treated this as one gap. It's actually two, and knowing which one you're in changes whether you should be writing more integration code or building a better human-review flow. I was collapsing them together until these two comments forced the split.

on September 26, 2026
  1. 1

    The split into "a source of truth exists, you're just not querying it" versus "no source of truth exists" is really useful. Building on octyn's point about treating every manual resolution as data: one thing we've seen in sprint retros is that the undecided bucket grows quietly, because each case feels rare on its own. Tagging each manual resolution with which of your two buckets it fell into would also tell you where to spend effort: if most land in the first, it's integration work; if the second keeps growing week over week, it's time to invest in the review flow.

    1. 1

      the tag is the part that closes the loop. the queue count tells you how much ambiguity you're carrying, but the tag tells you which direction it's drifting, and that's the decision that matters. and it costs the reviewer almost nothing, they're already resolving the case, the label just rides along.

  2. 1

    the human-review flow has its own failure mode. a flag queue fills up with the same three causes dressed as new events, and the reviewer becomes the API you wished existed. the version that works treats every manual resolution as data: resolve enough of cause X and it graduates into a rule or a retry, and the queue actually shrinks. if the queue stays flat week over week, the review flow is just the old swamp with better labeling

  3. 1

    we got the lucky version of this. for onchain actions the chain itself is the source of truth, so "did it happen" is always askable. the ambiguity just moves to "has the indexer caught up yet", and there the honest fix is the boring one: tell the user to check again in a minute