A knowledge diary that compounds runs on a capture to publish pipeline, not willpower. Here's the exact system that turns raw dev notes into published atoms.
For three years I lied to myself every January: this is the year I write more. Then I'd read some thread about learning in public, catch a jolt of motivation, publish two posts in a week, and go dark until summer. My drafts folder turned into a graveyard of half-formed insights I could no longer reconstruct. The problem was never discipline — I run an engineering team in Dubai and ship on deadlines I can't move. The problem was that I kept treating writing as a habit to summon on willpower, when what I actually needed was a pipeline that runs whether or not I feel like a writer that day.
This post is the reverse-engineering of that pipeline. Not "how to be more consistent," but the actual capture-to-publish system — a knowledge-management workflow built for people who ship code, not people who write for a living. It turns half-solved bugs at 2am into published entries without me having to be inspired. If you've ever bounced off the advice to "just write more," this is the version that finally worked for me. I'll walk it end to end: the capture layer, the smallest publishable unit, the weekly compaction pass, publishing as a forcing function, and the compounding curve you only see on the far side of it.
"Just write more" is advice at the wrong altitude. It tells you the output you want without giving you the mechanism that produces it. It's like telling a struggling team to "just ship faster." Faster is an outcome; it comes from removing specific bottlenecks, not from wanting it harder.
When I finally sat down and treated my own non-writing as a bug report, three root causes showed up:
None of those are willpower problems. They're system-design problems. And system-design problems have system-design fixes: reduce the cost of the first step, shrink the unit of work, and attach the work to a reliable trigger. That's the whole post, really. The rest is implementation detail — but the implementation is where most "learning in public" advice quietly gives up.
The single highest-leverage change I made was separating capture from writing. They feel like the same activity. They are not. Capture is a five-second reflex you do while your hands are still on the problem. Writing is a deliberate act you do later, in a different mental mode. Conflating them is why most note-taking systems die: you sit down to "take a note" and the note quietly demands to be a paragraph, so you skip it.
Here's the rule that made capture actually happen: it must be cheaper than not doing it. If saving a note costs more than the annoyance of losing the insight, I'll lose the insight every time — I'm mid-debug and I want my flow back. Every point of friction in the capture path is a place where a real lesson leaks out.
So my capture layer is deliberately dumb. A single append-only Markdown file per week, opened with one keybind. No app, no database, no tags, no template. When I finally understand why a Firestore listener was firing twice, I don't switch apps or think about structure. I dump a few lines:
2026-06-18firestore listener fired 2x on cold start.cause: attached listener in build() -> rebuild re-attached.fix: move to initState / use a StreamProvider so it's created once.the "aha": widget lifecycle != data lifecycle. stop conflating them.
That's it. Ugly, lowercase, half-sentences. The only discipline is capturing the aha line — the compressed lesson, not just the fix. The fix is googleable. The lesson is the thing that's actually mine, and it's the part memory deletes first. Six months from now I won't remember the bug, but "widget lifecycle != data lifecycle" is a mental model I'll reuse a hundred times.
On a busy week I'll dump 15 to 20 of these. Maybe two become posts. That ratio is fine — capture is cheap on purpose so the funnel can be wide. You are not deciding what's publishable at capture time. You're just making sure nothing that could be publishable evaporates before you get the chance to decide.
The scope-inflation problem killed me for years, so I attacked it directly by defining the smallest thing I'm allowed to publish. I call it an atom: one lesson, one reader, one takeaway. If a note can't be squeezed into a single clear claim, it's not one atom — it's several, and I split it.
The test I use is stupid but effective. Can I write the title as a sentence a specific person would say thank you for? Not "Firestore Listeners" (a topic, infinite scope) but "Attach your Firestore listener in initState, not build" (a claim, finite scope, one clear win). The second one I can draft in twenty minutes because the boundary is already drawn. The title is the scope contract — if the title is a topic, the post has no edges and will never finish.
Atoms have a shape. Mine is roughly:
Notice there's no room in that shape for a literature review or a "history of Firestore" preamble. An atom earns the right to exist by being useful and small, not comprehensive. Comprehensive is a book. I'm not writing a book on a Tuesday night.
Here's what that shape looks like filled in, so it's not just an abstraction:
Title: Attach your Firestore listener in initState, not buildScene: chat screen re-rendered on every keystroke; each rebuild opened a fresh snapshot listener. reads (and my bill) climbed.Wrong model: "build() is where my widget's data lives."Correction: build() runs many times; side effects that create resources belong in initState (or a provider created once).General: any subscription — sockets, streams, controllers — is a lifecycle concern, not a render concern. don't create it in render.
That's a publishable atom. It's four lines of thinking I already did while debugging; the compaction pass just moved it into shape.
The payoff of thinking in atoms is compounding in the literal sense: small units combine. Five atoms about Firestore lifecycle later became one genuinely good long-form piece, because I'd already done the hard thinking in pieces. Assembling proven parts is easy. Writing the definitive thing from a blank page is what I was failing at for three years. Atomizing isn't a compromise on ambition — it's the only way I've ever actually reached the ambitious version.
Capture is continuous. Publishing is not. The bridge between them is a single scheduled ritual I call the compaction pass, borrowed shamelessly from how databases and LLM context windows work: take a lot of raw, redundant, low-density input and compress it into fewer, higher-value artifacts. In a log-structured database, compaction is what turns a noisy append-only log into something you can actually query. Same idea here — the weekly capture file is my write-ahead log; the compaction pass is what turns it into durable, queryable knowledge.
Every Sunday, ~45 minutes, non-negotiable, on the calendar like a standup. I open the week's capture file and do three things:
drop, keep, or draft. Ninety percent are drop or keep. I'm not precious about it. A keep stays searchable in the diary forever even if it never becomes a post — that's still a win.draft, I create a stub file with just the atom's four-part shape and paste the raw note in. No writing yet. I'm building a queue, not finishing anything. The distinction matters: promoting is a mechanical sort, not a creative act, so a tired Sunday brain can still do it.The key insight: the compaction pass doesn't produce finished posts. It produces drafts that are 60% done before I ever try to write. When I sit down to publish, the blank page is gone. The scene is there, the lesson is there, the shape is there. I'm editing, not conjuring. Editing is a mood I can enter on command. Conjuring is not.
This is where the "system not a habit" claim earns its keep. I don't rely on wanting to write. I rely on a recurring 45-minute appointment that mechanically converts noise into drafts. Motivation is nice when it shows up. It is not load-bearing. If you take one thing from this post, take this: put a repeating calendar event on the thing, and measure whether the event happened — not whether you felt inspired.
For a long time I thought publishing was the scary output stage — the performance where people judge you. Reframing it fixed more than my anxiety; it fixed my quality.
Publishing is a forcing function. The moment you commit to putting something in front of strangers, your standard for "do I actually understand this?" jumps. Vague thinking survives in your head. It does not survive the sentence "here's exactly why this happens," because writing that sentence forces you to check whether you know. I've abandoned drafts mid-write because the act of explaining revealed I didn't actually understand the root cause. That's not a failure of the system. That's the system catching a bug in my own knowledge before I shipped it to my brain as "learned." Writing is the cheapest code review your own understanding will ever get.
The performance framing, by contrast, is poison. It makes you optimize for looking smart, which means hedging, over-citing, and never admitting the wrong turn — exactly the stuff that makes writing useless to read. My rule: write for the version of me from six months ago. That person is not judging me. That person is stuck, and grateful, and doesn't care about my prose.
Two practical guardrails keep publishing a forcing function and not a stage:
I need to be honest about something, because the alternative is the usual influencer fairy tale. I did not start this to build a personal brand. I started it because I kept re-solving the same problems and it made me feel like an idiot. The brand was a side effect, and understanding why it was a side effect is the actually useful part.
When you publish specific, correct, hard-won lessons consistently for a year, a thing happens that no amount of "personal branding" produces directly: people start associating your name with reliably useful. Not viral. Useful. A recruiter once told me she'd read three of my posts before a call and felt like she already knew how I think. A junior dev on another continent shipped a fix because of an atom I'd dumped at midnight and forgotten. That's the brand — it's just the accumulated residue of being helpful in public, on the record, with your name attached.
The trap is to reverse the causality. The moment I'd started writing for the brand — chasing topics because they'd perform, sanding off the specific details that make a post real — the well would have poisoned itself. Specific and honest is what compounds. Generic and impressive is forgettable. The brand is downstream of the diary. Optimize the diary; the brand takes care of itself. Try to optimize the brand directly and you get a LinkedIn thought-leader, which is a fate I'd like to avoid. Build in public as a byproduct of thinking in public, and the credibility is real because the work under it is real.
People imagine writing compounds like a viral hit — one post explodes and changes everything. In three-plus years and a couple hundred entries, that has never once happened to me, and I've stopped waiting for it. The real compounding is quieter and much better.
Here's what actually accrued:
grep my own diary constantly. A problem I solved eighteen months ago is a keyword search away, written in my own words, with the wrong turn included. This alone would justify the entire system even if I never published a word. A plaintext Markdown diary is the most durable second-brain format there is — no lock-in, greppable, diffable, outlives every note-taking app I'd otherwise have migrated between twice by now.The curve is boring for the first year. You publish into what feels like a void. Then the base gets wide enough that entries start referencing each other, readers start finding you through the back catalog, search engines start sending strangers to posts you forgot you wrote, and the thing starts pulling its own weight. Boring, then quietly unstoppable. Most people quit during boring — which is exactly why the ones who don't have so little competition on the other side.
A system is only as good as its known failure modes. Here are the three that have actually bitten me, and the guardrail I built for each.
The instinct to make every post definitive. It's scope inflation wearing a respectable disguise. Guardrail: the atom rule. If a post is trying to be comprehensive, it's not an atom, and I'm not allowed to publish it as one. Comprehensiveness is a feature of the back catalog, not of any single entry. Ship the atom.
Capturing diligently and never publishing. This is the sneakiest failure because it feels productive — look at all these notes! But a note that never becomes an atom is just a private hoard, and a hoard doesn't compound because it never touches the forcing function of an audience. Guardrail: the compaction pass has a quota. At least one stub gets promoted toward publish every week, or the system is failing silently. Capture without publish is just expensive journaling.
The dark side of streak-based motivation. Miss one week and the streak breaks, the guilt spikes, and the whole thing collapses because it was resting on an unbroken chain. I burned two separate attempts this way. Guardrail: I track the system running, not the streak. Did the compaction pass happen? Did captures land in the file? A week with zero published posts but a clean compaction pass is a healthy week — the queue is filling, the machine is turning. Measuring output weekly punishes the weeks where you're doing the invisible work that produces next month's output. Measure the pipeline, not the applause.
The meta-lesson across all three: every failure mode is what happens when you drift back toward treating this as a habit — a thing powered by feelings, streaks, and willpower. The system exists precisely to be robust to a bad week, a busy sprint, or a stretch where you feel like a fraud. Habits break under load. Systems are designed for load.
The habit version of learning in public runs on willpower and dies in February. The system version runs on a pipeline and compounds for years. Stop trying to want it harder. Build the pipeline.