* fix(stardust): make migrate output genuinely zip-and-deploy portable The 0.7.0 contract claimed "self-contained, zip-and-deploy" but emitted root-absolute paths (/assets/..., /beers/) plus directory-only nav links. Those work on a webserver at the host root only — they 404 on file:// and at any subpath. This PR delivers what the claim promised: - Output path is URL-literal: /beers/ -> beers/index.html, /about-us/history.html -> about-us/history.html. No more synthesizing /about/index.html from a slug. - Page map (state.json.migrate.pageMap[]) built once per run; per-page rendering and internal-link rewriting both consume it. - Reference shape is depth-aware relative: prefix is ./ for depth-0 pages, ../ * depth otherwise. Works on file://, at host root, and at any subpath without rewriting. - Phase 3 broadens the self-containment check into a full portability audit: refuses absolute internal refs, refuses directory-only nav, runs the new pageMap + file:// fixtures. - New fixtures: file-protocol-audit.mjs (Playwright file:// round-trip) and pagemap-audit.mjs (static pageMap consistency). - asset-bundling.md and migrate-output-format.md aligned to the new depth-aware-relative shape; state.json contract gains pageMap[]. Plugin bumped 0.7.0 -> 0.7.1. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * review: fix four flagged correctness issues - Directory-only-nav regex now catches `./beers/` (the cited example). Old pattern required a-z as first char; `./beers/` starts with `.` and would have slipped through. New pattern accepts ./, ../, /, or a bare segment, and excludes scheme-bearing URLs (no false positive on https://google.com/). - Add a second grep for absolute url() references inside inline style attrs and <style> blocks (and CSS files); the original href/src grep missed these. - SKILL.md Outputs row no longer claims the sidecar lives at <source-url-path>/_meta.json (nonsense for .html-leaf pages). Replaced with a row that points at the canonical sidecar rule. - migration-procedure.md § Page map now explicitly says same-origin absolute URLs are stripped to their path portion before pageMap lookup (per content-preservation.md § Internal link rewriting), closing the loophole that would let <a href="https://origin/foo/"> pass through verbatim. Regex patterns verified against a test fixture before commit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * review: update migrate-self-contained-bundle eval to 0.7.1 contract The eval was pinned to 0.7.0's root-relative /assets/<subpath> shape. This PR's contract change to depth-aware relative paths would have made the eval fail against correct 0.7.1 output. - detection_src_href criterion now asserts <prefix>assets/<subpath> (not /assets/<subpath>). - Renamed prefix_resolution_root_relative -> prefix_normalises_authoring; description flipped from "reference is left as-is" to "authoring is normalised to the depth-aware emit form". - Added 4 new criteria: depth_aware_paths (6pts), pagemap_constructed (6pts), internal_links_via_pagemap (5pts), portability_audit_passes (13pts). - Setup uses real source URLs that exercise the URL-literal rule: /, /beers/, /about/history.html (preserve .html leaf), /docs/api/ (depth-2 nested). - Prototype HTML now carries internal nav in three authoring styles (root-absolute, same-origin absolute, directory-only) plus a broken-link case, exercising the page map rewrite. - Run 1 expected behavior rewritten to expect depth-aware emission ('./assets/...'), pageMap built before render, broken-link flagging, and the 6-step portability audit passing. - Run 4 (cross-page dedup) updated so the second page emits its shared asset with its own '../' prefix while the underlying file on disk is a single copy. - Weights re-balanced to sum to 100; portability_audit_passes gets the largest weight (13pts) since it backs the contract claim. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Stardust v2 evals
Evaluation suite for the four-phase redesign pipeline plus the "open and reasoned" intent-reasoning principle that governs the master skill.
The v1 evals (brand-extract-from-url, briefings-from-prompt,
prototype-iterate, stardust-navigator, wireframes-render) were
tied to v1's stage decomposition (brand → briefings →
wireframes → prototype) and have been replaced wholesale to
match the v2 surface.
Format
Each eval lives in its own directory and contains exactly two files:
task.md— Setup, User prompt, Expected behavior. Human-readable scenario specification.criteria.json— Weighted scoring rubric. Each criterion has anid, aweight, and adescription.totalshould equal the sum of weights. Used by the eval runner to score the agent's output.
This format mirrors v1's structure (and the format other Adobe-skills plugins use), so the eval runner that worked for v1 should work for v2 evals without modification.
Evals in this suite
| Directory | Stage tested | What it pins down |
|---|---|---|
extract-multipage/ |
Phase 1 (extract) |
Multi-page crawl with cap + Playwright (not WebFetch) + correct file shapes + direct authoring of current PRODUCT.md / DESIGN.md. |
direct-from-phrase/ |
Phase 2 (direct) |
Dimensional restatement + at most two questions + plan-before-execution + direct authoring of target spec + direction.md trace. |
prototype-before-after/ |
Phase 3 (prototype) |
One proposed file per page + :root block + data attributes + content preserved + delegates to $impeccable craft + opens in browser. |
migrate-incremental/ |
Phase 4 (migrate) |
Both render paths (A and B) + nested index.html output + content preservation + idempotent skip on re-run. |
migrate-multi-template/ |
Phase 4 (migrate) |
Three render branches (Path A / A′ / B) + canon + modules + bespoke-slot promotion + broken-link reporting + color-reservation refusal. |
migrate-self-contained-bundle/ |
Phase 4 (migrate) |
Self-contained zip-and-deploy bundle — six asset detection shapes, nine edge cases, six acceptance criteria, state.json migrate block with selfContained: true. |
intent-reasoning-style/ |
Master skill principle | "Open and reasoned" — vague phrases get clarified, never silently mapped to commands. Pending direction persisted. |
Coverage map
| Layer of the v2 design | Covered by |
|---|---|
| Layer 1 — intent abstraction (open + reasoned) | intent-reasoning-style, direct-from-phrase |
| Layer 2 — navigator orchestrator (4 phases) | extract-multipage, direct-from-phrase, prototype-before-after, migrate-incremental |
| Layer 3 — migration tooling (per-page, incremental, idempotent) | migrate-incremental, migrate-multi-template |
| Layer 3 — migrate output contract (self-contained bundle) | migrate-self-contained-bundle |
The cross-cutting properties are pinned across multiple evals:
- Hard impeccable dependency — every eval expects the master setup to verify impeccable before proceeding.
- Direct authoring (no interview duplication via
$impeccable teach/documentfor files stardust seeds) — checked inextract-multipageanddirect-from-phrase. - Provenance everywhere — each eval has a provenance criterion.
- No EDS / framework / CMS leakage — every eval has a
no_eds_referencescriterion. - Stale-on-direction-change — covered in
migrate-incremental(the eval can be extended later with a re-direct mid-run scenario; for v0.2.0 we test the idempotent baseline).
Running
The eval runner is not bundled with this plugin (it lives elsewhere
in adobe/skills). Each eval is self-describing: a runner reads
task.md for the scenario, executes it against a clean stardust
project, and scores the output against criteria.json.
A criterion passes if its description is satisfied as judged by
the runner. Per-criterion verdicts are combined as a weighted sum
out of total (100 per eval).
What stardust v2 evals deliberately do NOT test
- Visual quality of the redesigned output. That's
$impeccable critiqueand$impeccable auditterritory; running them as a side effect of a stardust eval is not the right boundary. A redesign that is technically correct (passes all criteria) can still be ugly; that's a different evaluation. - Specific brand outcomes. The evals pin the procedure and the artifacts, not whether the resulting brand identity is "good for Stripe" or "young enough" — those are user judgements.
- Live URL availability. The
extract-multipageeval uses stripe.com as a stable, public, well-structured target. If stripe.com changes structure dramatically the eval may need updating; that's expected maintenance.