Part 6 of 8
🤖 Ghostwritten by Claude Opus 4.5 · Edited by GPT-5.2 Codex · Curated by Tom Hundley
This article was written by Claude Opus 4.5, fact-checked by GPT-5.2 Codex, and curated for publication by Tom Hundley.
This is Part 6 of the Professional's Guide to Vibe Coding series. Start with Part 1 if you haven't already.
Karpathy's original vibe coding concept was explicitly for "throwaway weekend projects." The approach he described—accepting all changes, not reading diffs, working around bugs randomly—is fine when failure has no consequences.
Production code is different. Production code:
The professional's workflow adapts AI-assisted development for contexts where quality matters.
The fundamental workflow is simple:
This isn't bureaucracy—it's the minimum structure needed to maintain quality while leveraging AI's speed.
Before writing any code, establish clarity:
Be explicit about what you're building and what you're not building:
I'm building a user authentication system with:
- Email/password login
- Session management
- Password reset flow
I am NOT building:
- OAuth/social login (future phase)
- Multi-factor authentication (future phase)
- User profile management (separate feature)Make project-specific constraints explicit:
Constraints:
- Must integrate with existing PostgreSQL database
- Must use existing bcrypt password hashing utilities
- Sessions stored in Redis, not database
- All endpoints must return JSON, not HTMLBefore asking for implementation, ask for a plan:
Before implementing, outline:
1. What new files you'll create
2. What existing files you'll modify
3. Dependencies you'll need to add
4. Database changes requiredReview the outline. Adjust before investing in code generation.
Don't ask for everything at once. Break implementation into testable stages.
For the authentication system above:
Stage 1: Database schema and models
Stage 2: Password utilities
Stage 3: Registration endpoint
Stage 4: Login endpoint and session management
Each stage is:
After each stage:
If a stage introduces problems, you can revert to the previous checkpoint instead of debugging a massive changeset.
Every piece of AI-generated code goes through review before integration.
For simple generations (under 50 lines):
If triage passes, proceed. If not, regenerate or fix manually.
For complex generations:
Before committing:
For projects using Claude Code or similar tools, a project context file maintains consistency across sessions.
# Project: [Name]
## Quick Facts
- Language: TypeScript with strict mode
- Framework: Next.js 15 (App Router)
- Database: PostgreSQL with Prisma
- Styling: Tailwind CSS
## Key Constraints
- All API routes require authentication except /api/auth/*
- Never log PII or secrets
- All database operations use the ORM; no raw SQL
- Tests are required for all new features
## Patterns to Follow
- Use existing /lib/utils.ts helpers before creating new ones
- Error responses use the ApiError class from /lib/errors.ts
- Form validation uses Zod schemas in /lib/schemas/
## Current Focus
- Building user authentication system
- See /docs/auth-spec.md for requirements
## Files NOT to Modify
- /prisma/migrations/* (managed by Prisma CLI)
- /.env* (contains secrets)Without persistent context, AI starts every session fresh. It doesn't know your patterns, constraints, or conventions.
With a CLAUDE.md file:
One of the most effective patterns I've found:
First, write test cases for a password strength validator:
- Should reject passwords under 8 characters
- Should reject passwords without uppercase
- Should reject passwords without lowercase
- Should reject passwords without numbers
- Should accept "ValidPass123" as validThen:
Now implement passwordStrengthValidator() that passes all these tests.Here's how I'd add semantic search to this blog:
I want to add semantic search to the blog. Requirements:
- Users can search via a search bar
- Results ranked by relevance
- Must work with existing PostgreSQL database
- Should use embedding-based search
Before implementing, outline the approach and list all files
that will need to be created or modified.AI provides outline. I review and adjust.
Create a migration to add a vector column to the posts table
for storing embeddings. Use pgvector extension.Review migration. Test locally. Commit.
Create a utility function to generate embeddings from post content
using OpenAI's embedding API. Follow the patterns in /lib/openai/.Review function. Test with sample content. Commit.
Create /api/search endpoint that:
- Accepts a query string
- Generates embedding for the query
- Finds similar posts via vector similarity
- Returns top 10 results with relevance scoresReview endpoint. Test with various queries. Commit.
Create a SearchBar component that:
- Renders a search input
- Debounces input
- Calls the search API
- Displays results in a dropdownReview component. Test in the UI. Commit.
Each stage is reviewable, testable, and committable. If stage 3 introduces problems, I don't lose stages 1 and 2.
Asking for entire features in one prompt leads to:
Fix: Break into stages.
Starting a session without establishing project context leads to:
Fix: Use CLAUDE.md or equivalent.
"It's just a small change, I don't need to review it" leads to:
Fix: Review everything. Smaller reviews are faster; use that as incentive to keep stages small.
Production vibe coding requires structure that weekend vibe coding doesn't:
This structure adds time, but not as much as debugging a production incident would.
Next in the series: The Enterprise Adoption Playbook: Vibe Coding at Scale
Ready to level up your team's AI development practices?
Elegant Software Solutions offers hands-on training that takes you from AI-curious to AI-proficient—with the professional discipline that production systems require.
Discover more content: