FUI9008: Rule override outranks a record's authored severity

moderate

A govern.rules entry enforces a different severity than the policy record next to it authored.

Details

diagnostic
{
  "code": "FUI9008",
  "ruleId": "config/overridden-record-severity",
  "category": "System",
  "defaultSeverity": "moderate",
  "lifecycle": "experimental",
  "fixAvailable": false,
  "evidenceRequired": false
}

Guidance

What it means

You authored a severity on a governance record — govern.styles[] or govern.jsx[] — and a govern.rules entry in the same policy enforces a different one. The rule entry wins, so the severity you can read on the record is not the severity that gates CI.

This usually comes from a broad rule id. tokens/hardcoded-values is a family: it stands for styles/no-raw-color, styles/no-raw-spacing, styles/no-raw-typography, tokens/require-dual-fallback and theme/no-theme-coupled-literal at once. Setting a severity on the family sets it on every one of those rules, including the one your record just authored at a different level.

You will not see this for a preset. A preset's family entry is a default — it says what the family looks like when nobody has an opinion — so your record's severity wins and nothing is reported. FUI9008 fires where that distinction cannot be made: a Cloud-served policy arrives whole, with no way to tell which of its entries came from a preset and which someone typed.

The diagnostic is verdict-neutral: it warns on stderr and never fails a run on its own. Turn it into a gate with govern.ci.failOnInert.

How to resolve it

Pick one place to say it. Either drop the rule override and let the record speak:

govern: {
  styles: [
    {
      kind: "style.rawColors.forbid",
      except: ["transparent"],
      prefer: "token",
      severity: "error",
    },
  ],
  // rules: { "tokens/hardcoded-values": { severity: "warn" } },  ← removed
}

…or keep the override and author the record at the severity you actually want enforced. If the override is deliberate for one rule but not the whole family, name the concrete rule id (styles/no-raw-color) instead of the family — a narrower key changes less.

Verify the change

Run npx @usefragments/cli check --format json and read the finding's severity and level: they should now match what the record says. check --ci gates on level, so this is the field worth confirming. Set govern.ci.failOnInert: true to keep the config honest from then on.

Intentional exception? Use a narrow, reasoned directive from the in-source suppression reference.

Next steps