My own architecture wouldn't let me steal my own data
Hedge is a daily calibration trivia game I build solo; the architecture lives in the case study. This one is from the August screenshot push, and it is the story of losing an argument with a decision I made in June.
Back in August I needed screenshots. The badges update was going to the App Store, and Apple wants pictures, and pictures of an achievements screen are only interesting if the achievements screen has achievements on it. Mine did. On my phone. A hundred days of real streaks, real badges, a real calibration curve with my actual overconfidence in it. The simulator I capture screenshots on had none of that.
A perfectly reasonable heist
Hedge syncs through CloudKit, privately, to your own iCloud account. I built that sync. I published the native module that powers it as open source. If anyone on earth was qualified to point a simulator at my own account and pull my own history onto it, it was me.
So I did it carefully, like a professional. I pointed the dev build at the production zone by name. I hard-disabled the push path first so the experiment could only ever read, never write (the one rule of poking production is that you do not poke production). Then I let it sync.
It worked great, until I looked at what arrived.
Fifty-one rows from July
Fifty-one answers, all from July. Not a hundred days of history. Fifty-one rows I recognized after a minute of squinting: they were test answers from a dev session weeks earlier. The sync was not broken. It had connected, authenticated, found a zone with exactly the right name, and faithfully delivered everything in it. It was just the wrong everything.
CloudKit has two parallel universes per container, Development and Production, and which one you land in is not a setting you pass. It is decided by how the binary is signed. A dev-signed build physically cannot see the production environment, no matter what zone name it asks for, no matter whose account it is signed into, no matter how good its reasons are. My zone name matched. My universe did not.
The signature is the wall
Here is the part I keep enjoying. I knew this. It is documented in the README of my own module, in a section I wrote, about why the Dev/Prod split makes it safe to develop sync features against your real Apple ID (your dev builds land in a sandbox by construction, so you cannot corrupt your live data even if you try). I wrote that paragraph as a promise to other developers. Then I spent an evening on the other side of it. I had been locked out by my own README.
The guardrail I wrote in June does not care that I had a good reason in August. That is the whole point of a guardrail, and it is a very different thing to know it than to feel it. Every safety rail I had added was aimed at accidents. This one turned out to also stop the author, on purpose, with authorization, in read-only mode, being careful. Belt and suspenders means the suspenders hold even when the person removing the belt is you.
The theme that crossed anyway
One detail made the lockout almost funny. While my answers stayed sealed on the far side of the environment wall, my purple theme showed up on the simulator immediately. Apple's key-value store (the little sync channel Hedge uses for preferences) is scoped to the account, not the environment. So the sim greeted me wearing my phone's outfit while knowing absolutely nothing about my past. It looked like me. It remembered nothing. A very specific kind of uncanny.
Working exactly as designed
The screenshots happened anyway, the boring way: I built a dev tool that seeds 88 days of demo history in one tap, with a calibration shape that is deliberately a little overconfident, because a chart with a flaw in it reads as more honest than a perfect one. That tool is now part of the repo, documented, reproducible, and better for screenshots than my real data would have been.
But the evening I remember is the failed heist. Somewhere in June I made a decision about signing and environments and wrote it down, and in August that decision looked at me, the author, the account owner, the guy with the private key and the good intentions, and said no. I have never been so pleased to lose an argument with software. Mostly because I won it in June.
If you want to see whether your gut is calibrated, it takes about ninety seconds a day: stiles.one/hedge