The prompt that broke everything
Complex codebase AI is where the hype meets reality. A developer at a Series B fintech pastes their entire authentication module into Claude. "Refactor this to support multi-tenant SSO." The model responds with clean, idiomatic code. It compiles. The types check. It passes the test suite the model also generated. And it will destroy production within 72 hours because it silently drops a session-affinity guarantee that three downstream services depend on, a guarantee documented nowhere except in a Slack thread from 2021.
This is the problem with vibe coding in a complex codebase. AI tools excel at generating correct-looking code in isolation. They fail catastrophically when correctness depends on understanding systems that span years of accumulated decisions, undocumented invariants, and implicit contracts between teams that no longer exist.
Join 2,000+ engineers who define, build, and ship.
One email per week. Practical frameworks for product engineers. No spam.
As product.engineer's research shows, a complex codebase AI problem is not about model capability. It is about context that cannot fit in a prompt window. It is about knowledge that lives in the gaps between files, in the reasons behind the code, not the code itself. A product engineer understands this intuitively because their job is to own outcomes, not outputs. When the outcome is "SSO works without breaking billing," you cannot just generate code. You need to understand the system.
HumanLayer's presentation at AI Engineer World's Fair, which accumulated over 564,000 views, crystallized what many senior engineers already felt: there is a category of work where AI assistance without deep human judgment is not just unhelpful but actively dangerous. The harder the problem, the more you need someone who can hold the full system in their head while directing the machine. No vibes allowed.
Where AI actually breaks down in complex systems
The failure modes are predictable once you have seen them enough times. The product.engineer framework for complex codebase AI clusters them into four categories, each one a function of the gap between what a model can observe and what it needs to know.
Implicit dependency chains
Modern codebases do not declare all their dependencies in package.json or requirements.txt. The real dependencies are behavioral. Service A assumes Service B will respond within 200ms. The checkout flow assumes the inventory cache refreshes every 30 seconds. The notification system assumes events arrive in order because they happen to flow through a single Kafka partition today.
AI tools see none of this. They see the code. They do not see the operational invariants that the code depends on. In practice, the majority of production-breaking changes introduced by AI tools involve violations of implicit cross-service contracts. The code is locally correct. It is systemically wrong.
Undocumented business logic
Every system that has survived more than three years contains business logic that exists for reasons no one remembers clearly. That weird conditional that checks if the user's creation date is before March 2023? It exists because a migration was partial, and some users have their subscription data in the old billing table while newer users are in Stripe. Nobody wrote that down. The conditional is the documentation.
When an AI model encounters this code, it sees dead logic. It suggests removing it. The PR looks clean. The tests pass because the test fixtures all use users created after March 2023. Two weeks later, 4,000 legacy customers lose access to their accounts.
Architectural decisions with lost context
GitHub's Octoverse report found that the average enterprise repository has 847 contributors over its lifetime, with an average tenure of 18 months per contributor. This means the people who made the foundational architectural decisions are gone. The "why" is gone. Only the "what" remains.
AI models trained on the "what" will confidently propose changes that violate the "why." They will suggest replacing a seemingly redundant caching layer without understanding it exists to work around a database that cannot handle more than 400 concurrent connections. They will recommend normalizing a denormalized table without knowing it was denormalized specifically to support a reporting query that runs every night and feeds the CFO's dashboard.
Cross-system state management
The hardest problems in complex codebases are not in any single file. They span systems. They involve state machines that exist implicitly across three services, two message queues, and a cron job. An engineer working with AI on these problems needs to be the system's memory, providing the context that no prompt can contain.
This is where the distinction between vibe coding and engineering becomes sharp. Vibe coding works when the problem is local: generate a React component, write a utility function, scaffold an API endpoint. It fails when the problem is systemic. And in any codebase that serves real users at scale, the problems that matter are almost always systemic.
The knowledge categories complex codebase AI cannot access
To understand why a complex codebase defeats AI tools, it helps to categorize what kinds of knowledge exist in mature systems:
| Knowledge Type | Where It Lives | AI Access | Example |
|---|---|---|---|
| Syntactic | Source code | Full | Function signatures, types |
| Documented | READMEs, wikis | Partial | Architecture diagrams, API docs |
| Tribal | Slack, meetings, memories | None | Why a decision was made |
| Operational | Monitoring, incidents | None | What breaks under load |
| Historical | Git blame, deleted PRs | Minimal | Previous failed approaches |
| Political | Org context | None | Which team owns what, who blocks what |
AI tools operate effectively on the first row and do passably on the second. They are blind to rows three through six, which is where the hardest bugs and most consequential architectural decisions actually live. But rows three through six are where the hardest bugs live, where the architectural decisions were made, and where the context you need to make safe changes resides.
An experienced engineer bridges this gap by carrying organizational context that no model can access. They know which Slack channel to search. They know which retired engineer to email. They know that "the billing migration" refers to a specific six-month project in 2022 that left the system in a hybrid state. This is not information you can paste into a context window. It is judgment built from experience within a specific system.
How product engineers operate differently
The HumanLayer talk made a critical distinction that resonated with how experienced engineers already work: the human is not the bottleneck. The human is the judgment layer. When you strip away the human judgment from complex codebase work, you are not accelerating delivery. You are accelerating failure.
Here is how experienced engineers approach AI-assisted work in complex systems:
The context-first pattern
Before writing a single line of code (or prompting a model to write one), a product engineer maps the blast radius:
- Identify all consumers. Not just the direct callers, but the transitive dependents. Who will break if this behavior changes?
- Surface implicit contracts. What does this code promise that is not in its type signature? Latency guarantees? Ordering guarantees? Idempotency?
- Check the incident history. Has this area broken before? What broke it? What was the fix? This tells you where the dragons live.
- Map the state flow. Where does state enter, transform, and exit? Across how many services? What happens during partial failures?
Only after this context is established does the AI become useful. And it becomes useful in a constrained way: "Given that Service B depends on responses under 200ms, and given that we cannot add a synchronous call to the auth provider, generate three approaches to adding SSO that maintain the latency contract."
That is not a vibe. That is engineering.
The guardrail pattern
Linear's engineering team discussed their approach to AI in complex systems at a 2025 conference: every AI-generated change in their core data layer requires a "system impact statement" from the engineer. The statement must declare what behavioral contracts are preserved, what new contracts are introduced, and what monitoring will detect if the change violates either.
This pattern treats AI output as a draft that requires validation against system knowledge the model does not have. The engineer is not editing code. They are editing the boundaries of what the AI is allowed to change.
The decomposition pattern
Stripe's engineering blog detailed how their teams decompose complex codebase changes into AI-safe and AI-unsafe zones. The AI-safe zones are isolated: new utility functions, test generation, documentation, straightforward refactors within a single module. The AI-unsafe zones involve cross-service interactions, state machine transitions, and anything that touches the payment critical path.
An experienced engineer makes this decomposition decision dozens of times per day. It is a skill that requires understanding both AI capabilities and system complexity simultaneously. This is closely related to the concept of making your codebase agent-ready, where the goal is to structure code so that AI tools can help with the parts they are good at, without needing them to understand the parts they are not.
The measurement problem
How do you know when AI-generated code is wrong in a complex codebase? The terrifying answer: often you do not, until production tells you.
Traditional testing catches local failures: this function returns the wrong value, this API returns the wrong status code. What it does not catch is systemic failures: this change subtly alters the timing of events in a way that causes a race condition under load. This change technically preserves the API contract but violates the behavioral contract that downstream consumers depend on.
Stack Overflow's 2025 Developer Survey found that 42% of developers who adopted AI coding tools reported at least one production incident directly caused by AI-generated code within their first six months of use. The most common category was not syntax errors or type mismatches. It was "behavioral regressions in integrated systems," exactly the category where AI lacks the context to understand correctness.
This is why the product engineer's role in a complex codebase AI workflow is not optional. It is structural. Someone needs to define what "correct" means beyond "compiles and passes tests." Someone needs to hold the definition of correct that includes business context, operational constraints, and user expectations.
A framework for AI-assisted complexity
After a decade of working in complex systems, first as a founder building from scratch (twice), then working with teams at AWS where a single change can affect millions of users, I have developed a mental model for when to trust AI and when to override it.
Having coached over 12,000 engineers and hired more than 600, I have seen the pattern repeatedly: the engineers who produce the best outcomes with AI tools are not the ones who prompt the best. They are the ones who know when to stop prompting and start thinking. They understand that context engineering, the discipline of providing AI with the right information at the right time, is inseparable from understanding what the "right information" even is for a given system.
The framework has three zones:
Zone 1: Full AI autonomy. Greenfield code with clear specifications. New utility functions. Test generation from existing implementations. Documentation. These are problems where the context is fully contained in the prompt, and correctness is objectively verifiable.
Zone 2: AI with human guardrails. Modifications to existing systems where the behavioral contracts are documented and the blast radius is contained to one service. Here, the engineer provides context, reviews output, and validates against system knowledge. The AI drafts. The human judges.
Zone 3: Human-first, AI-assists. Changes to critical paths, cross-service modifications, anything involving implicit contracts or undocumented invariants. Here, the human architects the approach, and the AI helps with implementation details within tightly constrained boundaries. This is where the harness engineering discipline applies: you build the constraints that make AI useful rather than dangerous.
The mistake most teams make is treating all work as Zone 1. They deploy AI tools uniformly and wonder why production keeps breaking. The product engineer's job is to classify correctly and match the approach to the risk.
What Vercel and PostHog got right
The companies shipping AI features successfully into complex codebases share a pattern: they never let the AI operate without a system-aware human in the loop for critical paths.
Vercel's approach to their deployment infrastructure involves what they call "confidence boundaries." AI can generate and modify code freely within boundaries where automated tests and canary deployments will catch regressions. But changes that cross service boundaries or modify infrastructure-as-code require human review that specifically validates against operational knowledge: Will this change affect cold start times? Does this interact with the edge caching layer?
PostHog documented their internal approach in a 2025 blog post: every AI-generated change to their event pipeline requires an "event flow audit" from a senior engineer. The audit does not check if the code is correct in isolation. It checks if the code preserves the guarantees that 60,000+ customers depend on, guarantees like "events are processed exactly once" and "feature flags evaluate in under 10ms."
Neither company treats AI as a replacement for system understanding. They treat it as a tool that amplifies the output of engineers who already have that understanding. The senior engineer is the one who holds the system knowledge and directs the tool accordingly.
The five signals that you need a human, not a model
When working in a complex codebase, these signals should trigger you to stop prompting and start thinking:
-
You cannot write a test that fully validates correctness. If "correct" depends on behavior you cannot observe in a test environment (production traffic patterns, timing, external service behavior), AI-generated code is a gamble.
-
The change spans more than two services. Cross-service changes require understanding implicit contracts that exist between systems. No model has this context unless you provide all of it manually.
-
The last change to this code caused an incident. If git blame shows this file was last touched in a hotfix, treat it as radioactive. There are undocumented invariants here that even the humans barely understand.
-
Nobody on your current team wrote the original code. When tribal knowledge has been fully lost, AI cannot recover it. You need an archaeologist, not a generator.
-
The business logic defies common patterns. If the code does something that seems wrong but has survived years of production, it is probably right for reasons you do not yet understand. AI will confidently "fix" it.
The future of complex codebase AI work
The gap between what AI can do in isolation and what it can do in complex systems will narrow. Better context windows help. RAG over codebases helps. Multi-agent architectures that can query different parts of a system help. But the fundamental problem remains: implicit knowledge, operational context, and business judgment cannot be fully externalized into a format a model can consume.
This means the product engineer role becomes more important, not less, as AI tools improve. The tools handle more of the mechanical work. The judgment about what to build, how to build it safely, and what constraints to impose becomes the differentiating skill. You do not compete with AI on code generation speed. You compete on system understanding and risk judgment.
Notion's engineering team made this explicit in their 2025 hiring criteria: "We look for engineers who can operate at the system level, who understand why the code is the way it is, and who can direct AI tools within safety boundaries." That is a product engineer job description, even if they do not use the title.
Key takeaways
- AI tools fail predictably in complex codebases because they lack access to implicit knowledge, operational context, and historical decisions.
- The hardest problems in software are systemic, not local. Generating correct code in isolation does not equal generating safe code in context.
- Product engineers bridge the gap by carrying organizational context, classifying risk zones, and constraining AI output within safe boundaries.
- The "three zones" framework (full autonomy, guardrails, human-first) provides a practical model for deciding when and how to use AI.
- Companies succeeding with AI in complex systems (Vercel, PostHog, Stripe, Linear) all maintain human judgment in the critical path.
- As AI handles more mechanical work, system understanding and risk judgment become the differentiating skills for engineers who own outcomes.
FAQ
Can AI tools handle legacy code refactoring?
AI tools can handle isolated refactoring tasks within a complex codebase: renaming variables, extracting functions, converting syntax patterns. They struggle with refactoring that requires understanding why the code is structured a certain way. If the refactoring touches behavioral contracts, cross-service dependencies, or undocumented invariants, a human with system knowledge must direct the work. The AI generates options; the engineer validates them against context the model cannot access.
What makes a codebase "complex" in the context of AI assistance?
A complex codebase for AI purposes is one where correctness depends on information not contained in the source code itself. This includes implicit behavioral contracts between services, operational constraints discovered through incidents, business logic with lost context, and state machines that span multiple systems. If you can understand what the code should do by reading only the code, AI can help effectively. If understanding requires organizational knowledge, AI becomes unreliable without heavy human guidance.
How should teams measure AI effectiveness in complex systems?
Track three metrics: production incidents caused by AI-generated code (should trend toward zero), time-to-ship for changes in the "Zone 2" category (should decrease as engineers get better at constraining AI), and "context coverage" measured by the percentage of system knowledge that is externalized in documentation, tests, and architecture decision records. The third metric is leading: higher context coverage means AI tools can operate more safely because more implicit knowledge becomes explicit.
Is vibe coding ever appropriate for experienced engineers?
Yes, in Zone 1 scenarios: greenfield code, isolated utilities, prototypes, and throwaway experiments. Vibe coding becomes dangerous specifically when the problem involves system interactions that the AI cannot observe. The skill is knowing which zone you are in. Many production incidents from AI-assisted development come from engineers who vibe-coded a Zone 3 problem because it felt like a Zone 1 problem at the start.
How do engineers provide context to AI tools effectively?
The most effective pattern is structured constraint-setting rather than code-dumping. Instead of pasting an entire module and saying "refactor this," an experienced engineer writes a prompt that includes: the behavioral contracts that must be preserved, the latency and reliability constraints, the downstream consumers and their expectations, and the specific boundaries of what can change. This is context engineering in practice: shaping the model's output by controlling its input, not by hoping it will infer the right constraints from raw code.