Two days. Eight apps. One stubborn bug that should have been caught earlier. And a security pass that touched every line of every server. This is what changed, in plain language, and what it took to ship it cleanly.
The Bug That Started It
It started with a 500 from one of the apps. Not on the first request. Not on the second. Only when a particular kind of request reached it -- the kind where the server starts writing a response before it has finished thinking. Every time that happened, the same line of code choked.
The bug had been there for weeks. It just hadn't been triggered by the right request yet. This is what dogfooding is for.
The fix wasn't a clever workaround. It was to throw the whole approach out and do the obvious thing in a slightly less obvious place, then make sure every other app was doing the same. Most of them weren't. Now they are.
A few days later, while I was testing the fix, a different app fell over for a completely unrelated reason. A small change elsewhere had shifted something under it. It was the kind of failure that only surfaces when you actually run the thing you just changed. I fixed it. It took about an hour. It would have taken three hours if I hadn't already had the right debugging posture from the first one.
The bugs that find you are the bugs you wanted to find. The ones you find before they find you are the ones you wrote tests for.
The Bigger Week
The same window, a much larger piece of work landed: a thorough security pass across every app in the suite. Not a checklist. A real audit, with findings ranked and reviewed and fixed one at a time. Some of the findings were embarrassing. Most were the kind of thing that only shows up when you stop building and start asking what could go wrong.
I won't go into specifics here. The details of how a given app handles sign-in, what its session cookie looks like, which third-party scripts it loads, or which security headers it sends are not for a public blog. They're the exact information an attacker would need to start probing. The short version: the suite is meaningfully harder to break into now. Not unbreakable. Harder.
The Diagrams Got Honest
Every app's architecture page got revisited. The diagrams were outdated in places, and in a few places they were simply wrong -- describing a feature I had removed months ago, or showing a flow that never worked the way I drew it. The fix was a quiet afternoon with a notebook and the source code open.
The dense ecosystem diagram got interactive controls. Zoom, pan, fit. The kind of thing you forget you needed until you try to read the diagram on a phone.
There's a deliberate split between the diagrams on the public site and the ones in the private docs. The public ones teach. The private ones specify. I want the public ones to be useful to a stranger, and the private ones to be useful to me six months from now when I can't remember how anything works.
The Suite Now Knows Who You Are
The piece of work I'm most quietly proud of: the apps now know how to talk about the same person without any of them having to share a database. The trick is unglamorous. Each app exposes a small endpoint that lists the identities it knows about -- an email here, a name there. One app asks the others, joins on what matches, and answers questions that no single app could answer alone.
That's how the weekly review can mention the meeting you have tomorrow with the same people you met last week, without any app having to call another app's database. Each app is sovereign. The data flows through a coordinator. The identity thread is just an email address.
The Smaller Things That Matter
- One of the apps now writes a weekly summary that survives me closing the tab. Three weeks of writing intentions and having them vanish was enough.
- The calendar app learned that a holiday is not a 24-hour meeting. The first version thought I'd worked 356 hours in a single week. There are 168.
- The email app now routes automated mail, no-reply mail, and receipts into a separate bucket. The model can no longer escalate a receipt into "needs a reply."
- The code review app got a stop button for the times the local model is wandering. Better that I interrupt than that I wait for a 4,000-word non-answer.
- One of the apps used to return a stack trace when asked to do something its current model couldn't do. Now it asks you to pick a different model, politely, in one sentence.
- Another app had a piece of plumbing that was missing a wire. The table existed. The methods didn't. A 500 became a 200.
What the Suite Looks Like Now
Eight apps. One sign-in. No central data store. Every app sovereign. Every app improved this week. The architecture refresh wasn't just an update -- it was a recognition that the suite has reached the point where the cross-app story is the story. One app asks. Another answers with time. Another answers with memory. Another synthesizes a narrative. Another ranks what needs you. Another listens. Another reviews what you wrote. Another draws it.
None of that worked two months ago. All of it works now. Some of it works beautifully. Most of it works the way software usually works: well enough to dogfood, not well enough to sell, and getting better one bug at a time.
The bug that started this week was the kind of finding that only shows up when you actually use the thing. That's also why I keep building it. The suite is the dogfood. The dogfood finds the bugs. The bugs make the suite better. Repeat.
If you are interested, reach out.