feat(ms-ai-architect): re-sync vendored design-system, source_commit now true [skip-docs]

DS-repo restored scripts/sync-design-system.mjs with an explicit source
allowlist and verified the command; ran their exact command (never one
reconstructed locally). MANIFEST.json was rewritten by the script itself,
never edited by hand.

source_commit now reads efaa3d0 (playground-design-system's main on the
public mirror), verified reachable via git ls-remote against the public
remote and git cat-file -t locally — in contrast to the previous c1b7bad,
which does not exist as a git object in that repo at all. 26/27 files
byte-identical to the source; only their README.md content differs.

Replaced the three stale prose points in README.md and docs/playground.md
that described the missing command and the untrustworthy source_commit.

Suite: 1070/1070 (tracked kb-update + kb-eval test files).

[skip-docs]: README.md and docs/playground.md are the doc update this task
required (vendoring section accuracy). CLAUDE.md's command/agent/skill
surface is unaffected — no new commands, agents, or skills.
This commit is contained in:
Kjell Tore Guttormsen 2026-08-27 10:40:57 +02:00
commit f1f27a4343
4 changed files with 181 additions and 50 deletions

View file

@ -1,13 +1,13 @@
{
"generated_by": "scripts/sync-design-system.mjs",
"do_not_edit": true,
"source": "shared/playground-design-system/",
"source_commit": "c1b7bad3899c5cfe9ff90663003609b018aa79a0",
"sync_date": "2026-05-15T14:11:07.444Z",
"source": "playground-design-system",
"source_commit": "efaa3d0e79f1b06976735831e5bf8cab42f7e6a9",
"sync_date": "2026-08-27T08:37:47.101Z",
"file_count": 27,
"files": {
"CHANGELOG.md": "b5018b46cd0830334109e915d23b5554c060412c2b7e132f97f2933e5dd5d79c",
"README.md": "83de0e29b207c979b7b2a3327b7a4ec0c2e1b4d3705ee2677f26c28c3a3ee643",
"README.md": "8d8e86251f0c5a5d2f29e91d3b5a1fd2b40d7a79e4791ade237c10112ce9ce3c",
"base.css": "df0db874473412eb771b7355b589f7478042987756898f0921584286bd5ba70a",
"components-tier2.css": "c2cb7e9d76d6af28d50db654030413777feb2f2f2b93213e598de8b686b14523",
"components-tier3-supplement.css": "51fab10377d80029d6552613069d46fd14ce66af77fe6705b1c6bdf5c9e6481e",

View file

@ -1,8 +1,37 @@
# Playground Design System
# playground-design-system
A shared design system for plugin Playgrounds — visual self-service UIs that complement terminal slash-commands. Built for Norwegian public sector with WCAG 2.1 AA compliance, Aksel/Digdir-aligned aesthetics, and self-contained HTML deployment.
Vendored, framework-free CSS design system for plugin playgrounds — design tokens, four component tiers, self-hosted fonts, and file:// operation with no build step.
**Version:** 0.1 (Phase 1 — 2026-05-02)
Playgrounds are the visual self-service UIs that complement a plugin's terminal slash-commands. This system gives them one shared visual language: Aksel/Digdir-aligned aesthetics for Norwegian public-sector users, WCAG 2.1 AA contrast and focus handling, and pages that open straight from disk with no server.
**Version:** 0.6.0 — see [CHANGELOG.md](CHANGELOG.md).
## Table of Contents
- [Non-goals](#non-goals)
- [Provenance](#provenance)
- [Directory layout](#directory-layout)
- [Quick start](#quick-start)
- [Vendoring and re-sync](#vendoring-and-re-sync)
- [Design principles](#design-principles)
- [Token system](#token-system)
- [Component reference](#component-reference)
- [Schemas](#schemas)
- [Theming](#theming)
- [Print mode](#print-mode)
- [Known limitations](#known-limitations)
- [Self-hosted fonts](#self-hosted-fonts)
- [Versioning](#versioning)
- [License](#license)
- [Contributing](#contributing)
## Non-goals
- **Not a JavaScript component library.** The system is CSS-only. Interactivity (tab state, sidepanel toggling, live-meter updates) is wired by each Playground in vanilla JS.
- **Not a general-purpose web UI kit.** Scope is the Playgrounds in this marketplace; Aksel/Digdir conventions and domain visuals (NS 5814 matrices, EU AI Act tiers) are baked in rather than configurable.
- **No build step, bundler or npm package.** Files are vendored and linked with plain `<link>` tags. Nothing is compiled, and nothing is published to a package registry.
- **No icon set.** Iconography is left to each Playground so the shared system stays small.
- **Not open to pull requests.** Solo project — see [Contributing](#contributing).
## Provenance
@ -13,35 +42,38 @@ Integration into the marketplace (file organization, path normalization, README
## Directory layout
```
shared/
├── playground-design-system/ # The design system (this directory)
│ ├── README.md # This file
│ ├── tokens.css # CSS custom properties (Aksel/Digdir-aligned)
│ ├── base.css # Reset, typography, primitives, focus, print
│ ├── components.css # Tier 1: radar, matrix, findings-browser, critique-card, wizard, live-meter
│ ├── components-tier2.css # Tier 2: decision-tree, traffic-lights, diff-review, treemap, distribution, command-pipeline, pyramide, pipeline-cockpit, verdict-pill+risk-meter, codepoint-reveal, small-multiples, OWASP badges
│ ├── components-tier3.css # Tier 3 wave 1: pair-before-after, AI Act timeline, 3-track entry, FRIA rights-matrix, capability-matrix, parallel-agent-status, ErrorSummary, GuidePanel
│ ├── components-tier3-supplement.css # Tier 3 wave 2 (12): toxic-flow, fleet-overview, kanban Keep/Review/Remove, maturity-ladder, classify-and-transform, cycle-ribbon, persistent-antipattern, suppressed-signals, ExpansionCard, ReadMore, FormProgress, Aspirational-vs-Committed
│ ├── fonts.css # @font-face declarations for self-hosted fonts
│ ├── fonts/ # Self-hosted woff2 + license attribution
│ │ ├── Inter-{Regular,Medium,SemiBold,Bold}.woff2
│ │ ├── JetBrainsMono-{Regular,Medium,SemiBold}.woff2
│ │ ├── SourceSerif4-{Regular,Semibold}.woff2
│ │ └── LICENSES.md # All three are SIL OFL 1.1
│ ├── print.css # A4 print stylesheet with B/W severity patterns
│ └── schemas/ # Cross-plugin JSON schemas
│ ├── finding.schema.json # Used by llm-security, config-audit, ultraplan-review, ms-ai-review
│ ├── okr-set.schema.json # Used by OKR plugin
│ └── ros-threat.schema.json # Used by ms-ai-architect ROS workflow
└── playground-examples/ # Showcase + reference scenarios
├── index.html # System showcase (browse all components)
├── ros-lier-kommune.html # Scenario A — ms-ai-architect ROS report
├── okr-baerum.html # Scenario B — OKR live writer
├── security-direktorat.html # Scenario C — llm-security findings review
├── templates.html # Skeleton + print-template demos
├── tier3-preview.html # Tier 3 wave 1 visual preview
├── components/ # Tier 3 wave 2 — 12 isolated demo pages
playground-design-system/ # This repo
├── README.md # This file
├── tokens.css # CSS custom properties (Aksel/Digdir-aligned)
├── base.css # Reset, typography, primitives, focus, print
├── components.css # Tier 1: radar, matrix, findings-browser, critique-card, wizard, live-meter
├── components-tier2.css # Tier 2: decision-tree, traffic-lights, diff-review, treemap, distribution, command-pipeline, pyramide, pipeline-cockpit, verdict-pill+risk-meter, codepoint-reveal, small-multiples, OWASP badges
├── components-tier3.css # Tier 3 wave 1: pair-before-after, AI Act timeline, 3-track entry, FRIA rights-matrix, capability-matrix, parallel-agent-status, ErrorSummary, GuidePanel
├── components-tier3-supplement.css # Tier 3 wave 2 (12): toxic-flow, fleet-overview, kanban Keep/Review/Remove, maturity-ladder, classify-and-transform, cycle-ribbon, persistent-antipattern, suppressed-signals, ExpansionCard, ReadMore, FormProgress, Aspirational-vs-Committed
├── components-tier4-project-view.css # Tier 4: project-view arketype
├── fonts.css # @font-face declarations for self-hosted fonts
├── fonts/ # Self-hosted woff2 + license attribution
│ ├── Inter-{Regular,Medium,SemiBold,Bold}.woff2
│ ├── JetBrainsMono-{Regular,Medium,SemiBold}.woff2
│ ├── SourceSerif4-{Regular,Semibold}.woff2
│ └── LICENSES.md # All three are SIL OFL 1.1
├── print.css # A4 print stylesheet with B/W severity patterns
├── schemas/ # Cross-plugin JSON schemas
│ ├── finding.schema.json # Used by llm-security, config-audit, ultraplan-review, ms-ai-review
│ ├── okr-set.schema.json # Used by OKR plugin
│ └── ros-threat.schema.json # Used by ms-ai-architect ROS workflow
├── scripts/
│ └── sync-design-system.mjs # Vendors the delivered files into a consumer (see Vendoring and re-sync)
├── tests/
│ └── sync-source-boundary.test.mjs # Pins what the sync may and may not copy
└── playground-examples/ # Showcase + reference scenarios (this repo's own demos)
├── index.html # System showcase (browse all components)
├── ros-lier-kommune.html # Scenario A — ms-ai-architect ROS report
├── okr-baerum.html # Scenario B — OKR live writer
├── security-direktorat.html # Scenario C — llm-security findings review
├── templates.html # Skeleton + print-template demos
├── tier3-preview.html # Tier 3 wave 1 visual preview
├── components/ # Tier 3 wave 2 — 12 isolated demo pages
│ ├── sankey-toxic-flow.html
│ ├── fleet-overview.html
│ ├── kanban.html
@ -54,10 +86,14 @@ shared/
│ ├── read-more.html
│ ├── form-progress.html
│ └── aspirational-committed.html
├── ros-app.js # Scenario A interactivity
└── ros-data.js # Scenario A mock data
├── ros-app.js # Scenario A interactivity
└── ros-data.js # Scenario A mock data
```
Consumers vendor this repo (its CSS/fonts/schemas, not `playground-examples/`) into their own
Playground at `<plugin>/playground/vendor/playground-design-system/` — copied in, not a git
submodule or shared symlink. See [Quick start](#quick-start).
## Quick start
To use the design system from a plugin's Playground:
@ -67,16 +103,41 @@ To use the design system from a plugin's Playground:
<html lang="nb" data-theme="light">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../shared/playground-design-system/tokens.css">
<link rel="stylesheet" href="../../shared/playground-design-system/base.css">
<link rel="stylesheet" href="../../shared/playground-design-system/components.css">
<link rel="stylesheet" href="../../shared/playground-design-system/components-tier2.css">
<!-- Theme bootstrap. Must run before the stylesheets parse to avoid a
flash-of-wrong-theme (FOUC). Priority order:
1) saved choice (localStorage '<plugin-name>-theme')
2) OS preference via matchMedia('(prefers-color-scheme: dark)')
3) the HTML attribute default ('light' above)
Sets both data-theme + colorScheme for native form controls and scrollbars.
Wrapped in try/catch — file:// + private mode can block localStorage. -->
<script>
(function () {
var theme = null;
try {
var saved = localStorage.getItem('<plugin-name>-theme');
if (saved === 'light' || saved === 'dark') theme = saved;
} catch (e) { /* localStorage unavailable */ }
if (!theme && window.matchMedia) {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
if (!theme) theme = document.documentElement.getAttribute('data-theme') || 'light';
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
})();
</script>
<link rel="stylesheet" href="vendor/playground-design-system/tokens.css">
<link rel="stylesheet" href="vendor/playground-design-system/base.css">
<link rel="stylesheet" href="vendor/playground-design-system/components.css">
<link rel="stylesheet" href="vendor/playground-design-system/components-tier2.css">
<!-- Optional: include components-tier3.css for Tier 3 wave 1 components -->
<!-- Optional: include components-tier3-supplement.css for Tier 3 wave 2 (12 additional components) -->
<!-- Optional: include components-tier4-project-view.css for the Tier 4 project-view arketype -->
<!-- Optional: only include print.css if scenario produces a printable A4 report -->
<link rel="stylesheet" href="../../shared/playground-design-system/print.css">
<link rel="stylesheet" href="vendor/playground-design-system/print.css">
<!-- Self-hosted fonts (no external requests) -->
<link rel="stylesheet" href="../../shared/playground-design-system/fonts.css">
<link rel="stylesheet" href="vendor/playground-design-system/fonts.css">
</head>
<body>
<header class="app-header">
@ -93,7 +154,77 @@ To use the design system from a plugin's Playground:
</html>
```
The relative path `../../shared/playground-design-system/` assumes the plugin's Playground lives at `plugins/{plugin-name}/playground/index.html`. Adjust the prefix to match your plugin's structure.
The relative path `vendor/playground-design-system/` assumes the plugin's Playground HTML lives at
`<plugin-name>/playground/<plugin-name>-playground.html`, with the design system vendored (copied
in) at `<plugin-name>/playground/vendor/playground-design-system/`. Adjust the prefix to match your
plugin's structure.
The theme-bootstrap script is not part of the vendored CSS — copy it into each Playground's own
`<head>`, replacing `<plugin-name>-theme` with a key unique to that plugin (both `ms-ai-architect`
and `llm-security` follow this pattern today). The `data-theme-toggle` button's own click handler
(written per Playground, not vendored) is what writes that key via `localStorage.setItem` when the
reader switches theme — the bootstrap script only reads it back on the next load. Without the
bootstrap script, the page renders in the HTML attribute's default theme for one frame before
JavaScript applies the saved/OS preference — the FOUC it exists to prevent.
## Vendoring and re-sync
Vendoring remains the recommended consumer model. Measured 2026-08-27 across both consumers
(`ms-ai-architect`, `llm-security`): 26 of 27 vendored files are byte-identical to this repo's
current content three and a half months after their last sync, and neither copy has been edited
locally. The only file that differs is this README.
### Re-sync
From a checkout of this repo, with the consumer repo checked out alongside it:
```sh
node scripts/sync-design-system.mjs <consumer-name> --target ../<consumer-repo>
```
That rewrites `<consumer-repo>/playground/vendor/playground-design-system/` — the 27 delivered
files plus a regenerated `MANIFEST.json`. `--target` is the consumer's **repo root**; the script
appends `playground/vendor/playground-design-system/` itself. `--source <dir>` selects a
different checkout of this repo to read from (default: the one the script lives in). Node 16.7+,
no npm dependencies, no install step.
The script refuses to overwrite a vendored file that was edited locally since the last sync;
`--force` overrides. It copies an explicit allowlist (`DELIVERED_FILES` in the script), not the
repo root — `STATE.md`, `.git/`, `docs/`, `playground-examples/`, `LICENSE` and `SECURITY.md`
stay here. `tests/sync-source-boundary.test.mjs` pins that boundary in both directions: nothing
outside the allowlist reaches a consumer, and a new design-system file that is missing *from* the
allowlist fails the sync loudly instead of silently not shipping.
```sh
node --test tests/sync-source-boundary.test.mjs
```
### Checking a vendored copy
Integrity, from the consumer side, needs no source checkout:
```sh
node scripts/sync-design-system.mjs <consumer-name> --target ../<consumer-repo> --check
```
It re-hashes the vendored tree against that copy's own `MANIFEST.json`, then prints
`MANIFEST OK (27 files, source_commit ...)` and exits 0, or lists the differing files and exits 2.
It reads only — `--check` writes nothing to the consumer.
**Without the script, do not compare a vendored copy to this repo with a plain `diff` or `cmp`.**
The sync injects `/* Code generated by sync-design-system.mjs; DO NOT EDIT. */` as line 1 of every
`.css`, and the source has no such line, so a raw comparison reports **all nine stylesheets as
drifted** when none of them is. Measured 2026-08-27 against `ms-ai-architect`: raw `cmp` matches
17 of 27 files; strip line 1 from the vendored `.css` files and it is 26 of 27, the only real
difference being this README. `--check` is immune, because it hashes the vendored tree against
`MANIFEST.json` — which was built after the header was injected — and never against the source.
`MANIFEST.json`'s `source` and `source_commit` fields in the existing copies still describe the
old monorepo layout, and the recorded commit is not merely unreachable but inaccurate. Leave them
alone: the next real re-sync rewrites both truthfully. Do not repair them by hand — rewriting only
the path would turn an obviously stale pointer into a plausible false one. See
[docs/vendoring-and-re-sync.md](docs/vendoring-and-re-sync.md) for the full decision and the
measurements behind it.
## Design principles