{"slug": "from-openspec-to-aidlc-how-i-improved-my-team-s-ai-code-quality", "title": "From OpenSpec to AIDLC: How I Improved My Team's AI Code Quality", "summary": "A Harness Engineering team lead replaced OpenSpec with the AIDLC workflow to improve AI-generated code quality, reporting that development speed increased but bug-fixing time remained high. The author spent over a month restructuring the team's AI coding workflow, finding that OpenSpec's complexity and failure to capture original intent hindered large, multi-team projects. The new AIDLC approach led to a significant jump in code quality.", "body_md": "[Harness Engineering](https://www.dataleadsfuture.com/tag/harness-engineering/)\n\n# From OpenSpec to AIDLC: How I Improved My Team's AI Code Quality\n\nNo new commands to learn, just pick it up and use it\n\nBy this August, our team had been writing code with AI for more than half a year. The biggest thing I noticed during this time was that our development speed went up, but code quality stayed pretty rough. Development often took just half a day, but hunting down bugs could take several days.\n\nSo recently I spent more than a month restructuring our team's AI coding workflow. I replaced OpenSpec with the AIDLC workflow, using a more detailed software development process and stronger team collaboration. Code quality finally jumped up a lot.\n\nIn today's article, I want to tell you how we did it.\n\nI put all the source code mentioned in this article at the end. Feel free to grab it and try it out.\n\n## Introduction\n\nAI coding has been around for more than a year now. People's focus in this field has slowly shifted from which model works better and how much it boosts efficiency, to how we can make sure the code AI generates is actually good quality.\n\nI recently noticed something. On social media, people talk more and more about questions like \"how do I actually make sure my AI coding output has good quality\" and \"who should be responsible for code AI writes.\"\n\nIf you asked me six months ago, I would have said the best answer to this question was SDD (Spec Driven Development). Based on rule frameworks like SpecKit and OpenSpec, you first talk things through in a question-and-answer style to nail down the requirements and implementation rules. Then you feed the spec files to the LLM as a prompt, and the LLM writes code strictly following those specs. This seemed like the best way to do AI coding.\n\nI even wrote a few [articles](https://www.dataleadsfuture.com/tag/harness-engineering/) about tips for using OpenSpec.\n\nIt wasn't until I rolled out my method to the whole development team that I realized something. SDD works pretty well for small projects. But once your project gets big, spans several years, and needs collaboration across multiple teams, OpenSpec just doesn't hold up.\n\n## What Actually Went Wrong with OpenSpec\n\nWhen I say it doesn't hold up, let's look at what actually went wrong with SDD frameworks like OpenSpec.\n\n### Using it got way too complicated\n\nHow many commands from OpenSpec's documentation on GitHub do you still remember? Do you know exactly when to use `explore`\n\nand when to use `propose`\n\n?\n\nWhen I rolled out OpenSpec to my team, I wrote a whole document explaining when to use each command, and I told everyone to follow the workflow I laid out.\n\nThings still went sideways. Should `explore`\n\ncome before `propose`\n\nor after? Why can't I just jump straight to the `plan`\n\nagent? I bet you can't answer that either, right?\n\nBecause the commands and their use cases got so complicated, everyone on the team ended up using OpenSpec differently. Some people even used OpenSpec just for show at the start and switched to pure vibe coding afterward. This shows that the extra learning cost didn't really pay off for developers.\n\n### It never captured the original intent\n\nSpeaking of the difference between the `explore`\n\ncommand and the `plan`\n\nagent, this brings up another problem. The spec files OpenSpec writes never save the user's original intent or original requirements, and they never keep the conversation the user had with AI during the `plan`\n\nphase.\n\nBecause of this, when I reviewed spec files written by another team member, I often felt completely lost. Why was this user story written this way? What problem was this method design actually trying to solve?\n\nGive it enough time, and even the developer who wrote the code might forget why a feature got designed a certain way.\n\nOnce you lose the original intent, your project drifts further and further from its original goal with every iteration.\n\n### It's hard to get the right level of detail for requirements\n\nOpenSpec's `explore`\n\nmode, or the `brainstorm`\n\nmode in other SDD frameworks, is honestly pretty powerful. This can pull you straight into the trap of wish-based coding without you even noticing. You start hoping that a single sentence is enough, that OpenSpec will chat with you and break your requirements down step by step, then gradually build out a complete product for you.\n\nBut AI can't do that yet.\n\nThe current generation of LLMs is really good at finding shortcuts. If you describe a vague goal for your project and expect OpenSpec to break it down into fine-grained requirements and iterations, that rarely works. What you get in the end is just a demo with the main features and nothing else. All the detailed implementation is missing, so it's really just a half-finished product that can't go live in a production system.\n\nSo experienced developers know that when doing SDD development, the best move is to break the product's features into small pieces and let OpenSpec iterate on them round by round. For example, build the project skeleton and tech stack in the first round, then build the login and authentication system in the second round, and so on. Only this way can a project slowly get polished into a real product.\n\nBut it's really hard to control how fine you break these requirements down. Break them too coarse, and your project turns into a demo. Break them too fine and your development speed drops. Sometimes the developer hasn't even thought of some necessary features at the start, so details easily get missed.\n\n### Documentation stops matching reality\n\nNext up is the documentation consistency problem. Your team member starts by using OpenSpec to write out the spec docs, then moves on to coding, adjusting the implementation along the way. But because they never explicitly called an OpenSpec command again, none of those later adjustments ever get written back into any document.\n\nThere's another situation too. While generating rule artifacts, you notice a problem in `tasks.md`\n\nand fix it, but unless you specifically ask, AI won't go touch `design.md`\n\non its own.\n\nAs your project grows bigger with each iteration, this kind of inconsistency shows up everywhere. Eventually, the spec files completely lose their value as a reference. Then you end up with a pile of messy code.\n\n### You never know when to start the process\n\nI once asked a teammate why they still chose vibe coding even though everyone knew SDD could improve code quality.\n\nOne reason they gave me was that the commands map to development phases in such a complicated way that they genuinely didn't know when to kick off the process.\n\nHere's an example.\n\nRight after you use `apply`\n\nto finish writing code, you suddenly find a bug in what got generated. Do you ask AI to fix it directly, or do you go run the `proposed`\n\nartifact flow first?\n\nOr say you're in the middle of fixing a bug and suddenly get a great idea to tweak an existing feature, or maybe you just want to delete this chunk of code and rewrite it a different way. Do you run the OpenSpec flow first, or just change it directly?\n\n### Team collaboration falls apart\n\nEvery open source framework like OpenSpec assumes the same thing. With AI's help, each of us becomes a super developer who can handle everything from start to finish alone.\n\nBut everyone on our team has a clearly defined role. Modern business has gotten complicated enough that no single person can handle everything alone anymore.\n\nAfter you finish writing the requirements analysis doc and user stories, shouldn't you check them with the product team? At the very least, you need to align on how metrics get calculated, right? The same goes for architecture design and coding plans. Shouldn't you run those docs by other developers or an architect? What if the design approach has a mistake somewhere?\n\nBut the OpenSpec framework ignores this kind of problem completely. From the moment you start using `propose`\n\nto write spec artifacts until you finish coding, the whole workflow only happens in your own environment. Nobody else looks at the docs you wrote unless you go show them yourself. OpenSpec also makes it really hard to plug in quality gates or review mechanisms for control.\n\nSure, even the best frameworks have some flaws. But the problems with SDD frameworks like OpenSpec make it much harder for them to succeed in enterprise development teams.\n\n## What's My Solution\n\nSo how did I solve this whole mess?\n\nAt first, I thought like most programmers in the AI era. Build a new wheel myself, and let AI write a brand new workflow under my guidance.\n\nBut I quickly realized this wouldn't work. A new development process that hasn't been tested by a lot of development teams just turns into another AI toy. It doesn't have the reliability you need for an enterprise development environment.\n\nSo I remembered a piece of news from six months ago about Amazon AWS's AI coding workflow.\n\nAmazon seemed to run into the same problem we did. Their unreliable AI development process caused disasters in production. So they required that any code written by junior or mid-level engineers get approved by another role on the team. Hmm, this matches exactly what we ran into.\n\nI figured that at the time, this response was probably just a temporary fix. Six months had passed, so they must have come up with a more systematic, more engineered solution by now.\n\nAfter some digging, I found the solution they came up with: [aidlc-workflows](https://github.com/awslabs/aidlc-workflows/tree/v1).\n\n*Note: Amazon already released version 2.0 of aidlc-workflows, but this article is still based on version 1.0 with some custom modifications. I think version 1.0 is lightweight enough and easy to extend, which makes it more convenient to use. Try the customized version I share at the end of this article.*\n\n### What is AIDLC\n\nAIDLC stands for AI Driven Development Life Cycle. It's a software development process that corresponds to the traditional SDLC, or Software Development Life Cycle.\n\nThe traditional SDLC breaks enterprise-level software development into six or seven main phases: planning, requirements analysis, design, development, testing, deployment, and maintenance.\n\nAIDLC builds on top of these seven phases and adds two new capabilities: dynamic workflows and dynamic team collaboration.\n\nHow does it pull this off?\n\nFirst, AIDLC doesn't just inherit SDLC's seven phases. It also groups these seven phases into three big stages.\n\nThe Inception stage handles workspace detection, conditional sub-stages, and workflow planning. This stage answers the questions of what and why.\n\nThe Construction stage handles sub-stages like design, implementation, building, and testing. This stage answers the question of how.\n\nHere's what it looks like.\n\nIt looks like there are a lot of sub-stages to go through, but don't worry. Not every new requirement goes through all of them. As the image shows, the ones marked green always run, while the ones marked yellow only run when certain conditions are met.\n\nWhat decides which ones run and which ones don't is what AIDLC calls its dynamic workflow planning capability.\n\n### What is dynamic workflow planning\n\nWhen we bring up a new development requirement, AIDLC works differently from traditional SDD frameworks that first chat, then write docs, then implement. Based on the current project environment and the choices the user makes during the conversation, AIDLC branches into different conditional paths, and each branch loads a different subworkflow. Complex projects load more subworkflow stages, while small projects load simpler ones.\n\nHere's an example.\n\nThe first time AIDLC loads, it checks whether the current project environment is brand new (Green Field) or already exists (Brown Field). If it's an existing environment, it loads the `reverse-engineering`\n\nworkflow to analyze what the existing code already does. If it's a brand new environment, it skips the `reverse-engineering`\n\nsubworkflow entirely.\n\nWhen we bring up a new requirement, AIDLC checks whether it affects the product's end users. If it does, it loads the `user-stories`\n\nworkflow to do user story analysis. If your requirement is just a non-functional requirement, or purely a frontend page development task, it skips `user stories`\n\nand moves straight to the next sub-stage.\n\nAIDLC also keeps a file called `aidlc-state.md`\n\n. Besides tracking which stage the workflow currently sits at, this file serves another purpose too. If you want to do wish-based development, AIDLC breaks down your one-sentence requirement, pulls out the sub-requirement that needs the most urgent action, and kicks off the workflow for that one. The other sub-requirements get recorded in `aidlc-state.md`\n\nand wait for the next round of the workflow to start. This solves the problem of requirement granularity.\n\nAIDLC's core workflow works like a butler that always stays in the conversation. When something you say or the project's state triggers a condition, the butler pulls out the matching subworkflow document from the cabinet and lets that sub-process take over. This way, you don't need to remember which command to use when. The butler figures it out for you. You don't need to worry about learning new commands you can't remember, and you don't need to think about when to start a process either. The butler handles all of that.\n\n### What is dynamic team collaboration\n\nAIDLC's dynamic team collaboration has two parts: requirements analysis logging and approval gates.\n\nUnlike traditional question-and-answer conversations that mostly keep the chat history in context, AIDLC starts conversations and asks the developer questions whenever the sub workflow calls for it, at any point in the process. Every question and every choice the developer makes gets recorded in a file called `{current-phase}-questions.md`\n\n.\n\nAt the end of each sub-stage, if you want to tweak the output of the current stage or you have some new thoughts to share, those tweaks and AI's response get organized and saved in a file called `audit.md`\n\n. This solves the problem of the original intent never getting recorded.\n\nAt the end of each sub-stage, AIDLC faithfully records what you typed, what the LLM responded, and how the LLM summarized the work for that stage. Then the workflow pauses and waits for a human review.\n\nIf you work solo, you just need to check that all the documents look good and reply with \"continue.\" But if you work on a team and you need another role to review the documents for you, you can commit the code through git and send it to your teammate for review.\n\nYour teammate's review notes and marks get recorded in `audit.md`\n\n, and then that gets sent back to you. Your instance of AIDLC only moves to the next stage once it sees the approval mark for the current stage. `audit.md`\n\nonly supports incremental updates and never gets edited, so you always have access to every change and every review record.\n\nAIDLC also lets you `extend`\n\nthe workflow using the extensions folder. You can set which key stages need review from which roles, and you can set every round of review to log the reviewer's info for future reference. So, compared to OpenSpec, AIDLC puts a lot more emphasis on team collaboration.\n\nOK, that covers the details of what AIDLC can do. I bet you're eager to hear how this works out in our team's actual development.\n\n## How We Put AIDLC to Work on Our Team\n\nSince everyone cares about different things, going through my specific project won't give you much to work with. So in this section, I'm not going to walk through a specific project. Instead, I want to walk you through the local customizations I made based on what our team's development actually needed.\n\nTo make things easier to use, I already rewrote all these customizations as Skills. You just need to grab the source code at the end of this article, put it in the right place, and let your coding agent load it. It kicks in automatically after that.\n\n### Turning AIDLC into a Skill\n\nAIDLC's core lives in two folders. The `aws-aidlc-rules`\n\nfolder holds the core workflow definitions, and the `aws-aidlc-rule-details`\n\nfolder holds the subworkflow files that load on demand.\n\nBy default, it supports Amazon's own coding agent Kiro. For other common coding agents, the setup steps the official site gives you get so complicated that nobody has the patience to read through them.\n\nBut at its core, AIDLC is really just made up of a dozen or so Markdown files. That means you can completely turn it into a Skill instead.\n\nThe transformation is really simple too. Just create a folder called `aidlc-workflows`\n\nunder `.agents/skills`\n\n, copy `aws-aidlc-rules/core-workflow.md`\n\ninto that folder, and rename it to `SKILL.md`\n\n. Then, following the Agent Skills spec, copy every file from `aws-aidlc-rule-details`\n\ninto the `aidlc-workflows/references`\n\nfolder. Finally, have your coding agent fix up all the file paths so they point to the right place.\n\n### Extending the AIDLC workflow\n\nAs I mentioned earlier, AIDLC's workflow is really easy to extend. Beyond the sub-workflows already customized for the existing `inception`\n\n, `construction`\n\n, and `operations`\n\nstages under the `reference`\n\nfolder, it also supports the `extensions`\n\nfolder, which lets you add optional custom workflows that load dynamically. Testing, security, and resilient deployment all fall into this category.\n\nAn extension workflow usually splits into two files: the core workflow file `{workflow-name}.md`\n\n, and a lead-in file with an opt-in.md suffix called `{workflow-name}.opt-in.md`\n\n.\n\nThe `{workflow-name}.opt-in.md`\n\nfile contains a question that needs clarification from the user. The answer to that question decides which stages the extension workflow `{workflow-name}.md`\n\napplies to.\n\nThe `opt-in`\n\nfile loads during the requirements analysis stage, and based on how the user answers, it decides whether the extension workflow loads later on. If your custom extension workflow only has a `{workflow-name}.md`\n\nfile and no `opt-in`\n\nfile, that workflow always loads. This mechanism makes sure multiple extensions can load dynamically, so you can maintain endless extensions without blowing up your context.\n\nAlright, now that you understand how AIDLC's workflow extension mechanism works, let me walk you through a few extensions I customized.\n\n### Keeping documentation consistent\n\nThis extension requires AIDLC to update every related workflow document whenever code changes happen. This keeps the docs consistent with the code, so you never run into the SDD problem where the code changes but the spec docs stay out of sync.\n\n### Separating approval from execution\n\nIn the default AIDLC flow, once you approve a stage, the workflow automatically moves on and keeps running.\n\nThat's fine if you work solo, but it breaks down when you need to review a colleague's document. Say you're the product manager. You can't just let AI generate code on your own computer the moment the requirements doc gets approved, right?\n\nSo I split the meaning of \"approved\" into two separate actions: approve and continue. Once you approve the documents at a certain stage, the workflow doesn't automatically move to the next step. Instead, you should send the docs over to whoever handles the next stage. Once your colleague sees that you approved the docs, they say \"continue,\" and only then does the workflow keep going.\n\nThis split keeps approval and action separate, making sure different roles handle different stages of the software development process. It lets each teammate's expertise shine where it matters most.\n\n### Signing off on the audit trail\n\nThis extension solves the problem of who should get held responsible for code AI writes.\n\nIn the default flow, AIDLC logs every round of conversation between the user and AI in `audit.md`\n\n. This makes it easy to audit where a requirement came from and to trace the approval history at each stage.\n\nBut the default `audit.md`\n\nfile never records who raised the requirement or the change, and it never records who approved the documents. When your project needs team collaboration, it gets hard to figure out exactly who to talk to just by reading through `audit.md`\n\n's history.\n\nSo I used this extension to modify `audit.md`\n\nand added two keys: User and Email. I use `git config user.name`\n\nand `git config user.email`\n\nto fill in these two keys. This way I always know exactly who each history record belongs to.\n\n### Using the question tool\n\nThe original version of AIDLC is a workflow module built for Kiro, so it doesn't play that well with other AI IDEs. The questions it asks users get written into a file called `{phase-name}-questions.md`\n\n, and it expects users to go into that file to answer and record their responses.\n\nBut ever since I started using AI IDEs, I haven't touched traditional editors like VS Code in a long time. I really don't want to open up a whole IDE just to answer a few questions. That's way too much hassle.\n\nSince I mainly use OpenCode, I built an extension that has AIDLC directly use OpenCode's `question`\n\ntool to ask the user right after generating the questions, then writes the user's answers back into the document. This way, I never have to leave OpenCode to go edit a file in another IDE.\n\n### Testing and other best practices\n\nThese next few items are default extensions in AIDLC, not something I built myself, but I think they're worth talking about.\n\nWhy did we pick Amazon's AIDLC instead of yet another open source SDD framework? Besides the fact that this workflow got tested through the software development process at a huge tech company, we also wanted to learn from the software engineering experience of a top-tier tech company through AIDLC.\n\nAnd AIDLC really lives up to that. Under the `extensions`\n\nfolder, the `testing`\n\n, `security`\n\n, and `resiliency`\n\nsubfolders each hold this company's best practices for software testing, security, and continuous integration and deployment.\n\nHere's an example.\n\nIn the past, when AI wrote unit tests for us, it would sometimes change the source code or tweak the test afterward, just to make the coverage numbers look good. Basically, AI wrote the exam questions and then changed its own answers to cheat the metrics.\n\nBut AIDLC does things differently. It requires using Property Based Testing, or PBT. Instead of checking a single fixed input, PBT randomly generates a huge batch of input conditions, making it really hard for the code to \"memorize the answer\" ahead of time. AI has no idea what input comes next, so it can't tweak the code to game the test.\n\nFor a lot of startup teams, these practices are valuable lessons that are hard to come across in everyday work. If you get the chance, I recommend turning on the related options and giving them a try.\n\n## Conclusion\n\nThat covers how I used AIDLC to rework our team's AI coding process.\n\nBased on how we've been using it, this workflow really works well. There's basically no learning curve, and you can pick it up and start using it right away.\n\nAnd since this comes from the best practices of a major tech company, this workflow puts a lot of focus on dynamic workflows and dynamic team collaboration. It's really convenient for customizing based on what your team's development process actually needs.\n\nIt also makes it easier to clarify what each team member is responsible for at every stage of development. If something goes wrong in production, it's easier to trace the root cause, figure out who's responsible, and get it fixed.\n\nOne thing worth noting is that this workflow really emphasizes a software lifecycle management style of development. The questions that need clarifying during the conversation get a lot more technical too. You might need to learn more software engineering knowledge to fully master this workflow. But software engineering is basic knowledge every developer should learn anyway, so I don't think this is a big deal.\n\nThis workflow gave our team a huge boost, both in development efficiency and in code quality. So I recommend giving it a try yourself. If you run into any problems along the way, leave me a comment, and I'll answer as soon as I can.\n\nThanks for reading. I'm [Mr. Qian](https://www.linkedin.com/in/qtalen/), and I focus on researching AI agents for enterprise applications and AI coding. Follow my personal blog **Data Leads Future** to get my latest updates.\n\nIf you found this helpful, feel free to share it with your friends too.\n\n## Further Reading\n\n## Source Code\n\nHere's the source code for this article. Sign up now to get it for free.\n\n[Grab the Source Code](#/portal/signup)", "url": "https://wpnews.pro/news/from-openspec-to-aidlc-how-i-improved-my-team-s-ai-code-quality", "canonical_source": "https://www.dataleadsfuture.com/from-openspec-to-aidlc-how-i-improved-my-teams-ai-code-quality/", "published_at": "2026-09-01 11:59:09+00:00", "updated_at": "2026-09-01 12:26:30.550076+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-research"], "entities": ["OpenSpec", "AIDLC", "Harness Engineering", "SpecKit"], "alternates": {"html": "https://wpnews.pro/news/from-openspec-to-aidlc-how-i-improved-my-team-s-ai-code-quality", "markdown": "https://wpnews.pro/news/from-openspec-to-aidlc-how-i-improved-my-team-s-ai-code-quality.md", "text": "https://wpnews.pro/news/from-openspec-to-aidlc-how-i-improved-my-team-s-ai-code-quality.txt", "jsonld": "https://wpnews.pro/news/from-openspec-to-aidlc-how-i-improved-my-team-s-ai-code-quality.jsonld"}}