Skip to content
ADR 0000 Federated Design Infrastructure & Storage Architecture

ADR 0000 Federated Design Infrastructure & Storage Architecture

Andi Lamprecht Andi Lamprecht ·· 6 min read· Draft
ADR-0276 · Author: Oleksii Naboichenko · Date: 2026-03-20 · Products: shared
Originally ADR 0000--Federated Design Infrastructure & Storage Architecture (v1) · Source on Confluence ↗

Our current monolithic Figma workflow has led to divergent component copies across product teams, inconsistent token usage, and an inability for AI agents to resolve a single source of truth. Design-to-code handoff is unreliable because there is no enforceable contract between design artifacts and React implementations.

Design team routinely copy-pasted components and tweak them locally, creating invisible drift that only surfaces during visual QA - often too late to address without significant rework. AI agents operating in this environment cannot determine which variant of a component is canonical, leading to non-deterministic code generation.

Decision Drivers

  • AI agents require deterministic, machine-readable sources; Figma files are opaque.
  • Component drift across products creates visual inconsistency and duplicated engineering effort.
  • Token-level governance is impossible without a version-controlled, CI-enforced pipeline.
  • The design-to-code pipeline must support fully automated code generation with predictable outputs.

Alternatives Considered

OptionRejected Because
Single monorepo for all design + product codeCouples release cycles; product teams can’t ship independently. Blast radius of a bad merge affects all products.
Figma + plugin-based sync (e.g., Tokens Studio)No CI enforcement; drift detection is manual and advisory-only. AI agents cannot reliably parse plugin output.
Package-registry-only model (npm-style distribution)Adds indirection; .pen files need direct Git-resolvable imports for AI context. Loses the ability to do cross-file AST analysis at CI time.

1. The Core Principle: “Centralize System, Localize Composition”

We are moving away from a monolithic Figma file. We are adopting a federated model where the Shared Repo owns the Language and the Product Repo owns the Usage.

2. Storage & Ownership Distribution

To ensure AI agents have the correct context, files must be stored according to these strict boundaries:

A. Shared Design-System Repo (ds-core)

Role: The Library. Defines the “Atomic” building blocks.

ArtifactDescription
TokensAll primitive and semantic JSON definitions.
Shared .lib.pen LibrariesThe source of truth for all base components.
PrimitivesBase shapes and low-level UI elements.
Variants & StatesComprehensive definitions of all component permutations.
React ContractsTypeScript interfaces that the AI must satisfy.
AI PromptsThe “System Instructions” for how agents should interpret these components.
Governance DocsRules for when to promote a local component to a shared one.

Versioning: ds-core follows semver. Product repos pin to a minor range (e.g., ~2.3.0) in a pen.lock or equivalent manifest. Major bumps require explicit opt-in. The Guardian Agent blocks builds if a product repo references a deprecated or yanked component version.

Dependency Resolution: .pen imports resolve via a Git submodule or package reference. The chosen mechanism must support offline resolution and deterministic builds. While a registry URL may be used as a fallback resolution path, the primary import mechanism must remain Git-resolvable so AI agents can perform cross-file AST analysis.

B. Product Repos (app-dashboard, app-mobile, etc.)

Role: The Implementation. Defines the “Molecular” and “Organism” layouts.

ArtifactDescription
ScreensFull-page layouts constructed from shared primitives.
FlowsMulti-screen logic and navigation paths.
Feature CompositionsHigh-level UI patterns unique to that product (e.g., a specific “Analytics Widget”).
Product-Specific ExceptionsDeliberate, reviewed deviations from the system.
Generated React CodeThe output of the AI Codegen agent.
Stories & TestsAutomated UI tests (Storybook) for the product-specific compositions.

Generated Code Ownership: Files in /components/generated are machine-owned. Manual edits are overwritten on regeneration. If a developer needs to customize generated output, they must wrap it in a handwritten component under /components/composed and never modify the generated file directly.

3. Ownership Boundary: Definition vs. Composition (“The Usage Rule”)

  • The Shared Repo owns the “What”: What is a Button? What color is Primary?
  • The Product Repo owns the “Where”: Where does the Button go on the Login screen?

Non-Negotiable: A product repo can create a DashboardHeader.pen (composition), but it cannot redefine Button.pen (primitive). If a product team needs a new “type” of button, they must submit a PR to the ds-core repo.

Token Resolution Order

Product repos may define theme-level overrides (e.g., dark mode mappings) but must not redefine primitive token values.

ds-core/tokens/primitive       →  Base values (color-blue-500: #3B82F6)
ds-core/tokens/semantic        →  Mapped meanings (color-primary: {primitive.color-blue-500})
product-repo/tokens/theme      →  Scoped overrides (color-primary: {primitive.color-indigo-500})
                                   ↑ Only semantic-tier remapping allowed.
                                     Primitive-tier keys must never be shadowed.

The Guardian Agent validates that no product-level token shadows a primitive-tier key.

4. Technical Rule: “No Silent Local Forks”

One of the primary failure points in our current Figma workflow is “copy-pasting a component and tweaking it locally.”

Pencil.dev Enforcement: Product-level .pen files should only reference the .lib.pen from the shared repo.

CI Detection Mechanism

The Guardian Agent runs a pen lint --no-local-shadows check during CI. It compares the AST of every .pen file in the product repo against the ds-core component registry. A match on component name + category (not content hash) triggers a hard failure with an auto-generated message:

❌ LOCAL_FORK_DETECTED: `Button.pen` in /design/components/
   shadows `ds-core/primitives/Button.lib.pen`.
   → Import: `@use "ds-core/primitives/Button.lib.pen"`
   → Or submit an extension PR:
     https://github.com/org/ds-core/issues/new?template=primitive-extension

5. Revised AI Pipeline for Storage Logic

The AI Agents are now “Repo-Aware”:

  • The Architect Agent sits in the Product Repo. It looks at the local Flow.pen and the imported ds-core library to generate the layout code.
  • The Reviewer Agent checks if a Product-Specific Exception is actually a new “Primitive” in disguise. If it detects a recurring pattern, it triggers an “Extraction Ticket” to move that pattern into the Shared Repo.

Extraction Threshold & Process

The Reviewer Agent uses a 3-screen / 2-product threshold:

  • A composition qualifies for extraction when it appears in ≥3 screens within one product, OR
  • it appears in ≥1 screen in each of ≥2 different product repos.

The agent opens an Extraction Ticket in ds-core containing:

  • Usage locations (file paths + screenshots)
  • Proposed prop interface
  • Diff from nearest existing primitive

SLA: DesignOps must triage extraction tickets within 5 business days. Until promoted, the composition remains product-owned.

6. Definition of Done (Storage Focus)

A feature is not “Done” until:

  • All primitives used are imported from ds-core.
  • The screen composition lives in the Product Repo’s /design folder as a .pen file.
  • The generated React code lives in the Product Repo’s /components/generated folder.
  • No raw values (hex/px) exist in the local product files.
  • Storybook stories exist for all product-specific compositions.
  • The Guardian Agent CI check passes with zero warnings.

7. Breaking Change & Deprecation Policy

When a shared primitive changes its prop contract or visual output:

  1. The old version is marked @deprecated in the .lib.pen metadata with a migration note.
  2. A compatibility window of 2 minor releases is maintained (both old and new coexist).
  3. The Guardian Agent emits warnings during the window; after expiry, it fails builds.
  4. The AI Architect Agent is updated to generate code against the new contract only after the compatibility window opens.

Consequences

Positive

  • Single source of truth for AI agents enables deterministic code generation.
  • CI-enforced consistency eliminates silent component drift.
  • Product teams retain full composition autonomy within clear guardrails.
  • Clear ownership boundaries reduce cross-team ambiguity and design review overhead.

Negative

  • Higher onboarding cost for product teams unfamiliar with the federated model.
  • PR friction for new primitive requests against ds-core may slow teams initially.
  • Requires Guardian Agent infrastructure investment before enforcement is possible.
  • Cross-repo dependency chain introduces versioning complexity that must be actively managed.

Neutral

  • Extraction Ticket workflow creates a new process that needs cultural adoption.
  • Theme-override scoping rules require documentation and team education.

Appendix: Open Questions

  1. Submodule vs. package reference: Which resolution mechanism should be the default? Needs a spike with the DevEx team.
  2. Multi-brand theming: If a product repo serves multiple brands, does the token override cascade need an additional tier?
Last updated on