Disclaimer: Opinions expressed are solely my own and do not express the views or opinions of my employer or any other entities with which I am affiliated.
I just shipped a tool called agent-rule-sync that automatically generates rules for AI coding agents by analyzing your codebase. The irony isn’t lost on me: I built a tool to help AI agents understand code better, while being helped by AI agents that didn’t understand my code well enough. If that sounds like a snake eating its own tail, welcome to modern software development.
We’ve fundamentally changed what it means to write software. We’re not writing code anymore. We’re providing context. We’re steering. We’re conducting an orchestra of AI-generated functions, classes, and modules that may or may not play in harmony.
And if you think “vibe coding” is just a faster way to ship features, you’re in for a rude awakening when your codebase turns into an unmaintainable mess of subtly inconsistent patterns that all technically work but feel like they were written by five different people—because they were, just none of them were human.
The Vibe Coding Illusion
Let me paint you a picture of what “vibe coding” looks like in practice. You open your AI coding assistant—Cursor, GitHub Copilot, whatever—and you describe what you want: “Create a function that validates user input and returns sanitized data.” Boom. In less than thirty seconds, you’ve got working code. You test it. It works. You ship it.
This is the seductive promise of AI-assisted development: describe your intent in natural language, get production-ready code. It feels like magic. It feels like we’ve finally achieved the holy grail of programming—writing software at the speed of thought.
But here’s what actually happened: the AI gave you code that works for the narrow case you described. It made assumptions about error handling. It picked a validation library (or didn’t). It chose a naming convention. It decided how to structure the return value. And every single one of those decisions was made in isolation, without any knowledge of how your team does things, what your architecture looks like, or what patterns you’ve established elsewhere in your codebase.
When I was building agent-rule-sync, I watched this play out in real-time. I’d ask an AI agent to add error handling to different modules across different sessions. Here’s what I got:
// Session 1 - analyzer.ts
async function analyzeCodebase() {
try {
const result = await runAnalysis();
return { success: true, data: result };
} catch (error) {
return { success: false, error: error.message };
}
}
// Session 2 (new chat) - rules-manager.ts
async function writeRules(data: AnalysisData) {
if (!data || !data.rules) {
throw new ValidationError(’Invalid analysis data’);
}
// ... rest of function
}
Two different error handling patterns, both technically correct, all completely inconsistent. One returns result objects, one throws custom errors, one logs and exits. Same codebase, different sessions, zero consistency.
Now imagine this at scale. Imagine a team of ten developers, all using AI assistants, all working on different parts of the codebase. Each developer’s AI is making independent decisions about patterns, conventions, and approaches. The code all works. The tests pass. But when you zoom out, you’ve got a Frankenstein codebase that looks like it was written by a committee that never met.
source: https://xkcd.com/844/
And here’s the truly insidious part: this isn’t obviously broken code. It’s not bugs you can catch in testing. It’s subtle inconsistency that accumulates as technical debt. It’s the kind of mess that makes onboarding new developers a nightmare, makes refactoring dangerous, and makes your codebase progressively harder to reason about.
The Context Problem
AI coding agents are incredibly powerful. They can generate boilerplate faster than any human. They can suggest completions that save hours of typing. They can even write entire features from scratch. But they’re fundamentally context-blind. They don’t know your patterns, your architecture decisions, your security requirements, or your team’s conventions.
The result? Every AI-generated pull request becomes a code review nightmare. You’re not just checking for bugs—you’re checking for consistency. Does this match our patterns? Does this fit our architecture? Does this meet our security standards?
And the hidden cost: technical debt accumulates faster with AI-generated code because it’s subtle. A human developer who doesn’t know your patterns will write obviously different code. You’ll spot it immediately. But AI-generated code looks professional. It looks reasonable. It’s only when you compare it to the rest of your codebase that you realize it doesn’t quite fit.
This is exactly the problem agent-rule-sync was built to solve. The tool analyzes your existing codebase, extracts the patterns and conventions you’re actually using, and generates rules that AI agents can understand. It’s like giving your AI assistant a style guide, an architecture document, and a security playbook all at once.
But here’s the meta-irony: I needed this tool while building this tool. I kept having to manually correct the AI’s output, explaining the same patterns over and over in each new chat session. “No, we use result objects with success/error fields, not thrown exceptions.” “No, we use verbose logging, not silent failures.” “No, we validate inputs at the boundary”.
The tool that helps AI agents understand codebases was built by an AI agent that didn’t understand the codebase it was building.
We’re Conductors Now, Not Coders
This isn’t a rant against AI coding tools, just FYI. I use them every day. They’ve made me more productive. But they’ve also fundamentally changed what my job is.
I’m not writing code anymore—at least, not in the traditional sense. I’m conducting. I’m providing context upfront, reviewing AI output, correcting inconsistencies, and maintaining coherence across AI-generated code. I’m teaching the AI my team’s way of doing things, one interaction at a time.
This is what “conducting” means in practice:
Providing context upfront: Before I ask an AI to generate code, I give it rules. I’ve learned that five minutes of context-setting saves an hour of corrections. Here’s the difference:
// Without context:
“Add error handling to this function”
→ AI generates whatever pattern it feels like
// With context:
“Add error handling to this function. Use our standard pattern:
return result objects with { success: boolean, data?, error? }.
Log errors with logger.error() including stack traces.
Never use process.exit() in library code.”
→ AI generates consistent code that matches your codebase
Reviewing and correcting AI output: I don’t just check if the code works. I check if it fits. Does it match our patterns? Does it use our conventions? Does it integrate with our existing code? If not, I happen to not just fix it—I explain why to the AI, so it learns for the next interaction and updates the rules.
Maintaining consistency across AI-generated code: This is the hardest part. When I notice the AI generating inconsistent patterns, I have to decide: do I update the new code to match the old patterns, or do I update the old code to match the new patterns? Either way, I’m the one maintaining coherence.
Here’s what people get wrong: they think AI makes coding easier. It doesn’t. It makes coding different. It shifts the skill from “writing code” to “steering code generation.” And that’s not less skilled work—it’s differently skilled work.
The best developers in the AI era won’t be the ones who can write the most lines of code. They’ll be the ones who can most effectively communicate context. They’ll be the ones who can articulate patterns, explain architectural decisions, and guide AI agents toward consistent, maintainable solutions.
Think about what this means for hiring. Companies are not looking for people who know syntax anymore—AI knows syntax. They are looking for people who understand systems, who can reason about trade-offs, who can maintain coherence across a codebase. They are now looking for conductors, not coders.
The Tooling Gap: We’re Building for the Wrong Problem
Here’s the uncomfortable truth: current AI coding tools are optimized for a different reason. They’re optimized for generation speed. How fast can we turn a prompt into code? How many lines can we autocomplete? How quickly can we scaffold a feature?
But that’s not the bottleneck anymore. The bottleneck is consistency. The bottleneck is maintainability. The bottleneck is ensuring that AI-generated code fits into your existing codebase without creating a mess.
We need tools that:
Extract and codify patterns from existing codebases: Your codebase already contains your team’s conventions. They’re implicit in the code you’ve written. We need tools that can analyze your code, identify the patterns, and make them explicit.
Feed those patterns back to AI agents: Once we’ve extracted the patterns, we need to give them to the AI. Not as vague guidelines, but as concrete rules that the AI can follow. “When handling errors, always return result objects with this structure.” “When validating inputs, always use this library.” “When logging, always include these fields or redact those.”
Validate AI output against team standards: After the AI generates code, we need automated checks that verify it matches your patterns. Not just linting—pattern matching. Does this error handling match our convention? Does this naming follow our style? Does this structure fit our architecture?
Make context portable and shareable: When a developer learns your team’s patterns, that knowledge should be captured and shared. When an AI agent learns your conventions, that learning should persist across sessions. Context should be a first-class artifact, not tribal knowledge.
agent-rule-sync is one attempt to bridge this gap. It analyzes your codebase, extracts patterns, and generates rules in a format that AI agents can understand. Here’s what an actual generated rule looks like:
Example from .cursor/rules/error-handling.mdc:
---
description: Error handling patterns
globs: [”**/*.ts”]
alwaysApply: true
---
- **Result Objects**: All async functions return result objects
- { success: true, data: T } for success
- { success: false, error: string } for failures
- Never throw exceptions in async functions
- **Error Logging**: Always log errors with context
- Use logger.error(message, { error, context })
- Include stack traces in development
- Redact sensitive data before logging
But here’s another challenge: even when you have great rules in Cursor or other AI tools, keeping them updated as your codebase evolves is a constant battle. You refactor your error handling, adopt a new pattern, or change your architecture—and suddenly your rules are stale. That’s why agent-rule-sync runs automatically: it keeps your rules in sync with your actual code, not what you think your code should look like.
We need to start treating context as seriously as we treat code. We need to document our patterns not just for humans, but for AI agents. We need to make our conventions explicit, our architecture decisions clear, our security requirements concrete.
Because here’s the thing: good documentation has always been valuable. But in the AI era, it’s essential. The better your context, the better your AI-generated code. It’s that simple.
The Path Forward: Embrace the Shift or Drown in Inconsistency
So where does this leave us? I’ve got a challenge for both sides of this equation.
To developers: AI agents aren’t magic. They’re powerful tools that need guidance—force multipliers, not replacements. The developers who thrive will be the ones who learn to conduct effectively: providing context, maintaining consistency, and guiding AI output toward maintainable solutions. The reality is you provide context, the AI generates code, you review and refine. That’s the new workflow.
To tool builders: Build for the conductor, not just the coder. Maybe prioritize pattern extraction, convention, maintaining coherence along with generation speed. Give us tools that make context portable and shareable. Give us tools that help AI agents understand not just syntax, but the team’s way of doing things.
And here’s the big picture: the future isn’t “AI replaces developers.” That’s never been the threat. The future is “developers become context engineers.” We’re shifting from writing code to providing the context that guides code generation. We’re shifting from implementing solutions to architecting them and then steering AI toward consistent implementations.
Those who embrace this shift will ship better. They’ll have AI agents that generate code that fits their codebase, follows their patterns, and maintains their standards. They’ll spend less time in code review and more time on architecture and design.
Good Tooling Amplifies Human Intent
There’s a beautiful irony in building agent-rule-sync. I built a tool to help AI agents understand codebases better, while being helped by AI agents that didn’t understand my codebase well enough. I was simultaneously the conductor and the audience, the teacher and the student.
And that’s the meta-lesson here: good tooling amplifies human intent, it doesn’t replace it. AI coding agents amplify your ability to generate code, but they don’t replace your judgment about what code should be generated. agent-rule-sync amplifies your ability to communicate patterns, but it doesn’t replace your understanding of what those patterns should be.
In traditional software engineering, inconsistency was messy.
In AI-generated engineering, inconsistency is a security vulnerability.
The developers who win in this era won’t just code — they will curate system coherence and architect the guardrails machines operate inside.
Code is cheap now.
Coherence is rare.
Context is the new leverage.
agent-rule-sync is open source and available on GitHub and npm. If you’re tired of inconsistent AI-generated code, give it a try. And if you’re building tools for the AI era, let’s talk.
Disclaimer - Fittingly, this was AI-co-edited. The machine helped tune the sentence-level coherence



