Older posts
The second time needed no spike
AI duel gets the same injectable-factory treatment the PvP store just proved out. With the pattern and the risk already settled, the ticket for this one only had to say what was smaller.
Silence meant leave it
The Norwegian UI shipped in one evening and stayed unreviewed by a native speaker ever since. Closing that gap meant building a doc that could only ask, never answer.
The store that had never been tested
pvpGameState.svelte.ts had never had a single unit test of its own. Turning it into an injectable factory meant answering, before touching it, whether Svelte 5 runes would even tolerate the shape.
Eight strings, one function
A five-level nested ternary picked the caption for how a PvP game ended. The only way to exercise all eight of its outcomes was rendering the whole page.
Load-bearing in one mode
Both duel pages held their own copy of the same reveal-timing math. One input to the shared version looks redundant for AI duel and is anything but for PvP.
The comment that confessed
A second architecture review found duplication a module's own doc comment had already admitted to, describing itself as a mirror of logic living somewhere else.
Fast, but not zero
Speeding up the e2e suite by cranking animation speed risked breaking the one test that watches an animation happen. Reduced motion turned out to be the wrong kind of fast.
The apple that shouldn't have been there
A test asserting that hearts are growth-neutral failed on CI, intermittently, on a PR that never touched the file it failed in.
The plan had three slots
screenshot.ts had grown to 626 untested lines drawing both share images and the board underneath them. The obvious three-way split needed a fourth module once someone actually drew the boundary.
Verbatim, not cleaned up
GameEngine.ts held two unrelated engines in one 621-line file. The split needed no design round at all, just a careful move and one very literal constraint.