Skip to content

14 min read

Choosing which rule to delete

On this page

A pull request that removes a rule from a prompt attracts a specific review comment, and it arrives quickly: rather than deleting, could we add a rule saying what we want on this case? It is strictly additive, it is easy to revert, and it does not risk regressing whatever the deleted rule was there for. Every clause of that is reasonable on its face, and the last one is the one doing the work — additions feel conservative and deletions feel dangerous.

The reason to resist it is not prompt hygiene in the abstract. A new rule fixes the reported case and leaves the defect resident, because the pair it is meant to overrule still collides on every input class the new rule's scope clause did not name; it adds a participant to every future contest in the prompt; and it costs tokens on every request and, more importantly, invalidates a cached prefix each time it changes. This chapter is about making that trade visible, and about the harder half of the job that follows it, which is deciding which of two clearly written rules is the one to remove.

What an addition repairs, and what it leaves behind

A rule written to close a ticket carries a scope clause taken from the ticket. A bug report about chargebacks produces if a customer message mentions a chargeback, dispute, or reversed payment, escalate to a human immediately — three trigger words, because those are the words in the ticket. If the underlying collision is between a rule saying to attempt a resolution before transferring and a prohibition on discussing disputed transactions in detail, the contested input class is not "messages containing the word chargeback". It is every message concerning a transaction the customer is contesting: billing disputes with no chargeback word, suspected card fraud, duplicate charges. The addition repairs the class the ticket happened to describe and leaves the rest depressed, so whoever files the next ticket files it about duplicate charges, and the natural response to that ticket, by the same logic, is one more rule.

There is also an arithmetic cost that is easy to overlook. A prompt with n rules contains n(n−1)/2 pairs that can potentially collide; going from 34 rules to 35 does not add one pair, it adds 34, taking the total from 561 to 595. The new rule has its own scope clause, its own explicit precedence claim over two other rules, and no statement of how it relates to the other thirty-two.

That count comes from one observation and one formula, and they agree. The observation is that the new rule forms a pair with every rule already present, and there are thirty-four of those, so the increment is thirty-four rather than one. The formula reaches the same place from the other side: the number of unordered pairs among a set of rules is the count times one less than the count, halved — every rule pairable with every other, and each pair otherwise counted twice. Put thirty-five through that and it returns the larger total; the difference between the two totals is the increment. The shape matters more than either figure. Pairs grow with the square of the rule count, so the price of an addition is not constant: the thirty-fifth rule brings thirty-four times as many new potential collisions as the second rule did.

The token cost is the smallest part and still not nothing. A rule of that shape is 28 tokens. On an agent handling 40,000 requests a day that is 1.12 million extra input tokens daily, which at $3 per million input tokens is about $3.40 a day and roughly $1,200 a year for one line of English. Prompt caching absorbs most of that as long as the prompt is stable, which is the second-order problem: every rule you append invalidates the cached prefix for the whole fleet, so a prompt that receives a rule a week never settles into the cache regime that made the budget work in the first place. A context budget is not only about how many tokens the prompt costs, it is about how often the prompt changes.

The caching half of that carries a mechanism rather than a multiplication, and it is worth unfolding once. A provider's prompt cache matches on a prefix: the stored entry is a run of tokens beginning at the very start of the request, and a lookup succeeds only as far as the first token that differs from what was stored. The system prompt sits at the front of every request, which is precisely what makes it the cacheable part. Append a rule to it and every subsequent request diverges from the stored entry at the point where the new rule begins, so the entry stops being usable and the next request pays the full rate to create another one. One append is a one-off cost, absorbed within a day. A prompt receiving an append a week never gets far enough from its last edit to spend much time in the regime the budget was written against.

Which of the two rules goes

Bisection hands you a pair and no ranking. Provenance, from the previous chapter, usually supplies the ranking: one of the two rests on an assumption that has since stopped being true, and that one is the deletion. When provenance does not settle it — both rules backed by live constraints, or no history to read — four questions do most of the remaining work, and they are worth asking in this order.

QuestionIf the answer favours one rule
Does a constraint outside the prompt still require this behaviour — a policy, a contract, a regulator, a metric someone is measured on?Keep that one; the other must be scoped or restructured
Can this rule be enforced somewhere other than prose — a schema field, a tool the model must call, a router (code in front of the model that inspects the request and chooses which prompt handles it)?Move it there and delete the prose; enforcement beats persuasion
Which rule's input class is broader?The broad one usually survives as the default and the narrow one becomes an exception, or vice versa if the narrow class is the one with the real cost
Which rule, if removed, produces a failure you would see?Prefer removing the one whose failure is visible, because you will learn about it

That last question inverts the instinct from the precedence chapter, and deliberately. When you are choosing between two rules to delete, the safer deletion is the one whose absence would announce itself, because you retain the ability to detect that you were wrong. Deleting the rule whose absence produces quietly wrong output is the deletion that needs the most evidence before it ships.

The second question does more work than its position in the table suggests, and the same support prompt contains a cleaner illustration of it than rules 33 and 34. Rule 7 says never to quote a refund amount before the finance check has returned, and rule 22 says always to end with a concrete next step, including a figure where one exists. Both were live, both had current owners who would defend them, and they collide on every refund conversation where the check is still pending. Neither had to be deleted as prose, because rule 7 is really a statement about data the model should not be holding: the refund figure reaches the model only inside the response of the refund_status tool, so removing the amount field from that response while the check is pending ends the conflict absolutely. The prose rule comes out with thirty tokens attached, and the constraint becomes something the model cannot violate rather than something it is being asked not to.

Deletion is also not the only subtraction available. Narrowing a rule's scope so that the two input classes stop intersecting removes the conflict without removing the capability, and it is the right move when both rules are genuinely live. If a transfer-rate objective were still current, the rule requiring a resolution attempt would become Attempt a resolution before transferring, except where the customer is contesting a transaction, which adds nine tokens and removes the entire intersection. That is a subtraction from the space of colliding inputs even though it is an addition to the character count, and it is a different thing from a new rule that claims precedence over two others while leaving their overlap in place.

Taken together with the provenance step, those questions form a short procedure, and it is worth holding the shape of it before the review starts rather than reconstructing it while someone is arguing with you.

Flowchart: Bisection returns a colliding pair → Does provenance show one rule's assumption is dead?; Does provenance show one rule's assumption is dead? → yes; yes → Delete that rule; Does provenance show one rule's assumption is dead? → no; no → Can either rule be enforced outside the prompt?; Can either rule be enforced outside the prompt? → yes; yes → Move it to schema, tool or router; delete the prose; Can either rule be enforced outside the prompt? → no; no → Must the two input classes intersect?; Must the two input classes intersect? → no; no → Narrow the broader rule until they stop overlapping; Must the two input classes intersect? → yes; yes → Delete the one whose absence fails visibly; Delete that rule → Measure every case family the pair touches, not just the ticket; Move it to schema, tool or router; delete the prose → Measure every case family the pair touches, not just the ticket; Narrow the broader rule until they stop overlapping → Measure every case family the pair touches, not just the ticket; Delete the one whose absence fails visibly → Measure every case family the pair touches, not just the ticket.

Making the argument in review

The claim to contest is that addition is the conservative choice. Both diffs are one edit and both are revertible in the same thirty seconds, so reversibility is not the difference. The difference is in which risks get measured. A deletion's risk is unmeasured but obvious to everyone in the room, so it attracts scrutiny and usually gets an evaluation run before it merges. An addition's risk is equally unmeasured and invisible, so it merges on the strength of one green case. Over a year of tickets, the process that scrutinises deletions and waves through additions produces a prompt with thirty-four rules, which is exactly the artefact under discussion.

The second thing to say is that the reported symptom is not the defect. Shipping the symptom fix means the defect is still resident, still firing, and now harder to find, because the next bisection will have to work through a rule that explicitly claims precedence over the pair you are trying to isolate.

The third, and the one that changes team behaviour rather than one review, is to make the deletion carry its own evidence. A pull request that says "removing this rule; here are six case families at fifty runs each before and after; the retired objective it was written for is linked" is a different object from one that says "this rule looks obsolete". The industry writing on this — Prompt Bloat vs Skill Systems is a reasonable entry point — is mostly about naming the symptoms of an over-grown system prompt, and it is persuasive about the disease without being much help on the day you have to justify a specific removal. The measurement is what makes the removal defensible.

When a new rule is the right change

There is a case where the reviewer is right, and it is worth being able to name it rather than treating every addition as debt. Suppose two rules are both live, their input classes genuinely have to intersect, and the correct behaviour on the intersection is not derivable from either one. A prompt that says to reply in the customer's language, and separately that legal disclosures must appear in the language of the contract, is not repaired by deleting either rule; a French customer asking about an English-law contract falls into a gap that neither sentence has an answer for, and closing it requires a third sentence.

The test is whether the new rule carries information. A rule saying to escalate on chargebacks says what the escalation rule already said; it adds nothing and simply re-runs a contest that the escalation rule was losing. A rule that names an input class neither existing rule anticipated is a real addition, and it is rare enough that being asked for one twice in the same quarter is itself a finding about the prompt.

There is an honest gap in the evidence above. The six-family table shows three rows improving and three staying flat, and the flat rows are what makes the deletion look safe. Those six families were written to exercise disputed-money behaviour, which is the area the deleted rule obviously touches, and that rule said something about transfers in general. Nothing in the table speaks to what happens on the several hundred conversation types nobody wrote a case for, and a regression suite frozen eighteen months ago will happily report no change on all of them while the removed rule quietly alters behaviour on a class the suite never sampled.

The asymmetry to hold on to is that both candidate changes carry unmeasured risk and only one of them looks like it does. An addition is a rule that repairs the class named in the ticket, competes with everything else in the prompt, and leaves the collision to be rediscovered by the next reporter. A deletion is a change to the class the pair was contesting, which is larger than the ticket and can be measured on every case family the pair touches for the price of an afternoon.

That measurement is what the argument turns on, and it is also where the next problem starts. A regression suite tells you what a deletion broke among the behaviours somebody thought to write down, and says nothing at all about the behaviour the deleted rule was written to prevent.

Instruction conflicts, over-constrained prompts, prompt bloat — read the current version at https://daviddominguez.dev/learn/en/instruction-conflicts-over-constrained-prompts-prompt-bloat/choosing-which-rule-to-delete

Back to top