Apr 28, 2026
A rainy Saturday experiment with automating grocery coupons that turned into a broader reflection on build-vs-buy decisions, system boundaries, and when not to automate at all.

A rainy Saturday coupon app experiment that reframed a classic build-vs-buy decision.
It started in a grocery aisle on an otherwise unremarkable trip. There is a cart slightly ahead of you, a basket in your hand, and a shelf edge crowded with small signs trying to turn attention into action.
One of them has a QR code. "Scan this to save." It looks simple enough, but the conditions are never really simple. The signal is weak. The app takes longer than expected. A login prompt appears that you do not immediately remember the answer to. You are holding a basket you do not want to put down in the middle of a store. So you skip it. You move on.
That part is easy to dismiss in isolation. But it repeats often enough that it stops feeling incidental. It becomes part of the background logic of the experience. You do not engage with the coupon in the moment, and you do not really plan to later. The savings exist in theory, but not in practice.
At some point, that gap starts to feel more structural than situational.
What if this did not require me to think about it at all? Not in the aisle. Not in the moment. Just handled ahead of time.
The problem, when stated directly, is small. I want to save money at a major grocery chain without manually clipping coupons inside an app at the exact moment I am least inclined to do it.
There is no complexity in the surface description of that problem. It is not technical in an interesting way. It is not even particularly novel. It is just friction that shows up in the wrong place, at the wrong time, often enough to notice.
That is usually where automation thinking starts to creep in. Not from necessity, but from repetition.
So I asked ChatGPT's deep research mode to explore what it would take to automate the behavior.
That is where the shape of the problem changed.
The response did not begin with implementation details. It began with constraints. More specifically, it reframed what kind of system this actually is.
From the outside, it looks like an app with an interface and some underlying services. But systems like this are not really designed as open interaction surfaces. They are designed around human behavior, and increasingly, around distinguishing human behavior from everything else.
What looks like a request and response flow is layered with bot mitigation systems, session continuity signals, and behavioral fingerprints that evolve over time. Headers that do not just describe a client, but imply a history. Timing patterns that matter as much as correctness. Interaction order that becomes part of the identity being evaluated.
It stops being a question of whether you can reproduce a request.
It becomes a question of whether you can reproduce a user.
A request can be valid and still fail to produce meaningful results. A session can authenticate correctly and still behave inconsistently. A flow can work once and then degrade without any obvious failure point. These systems do not always reject automation directly. They just stop aligning with it.
We still built a prototype.
That is usually where curiosity overrides caution.
A branch, a quick proof of concept, just enough to see if the idea survives contact with reality. We simulated a real session, established a token, and attempted to reproduce the weekly coupon clipping flow programmatically.
For a moment, it worked as expected. Coupons were clipped. Responses looked correct. The system behaved exactly like the model suggested it should.
That kind of moment is always more dangerous than it feels.
Because it suggests stability where there is only short-term alignment.
I cannot confirm or deny whether that prototype still works. In practice, that ambiguity is part of the pattern. These systems do not usually break in obvious ways. They drift. They stop producing consistent results under slightly different conditions. They degrade quietly rather than failing loudly.
From there, the idea expanded in the way these ideas tend to expand.
If it works locally, it can be generalized. If it can be generalized, it can be productized. If it can be productized, it can be priced. The shape of it becomes familiar very quickly: a small personal friction reframed as a lightweight SaaS. A background system that handles coupon clipping automatically. A browser extension that removes the interaction entirely.
It is an easy line of thinking to follow because each step feels like a natural extension of the previous one.
But the farther you go, the more you start to see what you are actually building against.
This is where the decision simplifies again.
Build it, buy it, or try it first.
Building gives you control, but it also commits you to maintaining alignment with a system you do not control. Buying usually means someone else has already absorbed that complexity, even if imperfectly. Trying it first is less satisfying, but often more revealing than either of the other two options.
It forces a different kind of clarity. Not whether something is possible, but whether it is worth turning into a system in the first place.
What stood out most in the process was not the feasibility of automation. It was how quickly the system revealed its boundaries once you started to inspect it closely.
Not through explicit rejection, but through structure. Through the way it distinguishes between a request and a user. Through the way behavior becomes a stronger signal than correctness. Through the way "working once" and "working reliably" are separated by assumptions that are not visible from the surface.
That idea connects back to something I wrote in AI Adoption Journey.
These systems do not just accelerate implementation. They surface constraints earlier than you are used to seeing them. They compress the distance between idea and execution, and in doing so, expose the structure of what you are actually interacting with.
In this case, the outcome was not a system. It was a reframing.
Not every repeated friction is worth eliminating. Not every inconvenience is a candidate for automation. Some things are just part of the shape of the environment you are operating in.
And sometimes the more correct move is to recognize that shape, and leave it alone.