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
+81
View File
@@ -211,3 +211,84 @@ def duplicate_values(tokens: Sequence) -> dict[str, list[str]]:
continue
by_value.setdefault(str(base).strip().lower(), []).append(name)
return {value: names for value, names in by_value.items() if len(names) > 1}
# ---------------------------------------------------------------------------
# Reading a sheet from the other side: does this code use it correctly?
# ---------------------------------------------------------------------------
#
# "The snippets use the tags from the sheet" is a verifiable relation, and
# nothing checked it before. Three questions, each a different failure:
#
# var(--x) where no --x exists -> renders as NOTHING. No error, no test
# failure, no visual clue beyond the thing
# silently not being styled.
# a superseded literal in code -> the value the sheet said to stop writing,
# and the sheet knows what to write instead.
# --x: declared inside a snippet -> a component minting its own token is the
# bloat a shared sheet exists to prevent.
#
# The first is not hypothetical: `--color-accent` was used throughout a new view
# in this codebase and does not exist.
_VAR_REFERENCE = re.compile(r"var\(\s*(--[A-Za-z0-9_-]+)")
_LOCAL_DEFINITION = re.compile(r"(?<![\w-])(--[A-Za-z0-9_-]+)\s*:")
def referenced_tokens(code: str) -> set[str]:
"""Every custom property the code reads through `var()`."""
return set(_VAR_REFERENCE.findall(code or ""))
def defined_tokens(code: str) -> set[str]:
"""Every custom property the code declares itself.
Excludes names it also reads: `--x: var(--x, fallback)` is a redeclaration
of something the sheet owns, which the unknown-reference check already
covers more precisely.
"""
return set(_LOCAL_DEFINITION.findall(code or "")) - referenced_tokens(code or "")
def _literal_pattern(literal: str) -> re.Pattern:
"""Match a literal value without matching a longer one that contains it.
`#fff` must not match inside `#ffffff` — they are different colours, and a
finding that fired on the wrong one would send someone to change code that
was already correct.
"""
escaped = re.escape(literal)
lead = r"(?<![0-9A-Za-z_#-])"
trail = r"(?![0-9A-Za-z_-])" if literal.startswith("#") else r"(?![0-9A-Za-z_-])"
return re.compile(lead + escaped + trail, re.IGNORECASE)
def check_code_against_tokens(code: str, tokens) -> dict:
"""What this code gets wrong about that token set.
`tokens` is any sequence with `.name`, `.value_by_mode` and `.supersedes` —
resolved tokens, or stored ones.
Reports rather than scores. Every finding here has a legitimate exception:
a snippet may target a system it isn't being checked against, and a literal
may be deliberate in a context the token doesn't cover. What it removes is
the SILENCE — all three currently fail with no signal at all.
"""
known = {getattr(t, "name", "") for t in tokens}
referenced = referenced_tokens(code)
superseded: list[dict] = []
for token in tokens:
for literal in getattr(token, "supersedes", None) or ():
if _literal_pattern(str(literal)).search(code or ""):
superseded.append({
"literal": literal,
"use_instead": getattr(token, "name", ""),
})
return {
"used": sorted(referenced & known),
"unknown": sorted(referenced - known),
"superseded_literals": superseded,
"local_definitions": sorted(defined_tokens(code)),
}