System · Vellum

DX

Developer + agent experience — golden path, load tiers, gates.

dx.md

Meridian — dx.md

Developer experience for humans and AI agents. Twin pillar with ux.md.
North star: north-star.md. Typed: uxLaws / dxLaws in lib/design/experience.ts.

1. Why DX is a product feature

Meridian’s primary consumer is an agent under pressure (and a human guiding it).
If the contract is hard to load, ambiguous, or unverifiable, the system fails — even when tokens are perfect.

DX goalSourceMeridian rule
Progressive disclosure of complexityVercel / Guillermo Rauch, layered systemsSane defaults; drop down a layer for flexibility — don’t eject
Closed token APIPandya — expose DS to LLMsImport @/lib/design; never invent hex / px soup
Spec + auditSuperdesign DESIGN.md, PandyaContracts + check:* gates
Always / Ask / NeverAddy Osmani — good agent specsdxLoadTiers in experience.ts
Self-verificationOsmaniAgent runs gates and reports before “done”
Compose, don’t forkshadcn/uinpx shadcn@latest add; no twin kits
Quiet evolutionLinear redesignEvolve chrome without disassembling the product

2. Golden path — into any project

Live install: /meridian/install.
Stack doctrine (law book · skills · gates · optional MCP): /stack · stack.md.

This product is a fail-closed design contract, not DESIGN.md vibes alone and not shadcn MCP (which installs components).

LayerJob
Law bookdesign.md / agents.md / DNA
SkillsVerified {id}-* cookbooks
CI gatesnpm run validate — the bailiff
Contract MCP (optional)Queryable kit: get_contractvalidate_ui
shadcn MCP / CLIBrowse / install registry atoms

Agent loop:

  1. Load law book (required first)
  2. Open matching skill + recipe when it fits
  3. npx shadcn@latest add … (or shadcn MCP) for atoms
  4. Compose under closed tokens
  5. npm run validate (required before done)
  6. Optional MCP tools when the session is tool-wired

In-repo compose proof

Live on /meridian/for-agents. When working inside this monorepo:

import { Button } from "@/components/ui/button"
import { typesetClass, bg, radiusIntent } from "@/lib/design"

export function Panel() {
  return (
    <section data-surface="application" className="shell-pad shell-stack">
      <h2 className="type-section">Issues</h2>
      <Button className={radiusIntent("control")}>New</Button>
      <div className={typesetClass("docs")}>{/* help HTML */}</div>
    </section>
  )
}

That’s enough for a correct first surface. Depth (cinema, knobs, proofs) loads on demand.

3. Load tiers (Always / Ask / Never)

TierLoad
AlwaysContract MCP get_contractdesign.md / kit JSON → closed tokens → validate_ui
Askux.md / dx.md, influences, skills, surface proofs, @/lib/design (this repo)
NeverInvent tokens/shells; skip empty/error; skip validate_ui; floating chatbot

Typed as dxLoadTiers — keep agents.md aligned.

4. Layers of abstraction (escape without ejecting)

From least flexible → most flexible (Capozzi / progressive disclosure):

  1. PresetstypesetClass("docs"), data-surface="application", knob presets
  2. Grammar helpersbg(), radiusIntent(), defineInteractiveProof()
  3. shadcn atoms — compose Button / Card / Input
  4. Owned CSSglobals.css / typeset.css variables (theme owners only)
  5. New frozen law — last resort; update design.md + lint in the same change

Never jump from (1) to inventing a parallel component kit.

5. Verification loop (mandatory DX)

npm run check:design && npm run check:shell && npm run check:proofs \
  && npm run check:typeset && npm run check:experience && npm run check:contrast

After implementing, agents must:

  1. Run the gates
  2. List any unmet MUST from design.md / uxLaws / dxLaws
  3. Fix or explicitly call out blockers

Hope is not a DX strategy — audit is (Pandya).

6. Machine-readable surface

EndpointJob
/meridian/design.md · /meridian/agents.mdNegotiated contracts (?raw=1)
/meridian/system/*Research specs
@/lib/designClosed TypeScript unions
check:*Fail-closed CI

Docs for humans and agents must stay one grammar — not three drifting stories.

7. Anti-patterns (DX)

BanWhy
Dumping all skills into every promptContext overload; use Ask tier
Storybook-only truth with no lintAgents can’t enforce screenshots
“Just make it look like X brand”Pastiche; absorb discipline only
New wrapper components for every demoShell zoo
Skipping empty/error because “demo”UX debt ships as product debt

8. Agent checklist

  • Followed Always load tier
  • Used closed grammar / presets (no invented scales)
  • Owned loading / empty / error if building a resource surface
  • Ran check:experience + sibling gates
  • Did not invent a twin component or shell

Sources

Raw