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-consoleMCPPull raw node tree, bindings, and property definitions.
Author JSON contract
Capture anatomy, tokens, states, variants, and anomalies.
Lint gate one
verify_all.pyvalidates 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-consoleMCPPull raw node tree, bindings, and property definitions.
Author JSON contract
Capture anatomy, tokens, states, variants, and anomalies.
Lint gate one
verify_all.pyvalidates 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.
