The ticket says: Add discounts to checkout. Three teams at an invented company each pointed a coding agent at it the same week. Here is the first line of each pull request description:
Pull request 1: Adds a discount code field at checkout. Codes take a percentage off the subtotal before tax.
Pull request 2: Adds automatic volume discounts. Orders of ten seats or more get a lower per-seat price.
Pull request 3: Adds a fixed-amount discount that sales can apply to an invoice from the admin panel.
All three pass their tests. All three are reasonable readings of four words. And at most one of them is what the person who wrote the ticket meant, because "discounts" was standing in for a pricing decision nobody had made yet. None of the agents sent the ticket back. Each one accepted it, filled in the gap with a guess, and produced something that looked finished.
That behavior has a name in the history of the internet, and the people who maintain the internet's protocols have spent decades learning what it costs.
Conservative in what you do, liberal in what you accept
In January 1980, the specification for the Internet Protocol, RFC 760, edited by Jon Postel, included a short paragraph about implementations built by different people. "While the goal of this specification is to be explicit about the protocol there is the possibility of differing interpretations," it said. "In general, an implementation should be conservative in its sending behavior, and liberal in its receiving behavior." It should send well-formed messages, and it should "accept any datagram that it can interpret."
The September 1981 specification for TCP, RFC 793, put it in the form people still quote: "TCP implementations will follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others."
For an early network of independently written programs, that was good advice. It let imperfect implementations talk to each other, and it let the network grow before every specification was perfect.
In 2023, the Internet Architecture Board published RFC 9413, "Maintaining Robust Protocols," by Martin Thomson and David Schinazi. It is a careful reassessment of what the principle did over forty years. It keeps the parts about withstanding bugs and attacks. It questions the part about tolerating the unexpected, including the interpretation in which "a faulty or ambiguous message be processed according to the inferred intent of the sender."
Its verdict on that part is short. "This premise that specifications will be imperfect is correct. However, ignoring faulty or ambiguous input is almost always the incorrect solution to the problem."
The reason is what happens over time. A receiver that quietly accepts something malformed hides the problem from the sender, so the sender never fixes it. Other receivers have to accept it too. RFC 9413 calls this "a pathological feedback cycle," in which errors "can become entrenched, forcing other implementations to be tolerant of those errors," until "a flaw can become entrenched as a de facto standard."
Its alternative is active maintenance. When an implementer finds an input the specification didn't anticipate, "the implementer can provide significant value to the ecosystem by reporting the issue and helping to evolve the specification." It even makes a case for refusing: "Choosing to generate fatal errors for unspecified conditions instead of attempting error recovery can ensure that faults receive attention." And it says where the error should go: "Interoperability problems also need to be made known to those in a position to address them."
Agents are liberal receivers
A ticket is a message between two parts of a product team. A product manager, a lead or a customer request sends it. An engineer, and now more often a coding agent, receives it. Like any message, it can be ambiguous, incomplete or wrong.
Engineers have long been somewhat liberal receivers. Coding agents are liberal by design. They are built to make progress on whatever they are given, and a vague ticket is something they can make progress on. They do exactly what RFC 9413 warns about: process the ambiguous message "according to the inferred intent of the sender." Three agents inferred three intents.
The consequences follow the RFC's feedback cycle closely.
The sender never learns the ticket was ambiguous. The ticket got three working pull requests, which looks like success. Nobody tells the author that "discounts" needed a pricing decision behind it, so the next ticket is just as vague.
The guess becomes the standard. Whichever pull request merges first defines what "discount" means in the codebase. Later tickets, and later agents, build on it. If it was the wrong reading, it is now what RFC 9413 calls a "de facto standard," and every later change has to stay compatible with it.
The error goes to the wrong place. The person in a position to resolve the ambiguity is whoever owns pricing. The agents' guesses went into pull requests, where a reviewer can judge whether the code is correct, but not whether the company decided to offer volume discounts.
Our essay on the modern product development lifecycle describes how much of this lands at once: coding agents work inside one of seven stages, and the idea has to travel through all seven. The decisions that should shape an agent's work are often made in the other six. When those decisions are missing, a liberal receiver doesn't stop. It fills them in.
Where Brief fits: conservative in what agents accept
Brief is the product strategy agent. The homepage says it "captures decisions where they happen, connects them into one graph, and acts on them." In the terms of RFC 9413, it gives agents two things a protocol needs: a specification to check incoming work against, and a place to record problems against the people who can fix them.
Agents check the ticket against what was decided. Coding agents set up with Brief search the recorded decisions before they start, and ask Brief to check significant changes. Instead of inferring what "discounts" means, an agent can ask whether there is a decision about discount types or pricing, and get the recorded answer and its reason. Once that decision exists, three agents asking the same question are pointed at the same answer, which is how three pull requests end up describing one feature.
When the decision is pending, the agent can hold. This is the conservative move RFC 9413 recommends, and the homepage shows it. An agent asked to add per-seat pricing to the checkout API learns that D-241, the seat-based pricing decision, "is pending," and replies: "Holding the pricing change until D-241 is decided." It doesn't infer the sender's intent and ship. When nothing has been decided at all, Brief's answer says so, and that tells the agent it has a question to raise rather than a decision to follow.
The question gets a name on it. Agents can call brief_list_pending_decisions to see what is still waiting, and a proposed decision can name Who should decide? In Slack, /propose turns an open question into a proposal, and Edit can add an owner. The open question stops living inside one pull request and becomes a pending decision with a name on it, visible to everyone who checks what is still waiting. That is closer to RFC 9413's advice about making problems "known to those in a position to address them": the ambiguity is recorded against the pricing owner, not left for a code reviewer to notice.
A conflicting reading gets flagged. brief ask --mode check checks a proposed change against existing decisions and flags conflicts. If pricing has been decided and an agent plans a discount type that contradicts it, running the check before it builds flags the conflict.
The specification gets maintained. RFC 9413's answer was to keep the specification alive. In Brief, a decision can be recorded with its Why?, can carry a Re-evaluate when condition, and keeps a History of its status changes. When an agent's question exposes a gap, the fix is to record the decision, so the next ticket that says "discounts" has something to be checked against.
None of this makes a vague ticket specific. If nobody has decided what "discounts" means, Brief can't decide it, and an agent that doesn't ask will still guess. What Brief changes is what happens when an agent does ask: the guess becomes a question that can be recorded against the person who owns the answer.
The robustness principle was written for a network that couldn't stop to fix every specification. A product team can. When your agents get a ticket that could mean three things, where does that ambiguity go?
Objections
What is the robustness principle?
The robustness principle, also called Postel's law, is the guideline that a system should be conservative in what it sends and liberal in what it accepts. Its best-known wording is from RFC 793, the 1981 TCP specification: "be conservative in what you do, be liberal in what you accept from others." An earlier form appeared in RFC 760, the 1980 Internet Protocol specification.
What is wrong with the robustness principle?
RFC 9413, published by the Internet Architecture Board in 2023, argues that tolerating faulty or ambiguous input causes problems over time. When receivers silently accept errors, senders never fix them, other implementations must accept them too, and a flaw can become "entrenched as a de facto standard." It recommends active maintenance of specifications and, in some cases, refusing unexpected input so that faults receive attention.
How does the robustness principle apply to coding agents?
Coding agents act as liberal receivers of tickets and specifications. Given an ambiguous ticket, an agent will usually infer what the author meant and build that, instead of sending the ticket back. Different agents can infer different meanings, the first merged guess can become the standard, and the person who should have resolved the ambiguity may never hear about it.
What does it mean for an agent to be conservative in what it accepts?
A conservative agent checks a ticket against recorded decisions before building, and holds when a decision it depends on is pending, instead of guessing. When nothing has been decided, it raises the question instead of picking an answer. With the user's approval, it can record the open question as a pending decision that names who should decide it, so the ambiguity is resolved once and the specification improves.
How does Brief help coding agents handle ambiguous tickets?
Coding agents set up with Brief check recorded decisions before they build, so a ticket can be checked against what was decided. When a decision is pending, the agent can hold the change, as in the homepage example where an agent holds a pricing change until D-241 is decided. Agents can list pending decisions, proposals can name who should decide, and brief ask --mode check, when an agent or a person runs it, flags planned changes that conflict with existing decisions. Brief cannot make a vague ticket specific; it helps record the question against the person who owns the answer.