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:

FieldPlain-language questionExample for an action Button
purposeWhat job does this component perform?Starts an immediate user-initiated action.
useWhenWhat must be true for this to be a good candidate?The user needs to submit, confirm or trigger an in-place action.
avoidWhenWhat conditions rule it out?The destination is another page; use a Link instead.
alternativesWhat might look plausible, and how do I decide?Link for navigation; Toggle for a persistent on/off setting.
noMatchWhen 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: primary

This 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 rules

This 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

LocationTypical authority
design.yamlPurpose, useWhen, avoidWhen, alternatives, semantic dimensions, content and composition intent.
development.react.yamlPackage, import, React props, code values, defaults, behavior and enforcement links.
mappings.yamlCorrespondence among semantic concepts, Figma properties, code props and documentation labels.
Button.types.tsLegal TypeScript shape. Prefer deriving API facts from it instead of copying them manually.
Button.tsxRuntime behavior and rendered semantics.
Storybook storiesExecutable examples and named states.
Tests and validatorsEvidence that particular rules are enforced.
manifest.jsonSmall 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.

  1. The agent searches the manifest for components related to actions and navigation.
  2. It retrieves compact Design Contract entries for Button and Link.
  3. It identifies Back as navigation and Place order as an immediate commit action.
  4. It retrieves the React Development Contracts only for the selected concepts.
  5. It maps the intended emphasis to the legal React property value.
  6. It generates the imports and component calls.
  7. Contract validation checks selection and composition rules; TypeScript checks the API; accessibility and interaction tests check their stated coverage.
  8. 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:

  1. Authors maintain design intent, boundaries and semantic definitions.
  2. A build extracts props, types, defaults and exports from code where possible.
  3. Figma and Code Connect identifiers are imported or checked.
  4. Storybook stories and test locations are indexed.
  5. Contract validation finds missing meanings, broken mappings, stale links and conflicting defaults.
  6. A versioned manifest is published with the design-system release.
  7. Agent tools retrieve focused packets from that manifest.
  8. Generated implementations run through existing build, lint, accessibility and contract checks.
  9. 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:

  1. Choose Button, Link and Toggle so selection alternatives are real.
  2. Author purpose, useWhen, avoidWhen, alternatives and property meanings.
  3. Derive the current React APIs and defaults from source.
  4. Map Figma properties and React props to the same semantic concepts.
  5. Publish a small manifest and retrieval command.
  6. Add two or three deterministic rules with actionable repair messages.
  7. 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.