feat(design-systems): the master sheet — purpose tokens, not per-element values
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / integration (push) Successful in 16s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 42s
CI & Build / Build & push image (push) Successful in 34s

Operator's new requirement (#2299, architecture in #2296): a design system does
not just hold tokens, it generates and manages a master CSS sheet. That settles
the milestone's open "authority mechanism" question — the record is
authoritative because the stylesheet comes out of it.

**The sheet is shaped by purpose and styles no elements.** It declares custom
properties, grouped by what they mean, and contains no `.btn-primary`, no
`table`, no `input`. That is the design, not a shortcut: a sheet that styled
elements would restate the same handful of values once per element and grow with
the UI, where purpose-named values are stated once and reused. Components live
as SNIPPETS that reference these names — a surface that already exists and
already carries prose, locations, drift checks, merge and write-path recall.

A token named after an element (`--fs-button-bg`) is the smell that the two have
been mixed; a purpose name (`--fs-action-primary`) is reused across all of them.

Alongside the CSS the endpoint returns what the text cannot say for itself:
which tokens are still valueless, and which VALUES are declared under more than
one name. The second is the operator's "reuse consistent values" constraint made
checkable — and it reports rather than refuses, because a design system
legitimately aligns colours on purpose ("Success = Moss, by design") and only a
human knows which case it is.

Mode maps to selector the way the codebase already does it: base on the root
selector, every other mode layered on `[data-theme="…"]`. The root selector is a
PARAMETER — #251 recorded that a container-scoped preview cannot use `:root`, so
hardcoding it would have made the generator useless to the preview surface.

A token the rulebook names but states no value for is emitted as a commented-out
declaration IN ITS GROUP rather than dropped. Its absence is the finding, and a
comment puts that finding where the reader already is.

Values are validated, not escaped, and this is a real boundary rather than
tidiness: design systems are shareable records (rule #47), so `red; } body {
display: none` in a system shared with you would otherwise inject CSS into your
page. A value containing `{ } ; @ < >`, a comment delimiter or a newline is
REFUSED and rendered as a comment saying so — rejecting beats stripping, since a
partially-sanitised value is one the operator never wrote and the sheet's whole
claim is that it is the record.

Not in scope, and deliberately: serving this as the app's actual stylesheet.
Generating and exposing a sheet is reversible; swapping theme.css for a
generated one is not, and it should be an explicit call rather than a side
effect.
This commit is contained in:
2026-07-30 21:42:08 -04:00
parent 4dc57f8ab2
commit b0a7d9e89b
9 changed files with 737 additions and 1 deletions
+230
View File
@@ -0,0 +1,230 @@
"""Rendering a design system as its master CSS sheet.
The generator is pure, so a whole sheet is one literal of tokens in and a string
out. Two things here are load-bearing rather than cosmetic: what the sheet
deliberately does NOT contain, and the fact that a value cannot escape its
declaration.
"""
from types import SimpleNamespace
from scribe.services.design_stylesheet import (
duplicate_values,
is_valid_token_name,
render_stylesheet,
safe_comment,
safe_value,
selector_for_mode,
)
def _token(name, value_by_mode, group_name=None, purpose=None):
return SimpleNamespace(
name=name, value_by_mode=value_by_mode,
group_name=group_name, purpose=purpose,
)
# --- safety -----------------------------------------------------------------
#
# Design systems are shareable records. A value that can close its declaration
# can inject arbitrary CSS into the page of anyone the system was shared with,
# which makes this a real boundary rather than tidiness.
def test_a_value_that_would_escape_its_declaration_is_refused():
"""`red; } body { display: none` is the whole attack: end the declaration,
close the block, open your own."""
assert safe_value("red; } body { display: none") is None
assert safe_value("#fff}") is None
assert safe_value("#fff;") is None
def test_at_rules_and_tags_are_refused():
assert safe_value("@import url(evil.css)") is None
assert safe_value("</style><script>") is None
def test_comment_delimiters_in_a_value_are_refused():
"""A value is not rendered inside a comment, but `/*` would comment out
every declaration after it — silently blanking the rest of the sheet."""
assert safe_value("red /* ") is None
assert safe_value("*/ red") is None
def test_a_newline_in_a_value_is_refused():
assert safe_value("red\n color: blue") is None
def test_ordinary_values_survive_untouched():
for value in ("#14171a", "8px", "cubic-bezier(0.2, 0.6, 0.2, 1)",
"0 4px 12px rgba(0,0,0,0.35)", "color-mix(in srgb, red 15%, transparent)"):
assert safe_value(value) == value
def test_a_rejected_value_is_dropped_not_cleaned_up():
"""Rejecting beats stripping. A partially-sanitised value is one the operator
never wrote, and the sheet's entire claim is that it IS the record — quietly
rendering a different colour would break that claim invisibly."""
css = render_stylesheet([_token("--fs-x", {"base": "red; } body { color: blue"})])
assert "body" not in css
assert "value rejected" in css
def test_comment_text_cannot_close_its_comment():
"""`purpose` is operator prose rendered into a comment — `*/` in it would
end the comment and spill the rest into the stylesheet as code."""
assert "*/" not in safe_comment("ends the comment */ then color: red")
def test_a_malformed_token_name_is_dropped():
"""A name is an identifier. A 'cleaned up' identifier is a different token
than the one recorded, so it is dropped rather than repaired."""
assert is_valid_token_name("--fs-obsidian")
assert not is_valid_token_name("--fs obsidian")
assert not is_valid_token_name("color: red")
assert not is_valid_token_name("fs-obsidian") # no leading --
css = render_stylesheet([_token("--bad name", {"base": "red"})])
assert "bad name" not in css
def test_a_mode_name_cannot_break_out_of_its_selector():
assert selector_for_mode('dark"] body {') == '[data-theme="darkbody"]'
# --- what the sheet is ------------------------------------------------------
def test_the_sheet_declares_properties_and_styles_no_elements():
"""THE shape decision. A sheet that styled elements would restate the same
handful of values once per element and grow with the UI. Purpose tokens are
stated once and reused; components are snippets that reference them."""
css = render_stylesheet([
_token("--fs-obsidian", {"base": "#14171a"}, group_name="surface"),
_token("--fs-moss", {"base": "#4a5d3f"}, group_name="action"),
])
assert "--fs-obsidian: #14171a;" in css
# No element or class rules — the sheet has exactly one block here, and
# every declaration in it is a custom property.
assert css.count("{") == 1
declarations = [
line.strip() for line in css.splitlines()
if ":" in line and line.strip().endswith(";")
]
assert declarations and all(d.startswith("--") for d in declarations)
def test_the_header_says_what_the_sheet_is_for():
"""A generated file with no explanation gets hand-edited, and then it has
diverged from the record it claims to be."""
css = render_stylesheet([_token("--fs-x", {"base": "1px"})], title="FabledSword")
assert "FabledSword" in css
assert "Generated" in css
assert "snippets" in css
# --- modes ------------------------------------------------------------------
def test_base_goes_on_the_root_selector_and_other_modes_layer_over_it():
"""Matches the convention already in the codebase, and the one-way scoping
#251 recorded: light on `:root`, dark layered on an attribute selector."""
css = render_stylesheet([
_token("--fs-bg", {"base": "#f5f1e8", "dark": "#14171a"}),
])
assert ":root {" in css
assert '[data-theme="dark"] {' in css
assert css.index(":root {") < css.index('[data-theme="dark"] {')
def test_a_mode_block_contains_only_what_that_mode_declares():
"""A mode block is an OVERRIDE layer, exactly as the storage model has it.
Repeating every token in every block would make the sheet claim each mode
redefines the whole system."""
css = render_stylesheet([
_token("--fs-bg", {"base": "#f5f1e8", "dark": "#14171a"}),
_token("--fs-radius-md", {"base": "8px"}),
])
dark_block = css.split('[data-theme="dark"] {')[1]
assert "--fs-bg" in dark_block
assert "--fs-radius-md" not in dark_block
def test_the_root_selector_is_caller_chosen():
"""A container-scoped preview cannot use `:root`. A generator that hardcoded
it could not serve the preview surface at all."""
css = render_stylesheet(
[_token("--fs-x", {"base": "1px"})], root_selector="[data-preview]"
)
assert "[data-preview] {" in css
assert ":root {" not in css
# --- grouping and honesty ---------------------------------------------------
def test_tokens_are_grouped_by_purpose_with_the_group_named():
css = render_stylesheet([
_token("--fs-obsidian", {"base": "#14171a"}, group_name="surface"),
_token("--fs-radius-md", {"base": "8px"}, group_name="radius"),
])
assert "/* surface */" in css
assert "/* radius */" in css
def test_a_purpose_becomes_an_inline_comment_on_the_base_layer_only():
"""Repeating the same prose in every mode block is noise: the token means
the same thing in dark mode."""
css = render_stylesheet([
_token("--fs-obsidian", {"base": "#14171a", "dark": "#000000"},
purpose="page bg, deepest surface"),
])
assert css.count("page bg, deepest surface") == 1
def test_a_declared_token_with_no_value_appears_as_a_comment_not_a_silence():
"""The rulebook named it, so its absence is a FINDING. A commented line puts
that finding where the reader is already looking; dropping it would make the
sheet look complete."""
css = render_stylesheet([
_token("--fs-obsidian", {"base": "#14171a"}),
_token("--fs-radius-sm", {}),
])
assert "--fs-radius-sm" in css
assert "no value set yet" in css
# Commented, so it cannot be mistaken for a live declaration.
assert " --fs-radius-sm:" not in css
def test_an_empty_system_renders_a_sheet_with_no_blocks_rather_than_failing():
"""A system with no tokens is an ordinary state (rule #115), including one
that was just created."""
css = render_stylesheet([])
assert "{" not in css
assert "Generated" in css
# --- the reuse report -------------------------------------------------------
def test_two_tokens_sharing_a_value_are_reported_not_refused():
"""The operator's constraint, made checkable: reuse consistent values rather
than restating them. But a design system legitimately aligns colours on
purpose — "Success = Moss, by design" — so this reports and lets a human
decide which it is."""
dupes = duplicate_values([
_token("--fs-moss", {"base": "#4A5D3F"}),
_token("--fs-success", {"base": "#4a5d3f"}),
_token("--fs-obsidian", {"base": "#14171a"}),
])
assert dupes == {"#4a5d3f": ["--fs-moss", "--fs-success"]}
def test_tokens_that_agree_in_one_mode_but_differ_in_another_are_not_duplicates():
"""A near-miss is a different, weaker finding, and calling it a duplicate
would send someone to merge two tokens that genuinely diverge."""
assert duplicate_values([
_token("--fs-a", {"base": "#fff", "dark": "#000"}),
_token("--fs-b", {"base": "#fff", "dark": "#111"}),
]) == {"#fff": ["--fs-a", "--fs-b"]}
def test_valueless_tokens_never_count_as_duplicates_of_each_other():
"""Otherwise every unfilled token would collide with every other one and the
report would be nothing but noise on a fresh import."""
assert duplicate_values([_token("--fs-a", {}), _token("--fs-b", {})]) == {}