On Day 1, PostAll was a script that called the OpenAI API and dumped the output into a text file. On Day 100, it's a platform with a formatting engine, a three-part quality gate, and CMS integrations for WordPress, Ghost, and Webflow.
I didn't plan most of that. I backed into almost all of it, one broken assumption at a time.
This is the retrospective I've been putting off writing, because it means admitting how much of the last 100 days was me being confidently wrong about something and finding out the expensive way.
The bet I made on Day 1
My original thesis was simple: businesses need content, AI can generate content, so the hard part must be the generation itself. Get the prompts right, and the rest is plumbing.
That thesis lasted about two weeks.
The actual hard part turned out to be everything around the generation — making sure the output was structured consistently enough to render as a blog post, a LinkedIn caption, and an email subject line without three separate rewrite passes. Making sure two generations of the same topic weren't suspiciously similar. Making sure the tenth request in a batch didn't quietly fail while the first nine succeeded and nobody noticed.
None of that is generation. All of it is what makes generation usable.
What I got right
I got the "parse once, render many" idea right early, and I didn't fully appreciate why until later. The instinct was laziness, honestly — I didn't want to write separate generation logic for blog posts, social captions, and email copy. So I built one internal content model and three renderers on top of it.
What I didn't anticipate was how much that decision would save me downstream. When I added CMS integrations for WordPress, Ghost, and Webflow, I wasn't teaching the system to generate content for each platform. I was teaching three renderers to speak three APIs. The generation layer never had to know a CMS existed.
I also got the editorial instinct right, even if it took a while to formalize: gotchas are worth more than happy paths. Every piece of the system that's held up under real usage is the piece where I sat down and asked "what silently breaks here?" before shipping it. The quality gate exists because I asked that question about uniqueness detection. The retry logic exists because I asked it about rate limiting.
What I got wrong
I was wrong about uniqueness detection, and I was wrong in a way that felt reasonable at the time. My first pass used Jaccard shingling — comparing chunks of text for overlapping word sequences. It's fast, it's simple, and it works great for catching near-duplicate content.
It does not catch paraphrased content. Two articles that share zero identical five-word sequences can still say the exact same thing in the exact same order. Jaccard saw them as completely unique. A human reader would've called them copies.
I only caught this because a beta user flagged two pieces of content as "suspiciously similar," and my quality scores said they were fine. That's a bad way to find out your quality gate has a blind spot — from a user who trusted the gate more than I had earned.
The fix was combining Jaccard with sentence embeddings, so the system catches both literal overlap and semantic overlap. It's slower and it's more code. It's also the difference between a quality gate that looks rigorous and one that actually is.
I was also wrong about scale in the most predictable way possible: I assumed the architecture that worked for 5 users would degrade gracefully for 50. It didn't degrade — it broke, specifically around connection pool exhaustion and a silent retry bug that was quietly dropping failed jobs instead of surfacing them. Nothing about that surprised me in hindsight. Everything about it surprised me at the time, which tells you how much I was coasting on "it works on my machine."
The part nobody tells you about building in public
Writing about PostAll's architecture on Dev.to while building it changed how I built it, and not always in ways I expected.
Knowing I'd eventually write a "what went wrong" section made me more honest with myself in the moment. If I caught myself reaching for a quick hack, I'd ask whether I'd be comfortable explaining that decision in an article. Usually the answer was no, and usually that meant I should fix it properly instead of patching around it.
The harder part was resisting the urge to make the story cleaner than it actually was. The real timeline isn't "I identified the uniqueness gap and elegantly solved it." The real timeline is "I shipped something with a known blind spot, didn't think hard enough about how bad it was, and got a wake-up call from a user." Writing the second version is less flattering. It's also the only version worth reading.
Where things actually stand
Right now, PostAll has 100s of beta users generating a combined 1000 pieces of content. The quality gate — readability plus uniqueness plus SEO validation — is catching roughly 50% of content that would've otherwise shipped with a real problem: duplication, thin structure, or SEO issues that would've hurt in search.
I'm intentionally not rounding those numbers up. 50% catch rate means the gate is still missing something, and I'd rather know that than pretend it's solved.
The business side has been slower and less linear than the technical side. Getting beta users has mostly come from people who read the technical writeups and reached out, not from any deliberate go-to-market motion. I don't know yet if that's a strategy or just what happens before you have one.
What I'd tell Day 1 me
Build the boring infrastructure first, even when it feels like procrastination. I wanted to spend my first two weeks making the generated content better. I should've spent it making sure a failed job never disappeared silently. Every scaling problem I hit later traced back to infrastructure decisions I made — or skipped — in week one.
Also: the first version of any quality check you write is going to have a blind spot you can't see yet. Ship it but go looking for the blind spot instead of waiting for a user to find it for you.
The next 100 days
The next stretch is less about new architecture and more about pressure-testing what exists. I want to push the quality gate against content types it hasn't seen yet, and I want to understand why beta adoption has been word-of-mouth instead of something repeatable.
I'm also sitting on a decision I haven't made: whether to open-source more of the pipeline the way I did with the formatting engine, or keep tightening it privately before showing more of it. I don't have a strong argument either way yet, which usually means I'm missing information, not that the decision doesn't matter.
Have you had a moment where building in public changed a technical decision you made — not just how you wrote about it, but the actual call? I'd like to know I'm not the only one who's caught themselves cutting a corner because they knew they'd have to explain it later.