Guides02/10
For enterprise design‑system teams
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 needs | Status |
|---|---|
| Decision log, append-only, with reasons | Works |
| Locked values | Works |
| House standards (455 rules, version 3) and project standards | Works |
| Drift check for hard-coded values in code | Works locally; not tested in CI yet |
| DTCG 2025.10 tokens with a resolver for modes | Works |
| Figma variables, one import file per mode | Works |
| Light and dark, three densities, reduced motion | Works |
| Style Dictionary, Terrazzo, Tokens Studio, Penpot | Named in the export skill; not tested |
| Several brands from one system | Not yet |
| React Native and Flutter exports | Not yet |
| Hosted service, SSO and roles | Not offered; your repository host's access control applies |
What runs where, and what can leave your computer: Security and data.
The decision log
opendesigner/ 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 answerLocked decisions
Lock any value that must not drift, such as an exact brand color:
engine.py set raw.brandColor '"#2563eb"' --why "brand team" --lockAfter 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
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.
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/.
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"--pathand--valuelock token values the rule sets.--review-patternletsengine.py reviewflag code that breaks the rule.--authoritymarks it non-negotiable or good-to-have.--beatsnames 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/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.tokens/ opendesigner/holds a single resolver file for tools that take one entry point.build/ dtcg/ - 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:
- Start with one product, not the whole portfolio.
- Run the sketch, then commit
DESIGN.md,opendesigner/and the exports.tokens/ - Accept the
AGENTS.mdnote, so coding agents read the system before they touch the interface. - Lock the values that must not drift:
engine.py set raw.brandColor '"#2338FF"' --lock --why "...". - Add your team's own rules as project standards, each with a reason (
--why). - Read the decision log together in your design review.
- Have each person run
engine.py reviewat the end of their work.--strictexits 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.