PRs That Don’t Look Vibe-coded: Spec-Driven and Harness in Practice
AI can write code fast, but fast code isn’t always good code.
If your pull requests look obviously AI-generated, the missing piece may not be a better prompt, it may be a better development process.
From Vibe Coding to Spec-Driven Development #
Fernando started with a simple problem: AI-generated code often worked, but it didn’t always match the team’s standards or the developer’s intent.
I wanted something that would help us be more productive, but that doesn’t sound like AI or look like bad code that won’t be in production. — Fernando
The key idea is spec-first, code-second. Instead of asking an AI agent to implement a feature immediately, you give it a structured path:
- Understand the project — document architecture, technologies, conventions, and constraints.
- Write the specification — describe what the feature should do and why.
- Create a plan — investigate the existing code and decide how the change should be made.
- Break it into tasks — turn the plan into small, concrete implementation steps.
- Implement — let the AI write code using the previous artifacts as guidance.
- Review and refine — check the generated work before it becomes a PR.
Tools such as GitHub Spec Kit and OpenSpec can help automate parts of this workflow. But the tool isn’t the main idea. The process is.
Why Specs Alone Aren’t Enough #
A specification can tell AI what to build, but it doesn’t necessarily tell it how your team builds software.
That’s where harness engineering comes in. A harness is the collection of instructions, project context, rules, skills, and conventions that guide the AI agent.
For example, your project might define:
- Naming conventions
- Error-handling patterns
- API and DTO conventions
- Architecture and layering rules
- Testing expectations
- Legacy areas that shouldn’t be refactored
- Framework and language versions
Fernando described the combination this way:
If we want to have a good result, good output of coding, that’s one way to achieve this: having iteration steps using some of these tools.
This is especially useful in large or older codebases. Instead of asking AI to guess how your system works, you give it a reliable set of rules to follow.
Make Your Rules Human-Readable #
Don’t create a 100-page AI manual that nobody wants to maintain.
Keep your specifications and guidelines short, focused, and readable. Yugo highlighted an important principle:
The spec should be short enough to be maintainable, so people can actually read and validate it. — Yugo
A practical approach is to keep your AI guidance in small files, such as:
docs/
ai/
coding-standards.md
architecture.md
testing.md
legacy-rules.md
Then connect these rules to your agent’s configuration or project constitution.
The goal isn’t to document everything. It’s to document the decisions that matter.
Treat AI Like a New Team Member #
Think about onboarding a developer. You wouldn’t simply say, “Build this feature,” and expect perfect results.
You’d explain the codebase, architecture, conventions, and constraints. You’d review their plan before implementation and give feedback when something doesn’t fit.
AI deserves the same structure.
Also, don’t try to automate every decision. Review the specification and plan when the feature is important, and let AI handle more of the routine work when the risk is low.
Improve the Harness Over Time #
Your first version won’t be perfect, and that’s fine.
When a PR contains an AI mistake, don’t only fix the code. Ask whether the harness could prevent the same mistake next time.
For example:
- AI repeatedly uses the wrong DTO naming → add the naming rule.
- AI refactors legacy code unnecessarily → document the legacy boundary.
- AI misses security requirements → add them to the specification template.
- AI misunderstands architecture → improve the project context.
As Fernando put it:
I will use the AI to improve my harness. Not only update this, but improve my harness files and update my guidelines. — Fernando
The Real Goal: Consistent, Reviewable Code #
Spec-driven development isn’t about making AI perfect. It’s about reducing randomness.
A strong workflow gives AI context, constraints, and checkpoints instead of one giant prompt. That makes the generated code more consistent with your team’s standards—and makes your PRs look less “vibe-coded.”
The biggest takeaway is simple: don’t just improve your prompts. Improve the system around your AI. When specifications, team conventions, and iterative reviews work together, AI becomes much closer to a productive pair programmer than a code generator.