skip to content

How do you retire a policy rule that other teams' pipelines import, without breaking them?

level: principalimportance: should knowfreq 35%

answer

  1. the rule is an interface with callers
  2. is the control going, or only this encoding?
  3. a date, not 'a future release'
  4. warn where the pipeline already prints
  5. delete it - no always-allow stub

basics

~20 s

Treat the rule as a published interface with consumers. Decide whether the control is going or only this encoding, enumerate who imports it, announce a dated removal sized to the slowest consumer, then actually delete it - never leave an always-allow stub.

solid answer

~50 s

The first question is not how, it is what is being retired. If the requirement still stands and only this encoding is going, retirement is a migration: the notice names the successor and maps old outcomes to new. If the requirement itself is being dropped, someone with the authority to accept that risk has to say so on the record - 'we deleted the rule' and 'we accepted the risk' cannot be the same unattributed commit. After that it is release management: enumerate consumers from the imports and from the engine's caller telemetry, publish a fixed removal date rather than 'soon', size the notice to the slowest consumer's release cadence, and put the warning in the decision output their pipeline already prints. On the date, delete it - an always-allow stub keeps consumers importing something that reads like coverage and enforces nothing. Then record when it stopped and why.

go deeper

for a junior

Know that a rule other teams import cannot simply be deleted, and that a deprecation needs a notice, a date, and a note saying what replaces it.

for a middle

Explain how you would find the consumers of a shared rule and why a warning inside the pipeline output reaches engineers when an email does not.

for a senior

Show the full sequence - consumers enumerated, dated notice, migration mapping, deletion rather than a stub - and why the retirement itself has to be recorded as evidence.

for a principal

Own the tension between holding a date and breaking a team that did nothing wrong, decide what flexes instead of the deadline, and make sure retiring a control has a named risk owner rather than a silent commit.

## A shared rule is an interface Once other teams' pipelines import your rule, you no longer own a file - you own a published surface with consumers you cannot see from your own repository. Deleting it is a breaking change to their build, and the discipline that applies is the one you would apply to any interface with callers: know who they are, tell them before you move, give them a fixed date, and honour it. ## Separate the control from its implementation The single most important distinction, and the one candidates skip: - **The implementation is being retired.** The requirement still stands; a newer rule, a platform default, or an upstream check now enforces it. This is a migration, and the burden on you is a mapping: what replaces it, what consumers must change, and what different outcomes they should expect. - **The control is being retired.** The organisation has decided this requirement no longer applies, or no longer applies at this cost. That is a risk decision, and it needs a named owner and a record. Retiring a control by deleting a file is how an organisation loses the ability to explain, later, whether a gap was chosen or accidental. Both are legitimate. Conflating them is not. ## The mechanics that make it non-breaking 1. **Enumerate consumers.** Search the organisation for imports and references, and cross-check with the engine's own telemetry for who actually evaluates the rule. The two lists differ: repositories that import it but no longer run, and callers you did not know existed. 2. **Publish a date, not an intention.** 'Deprecated, will be removed in a future release' produces zero migrations. A calendar date produces work, because it can be put in a sprint. 3. **Size the notice to the slowest consumer, not the average.** A team that ships quarterly needs more than one sprint. This is a judgment call: too short and you break people who did nothing wrong; too long and everyone defers until the last week anyway, which argues for a notice long enough to be reasonable and short enough to stay real. 4. **Warn where it will be read.** The deprecation notice belongs in the decision output the consumer's pipeline already prints - the same place the rule's verdicts appear - because that is the channel their engineers actually watch. Mail and chat announcements supplement it; they do not replace it. 5. **Provide the migration note with the announcement, not after it.** What replaces it, the mapping from old outcome to new, and the one-line answer for a team that finds nothing replaces it. 6. **Delete on the date.** Do not leave an always-allow stub. A rule that can never deny is indistinguishable from a working rule in every dashboard, keeps consumers importing something with no meaning, and quietly creates the false coverage this whole practice exists to prevent. ## Record the retirement as evidence Whatever the reason, write down that this rule enforced this control from this date to that date, and why it stopped. Twelve months later, a reviewer looking at a gap in the record cannot otherwise tell the difference between a control that was deliberately retired and one that silently broke - and those two have very different consequences. This is the cheapest artefact in the whole exercise and the one most often skipped. ## Make retirement routine, not heroic The reason retirement is hard is almost always that it is rare. A standing review - quarterly is the common cadence - that walks the rule set and asks three questions of each rule turns it into ordinary maintenance: is the requirement still real, is the rule still matching anything, and is this still the right place to enforce it. Two supporting habits make that review possible: every rule gets a named owner and a review date when it is created, and every rule's origin - the requirement it implements - is recorded with it. Without those, the review degenerates into a room of people who do not know why any of the rules exist and therefore delete none of them. ## The judgment a lead is expected to own Both failure modes are real and they pull opposite ways. Hold the date too rigidly and you break a team mid-release-freeze over a rule that was your idea. Slip it whenever anyone asks and the date stops meaning anything, the rule set never shrinks, and the review becomes theatre. The resolution that usually survives contact: the **date** holds, and what flexes is **who does the work** - the platform team lands the migration in the consumers' repositories rather than moving the deadline. That converts an argument about calendars into an allocation of effort, which is a thing you can actually decide. Where a consumer genuinely cannot move, the honest options are a scoped, dated carve-out owned by you, or an explicit decision to slip the date once, announced as such - never a quiet extension that nobody records.

  • A consumer says they cannot migrate before the removal date. What do you do?
    First check whether the blocker is real work or unallocated work. If the migration is small and they are simply out of capacity, I would rather my team land the change in their repository than move the date, because a date that slips on request stops driving anything. If it is genuinely structural, I take a scoped carve-out with my name and an end date on it, and record that I slipped it - once, visibly.
  • Why is leaving the rule in place but always allowing worse than deleting it?
    Because it is invisible. Consumers keep importing it, it still appears in the set, and every dashboard counts it as coverage, so the organisation believes it has a control it does not have. A deleted rule produces an honest gap someone can see and argue about; an always-allow stub produces a false assurance nobody will re-examine.
  • What do you record so next year's reviewer can tell retirement from silent breakage?
    The dates the rule was in force, the reason it stopped, what replaced it if anything, and who accepted the risk if nothing did. A gap in the enforcement record with no note beside it is the same shape as a rule that died from a field rename, and that ambiguity is what makes the record worth keeping.
  • How do you keep a rule set from only ever growing?
    Give every rule an owner and a review date at creation, record the requirement it implements, and run a standing review that asks of each one whether the requirement is still real, whether the rule still matches anything, and whether this is still the right place to enforce it. Without recorded provenance the review has no basis to remove anything.

saying these in an interview costs you the question

  • Deletes a shared rule without identifying who imports it
  • Announces deprecation with no removal date
  • Leaves the rule in place permanently allowing everything
  • Treats dropping a control and replacing its implementation as the same act
  • Removes a control with no named owner accepting the risk
  • Keeps slipping the removal date whenever a consumer objects

context