Covers March - April 2026.

Late in April, all six apps passed the commit gate. Three of them were broken.

The gate - typecheck, lint, build, format - was the thing I’d been treating as proof. It waved through a service that called a function it never imported, because a stale cache told it the import was fine. What caught that one was the heavier test: boot the production image, crawl every route, look at what comes back.

So lately I’ve been chasing a question: can one person keep six apps and their shared template healthy, continuously, using agents? After the last two months I think the answer is yes, but getting there humbled me a couple of times. I started calling each full run of the pipeline a dance, and the name stuck.

Spernakit v3.0.0 went out on March 16 with the plumbing a fleet needs: a shared/ workspace so frontend and backend can’t disagree about data shapes, config validation at boot, a check that the OpenAPI spec matches what the frontend types believe, and an automated template-upgrade script (more on that one below, unfortunately). Then I turned the audit machinery loose on every derived app at once. The week after release was mostly remediation of over a hundred findings across the fleet - real fixes, from MFA hardening down to accessibility corrections.

By late March, the routine had settled: bump the template, upgrade every app, run the automated tester, convert bugs to features, review, remediate, run the full end-to-end test, back-propagate improvements, commit, sync. One sweep across all six apps in parallel surfaced about thirty bugs in a session. If the same bug showed up in three or more apps, it was almost certainly a template bug, so the fix went into the template and flowed back out. One session from that stretch still delights me: five parallel agents cleared a backlog of almost seventy audit findings in about twenty minutes - work that would have taken me an afternoon at least.

The ten-step fleet upgrade cycle: bump the template, upgrade every app, run the tester, convert bugs to features, review, remediate, run the end-to-end test, back-propagate, commit, sync, and repeat 1 2 3 4 5 10 9 8 7 6 bump the template upgrade every app run the tester convert bugs to features review remediate end-to-end test back- propagate commit sync repeat
One dance. Step 8 sends shared fixes back to the template for the next fleet pass.

Deleting my own script

The auto-apply template-upgrade script shipped with v3.0 and mostly worked. When it didn’t, though, it would silently clobber files that apps had deliberately customized. (That’s bad.) On April 10, it stripped vital domain code out of an application and left a trail of typecheck errors behind it. On April 11, I spent thirteen hours on what should have been one workflow, and by the end of it I’d deleted the script from the template and all six apps.

The replacement is manual cherry-picking through six parallel subagents. Slower on paper, about nine minutes per fleet pass in practice, and every diff is one I can actually read.

My own notes had already warned me about the --apply issue. I ran it anyway to save time.

The false positives

April 14 was rough in a different way. A full tester sweep filed twelve bugs; triage rejected five of them as false positives. 42%. The testers had “observed” regressions that a curl against the running backend disproved in seconds, while the filings that had been verified against the live API before being written up had zero false positives among them. So the rule became: no bug gets filed without reproducing it against the running system, and the test agents re-dispatched under that rule filed far fewer bad reports.

The false positive that got me came four days later, in the April 18 regression pass - a “critical truncation bug” that turned out to be a 64-character token in a share dialog whose input field was narrow enough that the trailing characters scrolled out of view. The token was intact the whole time. The testers had transcribed the visible prefix and dutifully filed the 404 it produced.

The supertest

That gate is smoke:qc, and April clarified its role: it is not the commit gate I thought it was. The supertest - reset, build the production Docker image, boot it, crawl every route, screenshot everything - keeps catching things smoke:qc can’t see.

What else it caught over the month: a Docker base image that had quietly stopped being published upstream, a months-old SQLite bootstrap race no unit test would ever reach, and my favorite - the browser-automation helper’s mouse.click() fires mousedown and mouseup as a pair, which Radix dropdowns interpret as open-then-close. Weeks of “flaky” tester runs, explained by one dual-fire click. There were others (audit logs recording null IPs, but only in production…), and the common thread was that every one of them was invisible in development.

Between April 17 and 19, I went through five full dance cycles - two of them in a single day. The fifth cycle surfaced zero bugs; four passes earlier there had been fifty-plus. I took that as a cue to stop lapping the same track, as fun as that is…

I’m thinking about aidd v2 - it’s outgrowing the current architecture, which started with a few pretty simple shell-script wrappers.