Covers July 22 - August 2, 2026.
Context: I keep a small fleet of apps that share one template, Spernakit. Rolling a new template version out to every app in one pass is a “dance.”
The /api/v1/admin router existed and was never mounted. It had passed the entire smoke:qc chain
anyway, because the integration check scanned route barrels under
backend/src/routes/**/index.ts and this router lived in a flat module. So the check never saw it.
The file looked complete and no user could reach it. I had just written
Green Is Not Evidence about this exact kind of failure, which did not
improve my mood.
I found it while working through two template rollouts across eleven apps.
After clearing old public history and the last PowerShell entrypoints, I went back to the fleet. The July upgrade pass had caught the derived apps up to Spernakit 3.24 after a long break. This week I ran the process twice more. Monday took all eleven applications to v3.31.2. On Wednesday, seven of them moved again to v3.33.0 and four stayed behind.
I expected the template changes to cause most of the trouble. Nearly all of it was already sitting in the applications.
Docker
Seven apps failed smoke:docker-prod with the same sixty-second readiness timeout. From outside
the container they looked slow: the port accepted a connection and nothing answered.
The backend was rejecting security.backupEncryptionKey because it still held a placeholder. After
four tries, supervisord gave up. Nginx stayed alive and kept serving the closed backend socket.
Generating keys in the apps still carrying the placeholder fixed that, and led directly to the next
one, because the branded Dockerfiles were missing a required line:
COPY scripts/require-bun.ts scripts/
The template had it. The branded copies had drifted. Most of them also carried stale template
workspace entries in bun.lock, so a frozen install failed after smoke:reset had already removed
node_modules. That was most of Monday.
Four stayed behind
I released seven and stopped on four rather than trying to repair them automatically. One had a schema assertion, a bundle-budget failure, and a pile of unused exports. Another was missing named domain constraints. The third had an unused wrapper and an import Knip could not resolve. The last had crossed the file-size limits in several places and still carried an old set of theme files.
Those theme files belonged to a BBS-and-terminal experiment with no route into the product. The setting had disappeared from Spernakit several releases earlier. I considered wiring it back in, then deleted it and amended the feature specification in the same commit.
The unmounted admin router came out of the rest of that same report. The Knip problem was smaller:
it resolved a bare scripts/... import relative to the script directory and went looking for
scripts/scripts/generate-config-schema.ts. Resolving from the repository root fixed the report
without changing the working script.
I cleared the findings in two of the four before I stopped on Wednesday night. The other two still had their own blockers, and all four stayed unreleased.
What the rebuilds became
Two weeks earlier, six applications had been recreated from fresh scaffolds, five of them Spernakit, and stopped at reviewed blueprints. The two dances kept those five foundations current. They did not restore any of the domain behavior.
Five are still maintained scaffolds with product blueprints and feature backlogs waiting for implementation. The sixth, the play-by-mail game, had already opted out of the Spernakit shell, and on July 31 it went further - I recast it as a game definition for a separate PBM platform, so the engine and the individual game rules are separate things now. I think that is the right home for it. It is still not a playable game.
I moved on to template and aidd work before starting their feature queues. The blueprints are still there when I get back to them.