Creating an
Agentic
Design System
A design system for people and the agents building with them. Portable visual language, shared product decisions and measurable behavior, connected through a workflow that keeps change reviewable.
Follow the explorationActivate an action.
duplicate activation
What changes when agents become users of the system?
I started this as a personal exploration of how far I could take a design system. Aegis already had components and a visual language. The next question was how an agent could understand the decisions behind them, and contribute without creating another competing system.
- For people
- Make the purpose, anatomy and behavior of a component easy to understand.
- For agents
- Expose the same knowledge as structured requirements, source facts and reusable instructions.
- For the designer
- Define the language, the boundaries for change and what a good result must preserve.
Different ways in.
One set of design decisions.
Start with a system that is useful on its own.
The agentic layer grows around a conventional React design system. I kept the foundations, controls, data displays, patterns and layouts usable without an agent, a service or an AI model being online.
- Foundations
- Tokens, typography, color, spacing, shape and motion provide a common vocabulary.
- Components
- Forms, tables, overlays, feedback and AI interaction components preserve their own behavior and ownership.
- Compositions
- Page layouts and shared patterns connect those parts into a working application.
triggerA small surface, shaped by your design language.
data-display+12.8%vs previous period
Keep the rules. Make the visual language your own.
I wanted Aegis to work as design-system infrastructure. Its default appearance is a starting point: a project profile configures brand, semantic color, typography, shape and density while keeping the underlying interaction contracts intact.
- One profile
- Aegis Original, Atlas Precision and Solstice Studio exercise distinct visual directions through the same compiler.
- Independent axes
- Light and dark remain separate from Fundamental and Fundamental Floating presentation.
- Traceable values
- Profiles feed Primitive → Semantic → Group tokens. Nested components retain the tokens of their own category.
fundamentalfloatingaction.filltrigger.buttonCarry the design language between projects.
A configurable profile became a portable brand package. I added a versioned format and an import workflow that shows what will change before applying it. One package compiles the same language across both presentations in light and dark.
- Preview, then apply
- Validate compatibility, inspect the changed fields and review the compiled result before changing the active profile.
- Exchange decisions
- An explicit mapping imports a supported subset of DTCG 2025.10 tokens. Unsupported expressions are reported; they are never silently approximated.
- Preserve behavior
- The package changes visual identity while retaining component contracts and page recipes. Tokens and contracts are portable; the component implementation remains React.
Portable design language
packageVersion: 1.0.0#356ac3#006c67Give people a reference they can actually inspect.
I shaped Storybook around the questions a designer or engineer brings to a component. Anatomy, usage, states, API details and the authored contract live beside the real implementation, so the documentation explains decisions as well as properties.
- See the parts
- Connect the visible anatomy to the labels used in the component API and token mapping.
- Understand the choice
- Explain which decisions are independent, such as a Button’s intent and emphasis.
- Follow the source
- Keep generated API facts, authored guidance and behavior requirements identifiable.
native-buttonintent="function"emphasis="primary"size="md"Activate an action, with intent independent of emphasis.
Disable activation while loading. Preserve the action’s accessible name.
Choose submit explicitly. Own authorization, events and asynchronous state.
Make the expectations explicit.
An API can tell an agent that a prop exists. It does not explain who owns an asynchronous state, what loading must preserve or when a component is the wrong choice. I added authored contracts to make those obligations available alongside the code.
- Component
- Declare purpose, anatomy, states and invariants that the implementation must preserve.
- Application
- Name the host’s responsibilities, from meaningful labels to persistence and authorization.
- Evidence
- Keep requirements, implementation, linked checks and recorded results separate. A contract is not a certification.
dialog v1
A focused modal task with predictable dismissal and focus return.
Base UI modal interaction, an accessible title and normal focus return.
title-and-descriptionSupply a meaningful title, accepted open state and the async lifecycle.
controlled-openThe code supplies behavior.
API facts describe its props.
openonOpenChangeRun the relevant interaction.
Record inputs and results.
Test the experience where the component is used.
The next step was to connect written expectations to observable behavior. Shared browser checks now exercise push filtering, row density and modal dismissal in both isolated Storybook examples and the Forma application.
- One requirement, several contexts
- The same check measures whether filters reserve space, density changes the actual rows, or Escape returns focus to the opener.
- Recorded evidence
- A recorded build verification passed 72 finite scenarios: nine contexts across two widths, two modes and two presentations. Each run identifies the source, builds and checks used.
- Visible gaps
- The published inventory separately lists seven registered requirements as not run and 1,038 unsupported by this runner. Other tests exist; these numbers describe this specific acceptance layer.
DataGrid density
assertDensityChangesRegistered coverage
- Not run
- 7
- Unsupported
- 1,038
Recorded build run
Finite scenarios passed
Give an agent a route from intent to implementation.
I connected the same catalogue to Storybook, a portable command-line kit and a local MCP adapter. Seven read-only tools now support discovery, project inspection, recipe resolution and validation. Skills guide how an agent uses those facts.
- Behavior before shape
- A side panel could push results or cover them. Curated behavior discovery distinguishes those interactions and surfaces alternatives when the request is ambiguous.
- Resolve the project
- Read the pinned profile and saved recipe, then return the permitted components, bindings and application responsibilities.
- Check the proposal
- Validate the composition and audit product conventions. The two new tools are exposed when the installed kit supports them; the adapter does not edit or release code.
Same catalogue. Same context.
Contracts · profile · registry · project policy
Discover
Find the installed context and intended behavior.
inspect_project_contextsearch_contractsdiscover_by_behaviorCompose
Resolve the project recipe and validate the composition.
resolve_project_recipevalidate_page_recipevalidate_compositionVerify
Audit the product’s declared shared patterns.
audit_product_patternsTurn shared decisions into inputs to the work.
Documentation could describe a consistent product while each new page still made its own choices. I introduced saved project recipes for collection, detail, settings and dashboard pages, so reviewed decisions can guide construction directly.
- Save the choices
- Define headers, filtering behavior, search width, density, record details, reading width and dashboard columns within supported options.
- Resolve the responsibilities
- The recipe returns shared components and bindings alongside state the application must own, such as filters, the selected record and unsaved changes.
- Reject mismatches
- A push-filter recipe cannot quietly become a modal sheet. Unknown settings and unsupported combinations fail validation. Discovery and resolution are deterministic; they do not generate a page.
One project, shared page rules
"collection": {"filters": "push","searchMeasure": "wide","density": "comfortable","details": "side-sheet","narrow": "stack"}Discover by behaviour
Filter a collection beside live results in an in-flow panel that resizes the results.
Consistent components still need coherent pages.
The Forma pilot put the system under product pressure across Dashboard, Users, Products, Invoices and Settings. It first exposed inconsistent page decisions. It now consumes the saved recipe for search, push filtering, initial density, reading width and dashboard columns.
- Construction
- The collection recipe supplies a wide search field, comfortable initial density and an in-flow filtering panel. A person’s later density choice takes precedence.
- Product policy
- Canonical headers, controls and documented exceptions still establish implementation identity. Recipes choose supported behavior; policy checks how it is built.
- Rendered evidence
- The filter panel resizes the results beside it and stacks on a narrow screen. The shared acceptance checks verify that behavior in the actual application.
Manage the people and permissions in your workspace.
The same brief can leave different decisions open.
In the Relay experiment, two agents independently built the Requests page from the same brief, shared shell, product policy and installed kit. Both passed the measured checks. One discarded a cancelled draft; the other kept it.
- Shared inputs
- The experiment controlled the kit, profile, dataset and supplied patterns, rather than comparing unrelated products.
- Unspecified behavior
- The brief required Cancel to close without creating a record. It did not say what should happen when the form reopened.
- Design judgment
- Visual review also found clipped titles and unexplained counts that the passing checks had not identified.
Measured checks passed
Empty draft
Draft discardedMeasured checks passed
Cancelled draft observation
Draft retainedWhat should Cancel preserve?
Grow the system without multiplying interpretations.
TokenInput made the problem concrete. Two independently produced models passed their own tests but disagreed about duplicates, delimiters and confirmation. I used that disagreement to explore how a registry could support a deliberate consolidation.
- Discover first
- Search capabilities, aliases, status and canonical implementations before proposing another component.
- Resolve behavior
- Compare the contracts, choose explicit defaults and variants, then verify the combined implementation.
- Carry the change
- Record version and migration impact. The consolidated TokenInput is implemented and registered experimentally; it is not a stable, owner-approved release.
Reject duplicates
Request correlation.
Atomic value batches.
Ignore duplicates
Skipped-count feedback.
Draft revision checks.
One experimental TokenInput
- Reject by default; an explicit ignore variant.
- Combine request IDs with draft revision checks.
- Preserve failed batches and document migration.
Keep the installed system identifiable.
I extended the experiment beyond composition into operation. A project pins its release, profile and registry; an infrastructure service inventories configuration and prepares maintenance proposals. A shared workspace adds signed releases, reviewed activation and retained history.
- Known context
- Portable kits and exact pins make it possible to trace which decisions a project is using.
- Deliberate observation
- Usage collection starts disabled and requires both project and consumer opt-in. It accepts reviewed technical facts, not page content.
- Controlled change
- Prepare and inspect an update before activation. Rollback creates a new generation while retaining the previous evidence.
Installed project
PinnedObserve deliberately
Inspect broadly. Give repairs precise boundaries.
Expanding self-repair meant first understanding what the system could safely inspect and verify. The catalogue now covers all 127 authored entries, while source repair remains limited to three components with two trusted CSS repair policies.
- Explicit eligibility
- MetricCard and Sparkline share a containment policy. DataGrid has a density policy. The other 124 entries remain manual-review only until a trusted repair policy is added.
- Protect the evidence
- The worker can change only approved CSS. It cannot rewrite the contracts, tests, fixtures or thresholds used to judge the result. Passing a source scan alone never enables a repair.
- Test the test
- The new DataGrid fixture rejected both flattened row heights and hidden content across 16 scenarios. That experiment made zero AI requests: it tested the verifier, not a live AI repair.
Repair coverage
- Inventoried
- 127
- Bounded policy
- 3
- Manual review
- 124
| Component | Source repair |
|---|---|
| MetricCardContainment | Bounded policy |
| SparklineContainment | Bounded policy |
| DataGridDensity | Bounded policy |
| Button | Manual review |
| Modal | Manual review |
A repair should earn the right to become a change.
I separated deterministic repair of generated output from AI proposals that change source. In a controlled experiment, a real Codex request repaired a deliberately seeded MetricCard overflow, then faced the same browser and regression checks as the original implementation.
- Reproduce
- The healthy baseline passed 84 browser scenarios. The seeded CSS defect caused 56 of them to fail.
- Propose and verify
- One proposal removed the excessive minimum width. All 84 scenarios passed again, alongside 429 source tests and the recorded static checks.
- Review
- The result became a review commit. Source changes, merging, release and consumer updates remain separate decisions.
429 source tests · types · token ownership · headless boundaries
The designer’s work extends into the rules of the system.
Aegis Agentic is now a working beta that connects a portable visual language, authored behavior, saved product decisions and executable acceptance. The research moved my focus from making individual components consistent to keeping decisions intact as people and agents build, evaluate and change a product.
- Implemented
- Portable brand packages, explicit token exchange, project recipes and seven read-only tools sit around 124 API families and 127 component and pattern contracts, plus two service protocols.
- Demonstrated
- Forma consumes the shared recipes. A recorded 72-scenario run exercises three behavior families. Independent page and component experiments, and the earlier live MetricCard repair, provide separate evidence.
- Still open
- Framework portability, wider acceptance coverage, broader repair reliability and sustained delivery gains need further work. Inspection across the catalogue is not autonomous repair across the catalogue.
authored behavior
pattern contracts
protocols
Follow the decisions
into the system.
The illustrations focus on selected parts of the implementation. Storybook contains the working components; the repository records the contracts, experiments and their limits.