Redesign an existing website to make it better. Built on top of impeccable.
71
89%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
What migrate keeps from the existing site, what it transforms, and
what it explicitly drops. The default answer is "preserve everything";
deviations require a basis in direction.md.
These are the things the redesign never changes unless
direction.md § Anti-references or a sibling note explicitly
authorises it:
current/pages/<slug>.json § headings. The redesign restyles type, scale, and rhythm — not what
the headlines say.p, direct-child divs), each node's inline text joined with
spaces — never from splitting captured text on newlines.
get_text('\n')-style extraction breaks on every INLINE element (a
bolded lead, a link, a superscript), so "one line = one paragraph"
turned a 5-paragraph disclaimer into 16 fragment <p>s and doubled
the section height — a defect that reads as CSS at the pixel gate
but is an import bug (recorded).href resolves to the same target.
Internal links are rewritten to the migrated tree (see § Internal
link rewriting); external links are passed through untouched.direction.md explicitly authorises a structural change for this
page.When migrate cannot preserve a content item — it doesn't fit the
chosen component, it overflows a constraint, it duplicates something
the new IA already covers — the deviation goes in the provenance
block's contentDeviations[] array with { kind, source, target, reason } so the user can audit.
DESIGN.json.narrative.dos / donts (e.g., voice rules carried
from the divergence toolkit § 7). Migrate may apply minor tone
adjustments to button microcopy and inline labels — never to
headlines or body paragraphs. Each adjustment is logged in
contentDeviations[].<section><!-- TODO --></section>
in the current site). Drop and log.Every drop is logged in contentDeviations[] with kind: "dropped"
and a reason.
For every <a href>:
# (intra-page anchor),
mailto:, tel:, javascript:, or a non-HTTP scheme.state.json.site.originUrl):
pass through unchanged.Strip origin and tracking params (utm_*, gclid, fbclid).
Look up the target path in state.json.pages[].url to find the
slug.
If found, rewrite href to the migrated path (per the slug
mapping in migration-procedure.md § Output path mapping).
Use root-relative paths (/about/, /docs/api/) so the
migrated site moves cleanly across hosts.
If not found (target was never extracted or was filtered out),
compute the migrated path the slug would resolve to (per
migration-procedure.md § Output path mapping) and rewrite
the href to that path anyway. Mark the link
data-broken-link="true" and log under
provenance.brokenInternalLinks[]. The migrated tree stays
internally consistent — every same-host link is a relative
migrated path; broken links surface as an explicit signal,
not as escape hatches to the live origin. The user resolves
by extracting the missing page (and re-running migrate) or
accepting the broken link.
Partial-inventory carve-out (stardust-style e2e finding).
When the run is deliberately scoped to a subset of the
inventory (an explicit <slug> list, or siblings not yet
migrated), a rewritten-but-nonexistent migrated path makes the
mandatory file-protocol-audit.mjs fail on every page that
links a not-yet-migrated sibling — the two contracts are only
co-satisfiable on full-inventory runs. On a scoped run the
link to a known-inventory-but-unmigrated page keeps the
resolvable absolute origin URL instead, still flagged
data-broken-link="true" and logged; a later migrate run that
covers the target reconciles it to the relative migrated path
(the sha change re-renders the linking page). The audit
accepts data-broken-link-flagged origin URLs as known-broken
on scoped runs.
#section-3) and query string
(?ref=foo) exactly when rewriting.Asset bundling is run as the last step of the per-page render —
see reference/asset-bundling.md for the canonical contract.
Summary of the content-preservation surface:
asset-bundling.md § Detection) are
resolved against the asset-prefix set, copied into
stardust/migrated/assets/<subpath> with subdir structure
preserved, and rewritten to root-relative /assets/<subpath>.srcset, sizes, loading, decoding, alt,
width, height verbatim. The bundler updates srcset
URLs by splitting on commas, rewriting each URL, and
re-joining with the descriptors preserved.stardust/current/assets/<subpath>, the bundler still
rewrites the HTML reference (so the bundle stays internally
consistent) and logs under provenance.contentDeviations[]
with kind: "asset-missing". The bundle will 404 on that
asset at deploy time — a downstream concern that the migrate
report surfaces explicitly.For inline SVGs, preserve the markup verbatim (modulo class-name substitutions to match the new component classes when the component template requires it).
For iframes (YouTube, Vimeo, Calendly): preserve the embed code verbatim. They are external dependencies the migrated site depends on.
The form schema (action, method, field set) is preserved
verbatim. The form's visual treatment is restyled per DESIGN.json
component form (or input + button if no form component is
defined).
Form actions pointing at third-party services (Stripe Payment Links, Calendly, Typeform, Mailchimp, Formspree) are preserved as-is — they continue to work after deploy.
Form actions pointing at the origin's own backend (e.g.,
/api/contact) are preserved with a warning logged in
contentDeviations[] with kind: "self-hosted-form" and a hint:
"the origin's /api/contact endpoint must remain available at the
migrated site's origin, or the form must be re-wired to a static-form
service."
self-hosted-form is one instance of a general rule: nothing the
evidence recorded as dynamic may ship static silently. Before
rendering a page, look up the rows of stardust/dynamic-features.md
that touch it (by reach / evidence; per-page dynamic section when
the crawl ran with --dynamics):
embed-passthrough → preserve the markup verbatim (iframe, player
link, third-party form action, widget mount) — no log entry.index-backed / data-fed / rebuild-native / client-only → the
section is rendered by the block deploy builds for it; migrate
emits the authored fallback rows (or the #modal link, the player
URL) and logs contentDeviations[] kind: "dynamic-dependency" with
the disposition, the row id and the endpoint, so the report shows
what the page depends on at runtime.static-snapshot / decided-out → render the captured state and log
kind: "dynamic-dependency" with the disposition and the reason.stardust:dynamics Phases 1–3; if a dynamic dependency still has no
row, log disposition: "unclassified" and surface it first in the
report — a dynamic-gap learning.Deviation shape:
{ "kind": "dynamic-dependency", "disposition": "data-fed", "row": "reviews-rail",
"endpoint": "GET api.example-vendor.test/v1/reviews", "note": "authored fallback: 3 rows" }When the redesign moves the tone axis (per
direction.md § Movements), migrate may not re-write headlines or
body copy to match the new tone. It restyles only.
If the user wants tone-aligned copy, they run a separate pass:
$impeccable clarify stardust/migrated/<slug> after migration.
Stardust does not auto-trigger that.
Preserve the heading levels from current/pages/<slug>.json § headings. The redesign may re-style headings dramatically but must
not skip levels (an h2 cannot become an h4) or invent new
headings.
If the current site has skipped levels (h1 → h3), migrate
fixes them by demoting where needed and logs the fix in
contentDeviations[] with kind: "heading-level-fix". This is one
of the few accessibility corrections migrate makes by default.
<html lang="..."> is preserved from the current page's language
field. <html dir="ltr|rtl"> is added when DESIGN.md's
extensions.breakpoints.rtl is true or when the current page was
RTL.
The following come from direction.md and apply to every migrated
page identically (not page-by-page deviations):
/assets/logo.<ext>).prepare-migration Phase 4, linked via <link rel="icon">
per metadata-and-jsonld.md § Favicon.stardust/canon/header.html
on every page; re-iterating the canon-author prototype updates
it sitewide.This doc covers body content. Two adjacent concerns are delegated to dedicated references:
metadata-and-jsonld.md. The five-category model
(system-fixed, brand-level, preserved, derived, stripped)
governs head composition end-to-end.@font-face URLs are downloaded to
stardust/migrated/assets/fonts/ during prepare-migration
Phase 4 (assets prep). Migrate-time fonts are local; missing
downloads surface a warning per affected page in the run
summary..tessl-plugin
skills
audit
reference
deploy
diff
direct
extract
migrate
prepare-migration
prototype
replica
reskin
rollout
stardust
uplift
reference