For most of my career, I have approached technology from the perspective of a Program Manager.
Processes. People. Dependencies. Delivery. Risk. Governance. And, ultimately, one question:
Is what we promised actually going to work when it reaches production?
Over the past year, I have been moving much closer to the engineering side.
I have been building real software myself.
Not prototypes that stay on a laptop.
Not screenshots for a presentation.
Actual applications, utilities, methodologies, documentation systems, AI capabilities and production releases.
And increasingly, I have been doing it through what many people now call vibe coding — working with AI coding agents, particularly Claude Code, to design, build, test and iterate.
The experience has changed how I think about software development.
I originally thought the biggest challenge would be learning how to make AI write better code.
I was wrong.
The harder problem is:
How do you build a disciplined engineering and release process around an AI that can write code incredibly fast?
That is where the real learning has been.
The AI can write code faster than you can review it
This creates a completely different development dynamic.
A traditional developer may spend hours implementing something.
An AI coding agent can produce a substantial implementation in minutes.
That sounds like pure productivity.
But there is a hidden consequence:
The speed of generation can exceed the speed of human verification.
And that changes the risk model.
The question is no longer simply:
"Can AI build this?"
It becomes:
"Can I prove that what AI built is actually what I intended to release?"
That distinction became very real in my own work.
I had situations where something looked correct but wasn't.
A page appeared to be hidden because its navigation link had been removed.
But the route was still publicly reachable.
A layout looked correct from the code.
But the rendered result exposed a CSS behavior that wasn't obvious from reading the classes.
An API returned success: true.
But the real-world action behind it had not actually been verified end-to-end.
A dependency worked during the development session.
But the dependency declaration had not been updated.
And AI-generated business copy produced numbers that sounded completely plausible — but could not be traced back to a source.
None of these are exotic AI failures.
They are software engineering failures amplified by AI speed.
One of the most important lessons: "looks right" is not "works"
This may be the biggest lesson I have learned from vibe coding.
There are multiple layers of truth.
Something can be:
- syntactically correct
- logically plausible
- visually correct
- locally functional
- tested in the current environment
- actually working in production
- secure
- maintainable
- factually grounded
Those are not the same thing.
AI is exceptionally good at producing something that looks like it belongs in all of those categories.
That is why verification becomes more important, not less.
In my own projects, actual verification included things such as browser automation, screenshots at different viewport sizes, direct API testing, regression tests, source verification, package inspection and independent checks.
The principle is simple:
Never accept "it should work" when you can check whether it works.
I started treating Claude less like a chatbot and more like an engineering teammate
One of the most useful things I introduced was a persistent CLAUDE.md file.
It became a standing contract for how the AI should work with me.
Things such as:
- Don't push without explicit approval.
- Work step by step.
- Don't hallucinate.
- Don't hardcode information that should be sourced.
- Perform code review.
- Perform security review.
- Don't assume something is complete.
- Surface uncertainty and tradeoffs.
- Preserve working behavior during refactoring.
This turned out to be much more valuable than repeatedly giving instructions in conversation.
The rules survived context resets.
They became part of the working environment.
And they changed behavior.
Half-built features could remain in the working tree instead of accidentally becoming production features.
Unsupported claims could be rejected before publication.
Security and code reviews became part of the release process rather than an afterthought.
That was an important realization for me:
The quality of AI-assisted development depends heavily on the system surrounding the AI.
I also learned that AI needs to be challenged
Another pattern emerged.
Some of the most important problems were not discovered because Claude proactively identified them.
They were discovered because I asked uncomfortable questions.
"Did you actually change anything?"
"How do you know this works?"
"Where did this number come from?"
"Is this route actually inaccessible?"
"Show me the evidence."
"How did you miss this?"
Those questions mattered.
An AI can produce a confident explanation of what it believes it did.
That is not the same as evidence of what actually happened.
So I started thinking about an AI coding agent in a slightly different way.
It should not only be asked:
"Build this."
It should also be asked:
"Prove it."
And sometimes:
"Tell me what you are not sure about."
One mistake changed how I think about production releases
One of the clearest examples was a feature that had been hidden from the navigation.
It was tempting to think:
"The feature isn't visible, therefore it isn't live."
But the actual route remained reachable directly.
That distinction sounds obvious after the fact.
But it represents a broader engineering problem:
UI visibility is not the same thing as deployment state.
The eventual solution was proper production gating rather than simply hiding the navigation.
That experience reinforced something I now try to apply everywhere:
If something is not ready for production, don't merely hide it. Control whether it can actually be reached.
Another lesson: security begins before the first commit
I also learned a more uncomfortable lesson around sensitive information.
Real-world evidence, personal material and sensitive content can find their way into an AI-assisted working directory surprisingly easily.
Once something reaches Git history, removing the current file is not necessarily enough.
That changed how I think about the boundary between:
AI workspace → source repository → production system.
The repository's visibility, .gitignore rules, data classification and allowed content should be decided before sensitive information enters the workflow.
Not after.
This is especially important when an AI agent has broad access to a development environment.
The agent can only operate within the boundaries we create.
My biggest improvement was turning mistakes into controls
This is probably where my Program Management background has helped me most.
When I found a bug, I didn't want the solution to be:
"Remember not to do that again."
I wanted the solution to become part of the system.
A defect became a regression test.
A review failure became a review gate.
A security miss became a security-review requirement.
A deferred task became a tracked open item.
A hallucinated claim became a source-grounding rule.
A release mistake became a release checklist.
That is the difference between fixing a problem and improving the system that allowed the problem to occur.
It is also where I see a strong connection between program management and AI-assisted engineering.
The surprising advantage of being a Program Manager who codes
I am not trying to become a traditional software engineer overnight.
I am learning something different.
I am learning to operate at the intersection of:
Program Management + Software Engineering + AI + Security + Delivery Governance.
My Program Management background makes me naturally ask questions such as:
- What is the scope?
- What is the dependency?
- What is the acceptance criteria?
- What can fail?
- What is the rollback?
- Who approves the release?
- What evidence proves completion?
- What happens if the AI is wrong?
- What happens if the data is wrong?
- What happens after deployment?
Vibe coding has added another dimension:
Now I can participate directly in building the thing I am managing.
That changes the conversation.
Instead of only asking an engineering team whether something can be built, I can increasingly prototype the idea, understand the architecture, examine the implementation and participate in the technical tradeoffs myself.
That is an incredibly powerful capability.
But it comes with an equally important responsibility.
Vibe coding does not eliminate engineering discipline
If anything, it makes engineering discipline more important.
The temptation is to measure AI-assisted development by:
How much code did we generate?
I think that is the wrong metric.
A better set of questions is:
- How much of it was actually verified?
- How much is traceable to requirements?
- How much is covered by regression tests?
- How much has been security reviewed?
- How much is reversible?
- How much is observable in production?
- How much is based on trusted information?
- How much does the human actually understand?
The AI may generate 10,000 lines.
That doesn't mean you have created 10,000 lines of value.
You have created 10,000 lines of responsibility until you prove otherwise.
My current operating model
I am increasingly thinking about AI-assisted development as a loop:
Define → Build → Inspect → Test → Challenge → Review → Approve → Release → Observe → Learn
The AI can participate heavily in almost every stage.
But the human still owns the decision to release.
That distinction is important.
AI can recommend.
AI can implement.
AI can test.
AI can review.
AI can identify risks.
But ultimately:
The human owns the production decision.
What I would tell another Program Manager starting to vibe code
Don't start by trying to become an expert prompt engineer.
Start by becoming an excellent verifier.
Learn Git.
Learn how your application actually gets deployed.
Learn how to read logs.
Learn APIs.
Learn databases.
Learn testing.
Learn basic security.
Learn how authentication and authorization work.
Learn how to inspect network requests.
Learn how to read a diff.
Learn how to reproduce a bug.
And most importantly:
Learn to distinguish evidence from confidence.
Because AI will give you confidence very easily.
Your job is to obtain evidence.
I am still learning
I don't consider this a finished transformation from Program Manager to Engineer.
It is an evolution.
I am moving closer to a Technical Full-Stack Engineering role, while bringing the discipline I have developed through program and delivery management.
And I am discovering that the combination is more interesting than either discipline by itself.
The future I see isn't:
Humans vs. AI developers.
It is:
People who can direct AI effectively, understand what it builds, verify what it claims, secure what they deploy, and take responsibility for the outcome.
That is the skill I am working toward.
And perhaps the biggest lesson from my recent production work is this:
Vibe coding makes building software easier. Engineering discipline makes shipping software responsibly possible.
I am learning both.
— Ramani Viswanathan
Originally published on LinkedIn.
