feat(design-systems): check the components against the sheet they claim to use
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 16s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 43s
CI & Build / Build & push image (push) Successful in 35s

"The snippets use the tags from the sheet" was a relation nobody could verify.
Now it is three checks, and all three currently fail SILENTLY in this codebase:

  unknown             `var(--x)` where the system declares no `--x`. Renders as
                      nothing at all — no error, no failing test, no visual clue
                      beyond the element quietly not being styled.
  superseded literals a value the sheet said to stop writing, paired with the
                      token to write instead. Only possible because `supersedes`
                      is declared rather than inferred.
  local definitions   custom properties a snippet mints for itself instead of
                      reusing the sheet's — the bloat a shared sheet exists to
                      prevent, where a value stops being reused and starts being
                      restated per component.

The first is not hypothetical. Writing DesignSystemsView.vue earlier in this
same session I used `--color-accent` throughout; it does not exist, and nothing
in the toolchain noticed. This check is the thing that would have.

A token that is both defined and read locally is reported ONCE, as an unknown
reference — "--btn-bg does not exist in the sheet" is the more precise statement
of the same problem, and reporting both would double-count one fact.

Literal matching is boundary-aware and case-insensitive: `#fff` must not fire
inside `#ffffff` (different colours, and a finding on the wrong one sends
someone to change correct code), while `#FFFFFF` in a rulebook has to match
`#ffffff` in a stylesheet — the same trap `normalize_hex` exists for.

Snippets with nothing to report are omitted entirely. A list of everything that
is fine is a list nobody reads twice — the same principle the auto-inject menu
and the drift panel are both built on.

Two integration mistakes fixed while wiring it: `list_snippets` returns
`(rows, total)` and caps its limit at 100, and `get_snippet` returns a Note
model rather than a dict. The list rows carry a preview, not the code, so the
check reads each full body — checking the preview would have reported on a
truncation.
This commit is contained in:
2026-07-30 21:47:47 -04:00
parent b0a7d9e89b
commit 46d88f9e7e
8 changed files with 448 additions and 2 deletions
+36
View File
@@ -167,6 +167,41 @@ async def get_design_system_stylesheet(
return result
async def check_snippets_against_design_system(
design_system_id: int,
project_id: int = 0,
) -> dict:
"""Which recorded snippets disagree with a design system's sheet.
Snippets are the component layer — buttons, tables, input schemes — and they
are supposed to use the tags the sheet declares. Three findings per snippet,
each currently silent in the codebase:
unknown `var(--x)` where the system has no `--x`. Renders as
NOTHING: no error, no failing test, just an element
that quietly isn't styled.
superseded_literals a literal the sheet says to stop writing, paired with
the token to write instead.
local_definitions custom properties the snippet mints for itself rather
than using shared ones — the bloat a shared sheet
exists to prevent.
Snippets with nothing to report are omitted. Reach for this before writing
or reviewing component CSS.
Args:
design_system_id: The system whose sheet is authoritative.
project_id: Narrow to one project, or 0 for every project.
"""
uid = current_user_id()
result = await ds_svc.check_snippets_against_system(
uid, design_system_id, project_id
)
if result is None:
raise ValueError(f"design system {design_system_id} not found")
return result
async def import_design_system_from_rulebook(
design_system_id: int,
rulebook_id: int,
@@ -336,6 +371,7 @@ def register(mcp) -> None:
update_design_system,
delete_design_system,
get_design_system_stylesheet,
check_snippets_against_design_system,
import_design_system_from_rulebook,
create_design_token,
list_design_tokens,