Component Governance Framework
Repository:livepeer/docs, docs-v2 branchScope:
snippets/components/ – the governed component libraryPlatform: Mintlify (MDX-based)
Version: 1.0
Date: 7 March 2026
Author: Wonderland (Alison Haire) / Claude collaboration
Source deliverables: D1–D6 of the Component Governance Framework plan
Quick Start
You’re a contributor. You want to build, use, or modify a component. Here’s everything you need in 60 seconds.Find a component
Use the Component Registry or the published Component Library pages. Every component has a status badge, props table, and copy-paste example.Use a component
Import with the full explicit path in your MDX page:/snippets/ paths are permitted – the importing component handles its own dependencies, so the consuming MDX page does not need to re-import sub-components used internally. Circular imports are not allowed. Shared non-visual runtime logic may be kept inline in the exported component or imported from a colocated non-component .js helper module.
Decide which category
Follow the decision tree (first match wins):- Fetches, embeds, or binds to external/third-party data? →
integrators/ - Part of the page’s outer structure, typically used once? →
scaffolding/ - Takes content and presents it in a formatted way? →
displays/ - Exists to hold, group, or arrange other things? →
wrappers/ - Single visual piece – no wrapping, no arranging, no fetching? →
elements/
Build a new component
- Create your
.jsxfile in the correct category folder. - Use arrow function syntax (
export const X = () => ...). - Add the full JSDoc block (6 governance fields +
@aiDiscoverabilityif hook-using +@paramper prop +@example). - Use
var(--lp-*)CSS tokens for all colours. No hardcoded hex. No ThemeData. - Add defensive rendering – guard all props, never throw. A crash kills the entire page.
- Create an example in
{category}/examples/{file}-examples.mdx. - Write unit tests in
operations/tests/unit/components/{category}/{file}.test.js. - Verify visually in both light and dark mode via
mintlify dev. - Commit. Pre-commit validates JSDoc, regenerates the registry, and checks styling rules.
Component checklist (full)
1. Classification & Purpose Model
1.1 Category Taxonomy
Six categories. Every component belongs to exactly one.1.2 Decision Tree
Classify by answering in order. First match wins.1.3 Library Boundary
Inside:snippets/components/ and its six category subdirectories. Every exported component here is governed.
Outside (not governed by this framework):
Mintlify enforces that all importable JSX lives under
/snippets/. No “section-local components” are possible outside this path.
1.5 Data & Props Surface
Prop inputs are documented via@param tags on each exported component. For integrators, @dataSource identifies the external pipeline or API. See Section 5.2 for the full 6-field schema.
2. Repo Structure & Documentation Architecture
2.1 Folder Layout
examples/ subdirectory per category where the category uses runnable examples.
2.2 Naming Conventions
2.3 File Granularity
Grouped files with per-export JSDoc. Related components share a file. Each export gets its own 6-field JSDoc block. Non-exported helpers are implementation details.2.4 Import Paths
Full explicit paths. Mintlify requires file extensions. No barrel imports.2.5 Documentation Architecture
2.6 Registry
Single JSON atdocs-guide/config/component-registry.json. Generated by pre-commit hook when files in snippets/components/ are staged. Contains all 6 enforced governance fields per component plus derived fields (file, importPath). Script: operations/scripts/generators/components/library/generate-component-registry.js.
3. Styling Architecture & Standards
3.1 Three-Layer Hierarchy
var(--lp-*) tokens. They rarely define new variables (only for computed/dynamic values, with documentation).
3.2 Token Namespace
All tokens use--lp- prefix: --lp-color-*, --lp-spacing-*, --lp-font-*, --lp-radius-*, --lp-shadow-*, --lp-z-*.
Every --lp-color-* token has both light and dark values defined in style.css.
3.3 Banned Patterns (Pre-commit Blocks)
3.4 Advisory Patterns (Code Review Flags)
3.5 Dark/Light Mode
3.6 Mintlify Override Registry
Overrides instyle.css are documented technical debt. Each entry tracks: what’s overridden, which Mintlify limitation necessitates it, introduction date, review date, owner, status. Reviewed quarterly against Mintlify release notes.
4. Component Development Standards
4.1 Props Conventions (7 Rules)
- camelCase prop names
is/hasprefix for booleans (isCompact,hasIcon)onprefix for handlers (onClick,onToggle)- Defaults in destructuring (
({ variant = 'default' }) => ...) childrenfor slot content, named props for data- Spread last (
<div className={...} {...rest}>) - Required props: no default. Optional: always have default.
4.2 Composition
Inter-component imports are permitted via absolute/snippets/ paths. The importing component handles its own dependencies – the consuming MDX page does not need to re-import sub-components used internally by a component. Circular imports are not allowed.
Same-file references are also allowed (co-located components share scope).
4.3 Accessibility
All components: Semantic HTML, alt text on images, heading hierarchy, descriptive link text. Interactive components (SearchTable, CardCarousel, ShowcaseCards, CopyText, DownloadButton, ScrollBox): additionally require ARIA roles/attributes, keyboard operability (Tab, Enter/Space, Escape), and visible focus indicators.4.4 Error Handling (Mandatory)
Mintlify has no error boundary per component. A component crash kills the entire page. Defensive rendering is non-negotiable.
MDX-facing component rule: if a
.jsx file is imported directly by a routable MDX page, exported components in that file must not rely on private file-scope helpers. Keep defensive logic inline in the exported component or import it from a colocated non-component .js helper module. Do not hoist the logic into top-level private locals inside the .jsx file.
4.5 Testing (Three Tiers)
Core unit test cases (every component): renders with valid props, renders with no props, handles null/undefined data, handles missing required props, handles invalid prop types.
5. Documentation & Example Standards
5.1 JSDoc Template
Every exported component carries this block:@dataSource is additionally required for all components in integrators/. All other governance fields are required for every export.
5.2 Metadata Schema (6 Fields + 1 Conditional, Enforced)
@aiDiscoverability declares whether a component hides content from crawlers and AI pipelines at runtime, and where its static companion file lives:
snapshot→ external-fetch component; companion atsnippets/data/snapshots/[source-id].json(CI-regenerated)props-extracted→ interactive/paginated UI; companion atv2/[section]/[page-slug]-data.json(author obligation, adjacent to MDX)none→ hooks used for UI state only; no content hidden; no companion needed
5.3 Props Table Format (Published Docs)
Generated from
@param tags. Five columns.
5.4 Examples
One rendered MDX example per exported component in{category}/examples/{file}-examples.mdx. Copy-paste ready with import statement. Required for stable components only.
5.5 Published Docs Generation
Fully automated. Zero human maintenance.- Registry generation (pre-commit): JSDoc →
component-registry.json - Docs generation (manual/chained): registry +
@param+@example+ OpenRouter LLM → published MDX pages - LLM failure fallback: template-generated prose from metadata (deterministic)
5.6 Deprecation
6. Lifecycle & Governance
6.1 Lifecycle States
6.2 Transitions
Free transitions – any state to any state. Update@status in JSDoc. Document reason in commit message. Registry captures the change automatically.
6.3 Governance Taxonomy
Category-level. One governance label per folder. The current metadata field isowner, but it is taxonomy, not reviewer assignment or gatekeeper authority. Historical GitHub review maps may remain archived for reference, but tests, generated registries, and repair commands are the active contract.
6.4 Modification Rules
No immutability rule. Automated validation and the existing test infrastructure (58-script suite, 17 CI workflows, pre-commit hooks, browser tests) are the gates. Human review is collaborative, not ownership-based.6.5 Deprecation & Removal
Usage-gated. A deprecated component is removed only when@usedIn is empty – no pages reference it. The registry tracks consumers. Published docs surface remaining consumers as migration prompts.
7. Enforcement Summary
What’s enforced, where, and how.8. Generation Pipeline
8.1 Registry Generation
8.2 Published Docs Generation
9. Decision Register (All 33 Decisions)
D1: Classification & Purpose Model
D2: Repo Structure & Documentation Architecture
D3: Styling Architecture & Standards
D4: Component Development Standards
D5: Documentation & Example Standards
D6: Lifecycle & Governance Model
10. Upstream Dependencies
This framework consumes but does not redefine:11. Completed Work (D8 + D9)
The following were open items at framework inception and are now complete as of 2026-03-20:- ✅ All components classified and migrated to new taxonomy (elements/wrappers/displays/scaffolding/integrators/config)
- ✅ All JSDoc governance fields populated on every governed export (6-field schema enforced by
--strict) - ✅
generate-component-registry.jsoperational – generatesdocs-guide/config/component-registry.json - ✅
generate-component-docs.jsoperational – generates published MDX pages per locale - ✅ Pre-commit hook enforces JSDoc fields and auto-stages registry
- ✅ Published component library pages regenerated for all 4 locales
- ✅ Import paths updated across all MDX pages after folder restructure
- ✅ ThemeData removed from all components
- ✅ Duplicate components resolved and archived
component-layout-decisions.mdxupdate – see Section 12.3 below; unblocked as of 2026-03-21
12. Composable Content Layer
12.1 Three-Layer Architecture
Components (snippets/components/) are the middle layer of a three-layer content architecture:
Platform constraint (Decision D4): JSX inter-component imports are permitted via absolute
/snippets/ paths, but circular imports are not allowed. Composables are .mdx files because they compose multiple components with authored prose. MDX can freely import JSX components; JSX can import other JSX via absolute paths.
12.2 Composable Section Library
As of 2026-03-21,snippets/composables/ contains 8 composable section blocks:
Each composable includes a
@composable governance header (purpose, pageTypes, variables, notes) and uses {/* */} comments to show optional sub-elements inline at point of use.
Lifecycle rule: Content starts local to a page. Promote to snippets/composables/ only when a concrete second consumer appears.
12.3 @contentAffinity
@contentAffinity is a deferred JSDoc field (field #8 on the aspirational schema, deferred in prior sessions) that declares which page types a component is appropriate for.
Status: Not yet enforced. Page taxonomy is now locked (15 purpose values, 10 pageType values), making this field unblocked.
Proposed syntax:
--strict mode in generate-component-registry.js as part of CONTENT-STRUCTURE Phase 5.1.