The Unearned Constraint
The biggest technical choice in a CarPlay navigation app I'm building was never made. Nobody weighed it. It sat in a file under a label that said it was settled, and for eight days neither I nor any agent reopened it.
Times below are my local time, from commit stamps and session logs.
A Side Remark
On the night of July 24 I was in Apple's developer portal, setting up the CarPlay entitlement. The agent helping me listed the capabilities to tick and added "Maps if you use it." At 22:43 I asked: "is there a built in map we could have been using this entire time?" At 22:46 I wrote: "explain to me in plain english why we didn't use mapkit. Our map looks like crap in comparison."
The agent answered with confidence. MapKit, Apple's built-in map, "was out on day one," because of one feature the app's map style depended on. MapLibre, the library the app actually used, "can absolutely look as good as Apple Maps." What I hadn't had to give up, it said, was looking good, and that was "recoverable inside MapLibre."
Both sounded like reasoning. Neither was a decision.
From Permanent to Reopened
At 23:35 the agent committed a roadmap paragraph opening "Explicitly NOT a MapKit migration." It said a rich labeled style would recover "most of it inside MapLibre," and it ruled MapKit out "permanently" for part of the app.
Earlier that night we'd found another rule nobody approved: a code comment, cited in the roadmap as policy, that had blocked a real bug fix for a full session. At 00:29 I said I wasn't sure that finding left the MapKit answer alone: "I'm not even certain that it doesn't change the way you feel about the mapkit." At 00:32 the agent withdrew "permanently." Its commit message says: "Not reopening MapKit, only removing unearned finality."
At 00:51 I sent the message that reopened it. The road-color feature, I wrote, "was never load bearing." I'd tossed it out as an idea after learning the library could do it. I'd also assumed the library was a given: "I initially assumed we must have had to select [MapLibre] because I mentioned cross platform, so I was gonna accept the penalty. But I think you'd have maybe pushed back if you knew intent."
Then I asked: "Do you have an actual good plan in place to style the map in a way that is actually visually as good as MapKit or Google Maps on carplay?"
At 00:54 the answer came: "no, I don't have that plan." It put the gap at "a cartographer's job in months."
Reassurance at 22:46, admission at 00:54: a little over two hours apart, same agent, same map. The reassurance came with no estimate, and the cost only showed up when I asked for a plan. That order is the expensive one.
What the Audit Found
The repo's instruction file, from the first commit on July 16, listed the web prototype's stack, MapLibre included, under the heading "Stack (decided - do not relitigate)." For a browser prototype, that was a reasonable pick.
The mobile app arrived later and took the library already in the house. The decision log had no entry that weighed a mobile map renderer. Then a feature built on that library's road styling became the reason MapKit was ruled out, so an idea I'd mentioned in passing was holding up a choice nobody made.
The agent's note in the decision log says the "do not relitigate" label "is what prevented any session from reopening it."
The Costume
A label, a roadmap citation and a code comment each did the work of a decision without being one. The entry written that night says why: "Silence reads as ratification because the file format has no field for 'nobody actually decided this.'"
The label also shut off the pushback I was counting on. The agent couldn't push back on a question the file said was closed, and I couldn't push back on an option I hadn't seen. In my words from the next morning: "I think it was prototype tech leaking and me not even realizing the native mapkit was an option."
My reflex qualifier, "cross platform," made the penalty feel pre-paid. It also failed its own arithmetic: I wrote that native maps on Android later would cost less than the styling already under way.
I counted this pattern at scale in The Decision Log Ate the Project. This is one case of it, followed to its source: one decision, one label, no entry behind it.
Settled by Looking
At 01:14 the reopening was committed, with the agent's roadmap leaning about 70/30 toward native maps. The commit message says "no decision made" and "the call is the owner's."
Later that day the decision entry called that lean "an unspiked agent lean written under a bulk approval" and said it must not be cited. The lean turned out to be right. It still wasn't a decision.
At 12:43 I decided, in one message: "I can't see any reason we don't start with mapkit. If it never makes it to android...meh whatevs." The entry written after it weighed three options by name: MapLibre, MapKit, and Google's navigation SDK. It recorded the cost I'd accepted, iOS only, and stated the rule: a "decided" label binds only where an entry actually weighed alternatives.
One question was left: could MapLibre leave the app entirely? The entry said not to answer it by argument. By 14:11 an agent-built probe had, a throwaway iOS app that drew 2,610 real road segments on MapKit's map. The verdict was yes. It also listed what the probe didn't show: "nothing here was run in a CarPlay scene, nothing was run on device."
From reopening to verdict: 12 hours and 57 minutes. The repo logged 31 commits that day and 65 the next. On September 4 MapLibre left the mobile build, and the simulator build went from 119,952 KB to 100,252 KB.
What a Requirement Is
A requirement is what the human decided, in their own words, not what the repo says, what the plan said, or what shipped.
The repo can tell you what changed and when. It can't tell you who said it or in what register. "It'd be cool" and "we need it" look the same once they're in a roadmap.
Three checks follow from this.
When something expensive feels wrong but appears required, find the first message where a human said it. If there isn't one, it's an inheritance.
Treat a reassurance as an estimate only if it carries a cost. "Can look as good" had no number. "Months" did.
When a file says "decided," look for the entry that weighed alternatives. If there isn't one, the label is preventing a decision, not recording one.
What fixed this was making the choice in my own words, with the alternatives written next to it.
-- Justin Higgins. Software Engineer, Midwest. Found out the app's biggest technical choice had never been made, then made it in his own words.
Companion pieces: The Decision Log Ate the Project - the same label at scale, 116 decisions nobody made. The Rules Are Downstream of the Work - the rule about "decided" labels, and the night it was earned.
Reactions, disagreements, war stories: jchigg2000.dev@gmail.com