revert(design-systems): drop the rulebook import — a migration, not a feature
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 19s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 43s
CI & Build / Build & push image (push) Successful in 44s

Operator's call, and it corrects a scope error rather than a bug:

  "this is a path for a user to go from a rulebook to a design system. we don't
   need to build this path in the app itself ... you should be the one that does
   the import ... going forward no one else should have to do such a migration."

Right. Nobody starting from a design system will ever go rulebook -> system, so
the whole path was permanent product code serving a single act on one install.
Rule #22: remove it, don't flag it off. Gone from the service, the REST route,
the MCP tool, the UI panel, the API client and its tests.

There is a second consequence I had missed, and it is the better argument. The
parser was WORSE at this than doing it by hand. `propose_tokens` leaves radius
steps and type sizes valueless because "Small 4px" is not a hex and nothing here
parses it — a limitation I documented carefully and shipped anyway. But that
limitation only exists because the importer had to run unattended. Done as work
rather than as a feature, those values are just read and written, and the result
is a complete design system instead of one with a dozen blanks and a count
explaining them.

Scaffolding built around my own absence from the loop, when I am the loop.

KEPT: `extract_expectations` and `design_expectations` in
services/design_rulebook_import.py. The live drift panel still reads them until
it is repointed at a resolved design system (#2295), and removing them now would
take the /design page's only content with it. They go with that change, not this
one.
This commit is contained in:
2026-07-31 09:46:12 -04:00
parent 8eef9e7845
commit 23a385e2db
9 changed files with 5 additions and 749 deletions
-37
View File
@@ -210,42 +210,6 @@ async def check_snippets_against_design_system(
return result
async def import_design_system_from_rulebook(
design_system_id: int,
rulebook_id: int,
apply: bool = False,
) -> dict:
"""Seed a design system from a rulebook that describes one in prose.
Reads the rulebook's colour and token declarations and proposes the tokens
they add up to — joining "Obsidian #14171A" in one rule to `--fs-obsidian`
in another, since neither alone is a token.
Defaults to a PREVIEW. An import is a proposal: rulebooks are written
aspirationally and some of what they describe was never built, so read
`proposed` before setting apply=True. Every entry carries the rule and
sentence it came from so the claim can be checked rather than trusted.
Existing token names are never overwritten — a second run fills gaps and
lists the rest under `skipped`, so it is safe to repeat.
Args:
design_system_id: The system to seed.
rulebook_id: The rulebook to read.
apply: False (default) previews; True writes the tokens.
"""
uid = current_user_id()
report = await ds_svc.import_from_rulebook(
uid, design_system_id, rulebook_id, apply=apply,
)
if report is None:
raise ValueError(
f"design system {design_system_id} not writable, or rulebook "
f"{rulebook_id} not readable"
)
return report
# ── Tokens ──────────────────────────────────────────────────────────────
async def create_design_token(
@@ -388,7 +352,6 @@ def register(mcp) -> None:
delete_design_system,
get_design_system_stylesheet,
check_snippets_against_design_system,
import_design_system_from_rulebook,
create_design_token,
list_design_tokens,
update_design_token,