SYSTEM DESIGN

FRONT-END DEVELOPMENT

Shifting the paradigm from canvas to codebase

A UX-led migration of OpenText's Design System into a repo-native, agentic authoring workflow.

  • Suggested insights
    Identify Figma source node

    Select Blueprint V1 component flagged for migration.

    Extract via figma-console MCP

    Pull raw node tree, bindings, and property definitions.

    Author JSON contract

    Capture anatomy, tokens, states, variants, and anomalies.

    Lint gate one

    verify_all.py validates node integrity against token dictionary.

    ksc-usecase-card.contract.json

    {

    "component": "ksc-usecase-card",

    "type": "component",

    "version": "1.2.0",

    "anatomy": {

    "root": "card-container",

    "elements": ["heading", "body", "cta"]

    },

    "boundVariables": {

    "cta.background": "var(--aurora-action-primary-background)",

    "cta.text": "var(--aurora-action-primary-text)",

    "body.spacing": "var(--space-md)"

    },

    "states": ["default", "hover", "focus"],

    "verified": true

    }

    Jira insights — migration pipeline
    Avg. ticket turnover

    Last 90 days

    Time from ticket open to merge.

    Basline

    4.2 days

    Current

    2.1 days

    Delta

    50%

    Weekly cycle time

    Baseline

    Post-Workflow

    W1

    W2

    W3

    W4

    W5

    W6

    W7

    W8

    verify_all.py - lint gate two

    #Card-useCase

    1 issue detected

    Status: Failed

    Rule violated

    Hardcoded value in slot bound to a semantic token in the dictionary.

    background: #FF6B35;

    background: var(--aurora-action-primary-background);

    ksc-usecase-card.module.css : line 24

  • Suggested insights
    Identify Figma source node

    Select Blueprint V1 component flagged for migration.

    Extract via figma-console MCP

    Pull raw node tree, bindings, and property definitions.

    Author JSON contract

    Capture anatomy, tokens, states, variants, and anomalies.

    Lint gate one

    verify_all.py validates node integrity against token dictionary.

    ksc-usecase-card.contract.json

    {

    "component": "ksc-usecase-card",

    "type": "component",

    "version": "1.2.0",

    "anatomy": {

    "root": "card-container",

    "elements": ["heading", "body", "cta"]

    },

    "boundVariables": {

    "cta.background": "var(--aurora-action-primary-background)",

    "cta.text": "var(--aurora-action-primary-text)",

    "body.spacing": "var(--space-md)"

    },

    "states": ["default", "hover", "focus"],

    "verified": true

    }

    Jira insights — migration pipeline
    Avg. ticket turnover

    Last 90 days

    Time from ticket open to merge.

    Basline

    4.2 days

    Current

    2.1 days

    Delta

    50%

    Weekly cycle time

    Baseline

    Post-Workflow

    W1

    W2

    W3

    W4

    W5

    W6

    W7

    W8

    verify_all.py - lint gate two

    #Card-useCase

    1 issue detected

    Status: Failed

    Rule violated

    Hardcoded value in slot bound to a semantic token in the dictionary.

    background: #FF6B35;

    background: var(--aurora-action-primary-background);

    ksc-usecase-card.module.css : line 24

Solution summary (TL;DR)

Solution summary (TL;DR)

OpenText's Blueprint V1 design system had reached an inflection point. What was once a flagship Figma library serving as a centralized source of truth for the brand's atomic makeup had steadily drifted due to its inability to scale at the pace of rapid development.

Necessary maintenance protocols such as auditing for redundancies, identifying informed use cases for net new patterns, and spec documentation fell into the hands of a UX team already operating at capacity upstream, resulting in a forced culture of ad-hoc updates and a steadily growing queue of undocumented conventions.

With the organization setting its sights on a revitalized Design System as a bi-product of a wider brand restructure in 2026, my role as Lead UX Designer of AI-Enabled Systems was collaborating with Front-End engineering teams to conceptualize and implement an agentic two-stage migration workflow that automated the transition from canvas to codebase.

Learn how we reduced Jira ticket turnover windows by approximately 50% with a code-first framework that positioned Storybook as our unified source of truth for extraction and scale, increasing determinism, eliminating rogue LLM interpretation, and enabling rapid refinement and scale.

OpenText's Blueprint V1 design system had reached an inflection point. What was once a flagship Figma library serving as a centralized source of truth for the brand's atomic makeup had steadily drifted due to its inability to scale at the pace of rapid development.

Necessary maintenance protocols such as auditing for redundancies, identifying informed use cases for net new patterns, and spec documentation fell into the hands of a UX team already operating at capacity upstream, resulting in a forced culture of ad-hoc updates and a steadily growing queue of undocumented conventions.

With the organization setting its sights on a revitalized Design System as a bi-product of a wider brand restructure in 2026, my role as Lead UX Designer of AI-Enabled Systems was collaborating with Front-End engineering teams to conceptualize and implement an agentic two-stage migration workflow that automated the transition from canvas to codebase.

Learn how we reduced Jira ticket turnover windows by approximately 50% with a code-first framework that positioned Storybook as our unified source of truth for extraction and scale, increasing determinism, eliminating rogue LLM interpretation, and enabling rapid refinement and scale.

State of the system

Blueprint V1 was born inside Figma at a time when the discipline of maintaining a canonical library required the maintenance itself to live inside the file. Every component our product surfaces referenced traced back to a master node, and every net-new pattern was authored, versioned, and documented in-canvas by the UX team. Compounding the drift, the underlying V1 Front-End rested on custom CSS with no utility foundation, no shared token dictionary, and no formal nomenclature to distinguish a component (a single reusable atomic unit) from a pattern (a compositional arrangement of several components serving a specific job). Designers and engineers applied the same term to structurally different constructs across working conversations, resulting in ambiguity that made system authoring harder to reason about and harder to scale in any consistent direction.

Blueprint V1 was born inside Figma at a time when the discipline of maintaining a canonical library required the maintenance itself to live inside the file. Every component our product surfaces referenced traced back to a master node, and every net-new pattern was authored, versioned, and documented in-canvas by the UX team. Compounding the drift, the underlying V1 Front-End rested on custom CSS with no utility foundation, no shared token dictionary, and no formal nomenclature to distinguish a component (a single reusable atomic unit) from a pattern (a compositional arrangement of several components serving a specific job). Designers and engineers applied the same term to structurally different constructs across working conversations, resulting in ambiguity that made system authoring harder to reason about and harder to scale in any consistent direction.

Audit existing patterns

Deprioritized

Review the current library for redundancies, discrepancies, and components that have drifted from production repo.

Direct to deployment

Active

Steps 1, 2, 3 and 5 are bypassed for launch compression. Components ship without preceding audits, iteration cycles, or post-deployment documentation.

Market research

Deprioritized

Evaluative market research, scaling proposed UI pattern against best-in-class conventions through Claude web search.

Direct to deployment

Active

Steps 1, 2, 3 and 5 are bypassed for launch compression. Components ship without preceding audits, iteration cycles, or post-deployment documentation.

Preliminary creative exploration

Reduced to ad-hoc

Explore, prototype, and refine proposed solutions against distilled audit findings.

Direct to deployment

Active

Steps 1, 2, 3 and 5 are bypassed for launch compression. Components ship without preceding audits, iteration cycles, or post-deployment documentation.

Dev deployment

Active

Approved patterns are built and migrated into the codebase as HTML / CSS files.

Undocumented conventions accommulate

Active

Ad-hoc updates replace structured maintenance. The delta between the system;s canonical version and its live implementation continuously widens.

Spec documentation

Deprioritized

Post-deployment documentation, owned by UX to capture anatomy, usage guardrails and variant property structure.

The UX team operated at capacity upstream. Maintenance protocols were known and defined but could not be sustained at the pace of development.

Audit existing patterns

Deprioritized

Review the current library for redundancies, discrepancies, and components that have drifted from production repo.

Market research

Deprioritized

Evaluative market research, scaling proposed UI pattern against best-in-class conventions through Claude web search.

Preliminary creative exploration

Reduced to ad-hoc

Explore, prototype, and refine proposed solutions against distilled audit findings.

Dev deployment

Active

Approved patterns are built and migrated into the codebase as HTML / CSS files.

Spec documentation

Deprioritized

Post-deployment documentation, owned by UX to capture anatomy, usage guardrails and variant property structure.

Market research

Deprioritized

Evaluative market research, scaling proposed UI pattern against best-in-class conventions through Claude web search.

Preliminary creative exploration

Reduced to ad-hoc

Explore, prototype, and refine proposed solutions against distilled audit findings.

Audit existing patterns

Deprioritized

Review the current library for redundancies, discrepancies, and components that have drifted from production repo.

Dev deployment

Active

Approved patterns are built and migrated into the codebase as HTML / CSS files.

Spec documentation

Deprioritized

Post-deployment documentation, owned by UX to capture anatomy, usage guardrails and variant property structure.

Direct to deployment

Active

Steps 1, 2, 3 and 5 are bypassed for launch compression. Components ship without preceding audits, iteration cycles, or post-deployment documentation.

Undocumented conventions accommulate

Active

Ad-hoc updates replace structured maintenance. The delta between the system;s canonical version and its live implementation continuously widens.

The UX team operated at capacity upstream. Maintenance protocols were known and defined but could not be sustained at the pace of development.

Direct to deployment

Active

Steps 1, 2, 3 and 5 are bypassed for launch compression. Components ship without preceding audits, iteration cycles, or post-deployment documentation.

Undocumented conventions accommulate

Active

Ad-hoc updates replace structured maintenance. The delta between the system;s canonical version and its live implementation continuously widens.

The UX team operated at capacity upstream. Maintenance protocols were known and defined but could not be sustained at the pace of development.

My mandate was to lead the UX team through the transition architecturally: identifying the workflow efficiencies that would smooth the transfer of authoring conventions from Figma into the codebase, and co-designing, in collaboration with Front-End engineering, the workflows that would allow designers to operate confidently inside a repo-native environment without being asked to adopt the traditional obligations of a software engineer.

My mandate was to lead the UX team through the transition architecturally: identifying the workflow efficiencies that would smooth the transfer of authoring conventions from Figma into the codebase, and co-designing, in collaboration with Front-End engineering, the workflows that would allow designers to operate confidently inside a repo-native environment without being asked to adopt the traditional obligations of a software engineer.

Contracts before code: the migration workflow

Conventional practice, when converting a Figma component into code, is to prompt an LLM into interpretation of the source file. Interpretation is the layer where rogue LLM behaviour, hallucinated tokens, and hardcoded values are introduced, and no volume of prompt engineering adequately resolves what is fundamentally a structural problem. The migration workflow we architected removes the interpretation step altogether by inserting a machine-checkable intermediary between Figma and the React code that references it: a JSON contract, authored into token-dictionary/contracts/, that captures a component's real anatomy, its live token bindings, its property definitions, and any known anomalies in the source file. Every downstream step is verified against the contract rather than against the LLM's evolving memory and subjective assessment of a component's appearance and usage.

Conventional practice, when converting a Figma component into code, is to prompt an LLM into interpretation of the source file. Interpretation is the layer where rogue LLM behaviour, hallucinated tokens, and hardcoded values are introduced, and no volume of prompt engineering adequately resolves what is fundamentally a structural problem. The migration workflow we architected removes the interpretation step altogether by inserting a machine-checkable intermediary between Figma and the React code that references it: a JSON contract, authored into token-dictionary/contracts/, that captures a component's real anatomy, its live token bindings, its property definitions, and any known anomalies in the source file. Every downstream step is verified against the contract rather than against the LLM's evolving memory and subjective assessment of a component's appearance and usage.

Figma source

Legacy Blueprint V1 component identified in the existing Figma library and flagged for migration into Storybook.

Extract source (transition)

Live extraction

Figma-console MCP, running via Figma's Desktop Bridge Plugin API, pulls the raw node tree, every boundVariables binding, and every componentPropertyDefinitions entry directly from the source file. Bypasses the pre-resolved output of the official Figma MCP to preserve raw evidence for verification.

Author against extraction (transition)

JSON contract authoring

Claude Code authors a structured contract into token-dictionary/contracts/, capturing the component's anatomy, live token bindings, states, real variants, and any known anomalies in the source.

Contract complete (gate)

Lint gate one

Verify_all.py runs a paired verification, validating the generated token CSS and the contract's internal integrity against the token dictionary before a single line of React is written.

Lint pass required (gate)

Component build

Claude Code, working directly in the repo, authors the React .tsx implementation and its scoped CSS module against the contract, alongside a matching Storybook stories file.

Render in browser (transition)

Browser render check

The built component renders in a live browser session and is compared, element by element, against a Figma screenshot of the same node captured through the figma-console MCP.

Parity confirmed (gate)

Lint gate two

Verify_all.py runs a second time, re-checking the finished component against its contract and its rendered output. Any deviation returns the component to Node 5 for correction.

Clean pass (gate)

Merge to Storybook

Clean-pass component merges into the shared Storybook library through GitHub, four files intact: contract, .tsx, CSS module, and stories file.

Correction loop

The pipeline moves through eight sequential steps: live extraction, contract authoring, first lint gate, component build in React and Storybook, browser render check against a Figma screenshot, second verification pass, correction loop for any deviation, and merge into Storybook. Extraction is executed through the figma-console MCP via Figma's Desktop Bridge Plugin API, deliberately bypassing the pre-resolved output of the official Figma MCP so that raw evidence remains available for downstream verification. The first lint gate runs verify_all.py, pairing two checks: one validating the generated token CSS, and one validating the component's markup against its own contract. Only a clean pass merges.

During the migration of #ksc-usecase-card, live extraction returned every bound token binding from the source file, and a JSON contract authoring against the extraction. At the component build step, the LLM's initial React implementation introduced a hardcoded hex value on the card's primary call-to-action background; a slot where the contract had explicitly bound the value to var(--aurora-action-primary-background), a semantic token from the Aurora theme extension. This triggered the first lint gate, flagging the raw hex against our rule that no hardcoded value is permitted in any slot where a semantic token already exists in the dictionary. The contract supplied the correct binding, offered a mechanical resolution, and the corrected build cleared the second verification pass by matching the Figma node and merged.

The pipeline moves through eight sequential steps: live extraction, contract authoring, first lint gate, component build in React and Storybook, browser render check against a Figma screenshot, second verification pass, correction loop for any deviation, and merge into Storybook. Extraction is executed through the figma-console MCP via Figma's Desktop Bridge Plugin API, deliberately bypassing the pre-resolved output of the official Figma MCP so that raw evidence remains available for downstream verification. The first lint gate runs verify_all.py, pairing two checks: one validating the generated token CSS, and one validating the component's markup against its own contract. Only a clean pass merges.

During the migration of #ksc-usecase-card, live extraction returned every bound token binding from the source file, and a JSON contract authoring against the extraction. At the component build step, the LLM's initial React implementation introduced a hardcoded hex value on the card's primary call-to-action background; a slot where the contract had explicitly bound the value to var(--aurora-action-primary-background), a semantic token from the Aurora theme extension. This triggered the first lint gate, flagging the raw hex against our rule that no hardcoded value is permitted in any slot where a semantic token already exists in the dictionary. The contract supplied the correct binding, offered a mechanical resolution, and the corrected build cleared the second verification pass by matching the Figma node and merged.

In collaboration with engineering, we finalized the four-file scaffold every migrated component now ships with: a JSON contract, a .tsx React implementation, a scoped CSS module, and a Storybook stories file. The scaffold ensures each component is optimized for Storybook hosting rather than delivered as an isolated HTML and CSS artifact, giving the migration a consistent target for every step in the pipeline to be measured against. The React implementation serves as the shipped component itself, featuring props and markup, no content baked in, imported wherever the component is used in production. The stories file lives only in Storybook, feeding the component real sample copy from the JSON contract and carrying the play-function assertions that double as its regression tests, allowing stakeholders to add content and experiment with attached props to stress test it in a visual environment.

In collaboration with engineering, we finalized the four-file scaffold every migrated component now ships with: a JSON contract, a .tsx React implementation, a scoped CSS module, and a Storybook stories file. The scaffold ensures each component is optimized for Storybook hosting rather than delivered as an isolated HTML and CSS artifact, giving the migration a consistent target for every step in the pipeline to be measured against. The React implementation serves as the shipped component itself, featuring props and markup, no content baked in, imported wherever the component is used in production. The stories file lives only in Storybook, feeding the component real sample copy from the JSON contract and carrying the play-function assertions that double as its regression tests, allowing stakeholders to add content and experiment with attached props to stress test it in a visual environment.

The code-first horizon: post migration workflow

Once every Blueprint V1 component has moved through it, a second workflow is in development to take over. Figma is no longer the default entry point for new work; it becomes a tertiary exploration surface, reserved for highly stateful patterns whose logic is more efficiently reasoned about visually, of which the navigation mega-menu is our present example. Everything else begins in the codebase.

Once every Blueprint V1 component has moved through it, a second workflow is in development to take over. Figma is no longer the default entry point for new work; it becomes a tertiary exploration surface, reserved for highly stateful patterns whose logic is more efficiently reasoned about visually, of which the navigation mega-menu is our present example. Everything else begins in the codebase.

Content brief

Content team delivers new material for a page or surface.

Pattern research config

Research

Best-in-class interaction pattern audit via Mobbin MCP, contextual to where the content will live, appended by existing insights from live pages via Microsoft Clarity.

Prompt drafting

Claude in repo

React component drafted directly against the codebase, lands in Storybook on a feature branch.

First draft review

UX audit

Design intent reviewed against the drafted component; iterations proposed if required by stakeholders.

Formalize spec docs

JSON contract

Contract authored or updated to reflect the finalized structure, lives inside the component folder as persistent reference.

Front-End handoff

Front-End fine-tune

Implementation polished in the same branch, contract-aligned.

QA gate

QA and staging

Component validated in staging before release.

Correction loop

The second, post-migration workflow remains under development and is slated to be put into production by October 2026. When operational, the sequence will adhere to a predictable arc, with the one difference being democratized use cross-functionally. Content teams will deliver new material for a page. Mobbin, accessed via MCP, is queried by UX for best-in-class interaction pattern precedents. Microsoft Clarity is consulted simultaneously against the outgoing page, with scroll, click and attention data being triangulated to determine which content warrants prioritization, compression, or elimination entirely. A standardized template prompt will then be used to ask Claude, working directly in the repo, to draft a React component reflecting the intended treatment and visual language of the existing system; the component then lands in Storybook on a feature branch. UX audits the result, the corresponding JSON contract is authored or updated to reflect finalized structure, with Front-End fine-tuning the implementation in the same branch before the component proceeds through QA, staging, and final production.

Notably, the JSON contract's role shifts between the two workflows. In the migration workflow, it operates as a precondition to code: authored and verified before any implementation exists. Post-migration, it lives inside each component's own folder and is kept in lockstep with every subsequent edit; a persistent, structured reference that an LLM will parse before proceeding with an existing implementation, ensuring a fresh interpretation of the underlying code cannot reintroduce the rogue interpretation risk the project set out to eliminate.

The second, post-migration workflow remains under development and is slated to be put into production by October 2026. When operational, the sequence will adhere to a predictable arc, with the one difference being democratized use cross-functionally. Content teams will deliver new material for a page. Mobbin, accessed via MCP, is queried by UX for best-in-class interaction pattern precedents. Microsoft Clarity is consulted simultaneously against the outgoing page, with scroll, click and attention data being triangulated to determine which content warrants prioritization, compression, or elimination entirely. A standardized template prompt will then be used to ask Claude, working directly in the repo, to draft a React component reflecting the intended treatment and visual language of the existing system; the component then lands in Storybook on a feature branch. UX audits the result, the corresponding JSON contract is authored or updated to reflect finalized structure, with Front-End fine-tuning the implementation in the same branch before the component proceeds through QA, staging, and final production.

Notably, the JSON contract's role shifts between the two workflows. In the migration workflow, it operates as a precondition to code: authored and verified before any implementation exists. Post-migration, it lives inside each component's own folder and is kept in lockstep with every subsequent edit; a persistent, structured reference that an LLM will parse before proceeding with an existing implementation, ensuring a fresh interpretation of the underlying code cannot reintroduce the rogue interpretation risk the project set out to eliminate.

Naming as architecture

The naming problem served as a blocker for semantically classifying elements in groups within Storybook. Every component and pattern name in V1 reflected its appearance, not its use. Appearance-based nomenclature offers designers almost no context for when to reach for a given component, and the name itself breaks as its content and extended use cases evolve.

The naming problem served as a blocker for semantically classifying elements in groups within Storybook. Every component and pattern name in V1 reflected its appearance, not its use. Appearance-based nomenclature offers designers almost no context for when to reach for a given component, and the name itself breaks as its content and extended use cases evolve.

Research findings - naming convention audit
Anatomy of three published conventions

A competitive audit of Atlassian, IBM Carbon and Nord Design systems.

Prefix

Component

Modifier

State

Prop

Atlassian Design System

PascalCase Component + appearance prop

React Import

Button

Component

CSS Classs

aui

button

primary

React Import

appearance="primary"

appearance="subtle"

appearance="link"

appearance="warning"

IBM Carbon

PascalCase Component + kind prop

React Import

Button

Component

Compound

primary

Modifier

button

Base noun

CSS Class

cds

btn

primary

Variants

kind="primary"

kind="secondary"

kind="tertiary"

kind="ghost"

kind="warning"

Nord Health

Three-prefix system

Web Component

nord

Prefix

Button

Component

Modifier Class

.n

Prefix

button

Base noun

primary

Modifier

State Class

.is

State Prefix

loading

Status

React Import

kind="primary"

kind="secondary"

kind="tertiary"

kind="ghost"

kind="warning"

State (hover, focus, disabled, active, loading) is a switch on the component, expressed through props or a dedicated state class. Component state is never encoded into the component name.

Research of three leading Design Systems informed our syntax resolution, cross-referencing the conventions of Atlassian, IBM Carbon, and Nord Health directly. Atlassian's convention followed [Modifier] [Base Noun], with each meaningfully different component receiving its own dedicated name. IBM Carbon's shipped code adopted [Modifier][BaseNoun], favouring a single component with built-in options wherever variance is cosmetic rather than structural. Nord Health applied {prefix}-{name}, with modifiers applied through a separate class and states granted their own distinct prefix. Convergence occurred on one rule across these three systems: state, whether hover, focus, disabled, active, or loading, would serve as a switch on the component and never be directly encoded into the name itself.

Keystone's grammar, adopted for the new system's component library, is #ksc or #ksp followed by the modifier, followed by a base noun. #ksc denotes a component; #ksp denotes a pattern. The modifier's role is to distinguish a component variant from its siblings. The base noun is what the object fundamentally is, and it survives a full content swap without requiring rename. This nomenclature is supported through a three-layer token architecture that grants semantic names their assigned values: a Tailwind CSS foundation of variables at the base, a Themes semantic layer of variables aliasing them, and per-sub-brand theme extensions (Aurora, OT Digital, and Cyber Security) that inherit the Themes collection, with stylistic overrides where necessary.

Research of three leading Design Systems informed our syntax resolution, cross-referencing the conventions of Atlassian, IBM Carbon, and Nord Health directly. Atlassian's convention followed [Modifier] [Base Noun], with each meaningfully different component receiving its own dedicated name. IBM Carbon's shipped code adopted [Modifier][BaseNoun], favouring a single component with built-in options wherever variance is cosmetic rather than structural. Nord Health applied {prefix}-{name}, with modifiers applied through a separate class and states granted their own distinct prefix. Convergence occurred on one rule across these three systems: state, whether hover, focus, disabled, active, or loading, would serve as a switch on the component and never be directly encoded into the name itself.

Keystone's grammar, adopted for the new system's component library, is #ksc or #ksp followed by the modifier, followed by a base noun. #ksc denotes a component; #ksp denotes a pattern. The modifier's role is to distinguish a component variant from its siblings. The base noun is what the object fundamentally is, and it survives a full content swap without requiring rename. This nomenclature is supported through a three-layer token architecture that grants semantic names their assigned values: a Tailwind CSS foundation of variables at the base, a Themes semantic layer of variables aliasing them, and per-sub-brand theme extensions (Aurora, OT Digital, and Cyber Security) that inherit the Themes collection, with stylistic overrides where necessary.

Original nomenclature
#Card-useCase

#Card-useCase

#Three-pillar

#Three-pillar

#Compare

#Compare

Revised nomenclature
#ksc-usecase-card

#ksc-usecase-card

#ksp-narrative-pillars

#ksp-narrative-pillars

#ksp-catpositioning-argument

#ksp-catpositioning-argument

Obtsacles and Iteration: Extended collection overrides

During the migration of Aurora-themed components, the pipeline surfaced a 47% error rate across the token dictionary; 23 of 53 checkable Aurora tokens were returning incorrect values, consistently resolving against the base Themes collection rather than Aurora's own extended overrides. The root cause traced upstream to how the figma-console MCP handled extended collections in Figma, where Aurora's mode-level overrides were invisible to the extraction layer entirely. After raising the constraint directly with TJ Pietre, founder of Southleft and creator of the MCP, the fix shipped in v1.40.6, with TJ crediting the discovery in the GitHub release. Three compounding extraction bugs surfaced during the same investigation were corrected independently in the pipeline's own scripts.

During the migration of Aurora-themed components, the pipeline surfaced a 47% error rate across the token dictionary; 23 of 53 checkable Aurora tokens were returning incorrect values, consistently resolving against the base Themes collection rather than Aurora's own extended overrides. The root cause traced upstream to how the figma-console MCP handled extended collections in Figma, where Aurora's mode-level overrides were invisible to the extraction layer entirely. After raising the constraint directly with TJ Pietre, founder of Southleft and creator of the MCP, the fix shipped in v1.40.6, with TJ crediting the discovery in the GitHub release. Three compounding extraction bugs surfaced during the same investigation were corrected independently in the pipeline's own scripts.

Before v1.40.6

Sizing gaps

Resolving --aurora-action-primary-background

Aurora extension

34 real overrides on shared variable IDs

Not found

Themes semantic layer

Fallthrough returns base value instead of override

Fallthrough

Tailwind foundation

407 variables

Not reached

Resolved against Themes, not Aurora
Returned: #1E40AF (wrong)

23

Incorrect

2

Missing

47%

Error rate

After v1.40.6

Override visible

Resolving --aurora-action-primary-background

Aurora extension

Override: #FF6B35 (overridden)

Override found

Themes semantic layer

Base value correctly bypassed

Inherited

Tailwind foundation

407 variables

Not reached

Resolved correctly against Aurora
Returned: #FF6B35 (correct)

23

Correct

0

Missing

0%

Error rate

Obtsacles and Iteration: Min and max width extraction

A separate extraction gap emerged when the pipeline consistently failed to capture min-width and max-width constraints from Figma components, producing contracts whose sizing boundaries were omitted entirely from the JSON output. The downstream cost surfaced during the build of ksc-step-process-list, whose sizing chain collapsed in CSS because the slot's horizontal constraint and the row's fixed width were never recorded during extraction. After flagging the issue to TJ directly, the fix shipped in v1.40.8, extending min/max width and height capture across all JSON extraction paths and introducing a parity check that flags when a constraint present in Figma is absent from the generated code. Both releases credited the discoveries directly, with TJ attributing each fix to constraints surfaced through the migration workflow.

A separate extraction gap emerged when the pipeline consistently failed to capture min-width and max-width constraints from Figma components, producing contracts whose sizing boundaries were omitted entirely from the JSON output. The downstream cost surfaced during the build of ksc-step-process-list, whose sizing chain collapsed in CSS because the slot's horizontal constraint and the row's fixed width were never recorded during extraction. After flagging the issue to TJ directly, the fix shipped in v1.40.8, extending min/max width and height capture across all JSON extraction paths and introducing a parity check that flags when a constraint present in Figma is absent from the generated code. Both releases credited the discoveries directly, with TJ attributing each fix to constraints surfaced through the migration workflow.

Before v1.40.8

Sizing gaps

ksc-step-process-list.contract.json

12

12

“part”: “steplist”,

“part”: “steplist”,

13

13

“layoutSizingHorizontal”: “HUG”,

“layoutSizingHorizontal”: “HUG”,

14

14

“itemSpacing”: “spacing/4”,

“itemSpacing”: “spacing/4”,

// minWidth: 320

// minWidth: 320

Not captured

Not captured

// maxWidth: —

// maxWidth: —

Not captured

Not captured

// minHeight: —

// minHeight: —

Not captured

Not captured

// maxHeight: —

// maxHeight: —

Not captured

Not captured

15

15

“layoutMode”: “VERTICAL”

“layoutMode”: “VERTICAL”

Sizing chain collapsed in CSS

Slot rendered as shrink-to-fit. Row content drove total width instead of container constraints. List collapsed from 672px to 311px with short content.

After v1.40.8

Full extraction

ksc-step-process-list.contract.json

12

12

“part”: “steplist”,

“part”: “steplist”,

13

13

“layoutSizingHorizontal”: “FILL”,

“layoutSizingHorizontal”: “FILL”,

14

14

“itemSpacing”: “spacing/4”,

“itemSpacing”: “spacing/4”,

15

15

“minWidth”: “container/3xs”,

“minWidth”: “container/3xs”,

Captured

Captured

16

16

“maxWidth”: “container/lg”,

“maxWidth”: “container/lg”,

Captured

Captured

17

17

“minHeight”: “auto”,

“minHeight”: “auto”,

Captured

Captured

18

18

“maxHeight”: “none”,

“maxHeight”: “none”,

Captured

Captured

19

19

“layoutMode”: “VERTICAL”

“layoutMode”: “VERTICAL”

Sizing chain intact

Slot stretches to root width. Row fills slot. List holds at container width regardless of content length.

v1.40.8 parity check

v1.40.8 parity check

minWidth in Figma

minWidth in Figma

✓ Present in JSON

✓ Present in JSON

maxWidth in Figma

maxWidth in Figma

✓ Present in JSON

✓ Present in JSON

Sizing mode

Sizing mode

✓ FIXED / HUG / FILL

✓ FIXED / HUG / FILL

What's next?

Initial test cases have shown the workflow contributing to a 50% reduction in Jira ticket completion windows for rapid prototyping tasks, with designers being afforded more time to move upstream into more exploratory work; enabling dual-agile work streams where the pipeline operates deterministically via agents in one lane, with humans investigates net-new design challenges alongside it.

Initial test cases have shown the workflow contributing to a 50% reduction in Jira ticket completion windows for rapid prototyping tasks, with designers being afforded more time to move upstream into more exploratory work; enabling dual-agile work streams where the pipeline operates deterministically via agents in one lane, with humans investigates net-new design challenges alongside it.