James Coombs is a design engineer who built a design engineering function from scratch as a one-person team at a mid-size SaaS company. 60 components, 12 CODEOWNERS paths (more than any other individual in the file), zero legacy imports inside the migrated scope.
I built a design engineering function from scratch at a mid-size SaaS company. 60-component design system and its migration tooling, ~1,800 lines of codified rules, hooks, and tests, 35 reusable skills adopted by other engineers. 18 months, one person, no formal mandate.
The system works. The function was never recognized. My name is on 12 CODEOWNERS paths, more than any other individual in the file and the only whole package tree owned by a person rather than a team handle. The work is real; the org chart doesn't reflect it.
Here's what I'd keep and what I'd do differently.
What worked
Data-driven automation over manual guides
962 legacy framework files across dozens of packages. I started writing a migration guide. Within 10 days, 4 of the files it referenced had already been migrated and the counts were wrong.
Replaced the guide with 48 JSON data files driving all automation. Component mappings with prop-level transforms. A migration bot with 5-factor weighted confidence scoring. A state machine enforcing status transitions with gates. Counts are computed live via CLI, not hardcoded in prose.
If the data changes faster than you can update docs, the data IS the doc.
CSS-level isolation at the config layer
The legacy framework's CSS runtime and the new system's Tailwind utilities would collide. Teams needed both running side-by-side during migration. The organization had called coexistence "infeasible."
The fix was one line of framework configuration. Zero component changes. A CSS specificity trick that scopes new styles under a class. The "infeasible" label came from assuming the solution required component-level changes. Stepping back to the config layer dissolved the problem.
The "infeasible" label had been load-bearing for months. Nobody had tested it at the config layer.
Hooks-based enforcement over review comments
Engineers forget design system constraints. Catching violations in PR review is expensive and late.
PreToolUse hooks block forbidden patterns at write time. Block legacy imports, block non-semantic tokens. The edit is rejected before it lands. Zero legacy imports inside the migrated scope. Zero review comments needed for that class of violation.
One enforcement hook prevents more defects than a hundred review comments. Identify your top 3-5 must-block patterns and implement hooks in week 1.
Learning log as governance engine
Design decisions were scattered across git commits. Hard to trace which rule came from which failure.
Append-only log with mandatory fields: date, source, type, components, learning, applied-to. 10 entries over four months directly drove 11 codified rules. Static hex values not converted to tokens. Over-broad applicability checks adding config to bundles that didn't need it. Portal scoping breaking ref-forwarding. Each entry became a rule.
Ten entries, eleven codified rules. The log paid for itself in month one.
The handoff playbook as product
588-line playbook: decision trees, CLI references, Day-1 checklist, definition of done at 4 tiers. Spot-checked with three recipients before rollout: a cold-start EM, a technical EM, and an IC lead. Different backgrounds, different questions, different failure modes caught.
Over the next three months, engineers on four other teams migrated components against their own teams' tickets, without being walked through it.
What didn't work
CLAUDE.md as behavioral governance (0% compliance)
Put design system rules in CLAUDE.md. "NEVER VIOLATE" section. Ran a controlled study (n=9, fresh git worktree per run, 6-dimension scoring rubric). Result: 0% compliance. Identical to no guidance. (Covered in detail in "Your CLAUDE.md Rules Achieve 0% Compliance.")
Ran a second study (n=82 attempts, 11 scenarios). Strengthened CLAUDE.md with task-oriented tables and explicit tool pointers. Zero measurable improvement.
The agent cites the rules and rationalizes non-compliance. Governance through documentation is fiction. Governance through enforcement is real. If you can't block the violation, you haven't governed it.
In a separate three-version test of the design-system reference file, the most detailed version scored lowest (19.0 of 30, against 21.3 and 21.7), though the gap sat within the run-to-run noise.
Solo platform engineering has a structural visibility problem
This is the most important lesson in this document.
When all tickets are self-created and all initiatives are self-started, in my experience, organizational systems have no mechanism to surface the work. There's no manager saying "I tasked the team with X." There's no team whose output gets attributed to a function. This is a well-documented pattern in platform engineering generally: infra work is invisible to product-focused promotion committees.
Self-directed platform work has a visibility asymmetry: the engineers who ship faster, the designers who start writing production code, and the teams with fewer regressions are the visible outputs. The infrastructure that caused those improvements is not. It's a career risk when operating without structural protection. Those engineers on four other teams who migrated without being walked through it? Their outcomes showed up on their dashboards, not mine.
What I'd do differently:
Define the function before building the system. Draft a charter, even a single page, naming what design engineering owns. Without an org-chart entry, the work is a side project regardless of impact.
Create the evidence trail from day 1. Every initiative, every architectural decision, every cross-team assist should be logged as it happens. Reconstructing it from git history 14 months later is possible but lossy.
Publish externally by month 3. The interesting architectural decisions are freshest early. I had conference-talk-ready material in month 2 and published nothing for 18 months.
Instrumentation started too late
Built the system first, added metrics after launch. By the time a dashboard existed, 14 months of impact was undocumented quantitatively. The learning log started 3 months in; earlier failures had to be reconstructed from git history.
By the time the dashboard shipped, the strongest impact period was already behind me with no quantitative record.
The AI chapter
The same pattern (build the system, discover what works by watching it fail, encode the learning) also shaped how I used AI tooling. Most engineers use AI to write code faster. The skill that matters is three layers:
Delegation judgment. Knowing what to delegate vs. what requires human judgment. Implementation details, pattern application, boilerplate: AI. Architectural decisions, novel constraint solving, stakeholder empathy: human.
Codified governance. Encoding architectural judgment into machine-readable specs so AI operates under constraints. Not prompt engineering. Programming the boundaries within which AI operates at organizational scale.
Empirical validation. Measuring AI workflows with controlled studies rather than impressions. n=9 ablation, single scorer. n=82 agentic validation across 11 scenarios. Two counterintuitive findings that no one else has quantified: CLAUDE.md 0% compliance (covered in detail in "Your CLAUDE.md Rules Achieve 0% Compliance") and spec quality > intermediate fidelity.
AI didn't make me a better engineer. It removed the implementation tax: the hours spent on syntax lookup, boilerplate scaffolding, debugging .map() on nested nulls. When AI absorbs that cognitive bandwidth, it redirects to architecture, system design, and cross-team enablement. The vision was always there. AI compressed the implementation cycle.
If you're building a design engineering function
- Charter first, code second.
- Start the learning log on day 1.
- Build enforcement, not documentation.
- Ship the handoff playbook early. It's the delivery mechanism, not documentation.
- Find the minimal effective prompt.
- Publish externally by month 3.
- Build the evidence trail as you go. Reconstructing impact from git history 14 months later is possible but lossy.
Top comments (0)