About 1 result (0.09 seconds)
2026-04-23 · 7 min readThere's a common story about expertise that goes like this. When you're new, you verify every step. You double-check assumptions, read the docs twice, test the edges. When you're experienced, you develop intuition. You know what matters and what doesn't. Experience becomes a filter — the filter saves time, the filter is the skill.
I want to invert that story.
The amateur checking everything is doing the right thing. Not because they have good practices — they don't yet — but because they know they don't know. That gap between confidence and competence, which feels uncomfortable when you're living inside it, is exactly what makes a new operator careful. They ask. They stop. They read the error message three times before guessing.
The professional has the opposite problem. Experience does produce real filters, and most of those filters are right. But filters also create blind spots, and the blind spots live exactly where they're hardest to notice. You're moving faster because you can. You're trusting yourself because you've earned it. That's the posture where work ships unchecked.
This isn't a pitch for insecurity. Experienced people should trust their experience. The pitch is that verification discipline isn't a beginner's scaffolding you graduate from — it's a professional practice you keep.
I've been running my own test of this idea for two weeks.
I'm a demand gen operator. Twenty-plus years running marketing for B2B software companies. I'm not a software developer. I can read code — I've had to, over the years, to talk to engineers and diagnose broken tracking — but I don't write production systems from scratch.
Two weeks ago I started building one anyway. The product is a cross-platform ad budget management tool for agencies. The development partner is Claude Code. There are about ten warm agency contacts lined up for beta — the kind of people who would notice if I shipped something broken, and who would tell other people.
From day one, I've run verification as a daily practice. Multiple QA passes, bug-check sessions at natural shipping points, sanity-checks on every meaningful change. This wasn't panic. It was the only way I knew how to proceed. I'm a domain expert in marketing, not in software, and I didn't assume otherwise. I asked.
Last Thursday I escalated the practice. I had Claude Code perform a security audit across seven categories: authentication and authorization, credential and secret handling, Supabase data access and row-level security, input validation, dependency vulnerabilities, error handling and information disclosure, and rate limiting and abuse prevention.
Here's what I want to be honest about first: the codebase was above-average for a bootstrapped pre-beta SaaS. There were no authentication bypasses. No open admin routes. Row-level security was correctly enforced on the primary data tables. Stripe webhook signatures were verified. OAuth tokens never came back in API responses. Cron routes were authenticated. No secrets in git history. Claude Code got most of the important things right.
And then the audit found the other things.
I'm going to describe these at the category level, not the forensic level. Giving specific implementation detail on past vulnerabilities in a product I'm about to ship would be a blueprint for anyone poking at earlier versions. So: categories, severity, disposition.
One CRITICAL: an unauthenticated debug endpoint that could have produced meaningful API cost exposure if it had been discovered.
Eight HIGH: row-level security gaps on two Supabase tables, one of which transiently held sensitive tokens. An admin role privilege escalation path. File upload validation gaps. User input flowing into AI prompts without sanitization. Stack traces leaking to clients. A race condition in rate-counting logic. A missing rate limit on an expensive endpoint.
Sixty-plus MEDIUM: mostly raw database error messages surfacing to clients and exposing schema details.
None of these were the result of someone being careless in the way that word usually gets used. They were the result of a development process that had moved fast across a lot of surface area. Every individual decision had been reasonable. In aggregate, there were gaps.
I'm fixing them systematically. Session one closed the CRITICAL and three of the HIGH. The rest is sequenced across focused sessions over the coming week. I've also set up the infrastructure that keeps this from being a one-time event: Dependabot, CodeQL, ESLint security plugins, a pre-commit hook for lint and type-check. The audit wasn't the discipline. The discipline is what runs after it.
If you're new to software — a marketer building a tool, a founder shipping a prototype, anyone using AI coding assistants to produce systems you couldn't produce unassisted — the instinct that served me here is available to you for free. You already know you don't know. Keep asking. Run a QA pass every day. Ask the tool to look for what it might have missed. Ask it to review its own work from a skeptical frame. Most of what went right in my codebase went right because I was explicit, repeatedly, about wanting it to be right. The tool is not going to enforce discipline you don't ask for.
If you're an experienced developer, the message is different, and I want to handle it carefully. Your expertise is real. Your filters are mostly correct. Nothing in two weeks of building with AI makes me qualified to tell you how to do your job. What I'll offer instead is that the conditions that produced the gaps in my codebase — fast movement across a lot of surface area, reasonable individual decisions, a tool that does exactly what you tell it to do — aren't exclusive to amateurs using AI assistants. They're the conditions of most professional software development. Systematic verification at milestones isn't a concession to inexperience. It's a concession to how bugs actually get made.
The reason I invert the usual story is that verification has quietly become something people signal they've graduated from. Code review still happens, but on some teams it's ritual. Security audits still happen, but often late. "Senior" sometimes functions as permission to skip steps. I don't think it should, and I don't think most senior people think it should either — but the drift is real, and it's worth naming.
Pick a cadence. Daily for small projects, weekly for larger ones. On that cadence, explicitly look at what's shipped since the last check. Not at the feature — at the category of risk. Authentication. Data access. Input handling. Error disclosure. Rate limits. The categories stay the same whether you built it or a tool built it with you.
If you're using an AI coding assistant, make verification a named task, not an assumption. Ask it to audit. Ask it to find what it would critique in someone else's work. Then check its critique, because tools have blind spots too.
Instrument the work so some of the verification runs without you. Linters, type-checkers, dependency scanners, pre-commit hooks. These aren't substitutes for thinking. They're a floor under your thinking so the thinking can reach further.
And when an audit does turn something up — as mine did, and as yours will — the right response is neither panic nor embarrassment. It's a sequenced fix list, a root-cause note, and a tooling upgrade that makes the same class of issue louder next time.
Amateurs check everything because they have to. Professionals check everything because they want to. Between those two postures is where most of the preventable damage in software gets made, and if we've decided as a field that AI assistants are going to be part of how we build, the practice we bring to them is the practice we already should have been bringing to ourselves.
Gary Corriston runs Corriston Consulting, working with agencies and in-house marketing teams on paid media, SEO, marketing operations, and demand gen infrastructure. He's also building Campaign Budget Optimizer, an AI-native cross-platform budget allocation tool launching May 2026.
Book an intro call →