Structure Without Ceremony: AI in the SDLC
- Mark Waldron
- Mar 23
- 7 min read
The Ceremony Problem
The previous two posts covered using AI for specific tasks. Generating content at scale, then checking its quality. Both followed the same basic pattern: define a task, call the API, process the result. Useful, but each one was still a standalone tool.
This post is about what happened when I stopped thinking about AI as a tool for individual tasks and started thinking about it as something that could manage the development workflow itself.
I use Azure DevOps for project management on When To Travel. Planning, prioritisation, keeping all my ideas in one place. Work items, backlogs, pull requests, pipelines for deployment. The development flow for any piece of work looks roughly like this:
Read the story requirements in Azure DevOps
Plan the implementation
Create a feature branch
Write the tests
Write the code
Create a PR
Get it reviewed and merged
Clean up the branch
Close the work item
None of these steps are hard. But the overhead adds up. For smaller stories — adding a component, fixing a layout issue, tweaking metadata — the process around the work takes longer than the work itself. I could just vibe it, but I have worked this way for my whole career. There is value in structure, planning and understanding the work before just doing it. I want the decisions that go into the product to be deliberate and well thought out. For a team of one, that can be quite the overhead. For a team of many, it definitely adds value. I am becoming a team of me and Claude, so I want to retain that value but streamline the ceremony. And if this works for two, the same process should hold when the team grows. The structure is already there for the next person, human or AI, to slot into.
Onboarding the AI
Before I could hand the workflow to AI, I had to solve a context problem.
Claude Code reads a file called CLAUDE.md from the project root at the start of every session. It's essentially a standing briefing document. The tech stack, the file structure, naming conventions, styling rules, the project specific requirements (SEO, i18n patterns in this case), common pitfalls.
Without it, every session starts from zero. The AI doesn't know that we use Tailwind v4 without a config file, or that the proxy file replaced middleware in Next.js 16, or that .po files are the single source of truth for translations, or that we use logical CSS properties for RTL support. With it, the AI starts with the same baseline context a team member would have after a few weeks on the project.
This was more valuable than I expected. Writing down the project rules forced me to think clearly about what they actually are. Some of the conventions I thought I had were inconsistent or contradictory. The act of documenting them for the AI made me sharpen them for myself. It's like onboarding a new team member. The process of explaining your project reveals the bits you haven't thought through properly.
The file started as a few bullet points. It's now a detailed reference. And it's what makes everything that follows actually work.
The Skill
Claude Code has a feature called skills. They're Markdown files that define a reusable workflow — the steps, the tools available, the rules to follow. The AI reads the skill definition and executes it interactively.
I built one called /start-story. It takes an Azure DevOps work item ID, fetches the requirements, and runs the full lifecycle through to a completed pull request. A second skill, /close-story, handles cleanup after merge — removes the worktree, deletes branches, closes the work item. Two commands for the whole cycle.
But the mechanics aren't the interesting part. Three things about how this works have made a genuine difference to the way I build software.
Refinement Before Code
The skill's first job isn't writing code. It's asking questions.
I explicitly told it to push back before starting. "What's the expected behaviour when the locale isn't supported?" "Should this component handle the loading state or the parent?" "The story mentions a fallback. Do you mean a default locale or a 404?"
This is the refinement session. The same conversation that would happen in a team standup or a backlog grooming session, except it's me and a terminal. The back and forth matters. A vague story given to an AI produces vague output, fast. The discussion forces clarity before any code gets written.
It also surfaces things I hadn't considered. When you write a story as a solo developer, you're writing it for yourself. You skip over the bits you think are obvious. The AI doesn't know what's obvious. It asks. And sometimes the answer is "actually, I hadn't thought about that".
By the time we start coding, we have a shared understanding of what "done" looks like. That's not an AI feature. That's just good process. But having something that insists on it every time, without fail, is surprisingly valuable when you're a team of one with nobody to challenge your assumptions.
Small Commits, Clear Trail
After refinement, the skill plans the approach and breaks the work into small committable tasks. Each task gets its own commit with a reference to the story ID. Child task items get created back in Azure DevOps so there's a record of the plan.
This sounds like project management busywork. It's not. It does two things that matter.
First, it stops the work from wandering. AI is good at following a plan. It's less good at knowing when it's drifted off one. Breaking the work into discrete steps up front means each step has a clear scope. The AI works through them in order. No tangents, no scope creep, no "while I'm here I'll refactor this other thing".
Second, it creates an auditable trail. Every decision has a commit. If something doesn't work, I can walk it back to the exact point where the approach changed. Small commits mean small reversals. That's basic engineering discipline, but it's easy to lose when AI is writing code quickly and the temptation is to let it run.
Working in Parallel
Each /start-story sets up a git worktree. That's an isolated copy of the codebase on its own branch. The skill works inside the worktree while the main branch stays clean.
The interesting thing is what this enables. I can have multiple stories running at once in separate worktrees. Start one, let it work through the plan, switch to another, come back and review the first. I'm not writing all the code myself any more. I'm steering.
It's closer to being a conductor than a player. The AI handles execution. I handle direction. Which stories matter next. Whether the approach makes sense. When to push back on a decision. When to accept a compromise. The work moves forward on multiple fronts because I'm not the bottleneck on every keystroke.
This only works because of the first two points. If the refinement isn't solid, the AI wanders and I have to babysit. If the plan isn't broken into clear steps, I can't context-switch back and pick up where it left off. The parallel execution is the payoff, but the structure is what makes it possible.
/close-story
After a PR is merged, /close-story handles cleanup:
Verifies the PR is actually merged
Removes the feature worktree
Deletes local and remote branches
Moves the work item to Closed in Azure DevOps
Two commands. The whole lifecycle.
The Gotchas Nobody Warns You About
Getting this working wasn't smooth. The kind of problems you only discover by doing it.
Git worktree cleanup fails silently when node_modules exists in the worktree. git worktree remove --force just doesn't work. I had to use rm -rf on the directory first, then remove the worktree reference. Not elegant, but reliable.
If the shell's working directory is inside a deleted worktree, every subsequent command fails and you can't recover. The skill has to cd back to the main worktree before removing the feature one. I found this out the hard way when /close-story nuked the directory it was running from and then couldn't do anything else.
The MCP tools for Azure DevOps have type quirks. Work item IDs must be numbers, not strings. PR descriptions need actual newlines, not \n escape sequences. The API accepts the wrong types without error and just produces garbage output. These took longer to debug than the actual workflow logic.
Auto-memory helped here. Claude Code maintains a file where it records things it learns during sessions. Workaround patterns, gotchas, preferences. Once it learned about the worktree cleanup issue, it didn't repeat the mistake. Small thing, but it meant lessons from one session carried forward to the next.
Process You Can Actually Afford
Here's the thing I didn't expect. The conversation about AI in development is almost entirely about speed. Write code faster, generate more, ship quicker. That's real, but it's not the interesting bit.
What's actually changed is that I can afford process I couldn't justify before.
Refinement sessions. Planned approaches broken into auditable commits. Parallel workstreams with clean isolation. Backlog tracking and velocity dashboards. This is the stuff solo developers normally skip. When you're the only person, the overhead of doing it properly costs more than the mistakes it prevents. Stories and acceptance criteria feel like enterprise ceremony when there's nobody to hand them to.
But I'm not the only person any more. The team right now is Claude and me. The refinement conversation exists because Claude is there to have it with. The committable plan matters because something other than me is executing it. The process isn't overhead because I'm not the one carrying it.
I'm thinking about this from a team perspective deliberately. When To Travel is a side project, but I've spent my career in commercial environments. The way I've set this up — stories with clear acceptance criteria, planned approaches, auditable trails, proper branch management — that's not because a hobby project needs it. It's because I want to know this scales. When this approach moves into a team of five or fifteen, the process is already there. The skills, the CLAUDE.md context, the refinement step, the commit discipline. None of it needs to be retrofitted. A new developer joining the team gets the same onboarding the AI gets. An AI agent joining the team gets the same process a developer would follow.
The throughput difference showed up in the Azure DevOps dashboards. Burndown charts, velocity tracking, cumulative flow. There's a clear inflection point between the period before the skills were in place and after. I'm a team of one right now, so there's no ambiguity about what caused it.
But the real shift isn't speed. It's that proper engineering discipline became practical for a team of any size. The ceremony problem isn't solved by working faster. It's solved by not doing the ceremony yourself.
Right now the AI picks up work at the story level. The next obvious step is pushing it higher up the chain. Planning, prioritisation, deciding what gets built next based on real data. The orchestration moved from code to workflow. There's no reason it stops there.



Comments