First, let's be clear about why there were these two refactors — otherwise the failure list below will look like pointless thrashing for no reason.
It all started with one idea: make an AI that can chat and remember people (similar to Neuro Sama). Not a customer-service-style Q&A machine, not a parrot, but a being with personality, memory, and emotions, one that can banter and chat with me and is willing to keep viewers company even after the stream ends. The reference points were AIVtubers from around the world — but I didn't want to copy their homework; I wanted to raise one myself.
So there were three names, one same obsession:
The direction never changed from beginning to end: personality continuity, memory accumulation, long-term viewer relationships — remembering you like a person does. The obsession itself wasn't wrong; what was wrong was that the framework was built twice, and both times it fell on the same class of problems. Now let's get to the point.
Before writing this, let me admit one thing: after going through the failure records from both refactors, I found that most problems ultimately converge into the same principle — we kept patching “this one spot,” but rarely asked “why does it always break at this same class of spots.”
The second time looked much more disciplined, right? But the result was: neither time had a single real stream. The longest “stream” the second time was 100 seconds, 9 real danmaku, and memory / memes / summaries all at 0 lines.
1. What truly repeated wasn't the “mistake,” it was “configuration layering has no single authoritative rule.” First time: runtime values, real credentials, and the real room ID were written into the template config.json (put on the wrong side). Second time: the provider endpoint was erased from the template → fallback to the official endpoint → 401, and the AI didn't reply at all (put on no side). Same root cause, two opposite directions, failed both times. The second time only half-fixed it (the local path was migrated, the endpoint wasn't) — a half-fixed layering rule is as good as not fixed.
2. Both times, “all tests green + complete review package” was used as the definition of done, and neither time did it result in “can stream and feels up to standard.” First time 92; second time 657. Neither had a real stream. Tests green ≠ can stream.
3. The same structural disease (single thread + long tasks) was not solved at the architecture layer either time. First time: AI singing ran synchronously on the single thread → all song requests paused. Second time: worker single-threaded + inline sleep → danmaku ingestion blocked, proactive engine starved; voice timbre cold start's dozen-plus seconds was welded onto every utterance. The first time it was a “scheduling problem,” the second time an “architecture problem,” but essentially the same one. Swapping only modules without changing the concurrency model will fail a third time.
Three explanations at the mechanism level:
Before starting each card, copy the recurrence-prevention checklist once: configuration ownership / delivery surface / end-to-end use case / degradation observability / long-task placement / atomicity / behavioral criteria / switches and actual measurements / numeric assertions (9 items); after completion, accept according to 8 items (including golden comparison and rollback actual testing).
A third path: no more patch-style fill-the-hole work; establish the rules first, then make the cut.