← Back to Blog

Documentation-Driven Agentic Development

TL;DR: AI coding agents work better when you give them context. Write down your product decisions in markdown files alongside your code. Track architectural choices, technology selections, and component guidelines. The AI will reference these documents and produce more consistent, intentional code.


I've been trying a lot of different approaches to coding ever since Claude Code came out. Before that, it wasn't really feasible to use this style of coding - AI agents just weren't there yet. I was a strong advocate for using nvim. I really enjoy the plugin system, the ability to customize.

When I started learning to program in high school, I was told that the computer only does exactly what you have told it to do. I guess this part is out of date, but it's still mostly true. The AI might try its best to determine what you wanted when you prompted it with a half-baked thought. But, often times it just doesn't get things right. That's because you likely haven't specified what it's supposed to do!

The Solution: Document Your Decisions

Give it access to the documents and decisions that you have made about your product. Provide the relevant context so that your LLM is able to make decisions intelligently. Basically, what this means is that you need to make decisions about your business outside the context of your code. If you're familiar with hexagonal architecture, ports and adapters, or business driven development, this shouldn't seem too far fetched.

Again, so far I'm just advocating that you be a responsible developer and write up a specification, instead of jumping straight into vibe coding. This really starts with the core of the application. What are the resources that are important? Conceptually, what are you trying to achieve? That should be an easy enough question to answer.

Write them down. Then write more down. Then review what you've written. I know, it's annoying having to write things. You could get AI to help you format things if it makes you feel better, but don't get carried away and have AI generate you a full business specification. That's how you end up with a product that looks and feels like every other vibe-coded application on the market. We know that LLMs are just token predictors. It will give you something generic if not prompted correctly.

Why Track Decisions?

One of the biggest problems with projects built using agentic workflows is writing way more code than needed. The LLM is always more likely to add code than re-use or delete code that is no longer in use. If you have a source of decisions made in your project that AI must check in with, odds are higher that it will use them. In a sense this is the exact same problem that developers have, so it's not really an LLM-specific problem. So far so good, we're really just making good engineering decisions.

How to Track Decisions

This might upset some engineers. What I'm suggesting is using markdown files, managed in the same repo as the project.

I'm going to be honest, I don't really care if they're in the root of the project. You can put them in a folder if you'd like. When you're using AI to code, folder structure matters a lot less, and being able to navigate your file system is even more important.

This is the mindset I had when I was learning neovim - basically treating your project as a graph. Folders are an illusion. If you're grepping the project, it doesn't really matter. (You probably won't be grepping, Claude will.)

Concrete Examples

Here's what decision documents actually look like in practice:

Example: Database Selection

# Decision: Use PostgreSQL over MongoDB

**Date:** 2026-01-05
**Status:** Accepted

## Context
We need a database for storing user data, transactions, and relationships between entities.

## Decision
Use PostgreSQL for all persistent data storage.

## Reasoning
- Our data is highly relational (users, orders, products)
- We need ACID compliance for financial transactions
- Team has more experience with SQL
- Better tooling for migrations and schema management

## Consequences
- Need to manage migrations with a tool like Prisma or Drizzle
- Must define schemas upfront (less flexibility than document stores)
- Joins are performant, so we can normalize data properly

Example: Styling Approach

# Decision: Use Tailwind CSS

**Date:** 2026-01-03
**Status:** Accepted

## Context
We need a consistent approach to styling components across the application.

## Decision
Use Tailwind CSS utility classes instead of CSS modules or styled-components.

## Reasoning
- Faster iteration - no context switching between files
- Built-in design system constraints (spacing, colors, typography)
- Smaller bundle size with purging
- AI agents work better with inline styles (visible context)

## Consequences
- Class names can get long - extract components when repeated
- Team needs to learn Tailwind conventions
- Use @apply sparingly, prefer utility classes

Example: Component Library Usage

# Decision: Use Internal Component Library

**Date:** 2026-01-02
**Status:** Accepted

## Context
We have a component library with buttons, forms, modals, and other UI primitives.

## Decision
Always use components from `src/components/ui/` instead of creating one-off implementations.

## Guidelines
- Import Button from `@/components/ui/Button`, never create a new button
- Use the Modal component for all dialogs, even simple confirms
- Form inputs must use our FormField wrapper for consistent validation
- If a component doesn't exist, add it to the library first

## Anti-patterns to Avoid
- Creating a "quick" button with inline styles
- Copy-pasting component code instead of importing
- Building a custom modal "just for this one case"

Getting Started

Now you enter a dialog with your documentation. This is a replacement for Confluence, if you're a JIRA junkie. I think that this works better for actually moving quickly however. The idea is that you create a PRD, which relies on all of the product knowledge and decisions that you have made in the discovery phase. To be honest, it's ok to build a prototype, given they really don't take that long to generate these days with AI being the way it is.

Avoiding Duplication

If you want to avoid duplication in a codebase, there are some useful techniques that will help you out. You can create custom eslint rules, you can use hooks, and you can use directives. Directives are the easiest to implement because you're just instructing Claude how to use a widget/function/resource. This means telling it to use an API instead of accessing the database directly. Often times this works even better with correct separation of concerns. But, evidently, sometimes your agentic coding buddy just doesn't want to listen correctly. This is where the other techniques come in. I'll cover those in a future post.

Conclusion

Documentation-driven development isn't a new concept - it's just good engineering. But it becomes essential when working with AI agents. Here are the key takeaways:

  1. Write decisions down - Create markdown files in your repo that document architectural choices, technology selections, and coding guidelines.

  2. Be specific - Don't just say "use good practices." Say "use PostgreSQL," "import from the component library," "style with Tailwind utilities."

  3. Include reasoning - When you explain why a decision was made, the AI can apply that reasoning to similar situations.

  4. Keep it in the repo - Documentation that lives with the code gets read. Documentation in Confluence gets forgotten.

  5. Review and update - As your project evolves, update your decisions. Outdated documentation is worse than no documentation.

The goal isn't to create bureaucracy. It's to give your AI collaborator the same context that a human team member would have after being onboarded. The more context you provide, the better the output.

In a follow-up post, I'll cover how to use Obsidian to manage this documentation with linked notes, tags, and a graph view that makes navigating your project's knowledge base even easier.

Want to Work Together?

Get in touch to discuss your project needs.

Contact Me