/ds-drift
Review a branch, PR, or whole repo for design-system conformance. Report-only — verdicts, reviews, and remediation plans.
Claude Code
$ npx -y skills add igloude/ds-skills --skill ds-drift --agent claude-code
Codex
$ npx skills add igloude/ds-skills --skill ds-drift -a codex -y
Cursor
$ npx skills add igloude/ds-skills --skill ds-drift -a cursor -y
Gemini CLI
$ npx skills add igloude/ds-skills --skill ds-drift -a gemini-cli -y
GitHub Copilot
$ npx skills add igloude/ds-skills --skill ds-drift -a github-copilot -y
OpenCode
$ npx skills add igloude/ds-skills --skill ds-drift -a opencode -y
Windsurf
$ npx skills add igloude/ds-skills --skill ds-drift -a windsurf -y
SKILL.md
ds-drift.SKILL.mdname: ds-drift
description: Review a branch, PR, or whole repo for design-system conformance. Report-only — verdicts, reviews, and remediation plans.
disable-model-invocation: true
license: MIT
metadata:
author: Ian Gloude
version: "0.5.0"
ds-drift
Judge whether work — increasingly, work produced by other models — conforms to this repo's design system, render a verdict a team can trust, and specify every required change precisely enough that the generating agent or a cheaper executor applies it without you. The review is the product. A noisy gate is an ignored gate, so precision outranks recall everywhere in this skill.
This skill is **report-only** and every output must survive a **cold read** — both terms, the family rules they summarize, and the `plans/` directory conventions are defined in [references/conventions.md](references/conventions.md). Read it now; it is short and load-bearing.
Skill rules
1. **Report the gap the toolchain can't see.** If tsc, eslint, or an existing lint rule would flag it, it is not a finding — it is noise that erodes the gate's authority. 2. **Severity comes from policy, not per-run invention.** Use the manifest's severity map (fall back to the playbook defaults) and honor its waiver ledger. Consistency between runs is what makes the verdict meaningful. 3. **Review files carry a `-review-` slug** (`plans/NNN-review-<slug>.md`) so reviews and plans read apart in the shared directory.
Done means
A gate/batch run is done when: the review file exists and survives a cold read; every blocking finding carries a verify command with an expected result; every finding is tagged `introduced` or `pre-existing`; every element of the Phase 2 scope was audited or named under "Not audited"; and the verdict recomputes mechanically from the stated counts and policy. Phase 5 checks exactly this before you finish.
Workflow
Phase 1 — Recon (always)
**Manifest first.** The conformance manifest is both the rulebook and your recon cache. Locate it in this order: a `--manifest <path>` argument → `ds/MANIFEST.md` + `ds/tokens.json` in the repo root → `node_modules/<ds-package>/ds/` (design systems that publish their manifest; find packages by globbing `node_modules/{*,@*/*}/ds/MANIFEST.md`). Manifests are **per-package**: multiple hits are a monorepo consuming several DS packages, not an error — load each, judge every component and token against the manifest of the package that owns it (the package it is imported from, or whose token namespace it matches), and report per package. A component name claimed by two manifests is a conflict to report, never a guess. `--manifest` restricts a run to one. Read the severity policy, waiver ledger, exclusions table, component inventory, and synonym map — excluded paths are skipped entirely and listed under the review's "Not audited" line.
- **Stamp check**: three comparisons per manifest. (1) **Schema** — the header's `Manifest schema` number against what this skill reads (schema 1–2; see the manifest spec); an unknown schema → stop and report, don't parse by guesswork. (2) **Version** — the header's package stamp against the installed version. (3) **API hash** — the header's hash against a recompute over the installed package's `.d.ts` files, per the spec's recipe; a matching version with a mismatched hash means the package moved without a version bump, which is exactly the staleness a version compare misses. On any mismatch, record `manifest.stale` in the review header with a degraded-confidence note — a scope-level condition, never a verdict-counted finding — and do not silently proceed as if current.
- **No manifest**: derive a working inventory and token map from the DS package source or published types, say so in the report, and recommend running `/ds-doctor` — the gate's precision is bounded by the rulebook's quality.
Then the standard recon: exact build/typecheck/lint/test commands (these become verification gates in every remediation spec and plan), repo conventions with exemplar files, the default branch and merge-base for gate scoping, and which lint rules already exist (feeds Skill Rule 1). In gate mode, also check `plans/` for a ds-plan coverage map covering this branch's feature: a finding against an element the map marks Covered or Composable means the map was wrong — record a one-line "Map corrections" row in the index alongside the finding, so ds-plan's classification bar learns from it.
Phase 2 — Audit
**Read [references/review-template.md](references/review-template.md) before auditing, not before writing** — knowing the shape the evidence must land in changes what you collect. The skeleton you are filling:
> **Verdict** + one-line why → header facts (Scope · Manifest status · Counts, introduced only · Pre-existing count · Not audited · Toolchain note) → **Blocking (introduced)**, each finding carrying Evidence at `file:line`, why-blocking with its policy source, and a remediation spec (Change / Verify → expected / STOP if) → Should fix → Advisory → Waived table → Pre-existing backlog → Recurrence counts.
Scope follows the mode:
- **Gate** (default): files changed since `git merge-base origin/<default> HEAD`, plus their direct importers. **Tag every finding `introduced` (by this branch) or `pre-existing` (in touched files)** — verdicts are rendered on `introduced` only; a gate that blames the branch for legacy debt gets bypassed. The tag is mechanical, not a judgment call: a finding is `introduced` iff its evidence lines are added or modified in `git diff <merge-base>...HEAD` (a regression counts as introduced via the lines that removed the affordance); everything else in touched files is `pre-existing`.
- **Batch**: gate scope per ref, plus one cross-set pass for divergence — the same pattern independently invented on multiple branches is invisible to any single-branch review and is exactly how parallel agents fork a design system. Read each ref in place — `git show <ref>:<path
Read more
name: ds-drift description: Review a branch, PR, or whole repo for design-system conformance. Report-only — verdicts, reviews, and remediation plans. disable-model-invocation: true license: MIT metadata: author: Ian Gloude version: "0.5.0"
ds-drift
Judge whether work — increasingly, work produced by other models — conforms to this repo's design system, render a verdict a team can trust, and specify every required change precisely enough that the generating agent or a cheaper executor applies it without you. The review is the product. A noisy gate is an ignored gate, so precision outranks recall everywhere in this skill.
This skill is **report-only** and every output must survive a **cold read** — both terms, the family rules they summarize, and the `plans/` directory conventions are defined in [references/conventions.md](references/conventions.md). Read it now; it is short and load-bearing.
Skill rules
1. **Report the gap the toolchain can't see.** If tsc, eslint, or an existing lint rule would flag it, it is not a finding — it is noise that erodes the gate's authority. 2. **Severity comes from policy, not per-run invention.** Use the manifest's severity map (fall back to the playbook defaults) and honor its waiver ledger. Consistency between runs is what makes the verdict meaningful. 3. **Review files carry a `-review-` slug** (`plans/NNN-review-<slug>.md`) so reviews and plans read apart in the shared directory.
Done means
A gate/batch run is done when: the review file exists and survives a cold read; every blocking finding carries a verify command with an expected result; every finding is tagged `introduced` or `pre-existing`; every element of the Phase 2 scope was audited or named under "Not audited"; and the verdict recomputes mechanically from the stated counts and policy. Phase 5 checks exactly this before you finish.
Workflow
Phase 1 — Recon (always)
**Manifest first.** The conformance manifest is both the rulebook and your recon cache. Locate it in this order: a `--manifest <path>` argument → `ds/MANIFEST.md` + `ds/tokens.json` in the repo root → `node_modules/<ds-package>/ds/` (design systems that publish their manifest; find packages by globbing `node_modules/{*,@*/*}/ds/MANIFEST.md`). Manifests are **per-package**: multiple hits are a monorepo consuming several DS packages, not an error — load each, judge every component and token against the manifest of the package that owns it (the package it is imported from, or whose token namespace it matches), and report per package. A component name claimed by two manifests is a conflict to report, never a guess. `--manifest` restricts a run to one. Read the severity policy, waiver ledger, exclusions table, component inventory, and synonym map — excluded paths are skipped entirely and listed under the review's "Not audited" line.
- **Stamp check**: three comparisons per manifest. (1) **Schema** — the header's `Manifest schema` number against what this skill reads (schema 1–2; see the manifest spec); an unknown schema → stop and report, don't parse by guesswork. (2) **Version** — the header's package stamp against the installed version. (3) **API hash** — the header's hash against a recompute over the installed package's `.d.ts` files, per the spec's recipe; a matching version with a mismatched hash means the package moved without a version bump, which is exactly the staleness a version compare misses. On any mismatch, record `manifest.stale` in the review header with a degraded-confidence note — a scope-level condition, never a verdict-counted finding — and do not silently proceed as if current.
- **No manifest**: derive a working inventory and token map from the DS package source or published types, say so in the report, and recommend running `/ds-doctor` — the gate's precision is bounded by the rulebook's quality.
Then the standard recon: exact build/typecheck/lint/test commands (these become verification gates in every remediation spec and plan), repo conventions with exemplar files, the default branch and merge-base for gate scoping, and which lint rules already exist (feeds Skill Rule 1). In gate mode, also check `plans/` for a ds-plan coverage map covering this branch's feature: a finding against an element the map marks Covered or Composable means the map was wrong — record a one-line "Map corrections" row in the index alongside the finding, so ds-plan's classification bar learns from it.
Phase 2 — Audit
**Read [references/review-template.md](references/review-template.md) before auditing, not before writing** — knowing the shape the evidence must land in changes what you collect. The skeleton you are filling:
> **Verdict** + one-line why → header facts (Scope · Manifest status · Counts, introduced only · Pre-existing count · Not audited · Toolchain note) → **Blocking (introduced)**, each finding carrying Evidence at `file:line`, why-blocking with its policy source, and a remediation spec (Change / Verify → expected / STOP if) → Should fix → Advisory → Waived table → Pre-existing backlog → Recurrence counts.
Scope follows the mode:
- **Gate** (default): files changed since `git merge-base origin/<default> HEAD`, plus their direct importers. **Tag every finding `introduced` (by this branch) or `pre-existing` (in touched files)** — verdicts are rendered on `introduced` only; a gate that blames the branch for legacy debt gets bypassed. The tag is mechanical, not a judgment call: a finding is `introduced` iff its evidence lines are added or modified in `git diff <merge-base>...HEAD` (a regression counts as introduced via the lines that removed the affordance); everything else in touched files is `pre-existing`.
- **Batch**: gate scope per ref, plus one cross-set pass for divergence — the same pattern independently invented on multiple branches is invisible to any single-branch review and is exactly how parallel agents fork a design system. Read each ref in place — `git show <ref>:<path
Police large volumes of AI-generated frontend work for design-system adherence, plan features against the system before they're built, and audit the design system itself so it can be policed. The idea: generation is cheap, the bottleneck is judgment.
Other skills on ds-skills.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about ds-drift.
- Which coding agents can use ds-drift?
- ds-drift installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

