How DESIGN.md Handles Unknown Content: Parsing, Preservation, and Linting
DESIGN.md preserves unrecognized YAML keys and markdown sections while surfacing targeted warnings for potential typos or token-like maps that will be silently ignored during export.
The google-labs-code/design.md CLI employs a tolerant parsing strategy that accepts unknown content without failing, storing unrecognized keys for later linting analysis. This architecture separates the parsing phase from validation rules, allowing design systems to carry extra metadata while maintaining strict schema compliance where it matters.
Parsing and Storing Unknown YAML Keys
When the CLI parses a DESIGN.md file, it constructs a ParsedDesignSystem object defined in packages/cli/src/linter/parser/spec.ts. While the SCHEMA_KEYS constant enumerates known top-level YAML keys—such as version, name, colors, and typography—the parser deliberately stores every entry, recognized or not, in the rawValues record.
During the conversion from ParsedDesignSystem to the runtime DesignSystemState model (defined in packages/cli/src/linter/model/spec.ts), the handler in packages/cli/src/linter/model/handler.ts populates two specific fields for unknown data:
unknownKeys: An array of strings containing top-level keys not present inSCHEMA_KEYSunknownKeyValues: A record mapping those unknown keys to their raw YAML values
This preservation ensures that no data is lost during parsing, allowing subsequent lint rules to analyze the content and determine if it represents a typo, a valid extension, or a token map that will be dropped during export.
Lint Rules for Unknown Content
The linter examines captured unknown keys through specialized rules that emit warnings rather than errors, ensuring that unrecognized content never blocks the build pipeline.
Detecting Typographical Errors
The unknown-key rule, implemented in packages/cli/src/linter/linter/rules/unknown-key.ts, employs Levenshtein distance calculations to detect when an unknown key closely resembles a known schema key. When a potential typo is detected—such as colours instead of colors—the rule emits a warning with a suggested correction:
{
"severity": "warning",
"path": "colours",
"message": "Unknown key \"colours\" — did you mean \"colors\"?"
}
Identifying Ignored Token Maps
The token-like-ignored rule in packages/cli/src/linter/linter/rules/token-like-ignored.ts identifies unknown keys whose values resemble design-token maps—containing hex colors, CSS dimensions, or typography property names. This catches cases where users mistakenly use non-standard top-level keys for tokens that the export commands will silently ignore:
{
"severity": "warning",
"path": "brandTokens",
"message": "\"brandTokens\" looks like a design-token map but is not a recognized schema key (colors, typography, spacing, rounded, components). It will be silently ignored by export commands."
}
Handling Unknown Markdown Sections
For markdown content, the parser stores all section headings in state.sections regardless of whether they match the canonical schema. The section-order rule in packages/cli/src/linter/linter/rules/section-order.ts validates that known sections appear in the correct sequence based on CANONICAL_ORDER and SECTION_ALIASES definitions, but it never raises errors for unrecognized headings.
According to the consumer behavior documented in README.md, unknown section headings are preserved without error, while only duplicate headings trigger rejection. This allows documentation to contain supplementary sections—such as implementation notes or changelog entries—without breaking the linting process.
CLI Output and Report Structure
When running npx @google/design.md lint DESIGN.md, the compiler aggregates findings into a JSON report. Each warning includes the severity level, the path to the unknown key, and a descriptive message:
{
"findings": [
{
"severity": "warning",
"path": "colours",
"message": "Unknown key \"colours\" — did you mean \"colors\"?"
},
{
"severity": "warning",
"path": "brandTokens",
"message": "\"brandTokens\" looks like a design-token map but is not a recognized schema key..."
}
],
"summary": { "errors": 0, "warnings": 2, "info": 0 }
}
The path field corresponds directly to entries in unknownKeys, providing precise feedback on where unrecognized content appears in the YAML frontmatter.
Practical Example
The following TypeScript example demonstrates how the programmatic API surfaces unknown content handling:
import { lint } from '@google/design.md/linter';
const markdown = `
---
name: Demo
colours: # typo of "colors"
primary: "#112233"
brandTokens: # token-like but unrecognized
accent: "#ff00ff"
---
## Overview
A quick demo.
## Colours # unknown heading (preserved)
Some description.
`;
const report = lint(markdown);
console.log(report.findings);
// Output includes warnings for 'colours' typo and 'brandTokens' being ignored
Summary
- Unknown YAML keys are preserved in
unknownKeysandunknownKeyValuesfields during parsing inpackages/cli/src/linter/model/spec.ts. - The
unknown-keyrule detects potential typos using Levenshtein distance and suggests corrections. - The
token-like-ignoredrule warns when unrecognized keys contain values that resemble design tokens but will be ignored by export commands. - Unknown markdown sections are preserved; only ordering violations of known sections trigger warnings via the
section-orderrule. - All unknown content handling produces warnings, never errors, allowing exports to proceed while informing authors of potential issues.
Frequently Asked Questions
Does DESIGN.md fail validation when it encounters unknown keys?
No. The parser in packages/cli/src/linter/parser/spec.ts stores unrecognized keys in DesignSystemState.unknownKeys and continues processing. Validation only produces warnings, not errors, ensuring that exports can complete even with extra metadata present.
How does DESIGN.md distinguish between a typo and an intentional custom key?
The linter uses the unknown-key rule in packages/cli/src/linter/linter/rules/unknown-key.ts to calculate Levenshtein distance between unrecognized keys and known schema keys. If the distance is small (indicating a likely typo), it suggests the correct spelling; otherwise, it treats the key as an intentional unknown and checks if it contains token-like data via the token-like-ignored rule.
Will unknown sections in the markdown body be removed during export?
No. Unknown markdown sections are preserved in the document state. The section-order rule in packages/cli/src/linter/linter/rules/section-order.ts only validates the sequence of known canonical sections, leaving supplementary headings intact for documentation purposes.
What happens to design tokens defined under unknown keys?
Values under unknown keys that resemble token maps (hex colors, dimensions, or typography objects) trigger a token-like-ignored warning. These tokens are not exported to the final design system because the export commands only recognize keys defined in SCHEMA_KEYS, causing the data to be silently dropped while the build continues.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →