Covers February 2026.
I spent February using aidd to audit the code we’d been producing. There was plenty to fix. I also reset 25 features that were still marked passing even though their implementations had changed.
The v2 rewrite
On February 1, I started Spernakit v2 from scratch rather than migrating v1 forward. Every v1 technology had been picked because I already knew it, and by this point I had a much better idea of what actually fit. The most important swaps were replacing Express with Elysia (Bun-native, type-safe end-to-end) and Prisma with Drizzle (no codegen step), and there were half a dozen more like that. Fifty-eight dependencies banished by the time the dust settled. The first working v2 release landed six days later. Six days sounds impossible, but it wasn’t; everything v1 taught me was still fresh, so there was very little wandering around. Day one also set up the quality gate everything else now depends on: bun run smoke:qc (typecheck, lint, build, format).
Over the next 10 days, v2 went through ten audit passes, each with a different lens - security, performance, dead code, and so on. Every audit emitted its findings as feature.json files in the backlog, and aidd worked through the backlog. In parallel, three apps got rebuilt from scratch on v2 instead of migrated, and the rebuilds beat the migrations every time. I already knew the behavior I wanted from each of them.
Re-checking twenty-five features
Midway through the blitz, I realized the feature board was lying to me a little. Twenty-five features were marked passing based on verifications that predated the code they were sitting on. They had passed once, but against implementations that had since been audited, refactored, or replaced.
So I flipped all twenty-five back to failing and made the loop re-earn every green mark against the current build. Most came back quickly. A handful didn’t. Their “passing” status came from old behaviors that are gone now. Honestly, I wouldn’t have known which was which without the reset.
The rest of the month was the same loop applied everywhere. Spernakit hit 110/110 features, a security audit on the new DB admin panel caught a real SQL injection through unvalidated column names, an oversized route file got carved into domain modules, plus a pile of smaller fixes. The separate audit passes found things I had missed in review. Once filed as features, those findings could go through the same work queue.
Six apps on one template is past the point where I can honestly sync them by hand, and the v2 apps are already drifting in small ways. The template needs lifecycle tooling of some kind - shared type contracts between frontend and backend, a way to automate upgrades, validation that the API contract matches what the frontend believes.
For now, I’m expiring passing results when the underlying code changes. Keeping the apps themselves in sync is the next problem.