Book a callGitHub1

Guides02/10

For enterprise design‑system teams

Updated · Edit on GitHub

OpenDesigner gives a design-system team a written record and a set of checks: a decision log with reasons, locks, house and project standards, a check for hard-coded values in code, and DTCG 2025.10 tokens. Everything lives as files in your repository. It is early for teams: nobody has run a team pilot yet, and there is no hosted service and no SSO.

At a glance

What a team needsStatus
Decision log, append-only, with reasonsWorks
Locked valuesWorks
House standards (455 rules, version 3) and project standardsWorks
Drift check for hard-coded values in codeWorks locally; not tested in CI yet
DTCG 2025.10 tokens with a resolver for modesWorks
Figma variables, one import file per modeWorks
Light and dark, three densities, reduced motionWorks
Style Dictionary, Terrazzo, Tokens Studio, PenpotNamed in the export skill; not tested
Several brands from one systemNot yet
React Native and Flutter exportsNot yet
Hosted service, SSO and rolesNot offered; your repository host's access control applies

What runs where, and what can leave your computer: Security and data.

The decision log

opendesigner/decisions.md records every decision, newest last. Each entry has the value, the reason, the date, whether it is locked, and what it replaces. It also says how the value was set: chosen, confirmed default, auto default, assumed, delegated, or taken from a reference, an asset or a standard. Decisions, DESIGN.md and the overview page explains each one.

A suggestion nobody answered is never recorded as a decision. The log is append-only: a later entry replaces an earlier one, and nothing is edited or deleted. Here is one entry from a test run:

## D-0004 · raw.brandColor = "#2563eb"
- set_by: chosen · locked: no · date: 2026-10-14 · supersedes: none · source_ref: none
- reason: sketch: Level 0 answer
opendesigner/decisions.md
1## D-0004 · raw.brandColor = "#2563eb"
2set_by: chosen 3locked: no 4date: 2026-10-14 5supersedes: none 6source_ref: none
7reason: sketch: Level 0 answer
1The id, the path, the value. Ids count up; the path is the place in state.json.
2How it was set. chosen, confirmed default, auto default, assumed, delegated, reference, asset or standard.
3Locked or not. A locked value changes only with the owner's OK.
4The date.
5What it replaces. A later entry supersedes an earlier one; nothing is deleted.
6Where it came from. A reference, an asset or a standard, when there is one.
7The reason, in the person's words or the step that produced it.
One entry from the decision log, from a test run. Every entry has the same seven parts, so a reviewer, an auditor or a coding agent can read how any value came to be.

Locked decisions

Lock any value that must not drift, such as an exact brand color:

engine.py set raw.brandColor '"#2563eb"' --why "brand team" --lock

After that, the engine refuses to change it and says to ask the owner first. The accessibility floors are locked too, unless you raise them. The optional AGENTS.md note tells coding agents the same.

Lock what must not drift

Set the brand color with --lock. From then on the engine refuses to change it.

$ engine.py set raw.brandColor '"#2563eb"' --why "brand team" --lock
locked: yesset_by: chosen
A later session tries to change it
raw.brandColor is locked. Ask the owner before changing it, then run `engine.py unlock raw.brandColor` (or pass --force).

Leave the brand color unlocked

Every change is logged, but nothing stops it. OpenDesigner's own brand color moved three times in one day.

D-0004
raw.brandColor = "#e4572e"
locked: no
D-0005
raw.brandColor = "#d04418"
supersedes: D-0004
D-0025
raw.brandColor = "#2338FF"
supersedes: D-0005
Each entry was accepted without asking anyone.
A locked value is refused with a message that names the owner; an unlocked one is replaced by the next entry. The three entries on the right are from OpenDesigner's own decision log.

House standards and project standards

House standards are 455 rules (version 3, updated 2026-10-14) from sources the project owner marked non-negotiable. They cover areas such as motion, touch and components. The engine applies the ones that fit your platforms and locks them. In a test run, a web-only project got 289 of them. They are listed with their sources in opendesigner/standards.md.

A house standard changes only when someone explicitly asks. engine.py standard override changes one value or the whole standard, and records the reason. engine.py standard restore undoes it. engine.py standards --update applies newer house standards and keeps your overrides.

Project standards are your team's own rules:

engine.py standard add --rule "Buttons use sentence case" --why "Our content guide requires it" --source "design team, 2026-10-14"
  • --path and --value lock token values the rule sets.
  • --review-pattern lets engine.py review flag code that breaks the rule.
  • --authority marks it non-negotiable or good-to-have.
  • --beats names house standards your rule wins over.

Each standard change is recorded in the decision log.

Changes go through the extend skill

Before any change, the extend skill reads DESIGN.md, state.json, the decision log, the tokens and recent git history. It reports any drift and asks only about what is new. If a request clashes with an earlier decision, it shows both and the person chooses. It ends with a short change note for the team. See Change or extend a system.

Drift in code

engine.py review finds colors, sizes, radii, shadows and durations typed into your code by hand, and names the token to use for each. It also flags code that breaks a standard and DESIGN.md sections that are out of date. With --strict, it exits with an error when it finds anything. You could run it as a check in your pipeline, though we have not tested that.

Tokens your pipeline can read

  • opendesigner/tokens/ holds DTCG 2025.10 tokens: primitives, semantic roles, light and dark, three densities, and standard and reduced motion. One resolver file ties the modes together.
  • opendesigner/build/dtcg/ holds a single resolver file for tools that take one entry point.
  • The export skill names Style Dictionary, Terrazzo, Tokens Studio and Penpot as tools that read this format. We have not tested any of them yet.
  • Figma variables come with one import file per mode.

Accessibility floors

Every system gets WCAG 2.2 AA contrast, minimum target sizes, a focus ring and reduced motion, and errors block the build. These are a minimum, so people using assistive technology should still test. See Accessibility floors.

Themes and brands

Each system has light and dark colors, three densities and a reduced-motion mode. The interview can record that more brands will re-skin the system, but the engine doesn't build separate brand modes yet. Don't plan a multi-brand rollout on it today.

Governance questions

At deeper zoom levels, the interview asks questions only your team can answer. Examples: how strict the system is, who can add to it, how components get a status and a version, and how you announce changes. It records your answers in PRODUCT.md and never invents one.

Pilot it with one team

Nobody has piloted OpenDesigner with a team yet. If you try it, this order keeps the pilot small and reversible:

  1. Start with one product, not the whole portfolio.
  2. Run the sketch, then commit DESIGN.md, opendesigner/tokens/ and the exports.
  3. Accept the AGENTS.md note, so coding agents read the system before they touch the interface.
  4. Lock the values that must not drift: engine.py set raw.brandColor '"#2338FF"' --lock --why "...".
  5. Add your team's own rules as project standards, each with a reason (--why).
  6. Read the decision log together in your design review.
  7. Have each person run engine.py review at the end of their work. --strict exits with an error on drift, but it has not been tested in a pipeline yet.

Questions, gaps and results from a pilot are the most useful thing you can send back: open an issue with the issue forms. There is one maintainer and no support agreement.

Where it does not fit yet

  • No team pilots or watched user trials. The usability tests so far were role-played by AI testers.
  • No hosted service, accounts or SSO. Access control is whatever your repository host gives you.
  • No CI runs and no tagged release. Version 0.1.0 is planned. No test pass in each AI tool is recorded yet.
  • A small component set. Only buttons, a text field and a card are previewed. The overview lists 25 components as planned.
  • No React Native or Flutter export, and no translations.

Try it on one product, read the decision log with your team, and tell us what is missing.