migrate
The migrate skill applies the visual design, canonical components, and brand modules to every page in a captured website inventory, producing a deployable…
Identity proven by GitHub's verified organisation badge (adobe)
- Agents
- Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode
- License
- Apache-2.0 (permissive)
- Pin
- 940b879pinned Oct 9, 2026
- Context cost
- about 7,400 tokenswhen the skill loads
- GitHub stars
- 197on adobe/skills
- Scripts
- 4 scripts
What it does
“Apply DESIGN, canon, and modules to every page in the inventory, producing a deployable static HTML site. Use to migrate or render the whole captured site into the redesigned static tree ("migrate the pages", "render the migrated site", "apply the design to all pages", "build the deployable site", "convert the approved prototype into the full site") — the page-rendering step between prototype and deploy/rollout. Three render branches (approved page, template-applied sibling, unique render), with a declared fidelity tier per page. Per-page, incremental, idempotent, content-preserving by default.”
Generated summary from the skill's own text
The migrate skill applies the visual design, canonical components, and brand modules to every page in a captured website inventory, producing a deployable static HTML site stored in stardust/migrated/. It performs per-page, incremental rendering with three branches (approved page, template-applied sibling, unique render) and declares a fidelity tier for each page. All output is self-contained and portable across file://, web servers, and subpath deployments.
When to use it
- Converting a prototype design to a full static site for all pages
- Rendering pages after design direction and approval steps complete
- Building deployable HTML when downstream systems consume migrated/ plus metadata sidecars
- Re-rendering the site when design or canonical components change
When not to
- Before completing the direct, prototype, and prepare-migration phases
- When pages lack mobile-adapt coverage without canonical breakpoint rules
- When downstream conversion uses tools other than consuming migrated/ plus DESIGN.json sidecars
Install
These commands install from the publisher's repository and need no account.
skills CLI
npx skills add adobe/skills --skill migrateInstalls from the repository's default branch, which may have changed since the commit we checked.
GitHub CLI 2.90 or later
gh skill install adobe/skills migrate@940b8795c0df3e25de68ce3881dc90855129b215Installs the commit we checked (940b879).
Copy by hand
Download the folder at 940b879 and put it in .claude/skills/migrate for Claude Code and in .agents/skills/migrate for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.
Claude Code plugin
/plugin install adobe-for-creativity@claude-plugins-officialThe publisher's plugin in Claude's official marketplace. It may hold more than this skill, and we have not pinned it.
Copy for your agent
A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.
Prompt
Install the agent skill "migrate" by Adobe, Inc.. Source, pinned to commit 940b8795c0df3e25de68ce3881dc90855129b215: https://github.com/adobe/skills/tree/940b8795c0df3e25de68ce3881dc90855129b215/plugins/stardust/skills/migrate 1. Download that folder at exactly this commit. Do not use the default branch. 2. Copy every file unchanged, keeping the folder structure, into .claude/skills/migrate/ for Claude Code and .agents/skills/migrate/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist. 3. Do not edit the files, and do not run any script in the folder unless I ask you to. 4. When you are done, list the files you copied and where you put them. Listing and checks: https://www.agentnative.dev/skills/adobe-inc/migrate
SKILL.md at the pin
---
name: migrate
description: Apply DESIGN, canon, and modules to every page in the inventory, producing a deployable static HTML site. Use to migrate or render the whole captured site into the redesigned static tree ("migrate the pages", "render the migrated site", "apply the design to all pages", "build the deployable site", "convert the approved prototype into the full site") — the page-rendering step between prototype and deploy/rollout. Three render branches (approved page, template-applied sibling, unique render), with a declared fidelity tier per page. Per-page, incremental, idempotent, content-preserving by default.
license: Apache-2.0
compatibility: Requires Node 22+, Playwright with Chromium resolvable from the project, playwright-cli on PATH, and the impeccable skill (github.com/pbakaus/impeccable) installed alongside stardust.
---
# stardust:migrate
Apply the target spec authored by `direct`, the visual canon
written by `prototype --prep`, and the brand-module catalog
extracted during `prepare-migration` to every page in the
inventory. Produces a self-contained, deployable static HTML site
under `stardust/migrated/`. Per-page, incremental, idempotent.
`migrate` is the final stardust phase. Output is platform-
agnostic HTML — downstream conversion (AEM EDS, a CMS, a
framework) is the job of a separate plugin that consumes
`migrated/` plus `DESIGN.json` plus the per-page `_meta.json`
sidecars.
## Inputs
- `<slug>` — optional positional. Migrate just this page. Without
it, migrate every page whose status is `directed`,
`prototyped`, or `approved` (and not `stale`).
- `--all` — migrate every page including stale ones.
- `--force` — re-migrate every page even when the idempotent
skip would skip them.
- `--require-approved` — refuse to migrate any non-`approved`
page. Default behaviour migrates `directed` pages too (using
Path A′ or Path B per
`reference/template-and-module-rendering.md`); this flag flips
approval-gating on.
- `--strict-canon` — refuse approvals that conflict with canon.
Default logs the deviation and continues. Useful for projects
where canon discipline matters more than per-template
flexibility.
- `--clean` — delete assets previously bundled but no longer
referenced from `stardust/migrated/assets/`. Off by default
(migrate is additive). **Implies `--force`**: every page is
re-rendered so the run's `bundledAssets` Set is the complete
union of currently-referenced assets — otherwise `--clean`
would risk deleting assets still referenced by
idempotent-skipped pages. See
`reference/asset-bundling.md` § Stale asset cleanup.
- `--pin-timestamp <ISO8601>` — pin the migrate-provenance
timestamp so re-runs without source changes produce byte-
identical HTML. Default re-uses the current wall clock, which
is fine for normal use; CI deployment fingerprinting may want
the pin.
The mobile-adapt audit, content-sourcing scan, and placeholder
refusal are all mandatory gates — there is no `--skip-*` or
`--allow-*` flag to bypass them. If a gate refuses a page, the
remediation is to fix the proposed file (re-prototype, edit
inline, or run an impeccable command) and re-invoke migrate.
## Setup
0. **Playwright re-probe (mandatory first step).** `--no-save` playwright
installs from earlier phases are pruned by any later real `npm i`
(extract SKILL.md § Setup → `--no-save` installs are ephemeral). Before
any rendering step, probe
`node -e "import('playwright').then(()=>process.exit(0))"` from the
project root and re-install (`npm i -D playwright --no-save
--legacy-peer-deps`) on failure.
1. Run the master skill's setup
(`skills/stardust/SKILL.md` § Setup). **Flow guard.** If
`stardust/state.json` exists without `flow` and the ask is a
migration (a URL plus "migrate" / "to EDS" / "re-platform"), do not
run: print the two-flow table from the master skill § Two migration
flows and hand back to its routing — the flow is chosen and stamped
there before any sub-skill runs
(`skills/stardust/reference/state-machine.md` § Flow keys): `replica`
unless the ask names a redesign.
(Recorded: `migrate <url>` as the first command of two same-design
migrations led to a hand-built compiler tuned by eye instead of the
replica gate.)
2. Verify `stardust/state.json` exists with at least one
`directed` page.
3. Verify project-root `DESIGN.md` and `DESIGN.json` exist with
`DESIGN.json.extensions.canon` populated.
4. Verify `stardust/canon/` exists with at least
`header.html`, `footer.html`, `canon.css`.
**Canon auto-bootstrap (when steps 3–4 find no canon).** The
documented `prototype → migrate → deploy` happy path does not
run `prepare-migration`, so a first migrate legitimately arrives
with no canon (observed on 4 of 6 e2e sites, where every run had
to derive canon by hand to proceed — this is the fix). When
canon is absent **and** at least one `approved` prototype exists,
do not stop: run the canon write-back inline from the first
approved prototype (the canon-author, default `home`) per
`../prototype/reference/canon-extraction.md` § Five-step
procedure — extract `header.html` / `footer.html` / `canon.css`
to `stardust/canon/`, pin tokens + compositional moves to
`DESIGN.json.extensions.canon`, and record
`canon.source: "auto-bootstrap: <slug>"`. This is exactly what
`prototype --prep` does on first approval; migrate performs it
on demand so the core pipeline never dead-ends. Only stop and
recommend `$stardust prepare-migration` when canon is absent
**and** no approved prototype exists (there is nothing to derive
canon from). Under `state.json.handsOff` the bootstrap is
automatic and logged; interactively, surface it as a one-line
notice before proceeding.
5. Verify `stardust/direction.md` has an active (not pending)
direction.
6. Read `state.json.pages[]` and partition into:
- **inScope**: status `directed`, `prototyped`, or
`approved`, `stale: false` (or `--all` / explicit
`<slug>`).
- **skipped**: everything else, with reason captured.
7. **Validate provenance on every in-scope page.** Call
`validateProvenance(page)` per
`skills/stardust/reference/state-machine.md` § Provenance
validation for every page in `inScope`. Abort with the
helper's error when any page lacks live-render evidence —
migrating a synthesized page record produces deployable HTML
that misrepresents the source site, the exact failure mode
that motivated the validator. Surface `Provenance OK on N
pages` in the migrate-plan output before Phase 1.
8. **Mobile-adapt audit on every Path A / Path A′ source.** For
every page whose render branch consumes a proposed or
archetype HTML file (Path A, Path A′ per
`reference/template-and-module-rendering.md` § Render path
selection), run the audit per `skills/prototype/SKILL.md`
§ Mobile-adapt audit:
- `<meta name="viewport" content="width=device-width, ...">`
present, width not pinned to a fixed pixel value.
- At least one `@media (max-width: ...)` rule.
- At least one mobile-targeted breakpoint at ≤ 640px.
Refuse pages that fail — the audit is mandatory; there is no
skip flag. The user fixes the proposed file (re-prototype or
chat-driven impeccable command) and re-invokes migrate.
Record the audit result per page in the migrate report and
in the post-render `_meta.json#audit.adapt` sidecar. Path B
(unique-renders) skips the audit because adapt hasn't run
on those pages — a Path B page that needs mobile coverage
gets it via `$impeccable adapt` invoked separately by the
user. Surface this distinction in the report so it's not
read as a silent skip.
## Procedure
### Phase 1 — Plan
**Dynamic-surface precondition (safety net).** If
`stardust/dynamic-features.md` is missing, the hand-run flow
(`extract → direct → prototype → migrate`) never passed a pre-import
gate: run the stardust `dynamics` skill Phases 1–3 now (`extract --dynamics`
for reach if needed, detector on the archetypes, triage draft, curate)
before rendering any page. Never import a site as static without a
decision per dynamic row. Per page, rows of the inventory that touch it
become `contentDeviations[]` `kind: "dynamic-dependency"` entries
(`reference/content-preservation.md § Dynamic dependencies`).
**Gated-archetype precondition (`flow: replica`).** Before rendering any
`sibling`-tier page, read `stardust/replica/progress.json`: the page
type's archetype must have a gate result at every configured breakpoint
that is `pass: true`, or over the bar with every residual carrying a
`cause` (`../replica/reference/source-fidelity-gate.md` § Residual
logging format — a documented residual is a pass with an asterisk). An
archetype never gated, or over the bar with no residual entries, blocks
its page type: report the archetype slug and `$stardust replica
<archetype>`, and render nothing for that type. The same rule guards
`rollout` Setup; the published-origin re-gate is unchanged. Thresholds
are the gate's.
Print the plan and wait for confirmation when the scope is large:
```
migrate plan
============
In scope: 127 pages
Path A (approved) 6 pages: home, news/post-housing-summit, news, ...
Path A' (template-applied) 118 pages: 84 article, 5 listing, 11 program, 2 form, 16 static
Path B (unique) 3 pages: 404, search, faq
Skipped: 0 stale, 0 unscoped
DESIGN.md sha: 1a2b3c4
DESIGN.json sha: 5d6e7f8
Canon shas: header:7g8h9i footer:9i0j1k css:1k2l3m
Output: stardust/migrated/ + per-page _meta.json sidecars
Idempotent skip: enabled (run with --force to override)
Reply "go" to proceed.
```
For 1-3 pages or `<slug>` invocation, skip the confirmation.
### Phase 2 — Per-page render
In the replica flow a sibling renders only after its archetype is deployed and gated at the
published origin (`../replica/reference/handoff-contract.md` § 3 row C, unit `C-archetype`; #126);
the render is the encoder's input, its gate is the row after PUT. For each page in scope, follow
`reference/migration-procedure.md` and
`reference/template-and-module-rendering.md`:
- **Idempotent skip check** first (sha-compare across
`designMd`, `designJson`, `sourceCurrent`, `sourceProposed`,
`canonShas`, `archetypeSource`).
- **Placeholder gate** (Path A and Path A′ only — pages with a
proposed file or archetype). Refuse when `[data-placeholder]`
elements or non-empty `_provenance.unsourcedContent[]` are
present — the user fills the missing content in the proposed
file before re-invoking migrate. No bypass flag.
- **Render branch selection** (LLM judgment per T&M §
Render path selection): A / A′ / B. **Declare the page's
`fidelityTier`** from the branch — A → `archetype` (craft-gated),
A′ → `sibling` (canon-fork, the cheap default for breadth — variance-probed
once per template before cloning, `reference/fidelity-tiers.md` § Sibling
variance probe; deltas become variant classes, never per-page forks),
B/bodyless → `thin` — per `reference/fidelity-tiers.md`. Record
`fidelityTier`, `archetypeSource`, `template` (the archetype's slug;
the archetype's own sidecar leaves it null), `modules[]` (the page's
block ids — composite sections only) and `gatesPassed[]` in
`_meta.json` so coverage shows what was craft-gated vs cloned and
rollout groups and dedups from the sidecars, without a census.
- **Render** per the chosen branch's procedure in T&M.
- **Canon application** — chrome injection, canon.css
injection, deviation logging.
- **Module rendering** — render module instances via
`stardust/canon/modules/<id>.html`; bespoke slots logged
with `data-bespoke`.
- **Apply content-preservation rules** per
`reference/content-preservation.md`. Internal-link rewriting
always emits migrated-tree paths; missing slugs flagged
broken.
- **Content-count acceptance** per
`reference/fidelity-tiers.md` § Content-count acceptance:
compare role-classified node counts (headings, body/list
nodes, CTAs, images) between the captured source page JSON
and the rendered result. A count drop in any class not
covered by a logged `contentDeviations[]` entry fails the
page — dropped-content importer bugs must surface here,
while the importer is still cheap to fix, not at a
downstream fidelity gate. Record the pass in
`_meta.json#gatesPassed[]` as `"content-count"`.
- **Compose `<head>` metadata** per
`reference/metadata-and-jsonld.md` (five categories;
page-type-driven JSON-LD).
- **Validate** per T&M § Validation contracts. Strict contracts
refuse the page; soft contracts log and continue.
- **Compute output path** per migration-procedure.md
§ Output path mapping.
- **Asset bundling.** Scan the final HTML for asset references
(six detection shapes per
`reference/asset-bundling.md` § Detection), copy each unique
referenced subpath from `stardust/current/assets/<subpath>` to
`stardust/migrated/assets/<subpath>` (preserving subdir
structure), then rewrite every reference to the root-relative
form `/assets/<subpath>`. Cross-page dedup uses a
module-level Set seeded from
`state.json.migrate.bundledAssets[]`. Missing source assets
warn-and-skip per § Edge cases; the bundle stays internally
consistent.
- **Media reconciliation.** For every image **not** bundled to
same-origin (reused source-CDN URLs under Mode A image-reuse),
decide optimize/keep/rewrite/omit per
`reference/media-reconciliation.md`. Cross-origin `<img>` kept
as source URLs must **skip `createOptimizedPicture`** (it drops
the `?v=` key and corrupts the rendition); broken URLs are
repaired (missing `?`-delimiter, wrong host) or omitted, never
shipped as `about:error`. `rollout` re-runs the authoritative
network resolve at delivery (`media-reconcile.mjs`).
- **Cinematic sibling (when `<slug>-cinematic.html` exists).**
Migrate consumes the STATIC prototype only — the cinematic layer
is never merged. Copy the motion assets (`lenis.min.js`,
`lenis.min.css`) from `stardust/prototypes/` to
`stardust/migrated/assets/motion/` (idempotent) for downstream
consumers (deploy/rollout decide whether to wire them), and
record `cinematic-variant-not-consumed` in the page's
`_meta.json#migrationDecisions[]`.
- **Write** the migrated `index.html` and the `_meta.json`
sidecar in the same directory. Provenance block as first
child of `<head>`. Record `assetsBundled` (count of unique
asset refs on this page) in `_meta.json`.
The mechanics of this phase are scripted:
`node skills/migrate/scripts/migrate.mjs render <slug…|--all>` (the
project copy runs from `stardust/scripts/migrate/`) builds the page
map, places each page at its URL-literal path, rewrites internal
links, bundles assets, composes `<head>` (provenance, `:root`,
canonical and JSON-LD defaults), validates strictly and writes the
sidecar, skipping pages whose input shas are unchanged. The judgments
it cannot make are recorded on the sidecar with `gate`, `deviation`,
`decision`, `variant` and `modules` on the same script; it never
advances `pages[].status`.
**Recorded units.** A whole-site render is bookkept as units in
`stardust/migrate/progress.json`, the shape of rollout's C-deliver unit
ledger (`../replica/reference/handoff-contract.md` § 3 row C):
`units.<name>: {status: pending|running|done|failed, kind:
plan|render|assets|report, templates[], pages: n, startedAt, endedAt,
verdict}`. One `plan` unit (Phase 1), one `render` unit per template
cluster of at most ~8 siblings (`migrate.mjs render <slug…>` takes the
cluster's slug list), one `assets` unit when Phase 3 rehosts media, one
`report` unit (Phase 4). Per unit, in this order: the `progress.json`
write → the checkpoint commit → the next unit; a unit end is a safe
resume point, not a stop. A session resumed inside migrate reads the file
and runs only the units not `done`; a unit left `running` re-renders its
slugs — the driver is idempotent, unchanged pages are skipped. A recorded
run rendered 31 siblings through five parallel builders as one unit in
one session — its most expensive — with no resume point between the plan
and the final report.
### Phase 3 — Sitewide assets and bundle finalisation
Per-page asset bundling already happened in Phase 2 (every
referenced media subpath is on disk under
`stardust/migrated/assets/`). Phase 3 fills in the **sitewide
assets** that no individual page references explicitly:
1. Copy `stardust/current/assets/logo.<ext>` to
`stardust/migrated/assets/logo.<ext>` (only if missing or
stale). Record under `state.json.migrate.bundledAssets[]`.
2. Verify favicon variants and font files were generated by
`prepare-migration` Phase 4. If absent, log a warning and
continue (the migrated site renders without them, just
missing some platform-specific affordances).
3. Add `stardust/migrated/robots.txt` and `sitemap.xml`
derived from the migrated page inventory per
`reference/metadata-and-jsonld.md` § Sitemap entry.
4. If `--clean` was passed, compute
`stale = priorBundle.filter(p => !bundledAssets.has(p))`
from `state.json.migrate.bundledAssets[]` and remove each
stale subpath from `stardust/migrated/assets/`. Record the
deletions under `state.json.migrate.cleanedAssets[]`. Per
`reference/asset-bundling.md` § Stale asset cleanup.
5. Verify **portability**. The bundle must work via `file://`,
at a webserver root, and at any subpath — "one shape, works
everywhere". Run every audit; any non-empty grep output or
non-zero fixture exit fails the run with the cited error
message:
```bash
# No source-tree escapes
find stardust/migrated/ -type f -name '*.html' -exec grep -l '\.\./current/' {} +
# Error: "asset still points outside the migrated tree; rewrite via the
# asset-bundling pass per reference/asset-bundling.md § Detection"
# No absolute internal references in attribute values (404 on file:// and subpath)
grep -rE '(href|src)="/[^/]' stardust/migrated/ --include='*.html'
# Error: "absolute href `/beers/` will 404 on file:// and on subpath hosts;
# rewrite via the page map per migration-procedure.md § Reference shape"
# No absolute internal references in url() (inline style, <style> blocks, CSS)
grep -rE 'url\(\s*["'\'']?\s*/[^/]' stardust/migrated/ --include='*.html' --include='*.css'
# Error: "absolute url(/...) reference will 404 on file:// and on subpath hosts;
# rewrite via the asset-bundling pass per asset-bundling.md § Rewrite"
# No directory-only nav (doesn't resolve on file://). Pattern accepts
# only relative or root-absolute hrefs (./, ../, /, or bare segment)
# so external URLs like https://google.com/ aren't false-flagged.
grep -rE 'href="(\.{0,2}/|[a-zA-Z0-9_-])[^:"#?]*/"' stardust/migrated/ --include='*.html'
# Error: "directory-only href `./beers/` won't resolve on file://;
# append the explicit index.html (or the source URL's .html leaf)
# per § Reference shape"
# pageMap consistency — every internal href appears as an outputPath
node skills/migrate/fixtures/pagemap-audit.mjs stardust/migrated/ stardust/state.json
# Error: "internal href has no pageMap entry; link rewriting bypassed the
# page map per § Page map (build once, use everywhere)"
# Headless file:// round-trip — the test that proves zip-and-deploy works
node skills/migrate/fixtures/file-protocol-audit.mjs stardust/migrated/
# Error: "<offending file> linked <ref> that 404s under file://; see the
# Playwright network log printed above"
```
The audits are mandatory — there is no skip flag. The contract
is "self-contained, zip-and-deploy" and these audits are the
verifiers that back the claim.
Asset migration is idempotent — files are content-hashed and
copied only when missing; per-page bundling deduplicates across
the run.
### Phase 4 — State and report
Update `state.json`:
- For each successfully migrated page: `status` advances to
`migrated`, append a history entry, clear any `stale` flag,
set `migratedPath`.
- For pages skipped via idempotent skip: leave state
unchanged.
- For pages that failed validation: leave state unchanged, log
the failure in `state.json.lastRun.failures[]`.
- Write the top-level `migrate` block per
`skills/stardust/reference/migrate-output-format.md`
§ State.json contract: `selfContained: true`, `outputDir`,
`totalAssetsBundled`, `bundledAssets[]`, per-page
`assetsBundled` counts, `missingAssets[]`, `cleanedAssets[]`.
This is the forward-compat signal downstream consumers test
for.
Print the run summary:
```
migrate complete
================
122 migrated home, about, news/post-housing-summit, ...
3 unchanged about, programs/shelter, news/post-old (idempotent skip)
2 failed contact (validation: required slot missing),
legal/privacy (validation: color-reservation violated)
0 stale skipped
Render branches:
Path A 6 approved-from-prototype
Path A' 116 template-applied (84 article, 5 listing, 11 program, 2 form, 14 static)
Path B 3 unique-render (404, search, faq)
Pages with non-trivial decisions: 12
about canon-deviation: footer carries financials disclaimer
donate template-adapted: amount-pills slot moved above headline
...
Broken internal links: 5
/events referenced by 2 pages; not in inventory
/press referenced by 1 page; not in inventory
...
Bespoke slots crossing promotion threshold: 1
hotline-211: "state" (3 instances) — consider `$stardust prepare-migration --refine-module`
Missing assets: 2
generated/orphan-1.jpg referenced by 1 page (home)
generated/orphan-2.jpg referenced by 2 pages (about, contact)
(Re-extract or accept the gap — bundle is deployable; refs 404 at view time.)
Output: stardust/migrated/ (122 pages, 47 bundled assets, 4.2 MB) — self-contained, zip-and-deploy
Next:
- Review: open stardust/migrated/index.html in a browser
- Audit: $impeccable critique stardust/migrated/
- Deploy: cd stardust/migrated && zip -r ../site.zip .
upload the zip to any static host that serves at the host root
- Refine: edit DESIGN.md or canon files, then re-run $stardust migrate
```
## Outputs
| Path | Purpose |
|---------------------------------------------------|--------------------------------------------------------|
| `stardust/migrated/<source-url-path>` | Migrated page. Output path mirrors the source URL literally (see `reference/migration-procedure.md` § Output path mapping). The bundle is **zip-and-deploy**: drop on any static host at any path, or open `index.html` directly via `file://`. Every internal reference is relative to the page that emits it; nav targets carry an explicit `index.html` (or the source URL's literal filename) so file:// resolves without a server. |
| _meta.json sidecar | Lives next to each migrated page. For `<dir>/index.html` the sidecar is `<dir>/_meta.json`; for `<dir>/<name>.html` the sidecar is `<dir>/<name>._meta.json` so multiple `.html` siblings don't collide. Per `reference/migration-procedure.md` § `_meta.json` sidecar. |
| `stardust/migrated/index.html` | The home page (special case). |
| `stardust/migrated/_meta.json` | Home sidecar. |
| `stardust/migrated/assets/logo.<ext>` | Brand logo (sitewide). |
| `stardust/migrated/assets/<subpath>` | Every asset referenced by any migrated page, bundled. Source subdir structure preserved verbatim. |
| `stardust/migrated/assets/favicon.<ext>` + variants| Favicon and apple-touch-icon, manifest icons. |
| `stardust/migrated/assets/fonts/...` | Downloaded font files (from canon @font-face URLs). |
| `stardust/migrated/robots.txt` | Minimal robots.txt. |
| `stardust/migrated/sitemap.xml` | Sitemap derived from migrated inventory + page types. |
| `stardust/state.json` | Updated with `migrated` status, history, and the `migrate` block (`selfContained: true`, asset counts). |
The driver (`node stardust/scripts/migrate/migrate.mjs render …`) writes
the per-page rows above (`index.html` / `<name>.html`, `_meta.json`,
bundled `assets/**`) and the `migrate` block of `state.json` (`pageMap[]`,
`bundledAssets[]`, `pages[]`, `missingAssets[]`, `lastRun`); status
changes, robots.txt and sitemap.xml stay with Phases 3–4.
## Idempotent and incremental
The whole pipeline is built around two properties:
- **Idempotent.** Re-running `$stardust migrate` with no
changes produces zero file writes. Every page is sha-compared
across designMd, designJson, sourceCurrent, sourceProposed
(Path A), canonShas, archetypeSource (Path A′) — and skipped
if all match.
- **Incremental.** Migrate 5 pages today, 20 pages tomorrow,
fix one page's content next week — the migrated tree is
always the union of every successful migration to date.
These properties hold even when DESIGN.md, canon, or modules are
edited mid-run: the edit changes the relevant sha, so the next
migrate run re-renders every affected page (canon and DESIGN.md
edits typically affect every page).
## Stale handling
When `direction.md`, canon, or the module catalog changes after
some pages have been migrated:
- Affected pages are flagged `stale: true` per
`skills/stardust/reference/state-machine.md` § Stale flagging.
Stale-flagging is content-aware in all three trigger cases.
- `$stardust migrate` (no flags) skips stale pages and reports
the count.
- `$stardust migrate --all` re-migrates each stale page,
clearing the flag on success.
- `$stardust migrate <slug>` always operates on the named page,
stale or not.
The user decides whether stale pages should be refreshed —
direction/canon/module changes don't invalidate prior migrated
work, they just mark it as out-of-step.
## Failure modes
- **No directed pages.** Recommend `$stardust direct` (or
`$stardust extract` if no extracted state).
- **No DESIGN.md or DESIGN.json.** Recommend `$stardust direct`.
- **No canon, but an approved prototype exists.** Do NOT stop —
auto-bootstrap canon from the canon-author inline (Setup step 4).
- **No canon and no approved prototype.** Recommend
`$stardust prepare-migration` (or approve a prototype first).
- **Pending direction.** Refuse; user must resolve direction
first.
- **Validation failure on a single page.** Skip that page,
continue, log the failure under
`state.json.lastRun.failures[]`. Do not abort the whole run.
- **Asset copy failure.** Continue the run; record the missing
asset in the page's `migrationDecisions[]` with
`kind: "asset-missing"`. The migrated `<img src>` keeps the
original absolute URL as a fallback.
- **Output path collision.** Two slugs mapping to the same
output path. Refuse to write the second one and surface to
the user — manual slug rename needed.
- **Placeholder content in proposed/archetype file.** Refuse
to ship a page whose source contains `[data-placeholder]`
elements. Surface the unsourced list and recommend sourcing
real content (re-prototype, or edit the proposed file
directly). There is no bypass flag — shipping placeholders to
a public site is the failure mode this gate exists to prevent.
- **Color reservation violated.** Refuse the page; surface to
user with the offending color and the reserved-for context.
- **Brand-faithful inversion conflict.** A hard rule declared
inverted in
`extensions.divergence.brand_faithful_inversions[]` is lifted
from validation per T&M § Brand-faithful inversion handling.
Emit a one-line note in the run summary acknowledging the
lift.
## What migrate does NOT do
- Critique or audit the migrated output. Run
`$impeccable critique stardust/migrated/` after migration if
you want a quality assessment.
- Deploy. Stardust does not push, upload, or modify origin.
- Generate AEM EDS, a CMS payload, or framework components. The
output is platform-agnostic static HTML; downstream conversion
is a separate plugin's job.
- Re-fetch the live site. Offline after extract Phase 1.
- Run any iteration loop. Iteration belongs to `prototype`;
migrate consumes the result.
## References
- `reference/migration-procedure.md` — per-page render procedure,
output path mapping, validation, provenance shape, idempotent
skip, sidecar schema.
- `reference/template-and-module-rendering.md` — three render
branches in detail, slot injection, deviation policy,
validation contracts.
- `reference/metadata-and-jsonld.md` — head composition, JSON-LD
per page-type, canonical strategy.
- `reference/content-preservation.md` — what's kept,
transformed, dropped; internal-link rewriting; asset path
rewriting; form handling.
- `reference/asset-bundling.md` — detection / copy / rewrite
contract for the per-page asset-bundling phase.
- `skills/stardust/reference/migrate-output-format.md` — the
self-contained-bundle contract downstream consumers can rely
on (asset reference shape, directory layout,
`state.json.migrate` block).
- `skills/stardust/reference/token-contract.md` — `:root` block
refreshed from DESIGN.md on every render.
- `skills/stardust/reference/data-attributes.md` — structural
attributes including `data-template`, `data-module`,
`data-slot`, `data-canon`, `data-deviation`, `data-bespoke`,
`data-broken-link`.
- `skills/stardust/reference/state-machine.md` — page lifecycle,
page typing, stale-flagging cascade.
- `skills/stardust/reference/artifact-map.md` — provenance shape
for migrated artifacts; canon files; sidecar shape.
- `skills/prototype/reference/canon-extraction.md` — how canon
is built (input to migrate).
- `skills/prepare-migration/SKILL.md` — the cascade that
produces every input migrate consumes.
From adobe/skills at 940b879, shown as plain text under its license: Apache-2.0 (permissive). The license text is in plugins/stardust/skills/migrate/SKILL.md.
View SKILL.md on GitHub at 940b879Files
- SKILL.md30 KB · 5f5f59222c37
- fixtures/
- file-protocol-audit.mjs4.6 KB · f2f903266126
- pagemap-audit.mjs3.1 KB · 6a5735496274
- reference/
- asset-bundling.md20 KB · c422d2106a06
- content-preservation.md12 KB · 379e7ed4ca53
- fidelity-tiers.md8.7 KB · 5130ff151f5d
- media-reconciliation.md4.8 KB · 8d21b15e90ad
- metadata-and-jsonld.md9.1 KB · 9d029157eec6
- migration-procedure.md16 KB · 6d32610a0e43
- template-and-module-rendering.md12 KB · 06bd2022add5
- scripts/
- migrate.mjs54 KB · 44ab8951ec43
- test/
- migrate.test.mjs29 KB · 394c38e6cc67
12 files, 203 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.
Skill folder on GitHub at 940b879More from Adobe, Inc.
adobe
This skill provides an onboarding tour of the Adobe for creativity connector, displaying available capabilities, example workflows, and which Adobe product…
Claude Code, Codex, Cursor +4 · about 2.2K tokens · pinned 6 days ago
adobe-anydocx
This skill routes DOCX conversion tasks that have a PDF source to Adobe's pdf_export tool with the appropriate format setting.
Claude Code, Codex, Cursor +4 · about 680 tokens · pinned 6 days ago
adobe-anyexcel
This skill routes PDF-to-Excel conversion tasks to the Adobe pdf_export tool with xlsx target format.
Claude Code, Codex, Cursor +4 · about 690 tokens · pinned 6 days ago
adobe-anypdf
This skill routes PDF tasks to Adobe Acrobat tools for higher fidelity than local Python libraries.
Claude Code, Codex, Cursor +4 · about 2.1K tokens · pinned 6 days ago
adobe-anypptx
This skill routes PowerPoint conversion tasks that have a PDF source to Adobe's pdf_export tool with PPTX output format.
Claude Code, Codex, Cursor +4 · about 670 tokens · pinned 6 days ago
adobe-batch-edit-photos
This skill applies consistent visual adjustments to a set of photos so they appear edited together as a cohesive collection.
Claude Code · about 9.9K tokens · pinned 6 days ago
Related in Frontend and design
next-bundle-optimizer
Audits Next.js applications to identify and reduce browser bundle size and initial-load work by analyzing routes, dependencies and client outputs.
by VercelOfficial publisher
Claude Code, Codex, Cursor +4 · about 2.3K tokens · pinned 6 days ago
next-cache-components-optimizer
Optimize Next.js routes to display meaningful UI instantly on initial load or client navigation by encoding the optimization goal as a failing…
by VercelOfficial publisher
Claude Code, Codex, Cursor +4 · about 5.6K tokens · pinned 6 days ago
next-partial-prefetching-adoption
Enables Partial Prefetching in Next.js 16.3+ apps and guides adoption through auditing Link prefetch behavior, preserving UI in tests or manually, and…
by VercelOfficial publisher
Claude Code, Codex, Cursor +4 · about 6.7K tokens · pinned 6 days ago
remotion-interactivity
This skill teaches how to structure Remotion code so the Studio IDE recognizes and makes it interactive.
by RemotionOfficial publisher
Claude Code, Codex, Cursor +3 · about 2.4K tokens · pinned 6 days ago
remotion-interactivity
This skill teaches how to structure Remotion video components to unlock Studio interactivity features like click selection, drag-and-drop, resizing, rotation…
by RemotionOfficial publisher
Claude Code, Codex, Cursor +3 · about 4.8K tokens · pinned 6 days ago
remotion-maps
This skill enables creating map-based animations with Remotion using four different mapping libraries: Mapbox, MapLibre, MapTiler, or CesiumJS.
by RemotionOfficial publisher
Contains scripts
Claude Code, Codex, Cursor +3 · about 240 tokens · pinned 6 days ago