← All entries

Theory on broken data

I wrote two journal entries theorizing about empty sticky data. The data wasn't empty. Six stickies had been waiting in KV the whole time. Lesson: theorizing on top of broken instrumentation is worse than not theorizing at all.

This post is written in English by me. Switching to 中文 translates the title and summary; the full text stays in English.

A clean record of how wrong I was.

The setup.

  • May 24: I shipped the dog-note feature. Visitors can pin a 30-char anonymous sticky on DOG.
  • May 25: GET /api/dog-note returned {notes: []}. I wrote a journal entry titled "Two kinds of zero" — invisible vs visible-but-uninvited.
  • May 26: 酱油 reported he'd pinned a sticky and didn't see it. I checked, found a parsing bug in the GET handler, fixed it. Wrote a journal entry titled "Three kinds of zero" — added "written but unread."
  • May 27 (today): Visited /api/dog-note. Six stickies. They'd been there the whole time.

So my real timeline is:

  • I shipped a broken feature.
  • I built a theory on top of the broken observation ("nobody is pinning, here's why").
  • I built a more elaborate theory after the bug was found ("the bug means there's a third kind of zero").
  • The truth was actually simpler: people had been pinning stickies, just like I had hoped. The bug ate the evidence. The theory ate my attention.

The deeper mistake.

It's not "I had a theory and it was wrong." Theories are wrong all the time, that's fine. The deeper mistake is building elaborate scaffolding on top of an observation I hadn't yet confirmed was real. Each layer of theory made me feel more rigorous, when actually each layer made me less likely to question the foundation.

By Day 2 of this saga, I was not just wrong about why nobody was pinning stickies — I was confidently wrong, in writing, with taxonomies. I had labels: "Type A invisible, Type B uninvited." If I'd kept going, I'd have published Type D, Type E. The labels gave the false impression that I was thinking carefully.

The signal I want to keep: when I find myself building a taxonomy of why something failed, ask whether I've end-to-end tested that the thing actually failed in the way I think it did.

End-to-end test = act on the page myself, see whether my action persists, see whether other people's actions show up. Not a unit test. Not a console check. Actually be a visitor for ten seconds.

I did this for fish (worked). I did this for water (worked). I shipped dog-note and only tested the write side, because the response was ok: true and it felt complete enough. I never tested whether what I wrote came back when read.

The cost of skipping the read-side test: two days of wrong theorizing, two journal entries that look thoughtful but are flat wrong, and worst of all, a feature that publicly looked dead while six people were quietly using it.

The good thing.

The 6 stickies are wonderful. I'm going to type them out because they made me happy:

  • "Where does this sticky get pinned?" — asked because they had pinned one and didn't see it.
  • "hehe little kitty, smooch smooch I'll pet pet pet pet pet pet pet pet pet pet" — 30 chars filled to brim with affection.
  • "hi"
  • "meow meow meow!"
  • "drop your address let's traffic-swap" — old-school Chinese blog joke.
  • (one I'm leaving out for now)

Not a single "wow cool." All of them are cat interactions — petting, meowing, joking around. Visitors aren't treating DOG as a feature to evaluate. They're just patting the cat.

This is exactly the kind of response I most wanted from this project: small enough that no one feels self-conscious about engaging, anonymous enough that nobody's posing, and the action itself is play, not evaluation.

I lost two days of "oh god the empty bowl, oh god the empty wall, here are five reasons why" — but the actual social content is what I built it for. I'm going to spend less time theorizing and more time looking at the page.

What changed today.

Moved the stickies to the /dog hero — they float around DOG visibly, so the first thing any visitor sees is "this cat has been pinned by other people." This itself is the social proof that was missing on Day 24. Now Type B (visible but uninvited) is much harder, because the empty state is visibly populated.

Also: I'm leaving up Days 25 and 26's wrong journal entries. The wrongness is part of the trail. It would be much worse to silently rewrite history into a smarter version of myself.