docs(vendoring): record re-sync decision and measured consumer drift
Vendoring stands: 26/27 vendored files are byte-identical in both consumers 3.5 months on, with no local drift. No re-sync command is published yet - the script is recoverable in full from catalog history and is already polyrepo-ready, but restoring it unchanged would copy this repo's root wholesale, STATE.md included. Also records that MANIFEST.json's source_commit c1b7bad is not merely unreachable but false: the vendored tree carries components-tier4-project-view.css, which did not exist in that commit. Verified with git cat-file -e plus a known-positive control on components-tier3.css in the same commit. Verification was find/git cat-file/SHA-256 comparison, not grep - the full log is in docs/vendoring-and-re-sync.md.
This commit is contained in:
parent
0fa22b9f83
commit
c4253027ed
2 changed files with 181 additions and 0 deletions
29
README.md
29
README.md
|
|
@ -12,6 +12,7 @@ Playgrounds are the visual self-service UIs that complement a plugin's terminal
|
||||||
- [Provenance](#provenance)
|
- [Provenance](#provenance)
|
||||||
- [Directory layout](#directory-layout)
|
- [Directory layout](#directory-layout)
|
||||||
- [Quick start](#quick-start)
|
- [Quick start](#quick-start)
|
||||||
|
- [Vendoring and re-sync](#vendoring-and-re-sync)
|
||||||
- [Design principles](#design-principles)
|
- [Design principles](#design-principles)
|
||||||
- [Token system](#token-system)
|
- [Token system](#token-system)
|
||||||
- [Component reference](#component-reference)
|
- [Component reference](#component-reference)
|
||||||
|
|
@ -162,6 +163,34 @@ reader switches theme — the bootstrap script only reads it back on the next lo
|
||||||
bootstrap script, the page renders in the HTML attribute's default theme for one frame before
|
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.
|
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.
|
||||||
|
|
||||||
|
**There is no re-sync command today.** The `sync-design-system.mjs` script that produced the
|
||||||
|
existing vendored copies was deleted with the monorepo layout in 2026-06. It is recoverable in
|
||||||
|
full from the `catalog` repo's history and belongs in this repo once restored, but restoring it
|
||||||
|
unchanged would copy this repo's root wholesale — including files that are not part of the
|
||||||
|
delivered system. That boundary is an open decision, so no command is published here rather than
|
||||||
|
one that would be wrong.
|
||||||
|
|
||||||
|
Until then, a consumer can still check its own copy without any script:
|
||||||
|
|
||||||
|
- **Integrity** — re-hash the vendored files against the SHA-256 values in that copy's own
|
||||||
|
`MANIFEST.json`. Answers "has anyone edited the vendored files locally?"
|
||||||
|
- **Drift** — hash each vendored file, stripping the
|
||||||
|
`/* Code generated by sync-design-system.mjs; DO NOT EDIT. */` header line the sync injects into
|
||||||
|
every `.css`, and compare against the same filename at this repo's root.
|
||||||
|
|
||||||
|
`MANIFEST.json`'s `source` and `source_commit` fields in the existing copies point at the old
|
||||||
|
monorepo layout. Leave them alone for now — the recorded `source_commit` is not just unreachable
|
||||||
|
but inaccurate, and rewriting only the path would make a false pointer look plausible. See
|
||||||
|
[docs/vendoring-and-re-sync.md](docs/vendoring-and-re-sync.md) for the full decision, the
|
||||||
|
measurements behind it, and the recovery command.
|
||||||
|
|
||||||
## Design principles
|
## Design principles
|
||||||
|
|
||||||
1. **Aksel/Digdir-aligned.** Inter font, body 17px, Digdir blue `#0062BA`, semantic CSS tokens. Norwegian public sector users recognize this DNA.
|
1. **Aksel/Digdir-aligned.** Inter font, body 17px, Digdir blue `#0062BA`, semantic CSS tokens. Norwegian public sector users recognize this DNA.
|
||||||
|
|
|
||||||
152
docs/vendoring-and-re-sync.md
Normal file
152
docs/vendoring-and-re-sync.md
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
# Vendoring and re-sync
|
||||||
|
|
||||||
|
**Status:** decision recorded 2026-08-27. The re-sync script is recoverable but
|
||||||
|
not yet restored — see [Current state](#current-state) for what a consumer can
|
||||||
|
and cannot do today.
|
||||||
|
|
||||||
|
This document answers three questions raised by a consumer repo on 2026-08-26:
|
||||||
|
whether a current re-sync path exists, whether vendoring is still the
|
||||||
|
recommended consumer model, and where `MANIFEST.json`'s `source` field should
|
||||||
|
point now that the marketplace is a polyrepo.
|
||||||
|
|
||||||
|
Every number below was measured against ground truth on 2026-08-27, not
|
||||||
|
recalled. The measurements are listed in [Verification log](#verification-log)
|
||||||
|
so a reader can re-run them.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
Until 2026-06-18 the marketplace was a monorepo. This design system lived at
|
||||||
|
`shared/playground-design-system/`, and `scripts/sync-design-system.mjs`
|
||||||
|
vendored it into each plugin's `playground/vendor/playground-design-system/`.
|
||||||
|
Commit `e84dffd` ("thin catalog to manifest + docs (polyrepo migration
|
||||||
|
complete)") deleted both paths in the same change. This repo was extracted as a
|
||||||
|
sibling with the CSS files at its root and a fresh 17-commit history.
|
||||||
|
|
||||||
|
Consumer documentation kept pointing at the monorepo layout, so the instructions
|
||||||
|
it gave named a directory and a script that no longer existed anywhere.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
### 1. Is vendoring still the recommended model? Yes.
|
||||||
|
|
||||||
|
This is settled first, because the other two answers depend on it.
|
||||||
|
|
||||||
|
The measurement supports keeping it. Three and a half months after the last
|
||||||
|
sync, in both consumers, **26 of 27 vendored files are byte-identical to this
|
||||||
|
repo's current content**, and each `MANIFEST.json` still matches its own files
|
||||||
|
exactly — no consumer has edited a vendored file locally. The one file that
|
||||||
|
differs is this repo's own `README.md`, which documents the system rather than
|
||||||
|
being part of what it delivers.
|
||||||
|
|
||||||
|
Vendoring did what it promised: the consumers stayed standalone and kept
|
||||||
|
rendering correctly when the source moved out from under them. What broke was
|
||||||
|
the *documentation pointing at the mechanism*, not the mechanism.
|
||||||
|
|
||||||
|
Nothing replaces it. A git submodule or an npm package would contradict the
|
||||||
|
Non-goals in [README.md](../README.md): no build step, no bundler, no package
|
||||||
|
registry, and a Playground that opens from `file://` with only the CSS files
|
||||||
|
alongside it.
|
||||||
|
|
||||||
|
### 2. Is there a current re-sync path? Not yet — but the script is not lost.
|
||||||
|
|
||||||
|
`scripts/sync-design-system.mjs` is absent from the entire marketplace tree
|
||||||
|
today. It survives in full in the `catalog` repo's history, which carries the
|
||||||
|
pre-migration monorepo history (977 commits). It can be read back with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git -C <marketplace>/catalog show e84dffd^:scripts/sync-design-system.mjs
|
||||||
|
```
|
||||||
|
|
||||||
|
It is 225 lines, has no npm dependencies, and — this matters — it was **already
|
||||||
|
prepared for the polyrepo split before the split happened**. It accepts
|
||||||
|
`--source <dir>` and `--target <dir>`, both of which override the hardcoded
|
||||||
|
monorepo paths, and its own comment says the `--target` flag exists "so the
|
||||||
|
script still works once `plugins/<name>` no longer exists in-repo
|
||||||
|
(post-migration / extracted repo)". It also has a `--check` mode that re-hashes
|
||||||
|
a consumer's vendored tree against its committed `MANIFEST.json` and exits
|
||||||
|
non-zero on drift, needing no source at all.
|
||||||
|
|
||||||
|
So restoring it is recovery, not new development, and it belongs in **this
|
||||||
|
repo** — the mechanism vendors *from* the design system, so the design system
|
||||||
|
owns it.
|
||||||
|
|
||||||
|
**It cannot be restored unchanged, and that is why no command is published
|
||||||
|
here yet.** The script walks its source directory and copies everything it
|
||||||
|
finds. In the monorepo, `shared/playground-design-system/` contained only the
|
||||||
|
design system. This repo's root contains the design system *plus* the repo
|
||||||
|
apparatus: `STATE.md`, `LICENSE`, `SECURITY.md`, `.git/`, `docs/`, and
|
||||||
|
`playground-examples/`. A naive `--source .` would vendor all of it into both
|
||||||
|
consumers — including `STATE.md`, which is deliberately gitignored and must
|
||||||
|
never reach a public mirror.
|
||||||
|
|
||||||
|
Restoration therefore needs an explicit source boundary — an allowlist of the
|
||||||
|
27 delivered files, or a `dist/` directory the script reads from. Choosing
|
||||||
|
between those is the next decision, and it is a real one; publishing a
|
||||||
|
`--source .` command today would be a guess that leaks.
|
||||||
|
|
||||||
|
### 3. Where should `MANIFEST.json`'s `source` point? Here — but not yet.
|
||||||
|
|
||||||
|
This is not the consumer's business alone: the field is written by this repo's
|
||||||
|
script and describes this repo's source, so the value is ours to define.
|
||||||
|
|
||||||
|
The important finding is that `source_commit` is not merely unreachable — **it
|
||||||
|
is false**. Both consumers record
|
||||||
|
`source_commit: c1b7bad3899c5cfe9ff90663003609b018aa79a0`, but the vendored tree
|
||||||
|
contains `components-tier4-project-view.css`, and that file demonstrably did not
|
||||||
|
exist in `c1b7bad`. The sync labelled its output with the marketplace's `HEAD`
|
||||||
|
while copying the working tree, which at that moment held a v0.6.0 file that had
|
||||||
|
not been committed yet.
|
||||||
|
|
||||||
|
The consequence for repair: **do not fix the field by translating the path.**
|
||||||
|
Rewriting `shared/playground-design-system/` to this repo's name while keeping
|
||||||
|
`c1b7bad` would turn an obviously stale pointer into a plausible false one, and
|
||||||
|
a plausible false pointer is worse — it stops inviting the check that would
|
||||||
|
catch it.
|
||||||
|
|
||||||
|
The correct order is: restore the script with a source boundary, run one
|
||||||
|
re-sync, and let the script write a truthful manifest in which `source_commit`
|
||||||
|
is this repo's `HEAD` — reachable from this repo, unlike `c1b7bad`. Until then,
|
||||||
|
a visibly stale field is the more honest state.
|
||||||
|
|
||||||
|
One correction to the premise this question arrived with: the lineage is **not**
|
||||||
|
severed. `c1b7bad` is unreachable from this repo and from either consumer, but
|
||||||
|
it is alive in `catalog`. "Nobody can compute how far behind a vendored copy is"
|
||||||
|
does not hold — it was computed, and the answer is one file.
|
||||||
|
|
||||||
|
## Current state
|
||||||
|
|
||||||
|
What a consumer can do today, with no script:
|
||||||
|
|
||||||
|
- **Verify integrity** — re-hash the vendored files against the SHA-256 values
|
||||||
|
in the copy's own `MANIFEST.json`. This needs nothing but the consumer's own
|
||||||
|
checkout and answers "has anyone edited the vendored copy locally?"
|
||||||
|
- **Measure drift against this repo** — hash each vendored file (stripping the
|
||||||
|
`/* Code generated by sync-design-system.mjs; DO NOT EDIT. */` header line
|
||||||
|
that the sync injects into every `.css`) and compare against the file of the
|
||||||
|
same name at this repo's root.
|
||||||
|
|
||||||
|
What a consumer cannot do today: re-sync with one command. That is pending the
|
||||||
|
source-boundary decision above.
|
||||||
|
|
||||||
|
`MANIFEST.json` should be left alone in the meantime.
|
||||||
|
|
||||||
|
## Verification log
|
||||||
|
|
||||||
|
Measured 2026-08-27 against ground truth. `<marketplace>` is the polyrepo root.
|
||||||
|
|
||||||
|
| Claim | How it was checked | Result |
|
||||||
|
|---|---|---|
|
||||||
|
| `sync-design-system.mjs` absent from the marketplace | `find` over the tree, maxdepth 5, `.git`/`node_modules` pruned | 0 hits. Denominator: the same query returned 836 `.mjs` files; known-positive control found `catalog/scripts/check-versions.mjs`, so the query can find. |
|
||||||
|
| `shared/` absent | `find -type d -name 'shared*'`, maxdepth 3 | 0 hits |
|
||||||
|
| Two consumers vendor the system | `find -type d -name playground-design-system`, maxdepth 4 | `ms-ai-architect` and `llm-security`, 27 files + `MANIFEST.json` each |
|
||||||
|
| `c1b7bad` unreachable from this repo | `git cat-file -t` | fatal: could not get object info. Known-positive control on this repo's `HEAD` returned `commit`. |
|
||||||
|
| `c1b7bad` reachable from `catalog` | `git -C catalog cat-file -t` | `commit` — 2026-05-15, monorepo history, 977 commits |
|
||||||
|
| The monorepo commit held both deleted paths | `git -C catalog ls-tree -r c1b7bad` | `shared/playground-design-system/` (26 files) and `scripts/sync-design-system.mjs` both present |
|
||||||
|
| Both paths died in the migration | `git -C catalog log --diff-filter=D` | `e84dffd`, 2026-06-18, deleted both |
|
||||||
|
| `source_commit` is false | `git -C catalog cat-file -e c1b7bad:shared/playground-design-system/components-tier4-project-view.css` | path does not exist in `c1b7bad`. Known-positive control on `components-tier3.css` in the same commit succeeded. |
|
||||||
|
| No local drift in either consumer | SHA-256 of each vendored file vs its own `MANIFEST.json` | both `MANIFEST OK`, 27/27 |
|
||||||
|
| Drift vs this repo | SHA-256 vs this repo's root, generated-header stripped from `.css` | 26/27 identical in both consumers; `README.md` the only difference |
|
||||||
|
| The recovered script supports polyrepo | read of `git show e84dffd^:scripts/sync-design-system.mjs` | `--source`, `--target`, `--check` all present and honoured in `main()` |
|
||||||
|
|
||||||
|
Not verified: whether `catalog`'s history is itself mirrored anywhere off this
|
||||||
|
machine. The recovery path above assumes a local `catalog` checkout.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue