skip to content

Your team's Allure `categories.json` has collected dozens of rules over two years — how do you decide which rules stay, and who is accountable for pruning it?

level: principalimportance: should knowfreq 40%

answer

  1. a rule is a claim that decays
  2. dead rules look exactly like quiet ones
  3. delete rather than disable
  4. every rule needs an owner and an action
  5. results directory file or central report config

basics

~20 s

Treat it as versioned configuration with an owner per rule: a rule earns its place only if the failure recurs, is distinguishable from its message or trace, and has an action attached. Delete dead and shadowed rules at review time.

solid answer

~50 s

Start from what the file is: **order-sensitive shared configuration whose every rule is a claim about the world**, and claims decay. Three things rot in it — rules whose cause was fixed long ago, rules shadowed by a broader one above them, and a catch-all that has quietly grown to swallow new failure modes — and none of the three announces itself, because an empty bucket and a problem that stopped happening look identical. So keep the file in version control beside the suite, review changes to it as code, and require each rule to carry a `description` saying what a reader should do when a test lands there; a rule nobody can act on is a label. Give each rule an owner — normally the team that owns the failing area — and prune on a cadence by regenerating a kept results directory with a rule removed and seeing what moves.

go deeper

for a junior

Know that this file is checked into version control and reviewed like any other configuration, not edited by hand on a build agent when a report looks wrong.

for a middle

Explain what makes a rule worth keeping: a recurring failure, a stable fragment in its message or trace to match on, and an action written into the rule's description.

for a senior

Describe how you find dead and shadowed rules when nothing reports them, and why an empty bucket, a wrong pattern and a problem that stopped happening are indistinguishable from the file alone.

for a principal

Argue the placement — rules travelling with each suite's results versus one central list in the report job — and name who is accountable for deleting a rule, since a file with no deletion authority only grows.

## What you are actually governing `categories.json` looks like a small config file and behaves like a shared, order-sensitive policy document. Each rule asserts *this pattern of failure exists, it is worth naming, and here is what it means*. Every one of those assertions has a shelf life, and the file has no mechanism for telling you when one has expired. That is the whole management problem. It is made harder by one property: **an empty bucket has three explanations and the file cannot distinguish them.** The pattern may be wrong; a broader rule above it may be consuming everything; or the failure mode may genuinely have stopped. Nothing logs, warns or reports. Any governance you design has to work without that signal. ## The four ways the file rots 1. **Dead rules.** The defect was fixed; the rule remains. Harmless in isolation, corrosive in aggregate — a long list nobody has verified is a list nobody trusts, and that distrust is what stops anyone pruning it. 2. **Shadowed rules.** A broad rule drifts above a narrow one and the narrow one silently stops firing. The report still looks reasonable, which is why this survives for years. 3. **The greedy catch-all.** A rule with a status condition and no text condition collects everything, including **new** failure modes that should have stood out. This is the expensive one: the file's entire purpose is to make an unfamiliar failure visible, and this defeats it. 4. **Private vocabulary.** Bucket names encoding one engineer's mental model — an internal codename, a sprint reference, a joke — that nobody else can act on once that person moves teams. ## What earns a rule A rule is worth adding when all three hold: - **It recurs.** A one-off failure gets investigated, not bucketed. Bucketing a singleton adds a permanent line to a shared file to describe something that happened once. - **It is mechanically distinguishable.** There must be a stable fragment in the message or the trace — an exception type, a distinctive phrase — that is not a host name, a port, a timestamp or a generated identifier. If you cannot name the failure in text, a rule cannot either. - **An action attaches to it.** The `description` should say what to do: who to tell, what to check, whether to expect it to clear on its own. A bucket with no action is a label with extra steps. ## Who owns it, and how pruning actually happens Ownership has to be per rule, not per file, because the knowledge is per rule. In practice: | model | works when | fails when | |---|---|---| | the suite's owning team owns every rule | one team runs and reads the suite | several teams write into one results directory | | the team owning the failing area owns its rules | rules map cleanly onto areas | a rule spans areas, or its area has no owner | | a rotating triage owner prunes on a cadence | failures are triaged daily anyway | the rota has no authority to delete another team's rule | Whatever you pick, the mechanics are the same, and they are cheap because rules are applied at generation time over results already on disk: 1. Keep the file in **version control next to the suite**, never edited on a build machine. 2. **Review edits as code**, and treat a reordering as a real change — it alters the report without touching a pattern. 3. On a fixed cadence, **regenerate a kept results directory with a candidate rule removed** and see what moves. If nothing moves across several recent runs' results, the rule is a deletion candidate. 4. **Delete rather than disable.** A commented-out or inert rule is a decision the next reader has to make again, and version history already records why it existed. 5. **Re-derive the order** after any addition: narrow rules above broad, at most one deliberate catch-all, at the bottom. ## The placement decision you actually own The genuinely architectural choice is *where the rules live*. Allure 2 reads `categories.json` from the results directory, so the rule list travels with the run that produced the results. Allure 3 reads that file too, and additionally accepts category rules from its own configuration file, which lets one central report job define them. - **Per-suite, in the results directory:** the rules sit with the team that understands the failures, and one suite's rules cannot break another suite's report. The cost is drift — several near-identical files, each pruned at a different rate, and no single place to see what the organisation buckets. - **Central, in the report job's configuration:** one list, one review, consistent bucket names across suites. The cost is a shared file every team must negotiate over, an owner who has to understand every suite's failures, and a change that can affect everyone's report at once. The honest answer is usually **central for the small set of buckets that mean the same thing everywhere — infrastructure, environment, timeouts — and per-suite for anything domain-specific**, with a standing rule that a bucket promoted to the central list acquires a named owner as part of the promotion. Whichever you choose, the failure mode to design against is identical: a file that grows monotonically because nobody has the standing to delete from it.

  • How would you find rules that have not fired in months, given nothing reports it?
    Regenerate kept results directories from several recent runs with the file as-is and read the bucket sizes; a bucket empty across all of them is a candidate. Then remove the rule and regenerate once more to confirm nothing moved. It is cheap because generation reads results already on disk and needs no test execution.
  • A team wants a bucket for a defect they have already fixed but not yet released. Keep it or not?
    Keep it, with an expiry stated in its description and a named owner — it is doing real work until the fix ships, telling readers this red is expected. The discipline is that the rule leaves with the release. Rules added for a known temporary condition are exactly the ones that become permanent when nobody wrote down when they should go.

saying these in an interview costs you the question

  • Adds a rule for a failure seen once
  • Keeps dead rules because deleting them feels risky
  • Leaves a broad catch-all near the top of the file
  • Edits the file on a build machine, outside version control
  • Names buckets after internal codenames nobody else knows