feat(sync): restore sync-design-system.mjs with an explicit source boundary
The script that produced the existing vendored copies was deleted with the monorepo layout in 2026-06 and recovered from catalog's history (e84dffd^:scripts/sync-design-system.mjs). It could not be restored unchanged: it walks its source directory and copies everything, and this repo's root is no longer a directory holding only the design system. Run verbatim it vendored 109 files instead of 27, STATE.md and the whole of .git/ among them - and STATE.md is gitignored precisely because this repo's remote is public. The boundary is an explicit allowlist (DELIVERED_FILES) rather than a dist/ directory: one definition, read directly by the tests, with no copy step to go stale. The allowlist's own failure mode - a new design-system file forgotten from the list ships nothing, and --check stays green because it hashes a consumer's tree against that consumer's own MANIFEST - is closed by scanning the source for unlisted root-level *.css, fonts/* and schemas/* and refusing to run. tests/sync-source-boundary.test.mjs pins both directions. It was red on the verbatim script for the right reason (STATE.md present in the target, with tokens.css as the known-positive control) before the boundary was written. --target is the consumer's repo root; the script appends playground/vendor/playground-design-system/ itself. --check verified read-only against both consumers: MANIFEST OK (27 files) for ms-ai-architect and llm-security alike. No re-sync was run, so both MANIFEST.json files are untouched and the stale source_commit is still theirs to inherit at the first real re-sync. README and docs/vendoring-and-re-sync.md now publish the command, and warn that a plain diff/cmp against this repo reports all nine stylesheets as drifted because the sync injects a generated-header line the source does not have - 17/27 raw, 26/27 with line 1 stripped. Found by ms-ai-architect, re-measured here.
This commit is contained in:
parent
c4253027ed
commit
7448cec304
4 changed files with 601 additions and 51 deletions
|
|
@ -1,8 +1,8 @@
|
|||
# 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.
|
||||
**Status:** decision recorded 2026-08-27; the re-sync script was restored the
|
||||
same day with an explicit source boundary. See
|
||||
[Current state](#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
|
||||
|
|
@ -47,11 +47,11 @@ 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.
|
||||
### 2. Is there a current re-sync path? Yes, since 2026-08-27.
|
||||
|
||||
`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:
|
||||
`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:
|
||||
|
||||
```sh
|
||||
git -C <marketplace>/catalog show e84dffd^:scripts/sync-design-system.mjs
|
||||
|
|
@ -70,19 +70,31 @@ 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.
|
||||
**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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
|
@ -115,20 +127,40 @@ does not hold — it was computed, and the answer is one file.
|
|||
|
||||
## Current state
|
||||
|
||||
What a consumer can do today, with no script:
|
||||
Re-sync, run from a checkout of this repo with the consumer checked out
|
||||
alongside it:
|
||||
|
||||
- **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.
|
||||
```sh
|
||||
node scripts/sync-design-system.mjs <consumer-name> --target ../<consumer-repo>
|
||||
```
|
||||
|
||||
What a consumer cannot do today: re-sync with one command. That is pending the
|
||||
source-boundary decision above.
|
||||
Integrity check, which needs no source checkout and writes nothing to the
|
||||
consumer:
|
||||
|
||||
`MANIFEST.json` should be left alone in the meantime.
|
||||
```sh
|
||||
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](#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
|
||||
|
||||
|
|
@ -147,6 +179,11 @@ Measured 2026-08-27 against ground truth. `<marketplace>` is the polyrepo root.
|
|||
| 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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue