Principal Product Designer
I’m a product design leader with a strong foundation in brand strategy and conceptual design, and a hands-on approach to turning complex ideas into clear experiences. Two decades across agencies and client teams — including leading XD Product Design departments in NYC and San Francisco. When leading a team, I design alongside them; as an IC, I own the work from concept through production.
My passion lies in blending design with innovative technology. Lately that means building AI-native design systems, and designing 0-to-1 products with early-stage founder teams.
The most recent example of how I work is the site you’re on — designed and built with Claude Code, end to end. The method took longer to build than the site did.
-
The problem with a capable agent
01A capable agent doesn’t just write code well — it also fails well. Early on I spent days on relatively straightforward designs, each round rendering incorrectly on screen. I was stuck in a loop: describe a problem, get a fix, look at the screen, see the same problem, describe it again. Every cycle felt like progress. None of it was. So I stopped treating it as a code problem and started treating it as a governance problem.
-
What I built instead
02Three markdown files that sit above the codebase and govern how work gets done — RULES.md, STYLEGUIDE.md, TODO.md. Together they’re an agentic architecture: the workflows, the guardrails, and the long-term context an agent needs to be useful past the first session.
- RULES.md sets out who decides what. I own goals, scope, and design direction. The agent owns implementation — naming, file structure, technical trade-offs. It doesn’t ask me to choose between two equivalent approaches, and I don’t tell it how to write code.
- STYLEGUIDE.md is built from my Figma designs — the agent reads the files directly, so specs come from the source rather than from me describing them. Every value that’s confirmed on screen gets written down and locked. Once committed, it can’t be changed silently. Overriding it takes an explicit word from me.
- TODO.md tracks what’s open, what’s deferred, and what was ruled out and why. Each session hands off to the next in writing, so nothing lives in memory alone.
-
Keeping what didn’t work
03The files also keep what didn’t work. Superseded values stay in place, marked as superseded. Theories that were proposed, built, and then disproved stay too, along with the measurement that killed them.
That turns out to be the most useful part. Without it, every session starts by relitigating ground that was already settled — and an agent will happily rebuild something I abandoned three weeks ago, because nothing told it not to.
-
The rules came from failures
04Every rule in that file exists because something went wrong. Four that cost the most:
- When breaking my own rule was the fix. A gradient took twelve ships. I kept describing what it should look like. The agent kept building it in CSS and SVG. It was never going to work in either — the reference required a WebGL shader. In the end I broke my own rule about not prescribing implementation and named the mechanism myself. It landed in one ship.The rule: name the medium before describing the look. And if the same class of defect returns twice, the technique is wrong, not the values.
- Relaying instructions instead of directing the work. This was the most expensive habit I had. A single missing button label cost most of a day, because I kept describing the symptom instead of asking what caused it.The rule: every brief declares a position first — mapped, relaying, or blocked. Anything multi-layer defaults to mapped. And if the same surface fails twice, everything stops until the agent produces a cascade map.
- Trusting the tool over the browser. The agent had been reading values from a headless test harness — a browser running with no visible window, driven by a script. Measuring a page that isn’t actually being displayed is close to, but not the same as, measuring a real one. In one session it reported a viewport 87 pixels taller than the real one, sampled a layer no user ever sees, and froze an animation to report its first frame as the final state. Three wrong numbers, none caught. A tool doesn’t tell you it’s measuring the wrong thing — it just tells you what it measured.The rule: measurements come from the browser. Harness output is provisional until confirmed, must be labelled as such, and every measurement states its source and its values — not just its conclusion.
- A full day of work existed only in a working tree. I asked for a revert. There was nothing to revert to. The files had to be reconstructed from a session transcript.The rule: every shipped turn commits. No exceptions.
-
What it looks like in practice
05- The agent can’t tell me it’s finished. It ends every turn in one of two declared states: shipped, or held. Shipped means the code is in the served bytes and I can go look at it. Held means nothing changed and it’s waiting on me.
- Nothing gets committed to the rules until I’ve confirmed it on screen. Not confirmed in a log — confirmed with my eyes, in a browser.
- And when the agent can’t establish something honestly, the correct answer is to stop. The most recent bug on this site ended in a held state with a full cascade map, a leading theory, three ruled-out causes with evidence, and a list of exactly what it needs from me to close it. A diagnosis you can trust beats a fix you can’t verify.
-
Why this matters
06- The design question in AI-assisted work isn’t whether the output is good. It’s whether you can tell.
- What I built here is one answer to that: guardrails on what the agent decides, a defined standard of evidence for what counts as a measurement, a human gate before anything becomes permanent, and a written record so context survives between sessions.
- None of it is specific to me, or to this site. The problems it solves — an agent rebuilding what you abandoned, a tool reporting a number nobody checked, a decision nobody wrote down — get worse with more people, not better. Tribal knowledge doesn’t survive an agent.
- It’s the same work as designing any system. Decide what’s automated and what stays human. Make the constraints explicit. Put the gate where the judgment is.