Four spec-driven tools, one sentence, the same existing project with a separate backend and a database. All four shipped the feature. Nobody needed a fix from me. One did it in 4 minutes, another took 2 hours 11 minutes and most of a free credit tier.
Hope you saw the first article, "8 clicks or 54: what four spec-driven tools actually cost before you write a line of code". A lot of you wanted to see a workflow actually in action, so here it is.
The feature is drag and drop: move a task from one day column to another. Quite a simple one, but it requires some intelligence to choose the library and handle events.
The question is simple: how much do I have to do myself before the feature actually works? Not until there's a plan, until I can drag a task in the browser and it stays there after reload.
All four got there. Not one of them needed a fix from me. But the same sentence cost 6 actions and 4 minutes with one tool, and 105 actions and 3 hours with another. One of them planned 13 tasks, another 29, and one wrote no task list at all.
If somebody doesn't know some of the tools here, they are:
OpenSpec
github.com/Fission-AI/OpenSpec
GitHub Spec Kit
github.com/github/spec-kit
BMAD Method
github.com/bmad-code-org/BMAD-METHOD
Kiro (IDE)
kiro.dev
What counts as an action
Same definition as the first article, so the numbers still compare.
An action is one thing I do with my hands. A click, a command I type, an answer I pick, a dialog I confirm. Copy and paste is two actions. If something fails and I have to repeat it, the repeat counts too. Waiting for generation is not an action, it happens while I wait.
One thing is new this time. Actions are split into two groups. One-off actions are what you pay once when you set the tool up: install commands, picking your agent, config questions. Per-run actions are what you pay every single time you add a feature: the prompt itself, answers to its questions, approval clicks, manual fixes, restarts.
The first article mixed those two not in the best way, and a few of you pointed that out. Kiro's 15 actions before the first prompt are paid once. Its 32 approval clicks are paid on every feature. If you ship something new every week, the second number is the one that will bother you a year in.
The project
I built the base myself with plain Claude Code, no workflow, no spec tool, so nobody gets a head start. It's the same week planner from the first article, but a real one this time: TypeScript, Express, SQLite with SQL migrations, React and Vite on the front, one repo, two folders. It runs with one command, no Docker, no account.
It's finished and it works. You can add a task to a day, mark it done, delete it, and it's all still there after reload. There's a git history with real commits, and no trace of any of the four tools in the folder.
Every tool gets its own untouched copy of that repo, in its own folder with nothing around it. The agent reads what's next to the project, so siblings and my notes stay somewhere else. I learned that one the hard way in the first article, it cost me two restarts.
The feature
One sentence, the same one for all four:
Let me drag a task from one day column to another.
That's it. No hints about which files to touch, no mention of the API, no mention of the database.
Before the first run I wrote down which files a correct implementation has to touch and which ones it must not, and never changed that list. Five files on the front end, seven places that look related but are already done, all of them on the server, which handles day_index before anyone touches it.
When it counts as done
I open the app in the browser, make three drags in a row to different columns, reload the page, and the tasks are where I dropped them.
A task that moves on screen and jumps back after reload is not done. Order inside a column is not required. Animation, undo and keyboard support are not required either, and if a tool builds them anyway, that goes in the notes as extra work, not as a win.
After each run I also check by hand that nothing else broke: adding, marking done, deleting, reload, and starting the app with one command. If one of those broke, the feature still counts as done, but the break goes in the table.
The baseline
macOS 26.2, Node 22.22.1, npm 10.9.4, git 2.41.0, Claude Code 2.1.270. Express 4, better-sqlite3, React 18, Vite 6. Opus 5 on high effort everywhere except Kiro, which runs its own agent and picks its own model.
Here is what that looked like.
Actions are one-off plus per-run. Nobody needed a manual fix from me, all four passed on the first attempt.
Kiro's one-off column is zero because the app was installed and logged in during the first article, and a new project folder costs it nothing. OpenSpec was installed too, but its init has to run again in every new folder, so it still pays 4. Add 15 back to Kiro if you are starting from nothing.
Kiro is also the only paid one: 39.38 of its 50 free credits went into this single feature. The other three cost nothing.
OpenSpec
One-off actions: 4
Per-run actions: 2
Manual fixes: 0
Accepted: first attempt
Tasks planned: 13
Time: 4m 26s
Required files touched: 5 of 5
Untouchable places touched: 0 of 7
Things invented instead of reused: 0
Regression: 5 of 5 passed
Setup
Let's get to the first one, it was already installed from my previous testing so I don't need to do it again, but if you're wondering:
npm install -g @fission-ai/openspec@latest
Then, as needed, I ran "openspec init" which configures Agent Skills and workflow commands and shows in the quick start:
/opsx:propose to start a change
/opsx:apply to implement tasks
It already explains that /opsx:apply is for implementing tasks, so I don't need to look for anything in their README or docs, god bless. I would love to see a note that the folder is already holding a project. But i don't.
And also there's no mention regarding telemetry like the first time.
Then the tool list. 40 available, none preselected, Claude Code fifth. The same tool selection as last time. So it remembers the telemetry notice but not my tool choice, it's installed globally and I was expecting it to remember Claude Code, but it asks like I'm using it for the first time. Alright, choosing Claude Code.
Setup complete: 6 skills and 6 commands in .claude/, config in openspec/config.yaml. Nothing was said about the project that was already in the folder, nothing about git.
I ran git status to see what landed. Two new folders, .claude/ and openspec/, 2334 lines across twelve markdown files, both untracked. Not sure if they should be in .gitignore, but I would ask to put them there. No existing file was modified. Spec Kit warned me about exactly this in the first article, OpenSpec says nothing.
Four actions, and three of them I pay only once.
The prompt
/opsx:propose "Let me drag a task from one day column to another."
Nice, no questions, no stops, and really quickly it created the change file "drag-task-between-days".
Got four markdown files. Seeing in proposal.md: the move goes through the existing PATCH /api/tasks/:id with day_index, web only, the server and the API client already support it.
That's the whole point of this article. It read the project before it planned anything.
The plan
spec.md: 5 requirements, 12 scenarios. design.md: native HTML5 drag and drop, no dependency, and one line that tells you it looked at the code, moveTask mirrors toggleTask. tasks.md: 13 tasks in 4 groups, in dependency order, hook then TaskItem then DayColumn then WeekBoard then copy then verification.
It also decided two things by itself instead of asking: no reordering within a day, because that would need a server-side position column, and no keyboard handling.
Against my reference map: all five required files, plus the two CSS modules I had marked as expected. None of the seven places I listed as untouchable. Nothing invented, no new endpoint, no migration, no second write path.
Two of the thirteen tasks are copy, the README intro and the page subtitle. I didn't ask for either.
We're ready to apply our task, leeeet's go.
Getting it to work
Those who read the first article will remember that I had to move the project to the root directory because Claude Code was reading logs and other files around it. Well, now something else has happened: the agent started using the Claude in Chrome extension on its own. It's certainly perfect, and I don't know how I ever used Claude Code without it before, but for our testing it's cheating, and Kiro won't be able to use it at all. So I disabled the extension, threw the run away and started again from a clean copy.
/opsx:apply.
and In 4 minutes 26 seconds, it was finished, 13 tasks, straight through. It anyway tried to use Claude in Chrome, but it was disabled, so it used Playwright. Didn't see an agent test with Playwright for months, hahaha, that's nostalgia. 28 checks against the dev server, including reload persistence and exactly one PATCH with day_index.
Then I opened the app and saw test data it left after its own testing: Pending one, Walk dog, Buy milk. I don't mean to say that's a bad thing, it's just an observation. I cleared the database and created my own todos for testing.
Six tasks:
- Review PR and Team sync on Monday,
- Write migration on Tuesday,
- Fix the login bug on Wednesday, marked as done,
- Deploy to staging on Friday,
- Plan next week on Sunday.
Then the drags 😏.
"Review PR" Monday to Thursday. "Write migration" Tuesday to Saturday. "Deploy to staging" Friday to Monday. Reloaded the page. All three stayed where I dropped them, the counts followed, and "Fix the login bug" was still marked done.
The drag and drop works fine, no surprising stuff, just basic functionality. First attempt, zero manual fixes from me.
In my opinion, the tools had completed it perfectly exactly how i expected to see. But many of you will tell:
Artem, you tested adding a small feature to a small app, but when we add a feature to our big one, everything breaks. You’re right, but our goal here isn’t a stress test, it’s to check how well the tool follows instructions and executes them correctly.
If anyone actually wants a stress test, let me know, and I’ll set up a project that changed direction a bunch of times, used different AI systems, and was basically total chaos.
Spec Kit
One-off actions: 9
Per-run actions: 4
Manual fixes: 0
Accepted: first attempt
Tasks planned: 24
Time: 9m 40s
Required files touched: 5 of 5
Untouchable places touched: 1 of 7
Things invented instead of reused: 2 components nobody asked for
Regression: 5 of 5 passed
Setup
This one needs uv, no minimum version given, I have 0.12.10. The install command is already done from the first article, so I went straight to the init command from the README:
specify init my-project --integration claude
And stopped right there. It wants a folder name and it creates that folder. My project already exists, so I went looking in the README for what to run instead.
First thing on the page is a "Choose your process" table. Three rows: build a feature or application, diagnose and repair broken behavior, decide whether an idea deserves investment. Splits by intent, not by whether the code is already there.
"Build a feature or application" is exactly what I need, so I clicked the blue text next to it.
That gives the flow in one bold line: constitution once per project, then specify, plan, tasks, implement, converge per feature. Same six commands as the first article. So I have to start with /speckit-constitution because the project doesn't have a constitution. But no info regarding existing projects and how to deal with them.
Clicked "Command reference" to check if there are some commands for working with an existing directory. Eleven commands in a table, six in the main flow plus four optional gates. The intro says they become available after specify init. Two pages of docs read, still nothing about a project that already exists.
So I ran the command as given, with my folder name:
specify init week-planner --integration claude
Project: week-planner. Working Path: /Users/shken/week-planner. Target Path: /Users/shken/week-planner/week-planner.
It was about to install into an empty subfolder inside my project, and the only sign of that is one line in the header. Pressed Esc. The README gives this exact command with no warning about what happens in a folder that already holds a project.
Second try with a dot instead of the name:
specify init . --integration claude
Warning: current directory is not empty, 8 items, template files will be merged with existing content and may overwrite existing files. Continue? Default is N.
Specifying the dot instead of "week-planner" helped it recognize that this is an existing project. This is the first time either tool has said anything about the folder already holding a project, and the README never mentions the dot.
Typed y. Script type prompt, sh preselected. The same as with OpenSpec, I already chose the script type in the first article and it should have remembered that, but nvm. Enter.
Project ready. Installed the integration, shared scripts and templates, 6 scripts made executable, constitution copied from template, bundled workflow installed. Then the Agent Folder Security warning about credentials in .claude/, the same one as the first article, and nobody else gives it.
We got our setup, and it said "Constitution setup (copied from template)" so it means we're able to start from /speckit-specify. Hahah no. The constitution.md is just a mix of placeholders. So that line is confusing and makes me think it's done.
git status: two new folders, .claude/ and .specify/, 30 files in total. 30 against 12 from OpenSpec. And something was even added to .gitignore.
.specify ships its own .gitignore, .claude does not and you only get a suggestion to add it by hand.
Nine actions before I could say a word about my feature.
The prompt
/speckit-constitution.
Running first, because the file is still a template.
No questions at all. It read the code and derived six principles from it, each one pointing at a real file: module boundaries from the README rules, the response envelope from respond.ts and errorHandler.ts, validation from check.ts, tests from the existing Vitest coverage, plain tools from the hand-rolled helpers and SQL migrations, optimistic rollback from useTasks. Plus a commit style taken from my git history. Version 1.0.0, 1 minute 43 seconds. It even flagged the two rules it extrapolated furthest and offered to revise them.
In the first article this same command asked me three questions and invented a fifth principle on its own, because the folder was empty. Here it asked nothing and every principle points at a real file. Same command, completely different behavior, purely because there is code to read.
Then the feature:
/speckit-specify "Let me drag a task from one day column to another."
No questions here either. Three prioritised stories: drag to move, rollback on failure, keyboard-only move. 14 functional requirements, 7 measurable success criteria, 10 edge cases, and a 16-item checklist that passed on the first validation pass.
It generated 14 requirements and added keyboard support, which OpenSpec was missing. And it mentions "visible in the new column within 100 ms regardless of network", that's an important note and telling you about it is a big plus.
It read the code here too. The rollback story says it mirrors how add, toggle and delete already behave, and one of its recorded decisions states outright that nothing new gets stored.
I've just realized we have to execute four more commands to add drag and drop. Talking ahead, this workflow is definitely for something complex.
The plan
/speckit-plan.
No stack question this time, the stack is already in the repo.
Six artifacts hahah, it even has an api-contract.md, plan.md with a constitution check before and after design, research.md with 8 decisions and their alternatives, data-model.md where Task stays unchanged, contracts/api.md, contracts/ui.md, quickstart.md.
Headline findings: no server, schema or API change, the route and the gateway already support changing day_index, front end only plus one pinning test. Zero new dependencies. One risk flagged with a fallback, Firefox may refuse to start a drag when mousedown lands on the toggle button.
Same "Branch: 001-drag-task-between-days" line as the first article, and again no branch was created, git is still on main. This time the output says so itself.
/speckit-tasks.
24 tasks in 6 phases. Setup 1, foundational 4, drag 8, rollback 3, keyboard 5, polish 3.
24 against 13 from OpenSpec for the same sentence. Five of them are the keyboard story and a new MoveMenu component, neither of which is in the feature I asked for.
Against my reference map: all five required files, plus the two CSS modules I marked as expected. One of the seven untouchable places is in the plan, a new test in taskGateway.test.ts
The amount of commands I have to run is not the scariest part hahaha, we have 24 tasks to execute now. Of course it suggests an MVP cut, but we run it the way they recommend.
Suggested MVP scope. Phases 1-3 (T001-T013). Because Constitution VI requires the rollback to ship with the operation, T004 already includes it, so the MVP also covers the core of US2; Phase 4 only fixes the stale announcement and proves the failure paths.
Getting it to work
/speckit-implement.
Done in 9 minutes 40 seconds, nothing committed. 11 files modified, 2 new, 0 dependencies.
Same verification route as OpenSpec once the Chrome extension was gone, it drove the real app headlessly with Playwright, except this one ran two browsers, Chromium and Firefox. 11/11, 9/9 and 21/21 per story, exactly one PATCH with day_index. Two things it says it did not do: VoiceOver, which can't be driven headlessly, and touch. Then four suggested commits, and it asks whether to make them.
I opened the app and, same as OpenSpec, there was test data left behind: Call the bank on Monday, Buy milk on Wednesday. Two out of two so far.
And already seeing that it added a drag and drop icon on the left side of every task. That's a UI change that wasn't requested, and I wouldn't want my workflow doing that.
Cleared the database, ran the same three drags, reloaded. All three stayed.
The drag and drop works as expected, and it added a drop animation, a blue outline when the task is over a day, and a hover animation on the close icon. First attempt, zero manual fixes from me.
What it left in the code that I didn't ask for: a global .visuallyHidden class, the first global class in a codebase where everything else is a CSS module. A MoveMenu component that is the only place in the project touching document directly. Two hardcoded colours where every other colour resolves through a variable. A data-drop-target attribute nothing reads. And an exported helper used only inside its own file
BMAD Method
One-off actions: 10
Per-run actions: 4
Manual fixes: 0
Accepted: first attempt
Tasks planned: no task list
Time: 36m 5s
Required files touched: 5 of 5
Untouchable places touched: 0 of 7
Things invented instead of reused: 0, plus 3 dev dependencies
Regression: 5 of 5 passed
Setup
Requires uv, Node.js, npm, Git and an AI coding tool that supports skills. No minimum versions given, all covered by the baseline.
Almost at the start of their README I see this line: start anywhere, use BMad end to end, or carry its briefs, specifications and architecture into your existing delivery workflow. So users will already know that this is the right place. Then scrolling a bit down under the installation block, there are two links, and the second one is what I need: "Add BMad to an existing codebase". Clicking.
This page actually answers my question. For a small change it says use bmad-build, and for anything bigger bmad-spec first. It also says Build investigates the repository itself and writes down what to reuse and what not to change, which is exactly what I'm measuring here. There is an optional bmad-project-context that writes into AGENTS.md, and I don't have one, but that's setup, not the feature, so I noted it separately.
You do not inventory conventions beforehand. bmad-build investigates the repository, writes down what to reuse and what not to change, and follows that. It does not stop to ask whether to match the current codebase.
It also says I can type bmad-help if I don't know where to start. I was texting with the founder of BMAD when I dropped the first article and he said the same thing.
First of the three tools with a named entry point for an existing codebase, linked straight from the README.
OpenSpec never mentions the case, Spec Kit gave me nothing across two pages of docs.
npx skills add bmad-code-org/BMAD-METHOD
Clicked y to install the package and got the skills selection, and I see bmad-build, that's exactly what we need. Hitting Select All, same as before, 29 skills.
Then agents selection. 79 of them, 20 Universal ones installed automatically, and Claude Code was already marked as selected. I didn't click anything. There is no .claude folder in this project, so it didn't read it from there. That's great, the first tool that remembers something. OpenSpec asked from scratch even though it's installed globally, Spec Kit took the integration from the command line and still asked about the script type.
Installation scope: Project. Installation method: Symlink, recommended. I had no idea what a symlink was in the first article, so I read it up, it's a file that points to another file, acts like a desktop shortcut.
Then the security risk table for all 29 skills from three scanners. This time no High Risk at all, and I have no idea what caused that or why it's shown to me in the first place. In the first article there was one High Risk from Gen and another from Snyk. Same scanners, same skills, different verdicts.
Installation complete. 290 new untracked files. That's a crazy number for our use case, I guess because we hit Select All. For comparison: 30 from Spec Kit, 12 from OpenSpec.
Then, as the README says, open the coding tool in the project and ask the bmad skill to run bmad setup.
bmad setup
25 seconds, no questions, defaults. 12 more files, so now we're at 302. And then something no other tool did: it listed its own untracked folders by name and said to commit or ignore them as I prefer. OpenSpec said nothing at all, Spec Kit only warned about credentials in the agent folder.
Ten actions, and I still haven't said a word about the feature.
The prompt
bmad-build "Let me drag a task from one day column to another."
Before asking me anything, it read the project and said the server already supports PATCH /api/tasks/:id with day_index, so this is web-only work: moveTask in useTasks, drag and drop wiring on TaskItem and DayColumn, prop threading through WeekBoard and App.
That is the exact five files from my reference map, named before a single question.
And then it asks one. The first tool that asks anything about the feature itself, and I already miss them. Which drag and drop mechanism, native HTML5 recommended with no new dependency, or dnd-kit for touch and keyboard sensors. Didn't think it was going to ask that, the previous tools decided by themselves that no external library is needed. I usually prefer a package because it removes a pile of helper code. But nevermind, going with recommended.
A confession before the next part. I was about to finish the BMAD test when the final output of bmad-build said it had used Claude in Chrome. Fuck, why does it always decide to do that. Rolled back the branch, deleted the artifacts and ran the same command again with the extension off, and got a completely different question. In the first run with the extension on it asked about putting the feature into a new branch, and never asked about the mechanism. Everything below is the clean run.
The plan
There is no plan. No tasks.md, no task list, no phases. One spec file, then implementation in the same session. Same as the first article.
The spec is web only, adds moveTask mirroring the existing optimistic-update pattern, native HTML5, no new dependency, and excludes in-column reordering, touch and keyboard. Those are the same exclusions OpenSpec recorded as assumptions, and the opposite of Spec Kit, which turned keyboard support into a P3 story and built a whole MoveMenu component for it.
Then it stops again and wants me to choose what to do with the spec: approve and continue here, approve and stop so a fresh session picks it up, or have a subagent review it first. Approve and continue.
And it stops a third time. Its own spec requires a passing test for every row of its I/O matrix, but the web workspace has no test runner, so that check would fail by default. Add vitest, jsdom and testing-library, or waive the audit.
No claude extension available, my bro struggles. Haha.
That's the only tool in this article that stopped because it couldn't satisfy a requirement it had written itself.
Getting it to work
Done. moveTask goes through the existing PATCH with day_index, snaps back with the error banner on failure. The web workspace got its first test suite, 17 tests, alongside the server's 27. Its own review triaged 14 findings, patched 4, deferred one.
Then the line that no other tool wrote: nobody has dragged a task in a real browser yet, because jsdom can't do native drag and drop, so a manual walkthrough is worth doing.
It also committed on its own, straight to main, as 8ef3a6a.
We got the task done with a bunch of tests hehe. BMAD didn't use Playwright to see the browser like the other tools did, so now we're going to be the first to actually see it.
Opened the app and the board was empty. No test data left behind, the first of the three to leave the database clean.
Added my six tasks, ran the same three drags, reloaded. All good, drag and drop is working, and we also got an animation of the task dropping, a blue outline of the day. The animation of the task being picked up is a bit rough, sharp corners are visible even though the task itself is rounded.
First attempt, zero manual fixes from me.
36 minutes and 5 seconds from the prompt to a working feature, and four of those minutes were me answering its three questions.
What it left in the code that I didn't ask for: three dev dependencies and 47 new lockfile entries, the only tool that touched package.json. Module-level helper functions and a ref counter in DayColumn, which no other component in this project had. A constant exported from one component and imported by another, where shared constants live in days.ts. A setTimeout to defer a state update, the only timer in the whole web codebase. And 319 untracked files sitting in the project.
Kiro (IDE)
One-off actions: 0 this time, 15 paid in the first article
Per-run actions: 21, plus 84 approval clicks
Manual fixes: 0
Accepted: first attempt
Tasks planned: 29
Time: 2h 11m, 39.38 of 50 free credits
Required files touched: 5 of 5
Untouchable places touched: 0 of 7
Things invented instead of reused: 0, plus 7 dev dependencies
Regression: 5 of 5 passed
Setup
Nothing to install. The app, the account, the theme and the shell setup were all paid for in the first article, 15 actions that I never pay again. That is the whole point of splitting one-off from per-run: this is the only tool of the four where the setup column is zero this time.
The credit counter reads 7.46 of 50 used, all of it from the first article. Kiro runs its own agent and picks its own model, so Opus 5 on high effort does not apply here.
Opened the week-planner folder. Four optional workflows on the right, Spec, Plan, Bug Fix, Quick Spec. Clicked Spec, and nothing happened except the item getting underlined, exactly like the first article.
The prompt
Let me drag a task from one day column to another.
Great seeing in the text behind the question "It's a week planner with day columns and task items", this guy is clever actually 😂
Regarding the questions, I got the same one as in the first article, how to approach the spec, requirements or design, so choosing recommended.
One question did disappear though. In the first article, in an empty folder, it asked whether this is a new feature or a bugfix. It doesn't ask that here.
Then the first approval request, mkdir for the spec folder. Guys, now we will get a bunch of approval requests, I have to click Allow about 40 times or so. But that's important for this article.
And then a screen asking me to accept or reject two files it had just written itself. Have no idea why it asks to review its own files, okay for reading and changing mine, but its own.
The plan
15 minutes and 1.72 credits later we got requirements.md, 7 requirements. Requirement 3 points straight at the existing code: optimistic day_index update, PATCH, rollback on error, same as the toggle and delete that are already there.
And then it does something no other tool did. It stops and flags a conflict inside its own spec: requirement 7.3 asks for keyboard-accessible moving, but native HTML5 drag and drop has no keyboard support, so it would need a second mechanism, a move-to-day menu.
So it asks if I want to add one more button to allow dragging using keyboard. Not really sure if I get it, and we don't need it anyway, so typing "skip it for now".
That is the same wall Spec Kit hit and solved by building a whole MoveMenu component without asking, and that OpenSpec and BMAD both dropped as an assumption. Kiro is the only one that put the decision in front of me.
design.md follows. Native HTML5 drag and drop, WeekBoard owns the drag session state, useTasks gets moveTask following the exact same optimistic pattern as toggleTask. Same five files as my reference map, named without me pointing at anything. It also flags a dragDepth ref counter on its own, to stop the highlight flickering when the pointer crosses child elements, which is what BMAD arrived at independently.
It stopped again to tell me it updated requirements.md and asks if I want to generate the tasks. Yes I want, let's send "Generate the tasks". I would like it to just ask me if I want to execute them now with options, but it asks me to type, and that creates an additional risk that I type something and it interprets it differently.
Then I opened tasks.md to check how many tasks it holds, and there are 29 in total, 13 of them tests and the rest real logic.
29 against 24 from Spec Kit, 13 from OpenSpec, and no task list at all from BMAD.
Getting it to work
Typing: Yes run
2 hours 11 minutes and 39.38 credits later, it's done. That's the longest session I've had today and it's crazy boring. It leaves me 3.16 out of 50, and I have no idea if it takes credits for its own retries, would be weird if yes. So for the next one I would definitely have to upgrade. For comparison, the first article spent 6.94 credits and 41 minutes on the plan alone, with no code written.
Here is where those two hours went.
So it started to ask me now to edit files as well, and I wondered if it's going to happen to every file it is supposed to interact with. It does. Twelve Review changes dialogs, and between them the approval prompts for commands keep coming. useTasks.ts twice. Both CSS modules twice. tsconfig.json twice.
84 clicks on Allow by the end of the run. The first article cost 32, and that run never wrote a line of code.
It also keeps failing to run its own commands. It prefixes them with timeout, which does not exist on macOS, so the command dies before vitest even starts. It happened at least five times during the run.
And I didn't expect to have tests, but it added them by itself without any question or clarification. I would like to have had this mentioned before, because I asked to add drag and drop, not drag and drop covered by tests.
At one point it said:
First batch done, properties 1 to 5 all passing, dispatching the next batch.
Crazy, I have no idea how much it's going to take. The confirmations themselves take maybe half the time, but it was already executing for more than an hour.
Then the app. It didn't leave any test data, which is cool. Same three drags, same reload, all three stayed. First attempt, zero manual fixes.
But I saw that it added a drag and drop icon without asking or mentioning it, and it did it all wrong. It appears only on hover, so when there's no cursor we just see a big empty space. Which means I'll have to wait another three hours to fix it, hahaha, just kidding.
What it left in the code that I didn't ask for: seven dev dependencies, the largest addition of the four. A moveTask that takes an id while every other handler in this project takes the Task object, so it had to add a ref mirror and a lookup that nothing else needs, and WeekBoard already had the object in hand when it passed the id. And 24 tests that look impressive until you open them: three of the property test files re-implement the logic locally instead of importing it, so only one file actually exercises the real hook.
It is also the only tool of the four that changed no copy at all. The page subtitle still says click a task to mark it done, with no mention of dragging, and the README still claims npm test runs server tests only.
What they agreed on
All four read the code before they planned anything. Every one of them found the existing PATCH with day_index and said outright that the server needs no change. All five files from my reference map, every time, and not one of them touched anything in the seven places I listed as untouchable. Nobody invented an endpoint, a migration or a second write path.
That is the real difference from the first article. Four tools, four different plans, one identical conclusion about my codebase. Give them code to read and they stop guessing.
Three of the four also hit the same wall, keyboard support, and each handled it differently. OpenSpec and BMAD dropped it as an assumption. Kiro stopped and asked me. Spec Kit never asked and built a whole MoveMenu component for it, which is five of its 24 tasks.
Where they split
The same sentence cost 6 actions with OpenSpec and 105 with Kiro. It produced 13 tasks, 24 tasks, 29 tasks, and no task list at all.
Three of them added something to the project I never asked for. Spec Kit added a keyboard menu and a global CSS class. BMAD added a test runner, and asked first. Kiro added seven dev dependencies, and didn't.
Two of them left their test data sitting in my database. Only BMAD committed anything on its own, straight to main.
And the one thing I would not have caught without reading the diffs: Kiro's 24 tests look like the best coverage of the four until you open them, three of the files re-implement the logic locally instead of importing it.
My take
OpenSpec. 4 actions of setup, 2 commands, 4 minutes 26 seconds, and the drag and drop works fine, no surprising stuff, just basic functionality. First attempt, zero manual fixes from me. Nothing invented, nothing added that I didn't ask for except two lines of copy. For a small feature on an existing project this is what I would keep using.
Spec Kit. The docs still have nothing about existing projects, and the init command from the README quietly wants to create a folder inside my folder. Once you get past that, the constitution run is genuinely impressive: six principles derived from my own code with a file next to each one. But 24 tasks for one drag and drop, five of them for a feature I never asked for, and this workflow is definitely for something complex.
BMAD. The only one with a named entry point for an existing codebase, linked straight from the README, and the only one that told me what it left untracked and handed the git decision back to me. It asks more questions than the others, and after three tools that decided everything by themselves I actually missed them. It also says plainly what it did not verify instead of reporting green.
Kiro. Three hours and 39.38 credits of the 50 free ones for one small feature, and 84 clicks on Allow. It thinks well, it was the only one that put the keyboard decision in front of me, but I have no idea if it takes credits for its own retries, and for the next one I would definitely have to upgrade.
So what does this mean
The first article measured how much a tool costs before you write a line of code. This one measured what it costs every time you ship something. Those are different numbers, and for Kiro they are different by a factor of five.
All four shipped the feature. Not one needed a fix from me. What separates them is not whether they can do the work, it's how much of your day they take and how much of your codebase they touch on the way.
Thank you for reading. Tell me what you want measured next, that's what I measure next.
In my next article, I plan to compare Claude, Codex, Cursor, and possibly Grok to see how they handle adding a complex feature to my real-world product, so this will be a serious, in-depth analysis. Let me know if you're interested.