Documentation
Governance
One governance model, written once and read everywhere: rules become versioned codes that surface locally, in CI, and in Fragments Cloud.
Overview
Governance follows one path: Rules → FUI codes → Surfaces. You author or enable rules once; each rule emits a stable diagnostic code; and every surface reads the same codes, so the local checks, CI, and Cloud all agree on what a finding means.
Governance is the layer Fragments sells: an enforceable contract over the React code your team and your agents write. The component library is the open-source substrate it governs — useful on its own, but the contract is what keeps a codebase on-system as it grows. To author the contract itself, follow Set up your design contract.
Enterprise wrapper and token example
A confirmed bridge makes the local wrapper canonical, limits direct MUI imports to its implementation file, loads TypeScript and declared-package tokens into one static catalog, and enables the raw-color rule at warning severity. Run fragments identity and fragments doctor --json to inspect the resolved identity and compiler capability before enabling CI.
import type { FragmentsConfig } from "@usefragments/core";
export default {
"app": {
"path": ".",
"include": [
"src/**/*.{ts,tsx,css,scss}"
]
},
"components": [
"src/components/**/*.tsx"
],
"tokens": {
"sources": [
{
"path": "src/theme.ts",
"format": "auto"
}
],
"packages": [
"@acme/design-tokens"
],
"aliases": {
"colors.brand": "--acme-color-brand"
}
},
"govern": {
"canonicalBridges": [
{
"underlying": {
"packageName": "@mui/material",
"exportName": "Button"
},
"local": {
"componentKey": "src/components/Button#Button",
"moduleSpecifier": "@/components/Button",
"exportName": "Button",
"implementationFiles": [
"src/components/Button/Button.tsx"
]
},
"decision": {
"state": "confirmed",
"source": "authored"
}
}
],
"styles": [
{
"kind": "style.rawColors.forbid",
"except": [
"transparent"
],
"prefer": "token",
"severity": "warn",
"exclude": [
{
"glob": "src/legacy/vendor/**",
"reason": "vendor drop, tracked in DS-611"
}
]
}
],
"rules": {
"styles/no-raw-color": {
"enabled": true,
"severity": "warn"
}
}
}
} satisfies FragmentsConfig;Intentional one-line exceptions stay attached to the next statement, name the exact FUI code, include a reason, and may carry a real calendar expiry.
// fragments-allow FUI2005: vendor-owned color, tracked in DS-482 expires="2026-12-31"
const Banner = () => <div style={{ color: "#39594d" }} />;// @fragments-expect-error FUI1003 reason="legacy import migration tracked in DS-611" expires="2026-12-31"
import { Button } from "@mui/material";GitLab repositories include the generated Fragments job; GitHub repositories receive a GitHub Actions workflow. If both providers are present, setup requires an explicit choice and writes neither CI file. Fragments owns .gitlab-ci.fragments.yml and never edits your .gitlab-ci.yml. If your root file already has an include block, the job is still written and setup prints the one line to add.
include:
- local: '.gitlab-ci.fragments.yml'The generated job runs on merge requests and on your default branch, and publishes its findings as a Code Quality report. GitLab reads that report natively, so findings show up in the merge request itself — no bot, no token, no Fragments Cloud in the loop. Every finding carries a stable fingerprint, so GitLab follows the same one across pushes instead of listing it again.
fragments_governance:
image: node:22
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
script:
- corepack enable
- pnpm install --frozen-lockfile
- pnpm exec fragments check --ci --format json --codequality gl-code-quality-report.json
artifacts:
when: always
reports:
codequality: gl-code-quality-report.jsonEnforcement Layers
Fragments makes exactly one guarantee, and states everything else as measured probability: "A required CI check blocks covered violations deterministically. Agent guidance reduces how often they are drafted (measured, improving)."
The deterministic result lives in CI, which runs fragments check --ci deterministically on pull requests targeting the configured default branch. On repos where the check is required by branch protection, a covered violation cannot merge — regardless of which agent or human wrote it. Every layer upstream of the check exists to make it boring, and each is honest about being fail-open and bypassable:
- Generation time. A compact vocabulary card (canonical component names, import paths, token prefix) is injected into supported agents before they write code, so the first draft is usually already on-system. Probabilistic by nature — measured, improving, never claimed as a guarantee.
- Write time. The agent contract hook checks each governed write as it happens — advisory by default, optionally denying a small deterministic subset of what CI would fail. Fail-open by design: a hook error always allows the write, and
fragments doctoris the honest answer to whether the chain is armed. Writes made outside hooked tools (for example shell-mediated edits) are not intercepted — the CI check covers them. - Merge time. Repository rules can require the deterministic CI result described above. Only that configured combination carries a merge-blocking guarantee.
Deny With a Fix
In blocking mode, when the hook denies a write on a confirmed violation, the deny reason embeds a conformed replacement — the same deterministic rewrite engine that powers design_system/conform produces corrected content (canonical component swap, token substitution), plus any items it could not resolve. The agent retries with the fix instead of guessing.
Producing the fix is deterministic; the agent applying it is probabilistic — so the deny is capped. After two denies for the same file and finding set in one session, the hook downgrades to advisory and lets CI be the arbiter, so an agent never thrashes against a wall. Deny copy also names the sanctioned in-source suppression path (@fragments-expect-error) for intentional, reviewable exceptions. The deny set is a strict subset of what CI fails: the hook never blocks something the CI check would allow.
What "Caught Before Merge" Counts
The dashboard's "Caught before merge" number counts unique blocking violations observed on open PRs — deduplicated by finding fingerprint per PR, so repeated pushes to the same failing PR never re-count the same violation. A second line reports how many of those PRs later merged clean, verified against the merge commit's recorded verdict.
Both figures count observed events only. Fragments does not report counterfactual "violations prevented" numbers, and does not sum counts across enforcement layers into a single headline.
What Runs When
Start by choosing a contract: the canonical components your team should reuse and the files that define your tokens. That arms the four contract rules (Tier A); every other customer rule is opt-in (Tier B). Until a contract exists, the customer default produces zero findings, so there is no flood on day one.
The universal, fragments, and tailwind presets provide ready-made starting policies; the fragments preset turns every rule on. Only a small allowlist of rules may hard-block (stop) a write; everything else advises.
Rules
Governance rules live in @usefragments/core and run over the same usage facts extracted from your source. A rule decides whether a given fact is a violation; it does not care which surface asked.
This reference is generated from the core registries and currently covers 25 rules across 9 domains. The Fragments-only tokens/require-dual-fallback convention is available through the full fragments preset but is excluded from customer defaults.
Components
Rule | FUI code | Tier | Title |
|---|---|---|---|
components/unknown-prop | FUI6005 | Opt-in | Component prop is unknown |
components/forbidden-prop-value | FUI6004 | Opt-in | Prop value is forbidden |
components/preferred-component | FUI1002 | Opt-in | Preferred component should be used |
components/prefer-library | FUI1004 | Contract | Library component should be preferred |
components/shadow-component | FUI1007 | Contract | Component shadows a canonical primitive |
Props
Rule | FUI code | Tier | Title |
|---|---|---|---|
props/invalid-value | FUI6002 | Opt-in | Prop value is invalid |
Imports
Rule | FUI code | Tier | Title |
|---|---|---|---|
imports/preferred-path | FUI1003 | Opt-in | Import should use the preferred path |
Styles
Rule | FUI code | Tier | Title |
|---|---|---|---|
styles/no-raw-color | FUI2005 | Opt-in | Raw color should use a token |
styles/no-raw-dimensions | FUI2004 | Opt-in | Raw dimension should use a token |
styles/no-raw-spacing | FUI2006 | Opt-in | Raw spacing should use the scale |
styles/no-raw-typography | FUI2016 | Opt-in | Raw typography should use a token |
Tailwind
Rule | FUI code | Tier | Title |
|---|---|---|---|
tailwind/arbitrary-color | FUI2007 | Opt-in | Tailwind arbitrary color should use a token |
tailwind/arbitrary-spacing | FUI2008 | Opt-in | Tailwind arbitrary spacing should use the scale |
tailwind/forbidden-palette | FUI2009 | Opt-in | Tailwind palette is forbidden |
tailwind/off-scale-spacing-token | FUI2011 | Opt-in | Tailwind spacing token is off scale |
tailwind/raw-color-via-token | FUI2010 | Opt-in | Tailwind color should use a resolved token |
tailwind/unknown-class | FUI2012 | Opt-in | Tailwind class is unknown |
Tokens
Theme
Rule | FUI code | Tier | Title |
|---|---|---|---|
theme/no-theme-coupled-literal | FUI2014 | Opt-in | Theme-coupled literal should use a semantic token |
Accessibility
FUI Codes
Every rule emits a versioned FUI diagnostic code. The code is the stable identifier a finding carries across surfaces, so local checks, CI, and Cloud can all point to the same explanation. The Error Codes catalog is the canonical per-code reference, with an explain page for each code.
Surfaces
Because findings flow through the shared engine, the same code reaches three surfaces without per-surface wiring:
- Local.
fragments checkreports violations before you push, with eachFUIcode linking to its explain page. - CI.
fragments check --ciannotates the run and can emit SARIF for code-scanning pipelines. - Cloud. Fragments Cloud ingests the same findings and lists them in the issue inventory, grouped and filterable by rule and code.
Topology
Findings don't float free — they roll up by topology. You map your repo into product areas (checkout, dashboard, …), each with a criticality and owners, so risk and ownership aggregate by the parts of your product that matter most — and the highest-stakes areas rise to the top.