The doc argued that the first real re-sync is what makes source_commit truthful, but never said what the restored script actually writes: source is the repo name (not a path, not a machine-local absolute path) and source_commit is git rev-parse HEAD in the source checkout. Naming the second half makes an ordering constraint visible that was implicit: a re-sync run before this repo's commit reaches the public mirror stamps two public consumer repos with a hash that exists on one machine. That is the c1b7bad defect again with a fresher date, so the check to run first is written out.
12 KiB
Vendoring and re-sync
Status: decision recorded 2026-08-27; the re-sync script was restored the same day with an explicit source boundary. See Current state for the published command.
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 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: 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? Yes, since 2026-08-27.
scripts/sync-design-system.mjs was absent from the entire marketplace tree.
It survived in full in the catalog repo's history, which carries the
pre-migration monorepo history (977 commits), and was read back with:
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 could not be restored unchanged. The script walked its source directory
and copied everything it found. 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/. That is not a hypothetical: run verbatim
against this repo's root, the recovered script vendored 109 files instead of
27, STATE.md and the whole of .git/ among them — and STATE.md is
deliberately gitignored because this repo's remote is public.
The boundary chosen is an explicit allowlist (DELIVERED_FILES in the
script) rather than a dist/ directory. A dist/ would duplicate every
stylesheet and insert a copy step that can silently go stale; the allowlist
names the delivered set in one place that the tests read directly, so there is
no second definition to drift from.
An allowlist has one failure mode of its own: a file added to the design system
but not to the list would silently stop shipping, and --check would never
notice, because it hashes a consumer's tree against that consumer's own
MANIFEST.json and never against the source. This repo has already lived
through that shape once — components-tier4-project-view.css was added in
v0.6.0 and was missing from the README's own directory tree until 2026-08-18.
So the script scans the source for design-system files the allowlist does not
name (root-level *.css, plus everything under fonts/ and schemas/) and
refuses to run, naming the file. Both directions are covered by
tests/sync-source-boundary.test.mjs.
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.
Concretely, the restored script writes source: "playground-design-system" —
the repo name, not a path inside it and not the absolute path of whatever
checkout happened to be read, since either would be a machine-local string in a
committed file. source_commit comes from git rev-parse HEAD in the source
checkout. That makes the push order load-bearing: run the first re-sync only
after this repo's commit is on the public mirror, or the manifest gets a hash
that exists on one machine — the same unreachable-pointer defect as c1b7bad,
with a fresher date on it. Check with
git -C <this repo> rev-parse HEAD against git -C <this repo> rev-parse origin/main
before syncing.
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
Re-sync, run from a checkout of this repo with the consumer checked out alongside it:
node scripts/sync-design-system.mjs <consumer-name> --target ../<consumer-repo>
Integrity check, which needs no source checkout and writes nothing to the consumer:
node scripts/sync-design-system.mjs <consumer-name> --target ../<consumer-repo> --check
--target is the consumer's repo root; the script appends
playground/vendor/playground-design-system/ itself. Pointing --target at
the vendor directory instead makes --check look one level too deep, find no
MANIFEST.json, and report drift that does not exist.
One trap worth naming for anyone checking by hand instead. 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 plain diff or cmp
against this repo reports all nine stylesheets as drifted when none of them
is: raw cmp matches 17 of 27 files, and stripping line 1 from the vendored
.css files puts it back at 26 of 27 with this repo's README the only real
difference. --check is immune, because it hashes the vendored tree against
MANIFEST.json, which was built after the header was injected. This was found
by ms-ai-architect on their own copy and re-measured here (see the
Verification log).
MANIFEST.json should still be left alone. This session restored the script
but ran no re-sync, so the fields described in § 3 above are unchanged and the
reasoning there still holds: the first real re-sync is what rewrites them
truthfully.
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() |
| The verbatim script leaks this repo's apparatus | ran the recovered script unchanged, --source <repo root>, into a temp target |
109 files vendored instead of 27; STATE.md, .git, .gitignore, docs, playground-examples, LICENSE, SECURITY.md all present. tests/sync-source-boundary.test.mjs red on this build, with tokens.css present as the known-positive control proving the assertions read the right path. |
| The allowlisted script does not leak | node --test tests/sync-source-boundary.test.mjs after the boundary was added |
2/2 pass: 27 files + MANIFEST.json, none of the seven apparatus entries present |
| An unlisted design-system file fails the sync | test adds components-tier5.css to a complete synthetic source |
non-zero exit, filename named in stderr. Known-positive control: the same source without the extra file syncs cleanly. |
The published --check command works against both consumers |
node scripts/sync-design-system.mjs <name> --target ../<name> --check |
MANIFEST OK (27 files, source_commit c1b7bad3899c5cfe9ff90663003609b018aa79a0), exit 0, for ms-ai-architect and llm-security alike |
A raw cmp misreports the CSS as drifted |
cmp per file vs this repo's root, then cmp with line 1 stripped |
raw: 17/27 match, the 10 differing being 9 .css + README.md; line-1-stripped: 26/27, README.md alone. Independently re-measured here; matches ms-ai-architect's finding exactly. |
Not verified: whether catalog's history is itself mirrored anywhere off this
machine. The recovery path above assumes a local catalog checkout.