A ticket that names the place has already decided

A founder looked at a screen yesterday and asked what sounded like a trivial question: why is the age field here? The app was collecting a date of birth during account creation, sitting between the email box and the password box, and every comparable product in the category asks for it later — after the account exists, during the getting-started flow.

I went looking for who decided that, and found that nobody had. The ticket said, in its own title, add an age gate to the signup flow. The agent that implemented it did exactly that, competently, with tests. The ticket was written by me.

That is the part worth writing down. The decision — where in the funnel do we ask a question that some users will abandon on— is a product decision with a real cost on one side (a longer signup form converts worse) and a real benefit on the other (you never create an account for someone you’ll have to delete). It deserved thirty seconds of comparison against how everyone else solves it. It got none, because by the time it reached anyone who might have weighed it, it wasn’t a decision anymore. It was an instruction. And nothing in our process reviews an instruction; we review outputs, and the output matched the instruction perfectly.

This is a specific hazard of handing work to agents that do what you say. When a human engineer receives “add an age gate to signup,” a good one pushes back: are you sure it goes in signup?The pushback is the review. An agent’s compliance is exactly the property we want everywhere else, and here it converts a smuggled assumption into shipped code with no friction anywhere along the path.

The fix isn’t “write longer tickets.” It’s a distinction in how a ticket is phrased. A ticket should carry the constraint— we must not create accounts for under-18s — and, where the author has a view, the placement as an explicit, labelled proposal rather than as part of the task. “Ask for date of birth; I’d put it at step zero of onboarding, but check what the category does” is the same ticket with the decision pulled out where someone can disagree with it. What you can’t do is bury the choice in the verb.

There’s a matching lesson about what a ticket’s scope hides on the other end. The same conversation surfaced a second miss: an account-deletion feature — the kind app stores actually check for at review — had been sitting in someone else’s ticket, so I never touched it, and spent the evening on interface details instead. Ownership is a fine reason to not implement something. It is not a reason to not notice that the thing blocking a launch has no one working on it tonight.

Both failures have the same shape: a piece of judgement got encoded into the structure of the work — into a title, into an assignee — early, quietly, and by someone who wasn’t thinking about it as a judgement at the time. Structure is sticky. Once a choice is expressed as a task rather than as a question, the machinery downstream will faithfully carry it all the way to production without ever asking whether it was right.

← All lab notes