How the contracts work in practice
Type: Explainer
Status: Active proposal guidance
Canonical for: Plain-language operation, placement and retrieval of the candidate contract model
Depends on: Candidate package; this is not an empirically validated implementation prescription
This walkthrough explains the candidate model without assuming a particular metadata format or agent platform. The YAML and TypeScript below are illustrative. The important part is the information, its authoritative source and how an agent retrieves it.
The basic idea
A component currently has useful information in several places:
- design guidance explains when people should use it;
- Figma describes its design properties and visual configurations;
- TypeScript describes which code properties are legal;
- the implementation determines what actually happens;
- Storybook demonstrates known states;
- tests check selected rules.
An agent should not have to search all of those places independently and guess how they fit together. The contracts provide a connected index of those facts.
The flow is:
flowchart LR A["Product task"] --> B["Find candidate components"] B --> C["Read Design Contract"] C --> D["Choose or reject component"] D --> E["Read Development Contract"] E --> F["Generate valid implementation"] F --> G["Run contract, type and accessibility checks"] G -->|"failure + repair guidance"| F
The Design Contract helps the agent make the design decision. The Development Contract helps it implement that decision correctly.
What useWhen and avoidWhen mean
useWhen and avoidWhen are decision rules written as observable conditions.
They answer different questions:
| Field | Plain-language question | Example for an action Button |
|---|---|---|
purpose | What job does this component perform? | Starts an immediate user-initiated action. |
useWhen | What must be true for this to be a good candidate? | The user needs to submit, confirm or trigger an in-place action. |
avoidWhen | What conditions rule it out? | The destination is another page; use a Link instead. |
alternatives | What might look plausible, and how do I decide? | Link for navigation; Toggle for a persistent on/off setting. |
noMatch | When should the agent stop instead of forcing a choice? | The requested interaction is not covered by an approved component or pattern. |
These are not necessarily React props. A component would not normally be called like this:
<Button useWhen="submit a form" />Instead, useWhen guides the agent before it writes the component call:
<Button type="submit" appearance="primary">
Place order
</Button>The first block is selection knowledge. The second is executable application code.
Good and weak decision rules
Weak rules require the agent to supply the missing judgment:
useWhen:
- Use when appropriate.
avoidWhen:
- Do not overuse.Stronger rules identify conditions the agent can find in the task or interface:
useWhen:
- The control triggers an immediate action in the current workflow.
- The user must explicitly confirm or submit entered information.
avoidWhen:
- The control only moves the user to another location; use Link.
- The control changes a persistent binary setting; use Toggle.The contract does not eliminate every judgment. It makes the decision boundary visible and tells the agent when the available evidence is insufficient.
How design semantics connect to code
The Design Contract describes a semantic concept. The Development Contract maps that concept to the spelling used by a particular implementation.
For example, the governed concept might be emphasis.high. Figma may call it Hierarchy=Primary, while React exposes appearance="primary".
semanticConcept: emphasis.high
meaning: Most prominent action in the current action group.
designBinding:
figmaProperty: Hierarchy
figmaValue: Primary
reactBinding:
property: appearance
value: primaryThis mapping lets an agent understand that primary is the code spelling for a scoped hierarchy decision. The word primary alone does not provide that full meaning.
The mapping also allows design and code names to differ without pretending they are unrelated. A validator can report when Figma exposes a value that code no longer supports.
Where the files can live
The files do not have to live in one universal folder. They do need to be:
- versioned with the component or tied to an exact component version;
- reachable through a stable component identifier;
- explicit about which source owns each fact;
- included in a searchable manifest or registry;
- validated when code, design or documentation changes.
A practical starting layout is to keep the authored contract near the component and generate a system-wide index:
design-system/
packages/
button/
src/
Button.tsx
Button.types.ts
stories/
Button.stories.tsx
tests/
Button.test.tsx
contract/
design.yaml
development.react.yaml
mappings.yaml
contracts/
manifest.json # generated index of every concept
schemas/ # validates contract records
rules/ # reusable cross-component rulesThis is a reference layout, not a required architecture. A central contracts repository can also work. The essential safeguards are stable identity, version alignment and validation. Separating the files into an unversioned wiki with no implementation linkage would make stale or conflicting guidance more likely.
What belongs in each place
| Location | Typical authority |
|---|---|
design.yaml | Purpose, useWhen, avoidWhen, alternatives, semantic dimensions, content and composition intent. |
development.react.yaml | Package, import, React props, code values, defaults, behavior and enforcement links. |
mappings.yaml | Correspondence among semantic concepts, Figma properties, code props and documentation labels. |
Button.types.ts | Legal TypeScript shape. Prefer deriving API facts from it instead of copying them manually. |
Button.tsx | Runtime behavior and rendered semantics. |
| Storybook stories | Executable examples and named states. |
| Tests and validators | Evidence that particular rules are enforced. |
manifest.json | Small discovery index that tells an agent what exists and where to retrieve authoritative details. |
A small end-to-end example
The following record is deliberately smaller than the full candidate contracts.
conceptId: ds.component.action-button
preferredLabel: Button
status: stable
purpose: Trigger an immediate user-initiated action.
selection:
useWhen:
- The user submits, confirms or triggers an action.
avoidWhen:
- The user is navigating to another location.
- The control represents a persistent on/off value.
alternatives:
- conceptId: ds.component.link
chooseWhen: The outcome is navigation.
- conceptId: ds.component.toggle
chooseWhen: The outcome is a persistent binary setting.
properties:
- concept: emphasis
scope: action-group
values:
- concept: emphasis.high
meaning: Most prominent action in the group.
- concept: emphasis.medium
meaning: Supporting action in the group.
implementations:
- framework: react
package: "@example/design-system"
export: Button
mappings:
- semanticConcept: emphasis.high
property: appearance
value: primary
- semanticConcept: emphasis.medium
property: appearance
value: secondary
rules:
- ruleId: button.navigation-use-link
condition: outcome == navigation
requirement: select ds.component.link
severity: error
repair: Replace Button with Link and preserve the accessible label.Suppose the user asks an agent to build a checkout footer with Back and Place order.
- The agent searches the manifest for components related to actions and navigation.
- It retrieves compact Design Contract entries for Button and Link.
- It identifies Back as navigation and Place order as an immediate commit action.
- It retrieves the React Development Contracts only for the selected concepts.
- It maps the intended emphasis to the legal React property value.
- It generates the imports and component calls.
- Contract validation checks selection and composition rules; TypeScript checks the API; accessibility and interaction tests check their stated coverage.
- If a rule fails, the agent receives the stable rule ID, explanation and repair instruction rather than a generic error.
The agent therefore does not receive every design-system document in its prompt. It receives the smallest current packet needed for this decision.
How an agent finds the contracts
An agent needs a supported access path. The contract files merely existing in a repository is insufficient unless the agent knows how to discover them.
When that access path lets the agent reliably find and inspect current governed design or implementation artifacts, the component is AI-exposed for that access path. It may still not be AI-ready for selection or composition if useWhen, avoidWhen, alternatives, relationships or constraints remain implicit. Exposure answers “can the agent get the material?” Readiness asks “does the material make enough governed meaning explicit for this decision?”
Three common access paths are possible:
1. Repository access
The agent reads a generated manifest, then opens the referenced local files. This is the simplest path for coding agents working inside the design-system or product repository.
2. Documentation or registry API
A service exposes search and retrieval operations such as:
searchComponents(intent, context)
getDesignContract(conceptId, version)
getDevelopmentContract(conceptId, framework, version)
validateConfiguration(proposal, context)The operations could be implemented as ordinary HTTP endpoints, a package CLI or another internal service.
3. MCP or agent tool
An MCP server can expose the same search, retrieval and validation operations to multiple agent clients. MCP is the delivery mechanism; it does not make incomplete guidance semantically complete.
In all three cases, the agent-facing result should include:
- the contract and artifact versions;
- relevant alternatives, not only the first search result;
- applicable decision and composition rules;
- the authoritative framework binding;
- unresolved conflicts or missing information;
- validation and repair feedback.
What happens during design-system development
A workable publishing pipeline could perform these steps:
- Authors maintain design intent, boundaries and semantic definitions.
- A build extracts props, types, defaults and exports from code where possible.
- Figma and Code Connect identifiers are imported or checked.
- Storybook stories and test locations are indexed.
- Contract validation finds missing meanings, broken mappings, stale links and conflicting defaults.
- A versioned manifest is published with the design-system release.
- Agent tools retrieve focused packets from that manifest.
- Generated implementations run through existing build, lint, accessibility and contract checks.
- Later agent evaluations are attached as AI-optimisation records for the exact contract version tested.
This pipeline avoids requiring designers or developers to manually duplicate facts that already have an authoritative machine-readable source. Human authorship is concentrated on meaning and judgment that cannot be reliably extracted from code.
What remains human-owned
The contract should not invent product strategy. Product teams may still need to provide:
- the user’s goal and workflow context;
- business consequence and risk;
- which action is most important in this specific group;
- content particular to the product;
- exceptions approved by product or policy owners.
The design system owns the meaning of its concepts and their general rules. The product supplies the situation to which those rules are applied.
An illustrative first implementation slice
The smallest useful pilot is one component family rather than the entire system:
- Choose Button, Link and Toggle so selection alternatives are real.
- Author purpose,
useWhen,avoidWhen, alternatives and property meanings. - Derive the current React APIs and defaults from source.
- Map Figma properties and React props to the same semantic concepts.
- Publish a small manifest and retrieval command.
- Add two or three deterministic rules with actionable repair messages.
- Test whether agents select and implement the three components correctly.
That pilot would reveal whether the contract is retrievable, maintainable and useful before a broader format or tooling commitment is made.