rollout について
rollout は、移行済みのサイト全体を AEM Edge Delivery Services に公開する Stardust スキルです。ページ単位で段階的に配信し、既存の deploy 手順を使って進捗を追跡します。ページの再設計は行いません。
主な機能
- 01サイト全体のページ一覧作成
- 02ブロックの重複排除計画
- 03段階的で再開可能な進捗管理
- 04アーキタイプのみの配信モード
- 05インポート前と配信時のゲート
活用シーン
- 01移行済みサイトをページごとに配信
- 02兄弟ページのコンテンツ完成前にアーキタイプのブロックコードを公開
- 03配信を再開し未完了ページを特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ adobe/ skills --skill rolloutインストール後、Claude Code で/rolloutを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
reference/audit-sources.mdchecks.mdcoverage-model.mddelivery-gates.mddelivery-lint.mdmultilingual.mdoperational-learnings.mdschemas/rollout-blocks.schema.jsonrollout-config.schema.jsonrollout-findings.schema.jsonrollout-pages.schema.jsonrollout-scorecard.schema.jsonrollout-templates.schema.jsonscripts/assemble.mjsautofix-aem.mjsblocks.mjsdashboard.mjsdelivery-lint.mjsdone-check.mjsfindings.mjsinventory.mjslib.mjsmedia-reconcile.mjsoptimize.mjsplan.mjssection-fidelity.mjsseed-redirects.mjsscripts/test/assemble.test.mjsdelivery-lint.test.mjsdone-check.test.mjs詳細
stardust:rollout — サイト全体 → AEM(Edge Delivery Services)
deploy は 1 ページを AEM に変換します。rollout はサイト全体を配信します。まず migrate の汎用的な出力を一覧化し、その後、すべてのページに対して deploy を実行し、配信の進捗を追跡するため、完了した作業と残っている作業を常に把握できます。
rollout は配信のみを行い、再設計はしません。ページごとの再設計(extract → direct → prototype → migrate)と deploy 自体は変更ありません。rollout はその上に重ねる、ページ横断のレイヤーです。設計の根拠、進捗モデル、段階的な実施方法については、notes/rollout/PLAN.md を参照してください。フローは以下の A→I で進みます。
使用するタイミング
フルモード — ユーザーが stardust/migrated/ に移行済みのサイト(stardust migrate によるページごとの HTML + _meta.json)を用意しており、EDS/AEM プロジェクトと DA の配信先(deploy に必要なものと同じターゲット)があり、サイト全体を段階的に、再開可能な形で配信したい場合です。
アーキタイプのみモード — ユーザーがテンプレートごとに移行済みのアーキタイプを 1 つと、stardust/state.json にページ全体の一覧(各ページの type を含む)を用意しており、すべてのページの移行を待たずに、ブロックコードをすぐにすべて公開したい場合です。同じテンプレートを使うページは content-pending として登録され、別の作業経路で後からコンテンツが追加されます。
stardust/migrated/ が存在しない場合は、まず少なくともアーキタイプのページに対して stardust migrate を実行するよう案内してください。単一ページの場合は、stardust deploy を直接使用してください。
セットアップ
- マスタースキルのセットアップを実行します(
skills/stardust/SKILL.md§ Setup)。フローガード: 移行の依頼時にflowがないstardust/state.jsonがある場合は、ロールアウトを実行しないでください。マスターの 2 フローの表を表示し、ルーティングに戻してください(skills/stardust/reference/state-machine.md§ Flow keys)。 stardust/migrated/に少なくとも 1 つの*.htmlページがあることを確認します(フルモード:全ページ。アーキタイプのみモード:アーキタイプと、typeが入力されたstate.json)。そうでない場合は、アーキタイプに対してstardust migrateを実行するよう案内し、終了してください。ゲート付きアーキタイプの前提条件(flow: replica)。stardust/replica/progress.jsonを読み取ります。ページタイプを公開できるのは、アーキタイプが設定済みのすべてのブレークポイントでゲート結果を持ち、その結果がpass: trueであるか、基準を超えており、かつすべての残差にcauseが記録されている場合に限ります(skills/replica/reference/source-fidelity-gate.md§ Residual logging format — 記録済みの残差は、アスタリスク付きの合格を意味します)。アーキタイプがゲートを一度も通過していないページタイプ、または基準を超えているにもかかわらず残差の記録がないページタイプはブロック対象です。そのタイプをアーキタイプのスラッグと、ゲートを実行するコマンド($stardust replica <archetype>)とともに列挙し、同じテンプレートを使うページへの展開も、そのページを対象とするPOST /live/も行わないでください。ハンズオフモードで記録済みの残差を受け入れても、ゲート未実施のアーキタイプを迂回することにはなりません。しきい値はゲートの値をそのまま使用し、変更しません。(記録例:一度も合格していないアーキタイプから 24~28 % の差分がある 2,207 ページが公開されました。ランダムレビューでゲートが検出したはずの問題が判明し、3,366 ページを再インポートしました。)deployの要件どおりに、EDS/AEM のターゲットが準備できていることを確認します(プロジェクトの足場、DA_TOKEN、プッシュ可能なコードブランチ)。rolloutに新しい転送方式は追加されません。state.json.handsOffが true の場合(skills/stardust/SKILL.md§ Hands-off mode)、フルオートで実行し、フェーズごとの一時停止は行いません。以下のすべてのゲートと検証手順は変更なく実行します。ハンズオフによって省略されるのは待機のみであり、検証ではありません。
手順
フェーズ A — インベントリ(カバレッジを構築する)
node skills/rollout/scripts/inventory.mjs --site-url <source-url>
# defaults: --migrated stardust/migrated --out stardust/rollout
# archetypes-only mode: add the full page roster from state.json
node skills/rollout/scripts/inventory.mjs --site-url <source-url> --state stardust/state.json
coverage/pages.json(ページごとに1行:slug、配信済みのpath、templateId、blocks、sourceHash、deliveryステータス)、coverage/templates.json(テンプレート別にグループ化されたページ)、rollout.json(ターゲット+DA設定+lastRun)を書き込みます。
アーキタイプのみのモード(--state):_meta.jsonがあるページはフルモードと同様にシードされます。state.jsonのみに存在するページは、typeからtemplateIdを、アーキタイプのサイドカーファイルからblocksを設定し、delivery.status: content-pendingとしてシードされます。
インベントリは冪等で段階的に更新されます:配信ステータスは保持されます。配信後に移行済みHTMLが変更されたページは、再度staleとしてフラグ付けされます(固定行にはなりません。レプリカの最初のページが最優先です)。推定できない場合は、rollout.jsonのDA座標(site.da.org、site.site、site.da.ref、site.liveHost)を入力してください。
フェーズ B — ブロックの重複排除計画(最優先事項として、変換の前に実施)
node skills/rollout/scripts/blocks.mjs # → coverage/blocks.json (the dedup unit)
node skills/rollout/scripts/plan.mjs # → plan.json + a readable conversion plan
blocks.mjsは、すべてのブロックインスタンス(ページごとのmodules、widgets+共通要素)をまとめて重複のないセットにし、それぞれに正規のedsBlockName(ケバブケース、予約クラスを保護)を割り当て、usedByPages/instanceCountを記録します。共通要素(header/nav/footer)はkind: chromeで、サイト全体で使用する作成済みドキュメント(/nav、/footer)になります。ウィジェット(サイドカーファイルのwidgets[] {id, href}に由来するkind: widget)にはドキュメント行は不要です。コードはwidgets/<path>/<name>.htmlに配信され、ページには/widgets/…htmlリンクが1つ含まれます(#133)。アーキタイプのみのモードでは、アーキタイプのサイドカーファイルによってブロックセットが決まります。content-pendingのページはブロックを追加しません。EDSのデフォルトコンテンツ(title、text、image、button、separator)にマッピングされるモジュールにはブロックは不要です。update-coverage.mjs --block <id> --status converted --eds-name default-contentで記録してください。この行はステータスにかかわらず、保留中としてカウントされることはありません。plan.mjsはテンプレートごとにページを代表ページ優先で並べ、それぞれのブロックを1か所だけで変換します。そのブロックを使用する最初のページで変換し、それ以降のページでは名前で再利用します。ページごとのconvert/reuseリストは、deployのステップ7の概要入力となります。content-pendingのページは常にconvert: []です。
配信済みサイトを拡張する場合:まず
blocks/とwidgets/を監査してください。「新しいテンプレート」は通常、これらを新たに組み合わせたものです(reference/operational-learnings.md)。
フェーズ B2 — 動的要素(インポート前のゲート — インベントリを検証)
フェーズ Cの前に実施してください。 stardust/dynamic-features.md(prepare-migration 4.5またはレプリカのフェーズ2で作成)が存在し、すべての行に処置が記載されている必要があります。ここで最新の証拠と照合して検証してください — dynamics-detect.mjs --from-state … --reach stardust/currentおよびdynamics-plan.mjs --target-origin <live host> --migrated stardust/migrated(ホストにひも付くAPI、キャプチャですでに配信済みの行)。新たな証拠が見つかった場合は、新しい行を追加します。リストの契約(タイプごとの<meta>フィールド+helix-query.yaml)は、フェーズ Cのdeploy概要によってページごとに出力されます。公開済みページ全体にメタデータを後から追加するには、2回目の移行が必要になります。インベントリがない場合は、今すぐstardustのdynamicsスキルのフェーズ1~3を実行してください。契約については、skills/dynamics/reference/triage.md、reference/listings.mdを参照してください。
フェーズ C — サイトを配信(計画に従い、ページごとにdeployを実行)
フェーズ B2が完了するまで実行できません — 配信中に各ページのメタデータ契約をメタデータブロックに記述し、インポート時にインデックスを充実させます。
plan.json.stepsを順番にたどります(代表ページを先に処理します)。各ページについて、次の手順を実行します。
-
変換してプッシュする:移行したHTML(
source.migratedHtml)をdeployの手順でAEMに反映します。計画ステップをdeployのbriefに渡してください:convertにあるブロックのみを作成します。reuseにあるブロックは、それぞれのedsBlockNameに基づいて既存のブロックを再利用します(再作成しません)。briefにはExperience Workspaceの編集可能性に関する契約(deploy SKILL.md § 8、EW1~EW10)を必ず含めてください:変換したブロックはすべて、作成済みの要素をテキストから再構築せずにラッパーへ移し、配信済みとみなされる前にEWゲート(block-roundtrip --ew)に合格する必要があります。実際のサイトでは、契約を含まないbriefにより27個すべてのブロックで契約が適用されませんでした。briefには、アーキタイプのcaptureState[].restoreAtDeliveryリスト(レプリカのprogress.json)も含めてください:ゲートが必要とするフリーズ状態(動画のフレーム0、カルーセルのスライド1)は、納品するべき動作であり、仕様ではありません(../replica/reference/recreation-procedure.md § Carousels)。先にデプロイし、プレビューオリジンで判断してください。 ローカルハーネス(
build-harness.mjs→qa-gate.mjs、block-roundtrip.mjs --ew)で検証できるのは構造上のアサーションのみです。ピクセルや見た目に関する判断はすべて、レプリカのソース忠実度ゲート、ヘッダー/フッターのcrop-compareバンド、デプロイ後の目視確認も含め、最初のPUTより前にハーネスで行うのではなく、PUT → previewの後にページのプレビューURLを使って行います(deploy SKILL.md § Local QA before deploy、§ Step 10)。記録されたある配信セッションでは、予算をすべてローカルハーネスのピクセル差分に対するCSSの反復に費やし、ページを1つも納品できませんでした。クロームとフラグメントのドキュメントには
Robots | noindexを設定してください。content/nav.html、content/footer.html、ロケールごとのすべてのnav-*/footer-*ドキュメント、およびページではないロケールシェルには、書き込み時にメタデータブロックの行をもう1つ追加します。<div><div>Robots</div><div>noindex</div></div>(<meta name="robots" content="noindex">として表示されます)。これがない場合、公開済みドキュメントのプラットフォームのインデックスと、それが提供する/sitemap.xmlに、これらがページとして掲載されます。記録された、手動操作なしの実行では、36ページのサイトに対して58件のサイトマップURL(全ページに加えてクロームドキュメント22件)が提供されました。フェーズDで提供されたサイトマップを検証します。content-pendingページ(アーキタイプのみ):移行済みHTMLがないため、ドキュメントのプッシュは完全にスキップします(シェル/プレースホルダーは作成しません)。content-pendingとして記録し、「コンテンツトラック待ち」として表示します。ブロックコードはアーキタイプ経由ですでにデプロイ済みです。 -
静的契約のリンティング(PUT前、決定論的)。 プッシュする前に、delivery-contractリンターを実行します。ラッパー、
<p>ごとにCTAが1つ、末尾のスラッシュ、パスの安全性、/img/のsrc、about:errorといった、低コストで決定論的な問題をオフラインで検出し、問題のあるページがプレビューに到達するのを防ぎます。手順についてはreference/delivery-lint.mdを参照してください。P0/P1がある場合、PUTを実行してはいけません。node skills/rollout/scripts/delivery-lint.mjs --file <html> --path </da/path> node skills/rollout/scripts/media-reconcile.mjs --file <html> --deploy-host <branch>--<repo>--<owner>.aem.live [--media-ledger <file>] [--apply]media-reconcileは、ホストされていないすべての画像をネットワーク経由で解決し、最適化/維持/書き換え/省略のいずれかを決定します(skills/migrate/reference/media-reconciliation.md)。これは、以下の画像忠実度ゲートにおける正式な形式です。コンテンツホストのURL(content.da.live)は、代わりにhostedと判断します。メディア台帳(--media-ledger <file>、自動検出)を使ってオフラインで確認し、匿名では取得しません(仕様により401)。台帳にない場合はゲートに失敗します。 -
ページの状態を
deployedに切り替える前に、デリバリーゲートを実行します。 各ゲートのルールはここに一行で記載しています。実行方法とヘルパーについてはreference/delivery-gates.mdを参照してください。- ソースとの忠実性 — ソースにないセクションを追加せず、事実を捏造しないでください。
node skills/rollout/scripts/section-fidelity.mjs --file <html> --source <url>(作成したファイルに対する静的なアウトラインチェックです。deployed後に公開オリジンで実行する replica のピクセルベースのソース忠実性ゲートではありません) - 画像との忠実性 — 作成したすべての
<img>の src が 200 を返すことを確認し、そうでない場合は省略してください。<img src="about:error">を絶対に公開しないでください。media-reconcile.mjsを実行します(手順 2)。 - パスの安全性 —
reference/delivery-gates.md§ ゲート 3 を参照し、stardust/redirects.tsvに元のパス→正規化後のパスを記録します。(delivery-lint が違反を検出します。) - ソースコンテンツの衛生性 — 無効なソース URL はスキップします。本文のないソースや PDF のみのソースは、内容を薄く忠実に作成し(
skills/migrate/reference/fidelity-tiers.mdのthinティア)、創作した文章で水増ししないでください。 - 忠実性ティアの宣言 — 各ページの
fidelityTier(archetype/sibling/thin)を記録し、どのページが作り込みゲートの対象で、どのページが複製されたかをカバレッジで示します(skills/migrate/reference/fidelity-tiers.md)。
- ソースとの忠実性 — ソースにないセクションを追加せず、事実を捏造しないでください。
-
state-writer で結果を記録します(台帳を手動で編集しないでください)。
node skills/rollout/scripts/update-coverage.mjs <slug> --status converting node skills/rollout/scripts/update-coverage.mjs --block <id> --status converted --eds-name <name> node skills/rollout/scripts/update-coverage.mjs --block <id> --status converted --eds-name default-content # maps to default content, no block node skills/rollout/scripts/update-coverage.mjs <slug> --status deployed --url <branch-preview-url> node skills/rollout/scripts/update-coverage.mjs <slug> --status content-pending # no document pushプレビューで止めず、ループ内で公開します(
PUT → preview → live)。 クエリーインデックス(フェーズ D2)はすべて live ツリーから構築されるため、プレビューのみのデリバリーではインデックスが空のままになります。失敗した場合は--status failed --error "<reason>"を指定して続行します(1 ページの失敗によってロールアウト全体が中断することはありません)。
基盤を先に確認するゲート(ハードブロック、ロールアウトごとに 1 回)。 最初の archetype ページの状態を deployed に切り替えたら、2 ページ目を作成する前に停止し、基盤が正しいことを確認してください。stardust の diff スキルを使い、プロトタイプに対して両方のプローブを実行し、さらにヘッドレスレンダーで計算済みスタイルの不変条件も確認します。具体的には、グリッドコンテナの計算値が display: grid(単一列に積み重ならない)であること、デザイン上フルブリードであるべきセクションがフルブリードであること、CTA/ボタンのクラスに実際にスタイルが適用されていることを確認します(stardust/runtime-contract.json、skills/deploy/SKILL.md § ランタイム検出プローブを参照)。deployed とは、PUT とプレビューの後の状態を意味します。ゲートのプローブは、ローカルハーネスではなく、ページのプレビュー URL に対して実行します。デプロイ前のハーネスでのピクセル差分チェックは、このゲートの代わりにはなりません。ランタイムについての誤った前提(ブロックラッパーのクラスやボタンのクラスなど)は、サイト全体に影響するうえ、気づきにくいものです。タイポグラフィは問題なく見えても、すべてのグリッドが縦に積み重なることがあります。このゲートを通すかどうかで、1 ページを修正するだけで済むか、すべてのテンプレートを再構築するかが決まります。同じゲートでは、オリジンに対して qa.mjs --checks metadata も実行します。favicon-default は、サイトのアイコンが一度も公開されていないことを意味します(デプロイ手順 3 § ファビコン)。記録された初回の確認では、/favicon.ico が 200 を返していたにもかかわらず、ボイラープレートのアイコンが配信されていました。テンプレートごとに archetype を最初に処理します(#126): いずれかの sibling をレンダリングまたは変換する前に、そのテンプレートの archetype をデプロイし、プレビュー URL 上で完全なゲート行を通過させます(gate-all.mjs --only、修正ラウンドは最大 3 回)。記録上の単位は C-archetype です(引き継ぎ契約 § 3、行 C)。
実行モデル:ウェーブ方式。 並行する編集専用エージェントをウェーブ単位で投入します。各エージェントはソースページを curl してファイルを書き出すだけで、デプロイやブロックの編集は行いません。テンプレートクラスターは(重複しないページを対象に)並行して処理し、再利用するブロックが揃うよう代表ページから着手します。次にページごとに中央デプロイを実施し、その後、ページごとの OK/FAIL 台帳を付けてバックグラウンドバッチを実行し、FAIL のみを再実行します。兄弟ページが 6~20 件以上あるクラスターでは、一連の手順全体について reference/delivery-gates.md § Batched delivery を参照してください(クラスターエージェント自身がデプロイする唯一のバリアントである replica の Phase 5 fan-out、クラスターごとのデプロイ台帳、ロックセーフな共有台帳についても記載されています)。中央デプロイでは、逐次ループではなく、バンドル済みの再開可能なドライバーを実行します。
node skills/deploy/scripts/deploy-batch.mjs --org <org> --repo <repo> --branch <branch> --content <dir>(並行処理プール、すでに公開済みのページをスキップする永続台帳、リトライ/バックオフ、追記専用ログ、配信済みの .plain.html チェック)。
ドライバーと各バッチはバックグラウンドで実行し、そのログと台帳を進捗ファイルとして扱います。確認は最大 4 分おきに行い、固定で 5 分以上の sleep は決して使いません(プロンプトキャッシュのウィンドウです)。マスターのスキルにある待機ルールです。記録されたバッチでは、9~10 分の待機のたびに約 650k のプレフィックスを書き直していました。一時的な障害が発生した場合は、同じコマンドを再実行します。FAIL のみが再実行されます。その後、update-coverage.mjs で台帳をカバレッジに反映します。
まず基盤を整えます: 最初のエージェントを起動する前に、styles.css、ヘッダー/フッター CSS、コントラクトファイルを lint してコミットします。fan-out 後はトークン名やカスタムプロパティ名を変更しません(3 つのエージェントが実行中に名前を変更した記録では、調整メッセージが 7 件必要になりました)。依存関係のないクラスターは並行して起動します。ウェーブが待つのは実際の依存関係がある場合だけです(記録されたケースでは、無関係な第 1 ウェーブのために第 2 ウェーブが 14 分間待機しました)。すべてのツール呼び出しは、メインエージェントの呼び出しも含めて 4 分未満に収めます(プロンプトキャッシュの保持時間は 5 分です。5.2 分と 6.6 分の呼び出しではコンテキスト全体が書き直されました。また、ピクセルループを実行しながら deploy-batch の開始と待機を行ったメインエージェントの 338 秒のフォアグラウンドターンでも同じことが起きました)。長時間かかる処理(ゲートの反復、ピクセルループ、Playwright のキャプチャ、デプロイバッチ)は run-bg.mjs start 経由で実行し、次のツール呼び出しで wait を実行します。wait は --max(デフォルトは 100 秒)以内に戻ります。1 ターン内で 2 つの長時間処理を並行するツール呼び出しにしないでください。また、1 つのコマンド内で wait を 2 回実行しないでください。
フェーズ D — サイトの組み立て(サイト全体の成果物)
node skills/rollout/scripts/assemble.mjs # → rollout/site/{sitemap.xml,robots.txt,manifest.json} — the EXPECTED set
node skills/rollout/scripts/assemble.mjs --verify-origin https://<branch>--<repo>--<owner>.aem.live # vs the SERVED /sitemap.xml; exit 1 on a mismatch
配信済みパスからサイト全体の成果物である sitemap.xml と robots.txt を生成し、
クロームブロックを作成済みのクロームドキュメント(content/nav.html、
content/footer.html)およびその canon/*.html ソースに対応付けるフラグメント
マニフェストを生成します(deploy は通常のコンテンツチェーンを通じてドキュメントを
作成・デプロイします。クロームがサイト全体で 404 にならないよう、ドキュメントは
必ず公開してください)。
組み立てられたサイトマップが配信されることはありません。 stardust/rollout/ は
.hlxignore に含まれるため、site/sitemap.xml はローカル成果物であり、期待される
URL セットです。プラットフォームは、各ドキュメントに Robots | noindex
(フェーズ C)が指定されていない限り、クロームドキュメントも含め、公開済みのすべての
ドキュメントのインデックスから独自の /sitemap.xml を生成して配信します。記録された
ハンズオフ実行ではローカルファイルを読み取り、「sitemap 36 urls」と報告しましたが、
配信されたサイトマップには 58 件(36 ページ + 22 件の nav /
footer ドキュメント)が含まれていました。対処方法は 2 つあり、1 つ目は必須です。
- 作成時の対応: すべてのクローム/フラグメントドキュメント(
/nav、/footer、 ロケールごとのnav-*/footer-*、ページではないロケールシェル)にメタデータ行Robots | noindexを指定します。すでにこれを指定せずに公開済みのドキュメントは、 以下の確認を行う前に再作成して再公開します(プレビュー → ライブ)。 - 設定による対応(代替手段・追加対応): コードブランチに書き込み可能な場合は、
プロジェクトルートに
helix-sitemap.yamlを配置します (sitemaps.default.include: ['/**']、exclude: ['/nav', '/footer', '/**/nav*', '/**/footer*', '/fragments/**']、properties.lastmod: lastModified)。これにより、ドキュメントに該当行がなくても クロームが配信サイトマップから除外されます。同じexcludeグロブをhelix-query.yaml(フェーズ D2)にも指定し、インデックスにも含まれないようにします。
ローカルファイルではなく、配信されるサイトマップを確認してください。
assemble.mjs --verify-origin <live-origin> は <origin>/sitemap.xml を取得し(サイトマップインデックスの場合は
その先もたどります)、<loc> のパスをカバレッジ行と比較します。配信版と組み立て版の
件数、および余分なパスと不足しているパスをすべて出力し、結果を site/manifest.json
(servedSitemap)に記録します。不一致がある場合は 1 で終了します。余分なパスは、
noindex のないクロームドキュメントか、カバレッジ行のない、移行対象ツリー外で構築
されたページです(update-coverage.mjs --new、フェーズ D2)。不足しているパスは、
ライブ環境で公開されていないページです。終了コードが 0 になるまで、修正後に再実行して
ください。D-site 台帳の end 行には、組み立て版ではなく配信版の件数を記載します。
例:--detail "sitemap served 36 = assembled 36; redirects wired; / 200"。
D-site チェックリスト(すべて D-site end 行より前に完了すること):
assemble.mjs --verify-origin の終了コードが 0 · すべてのクロームドキュメントに
Robots | noindex が指定され、公開済みである · リダイレクトシートが公開済みである
(下記参照) · curl -sIL <origin>/ の結果が 200 で終わる。
リダイレクト: フェーズ C のパス安全性ゲートで stardust/redirects.tsv が出力
された場合は、元の受信 URL が 404 にならないよう、ここで EDS のリダイレクト機構に
接続します。コンテンツルートにリダイレクトシートを置きます(DA を使用するサイトでは
/redirects.json、列は Source / Destination。管理 API 経由で PUT し、ページと同様に
プレビューして公開します)。ルートの扱いは必ず次のとおりにしてください。ソースルートが
ページを配信する場合は、それをルートの index ドキュメントとして配信します
(パイプラインはそこから / を配信します。/index ≡ / です。これを置き換えてしまう
/ の Source 行を追加してはいけません)。ソースルート自体がリダイレクトする場合に
限り(curl -sI <source-url> を実行し、Location チェーンをたどります)、シートに
/ と /index.html → ランディングページを記載します。その後、
curl -sIL https://<branch>--<repo>--<owner>.aem.page/ の結果が 200 で終わることを
確認します。/ が 404 の場合、すべてのフェーズに合格していても配信全体が失敗します
(記録例:すべての .html パスに行があり、/ には行がないシート)。
フェーズ D2 — 動的機能(dynamics フェーズ 4~5)
パターンカタログ(skills/dynamics/reference/patterns.md)にある、再現性のある self の行(インデックスを利用した一覧と検索、モーダルローダー、URL としてのメディア、クライアント側で計算するブロック、無効化したオーナー向けタグ設定、オリジン外データの階層、シート同期)の計画を実装します。それ以外の行はすべて1つのオーナー判断バッチとして提示し、暫定的な階層をリリースします。
クエリインデックスは公開済みツリーから構築します。フェーズ C でページごとに公開してから、total をポーリングします。
各機能の最後に、再実行可能なチェックを記載したパリティ行を stardust/dynamics/parity.json に追加します。フェーズ H の前に dynamics-check.mjs --origin <live host> を実行し、レポートにその表を掲載します。
再実行に失敗した場合は、サイレントな成功として扱わず、dynamic-gap/api-dependency の学びとして記録します。
インデックスを利用した一覧はドキュメント優先でリリースします(作成者が記述した行を使用し、インデックスは非テキストと補完に使用します。dynamics/reference/listings.md)。デプロイ時の AI 可読性ゲートは、すべての一覧ページで実行します。
クエリインデックスが見つからない場合、設定サービスの問題ではなく、コードブランチの欠落です。
/query-index.json が 404 を返すのは、プロジェクトに helix-query.yaml がないことを意味します。コードブランチのルートに作成してください(仕様の knowledge/helix-query.yaml はドラフトです)。ページを LIVE として公開し、total をポーリングしてください。詳細は skills/dynamics/reference/listings.md の「インデックスを取得する」を参照してください。設定サービスから 403 が返るのは想定どおりです。シートを利用した暫定インデックスがリリースされるのは、書き込み可能なコードブランチがない場合のみです(interim として記録し、判断内容に名前を付けてください)。
検索パリティは、結果の有無ではなく件数とタイトルで確認します。 結果ブロックはタイトルの一致を優先して順位付けし、タイトルの一致が N 件未満の場合に限り、説明、次に本文を参照します(N = 調査対象の語句について、ソースに表示される件数)。タイトルと説明の組み合わせで重複を除外し、入力補完の結果数を N 件に制限します。N、上位タイトル、既知の一致結果 1 件は、検出時に SOURCE から読み取り、search-query チェック(expectCount、expectTitles、expectIncludes)に記録します。件数が一致しない場合、dynamics-check.mjs はチェックを失敗させます(skills/dynamics/reference/patterns.md の「search-index-backed」)。
ここで構築したページはカバレッジに含めます。 結果ページ(またはキャプチャのないページ)にはインベントリ行がないため、登録しない限り verify.mjs --all、optimize.mjs、統合サイトマップの対象外のままです。
node skills/rollout/scripts/update-coverage.mjs --new search --path /search --template search --origin dynamics --title "Search"
その後、ほかのページと同様にステータスを記録します。inventory.mjs は再実行時もそのような行を保持します(source.migratedHtml のオリジンマーカーで識別し、ステータスは変更しません)。そのため、この行は一度だけ実行されます。
フェーズ D3 — 多言語対応(言語ごとのツリー)— オプション
ソースに言語ツリー(/fr/…、/en/…)がある場合は、同じブロックライブラリを再利用する並列コンテンツツリーとして追加します。変更するのは、作成者が記述するコンテンツと少量の配線だけです(言語別ルーティングに対応したクロームドキュメント、言語別インデックス、言語別のパス安全性)。
reference/multilingual.md を参照してください。
フェーズ E — サイト全体の検証
node skills/rollout/scripts/verify.mjs # uses rollout.json site.liveHost
# or: --base <url> (explicit host) | --root <dir> (offline, against a local export)
納品したすべてのページについて、verify は HTTP 200、about:error がないこと(デプロイ
#75)、および各内部 href="/…" が既知の納品済みパスに解決されることを確認し、その後、
各ページを verified または failed に切り替えます。いずれかのページが失敗した場合は、ゼロ以外の終了コードで終了します。
ヘッドレスレンダリングチェック(テンプレートごと)。 200 を返す .plain.html でも、空白のままレンダリングされることがあります。装飾の失敗(スクリプトの欠落、ブロックのラッパークラスの誤り、404 のクローム)はテキストチェックでは検出できません。各テンプレートの最初の納品ページ(ホームを含む)で、ライブ URL をヘッドレスブラウザーで読み込み、装飾が実行されたことを検証します。ランタイムの body.appear クラスが設定されていること(stardust/runtime-contract.json に準拠)、main .section の数が 0 より多いこと、pageerror イベントが 0 件であること、壊れた画像が 0 件であること、さらにテンプレートのアーキタイプにあるすべての restoreAtDelivery 項目が満たされていることを確認します。autoplay の <video> が少なくとも 4 分の 1 見えている場合に再生中であること(単に存在するだけでなく、!paused で currentTime が進んでいること)、回転式カルーセルが操作なしで進むことを確認します。
ロスター全体に対する公開オリジンゲート(#125)。 verify はページがレンダリングされることを確認します。DELIVERY の判定には、デプロイされたページごとのピクセル・高さ・クリップ・コンテンツを検査する replica の gate-all.mjs を使用します(../replica/reference/source-fidelity-gate.md § すべてのページを対象とする公開オリジンゲート)。update-coverage.mjs --gate stardust/replica/gates/all-<w>/summary.json は各行を delivery.gate に書き込み、失敗したページを failed に切り替えます。ゲートが失敗している間、verify がページを verified にすることはありません。完了判定は一元化され、ピクセル数だけに依存することはありません。C-deliver では、ロスターの実行単位として記録されるのは gate-all(引き継ぎ契約 § 3、行 C)です。
フェーズ E2 — リンク監査の完全性
verify.mjs は納品済みページ上のリンクをチェックします。このフェーズでは、名簿ベースのバッチで見落とされるリンク先を網羅します
(reference/operational-learnings.md § 2 つの verify チェック)。
- ナビゲーション/フッター/ランディングページのリンク先は、アーキタイプの兄弟ページではありません。
/navと/footerのドキュメントにあるすべてのhrefと、各セクションのインデックス/ランディングページを列挙し、それぞれがデプロイ済み+公開済み+検証済みであることを確認します。また、ナビゲーションとフッターのドキュメント自体も公開済みであることを確認します。そうしないと、コミットされても公開されず、リンクが 404 になり、ダッシュボードには 100% と表示されたままになります。 - デプロイ段階で、手作業ではなく、元サイトへの戻りリンクをローカライズします。
node skills/deploy/scripts/localize-links.mjs --source-host <live-host> --content content --redirects stardust/redirects.tsvは、コンテンツツリーに存在するパスへの元サイトホストのhrefをすべて正規のルート相対形式に書き換え、絶対 URL のままにしたリンク(ローカルページがない場合。404 より元サイトへの戻りリンクの方が適切です)を一覧表示します。各ウェーブの後、ツリー全体に対して必ず再実行します。後続のウェーブでページが公開されて初めて、先行ウェーブのページに有効なリンク先が追加されるためです。--checkをゲートとして使用します(終了コード 2 = ローカライズ可能なリンクが残っています)。 - 各内部ページには、配信 URL でリンクします(
deploy/scripts/eds-path.mjs)。.htmlは付けず、フォルダーのインデックスにのみスラッシュを付けます(/x/)。.htmlと、末端ページに付けたスラッシュは 404 になりますが、.plain.htmlは通ります。ローカルページがない.htmlリンクは、有効な元サイトの URL に付け替えます。 - 監査では、各
hrefをライブツリーに対して GET します。台帳だけでは、スラッシュや大文字小文字の不備を検出できません。 - キャプチャに含まれていないリンク先。 どちらの場合も、対象リストとともに、名前付きの判断として
direction.mdに記録します。方向性の上限設定に含まれるべきリンク先はキャプチャ漏れです。まずクロールし(キャプチャ → 移行 → ゲートの順で行い、ライブページを参照して作成してはいけません)、不足が 12 ページ以下なら納品します。それを超える場合は元サイトに付け替え、スコープ上の負債として一覧にします。宣言された上限設定の範囲外にあるリンク先はスコープ拡張です。件数に関係なく付け替えます。外部リンク先は元サイトに付け替えます。他のロケールのリンク先は、そのロケールのルートが一度もキャプチャされていない場合にのみ付け替えます。キャプチャ済みのページはすべて(duplicateOfのシェルやロケールルートを含むstardust/state.jsonの行)、対象範囲内であり、納品対象です。付け替えてはいけません(12 ページ以下というルールは未キャプチャのページに適用されます。このルールを理由に、キャプチャ済みのロケールルートを 10 件も除外した実行記録があります)。404 は絶対に残さないでください(ある監査では、スコープ内の未キャプチャページが 10 件見つかり、それらを納品したのは正しい判断でした)。
フェーズ F — 最適化:複数ソースの監査 + ゲート(納品品質)
フロー内の品質ゲートです。optimize は、既存の監査スキルからの検出結果を集約して 1 つの台帳(optimize/findings.json + optimize/scorecard.json)にまとめ、それぞれに修正可能性のタグを付け、ロールアウトをゲートします。ソース(完全な対応表は reference/audit-sources.md を参照):
rollout:baseline— 組み込みの決定論的検出器:node skills/rollout/scripts/optimize.mjs # uses rollout.json site.liveHost # or: --base <url> | --root <dir> | --slug <s> | --allimpeccable:critique+impeccable:audit— デザイン品質 + アクセシビリティ/パフォーマンス。- マーケティング SEO スキル —
seo-audit、schema、ai-seo、site-architecture。 stardust:tensions—stardust/current/brand-review.htmlに基づく、デザイン上の機械的な緊張関係。
ソースとの同等性。 抽出データのキャプチャが存在する場合(stardust/current/pages/<slug>.json
とそのレンダリング済みサイドカー。別の場所を指定するには --current <dir> を使用)、ソースと共有されているベースラインの検出結果(同じ <title>、ソースにも description がない、ソースにも JSON-LD がない、同じページ同士でタイトルが共有されている)は、fixability: out-of-scope とタグ付けされ、source parity: というエビデンス接頭辞とともに、専用のレポートセクションに記載されます。これらは情報提供のみを目的とし、ヘルススコアおよび未解決の P1/P2/P3 件数から除外され、ゲートの対象にならず、自動修正もされません。記録された手動確認のみの実行では、このような検出結果 63 件が手動で受け入れられました。それ以外は従来どおり振り分けられます(reference/checks.md § Source parity)。
writer を使って、各ソースの検出結果を台帳に正規化します:
node skills/rollout/scripts/findings.mjs record \
--source marketing:seo-audit --layer seo --check thin-content \
--severity P2 --fixability platform-migration \
--scope-ids blog/post --evidence "…" --recommend "…"
node skills/rollout/scripts/findings.mjs resolve <id> --status accepted --note "…"
すべてのソースで、1 つの ID 空間、重複排除、スコアカード、および検出 → 修正 → 検証ループを共有します。ソースを再実行すると、そのソースで消失した検出結果が解決済みになり、fixed の検出結果に再発があれば再オープンされます。人間が設定した accepted/wontfix は保持されます。修正可能性による振り分け: platform-migration → 自動修正/再デプロイ、design-pass → 上流(表示のみ)、out-of-scope → 情報提供。未解決の P1 がスコープ内に 1 件でもあると、ゲートはゼロ以外の終了コードを返します。ページが納品可能な状態になるのは、verify が成功し、かつ台帳に未解決の P1 がない場合のみです。
約 1,000 ページの規模では、
head.htmlレベルの修正を反映するにはサイト全体の再公開が必要で、ページごとの検出結果も更新されます。optimize ゲートの監査対象はcoverage/pages.jsonに含まれるページのみです。また、忠実に移行された並行ソースツリーでは、正当な重複タイトル検出が発生します(バグではなく、canonical の判断が必要です)。reference/operational-learnings.mdを参照してください。
brand-tensions、design-ux、content-conversion の判断レイヤーは、impeccable/tensions ソースから値が設定されるまで null として採点されます。スコアカードには、偽のスコアではなく未評価と表示されます。
フェーズ G — AEM 自動修正(ループを完結させる)
node skills/rollout/scripts/autofix-aem.mjs --project <eds-root> # [--dry-run] [--slug s] [--check c]
プラットフォームの自動修正エンジン(AEM-EDS、v1 — 積極的)。check に登録済みの EDS 修正機能がある未解決の検出結果すべてについて、EDS のプロジェクトファイルを編集し、変更を finding.autofix に記録して、検出結果を in-progress にします:
- 決定論的 —
eds-fix-h1(<h1>が正確に 1 つ)、サイトマップ(再構築)。 - コンテンツの下書き(レビュー用に記録)—
eds-metadata-title/eds-metadata-description、eds-alt-draft、eds-disambiguate-title。 - 手動(ガイダンス/ペイロードを準備)—
eds-jsonld(marketing:schemaを使用)、eds-canonical、eds-landmark-main。
最初に --dry-run を使用してください。適用後、編集したページを再デプロイし、続けて verify + optimize を再実行します。ステージされた検出結果は fixed に変わります。design-pass の検出結果は表示されますが、自動修正されません。
フェーズ H — レポート
動的パリティ表(フェーズ D2 の stardust/qa/dynamics-report.md)をデリバリー台帳の隣に含めます。各機能について、そのクラス、到達状況、ステータス、担当者の判断、再実行したチェックを記載し、レポートがサイトの「表示内容」だけでなく、サイトの「実際の動作」も正直に示すようにします。
rollout.json.lastRun と optimize/scorecard.json を読み込みます(または inventory.mjs を再実行します)。
rollout — <site> → aem-eds
==================================================
Pages <N> total · <v> verified · <d> deployed · <p> pending · <cp> content-pending · <s> stale
Templates <T> (per-template delivered/total)
Blocks <B> total · <c> converted · <p> pending
Quality health <H>/100 · open P1 <n> / P2 <n> / P3 <n>
Pixel table prototypes <p>/<P> PASS · deployed <d>/<D> PASS (pixel-only <x>/<D>) — gates/{prototypes,all}-1440/summary.md
To deliver <list of remaining slugs>
Content <cp> pages awaiting content track (block code deployed, document not yet pushed)
pending/stale/failed を「不足しているもの」の明示的な一覧として提示します。ピクセル表の行は、2 つの summary.json の合計(pass、pixelOnlyPass、pages)から作成します。all-1440/summary.json に含まれていないデプロイ済みページはゲートされておらず、その一覧に含めます(#125)。
content-pending ページは別途一覧にします。失敗ではありません。そのブロックコードは有効で、migrate が HTML を出力して inventory を再実行すると、自動的に pending に進みます。
また、stardust/learnings.md を作成/更新します。skills/stardust/reference/learnings.md に従い、この実行で明らかになった失敗クラスごとに 1 件記録します(根拠、変更を提案するスキルとセクション、status: pending)。
プラグインのメンテナーが pending の記録をスキルの差分に取り込みます。これにより、実行中に苦労して得た修正が再び一から学び直されるのを防ぎます。
フェーズ I — ダッシュボード
node skills/rollout/scripts/dashboard.mjs # → dashboard/index.html + data.json
プロジェクトのデザインアイデンティティ(移行済みページの :root から読み取ったブランドトークン)でレンダリングする、自己完結型で外部 JavaScript を使わないダッシュボードです。中心となるのは、特定したすべてのページを URL パスでネストしたページツリーです。各ノードは、到達したライフサイクル段階のうち最も進んだ段階に応じて色分けします。
identified → prototyped → deployed → optimised
段階は、state.json(rostered/extracted/directed → identified、prototyped/approved/migrated → prototyped)、ロールアウトのカバレッジ(deployed/verified → deployed)、および最適化(optimised = verified かつ未解決の指摘事項がない)にまたがります。content-pending の兄弟ページは identified のままです(デリバリーを追跡できるよう台帳には含まれていますが、設計済みドキュメントはまだありません)。凡例の件数は累積です。テンプレートのアーキタイプには T バッジが付き、未解決の指摘事項があるページには赤い件数が表示されます。さらに、テンプレートの表と品質スコアカードもあります。
dashboard/data.json は内容を確認できるスナップショットです。各イテレーションの区切りで再生成してください(state.json は読み取り専用で、任意です)。
完了は 1 つの判定で決まります。 node skills/rollout/scripts/done-check.mjs が 0 で終了すればロールアウトは完了です。それ以外の場合は、不足項目が 1 行につき 1 件表示されます。
入力
| 入力 | ソース | 用途 |
|---|---|---|
stardust/migrated/*.html | migrate | デリバリー対象のページ(読み取り専用) |
stardust/migrated/**/_meta.json | migrate | templateId(template。template: null のアーキタイプは独自のスラッグでグループ化し、それ以外は type)、blocks(modules — インベントリレポートでは空のリストを持つサイドカーファイルもカウントされるため、フェーズ B の前に内容を入力してください)、widgets(widgets[] {id, href})、title |
stardust/state.json | stardust コア | (アーキタイプのみのモード) ページの全一覧と、未移行ページの type |
stardust/rollout/rollout.json | rollout/ユーザー | DA の対象座標 |
出力
| パス | 用途 |
|---|---|
stardust/rollout/coverage/pages.json | ページごとの配信台帳(スキーマ:schemas/rollout-pages.schema.json) |
stardust/rollout/coverage/templates.json | テンプレートのグループ化と集計(スキーマ:schemas/rollout-templates.schema.json) |
stardust/rollout/coverage/blocks.json | ブロックの重複排除台帳と EDS マッピング(スキーマ:schemas/rollout-blocks.schema.json) |
stardust/rollout/plan.json | 重複排除に基づく配信順序と、ページごとの変換/再利用の概要 |
stardust/rollout/optimize/findings.json | 複数ソースの品質指摘事項の台帳(スキーマ:schemas/rollout-findings.schema.json) |
stardust/rollout/optimize/scorecard.json | 品質スコアカードと履歴(スキーマ:schemas/rollout-scorecard.schema.json) |
stardust/rollout/rollout.json | 設定と lastRun の概要(スキーマ:schemas/rollout-config.schema.json) |
stardust/rollout/site/{sitemap.xml,robots.txt,manifest.json} | サイトレベルの組み立て成果物 |
stardust/rollout/dashboard/{index.html,data.json} | 自己完結型の進捗ダッシュボードとスナップショット |
EDS プロジェクトの編集(content/**、styles/) | autofix-aem が適用(stardust/rollout/ の外部で rollout が書き込む唯一のファイル) |
| 配信された EDS サイト | ページごとに deploy が生成(blocks/、widgets/、content/、fragments — deploy の管理対象) |
rollout は stardust/rollout/ の下に書き込み、配信先のEDS プロジェクトには autofix-aem を介した場合に限り書き込みます。非依存コア、state.json、migrated/ は変更しません。これらは読み取り専用の入力です。
依存関係(監査ソース — 参照のみ、同梱されません)
optimize は既存の監査スキルを呼び出して連携するため、これらのスキルがインストールされている必要があります。
- impeccable(
critique、audit) — すでに stardust の依存関係です。 - marketing skills —
seo-audit、schema、ai-seo、site-architecture。 オプションです。存在しない場合は注記を表示します。 - stardust tensions —
extractがリポジトリ内に出力(brand-review.html)。
各出力を findings.mjs record で台帳に正規化します。reference/audit-sources.md を参照してください。
rollout が行わないこと
- 上流の再設計は行いません。
design-passの指摘事項は提示しますが、ここでは修正しません。autofixが変更するのは、EDS プロジェクト内でプラットフォーム側で修正可能な指摘事項のみです。 - 新しい転送方式は追加しません。 配信には変更のない
deployの DA Source API パスを使用します。 - 非依存コアの再設計は行いません。
extract/direct/prototype/migrateとdeployは変更されません。 - 移行完了を事前に求めません。 Archetypes のみのモードも正式にサポートされています。ブロックコードは archetypes から配信され、残りのページは
migrateが HTML を出力するとcontent-pendingからdeployedに進みます。rollout の再起動は不要です。
スクリプト
scripts/inventory.mjs— 移行済みツリー → ページ + テンプレートのカバレッジ(冪等で、古いデータを考慮します)。--state <path>を指定すると、アーキタイプのみのモードが有効になります。scripts/blocks.mjs— 個別ブロックの重複排除台帳(blocks.json)。scripts/plan.mjs— 重複排除に基づく実行順序 + ページごとの変換/再利用の概要。scripts/update-coverage.mjs— ページとブロックの決定論的な配信状態更新ツール。すべてのロールアップを再導出します。--new <slug> --path --template --originを指定すると、移行済みツリーの外部で作成されたページ(D2)を登録し、カバレッジに含めます。scripts/section-fidelity.mjs— ソース忠実度ゲートの足場(作成済みセクションとソースの見出しアウトラインを比較し、ゲートの判断材料を提供しますが、自動判定はしません)。scripts/assemble.mjs— サイトレベルのサイトマップ/robots/フラグメントのマニフェスト(EXPECTED セット)。--verify-origin <live-origin>を指定すると、配信中の/sitemap.xmlと比較し、不一致がある場合は終了コード 1 で終了します。scripts/verify.mjs— サイト全体の構造検証(HTTP またはオフラインの--root)。scripts/optimize.mjs—rollout:baseline検出器 + マルチソースゲート。未解決の P1 がある場合は、0 以外の終了コードで終了します。ソースの取得内容を反映した指摘にはsource parity:のタグが付き、情報提供のみを目的とし、スコアリングやゲート判定の対象にはなりません。scripts/findings.mjs— 外部監査ソースからの指摘を記録/解決します。scripts/autofix-aem.mjs— AEM 自動修正エンジン(EDS プロジェクトを編集します)。scripts/dashboard.mjs— デザインアイデンティティのダッシュボード +data.jsonスナップショット。scripts/done-check.mjs— 完了判定(Phase I)。終了コード 0 は完了を意味します。scripts/lib.mjs— 共通の IO + ロールアップ + ページ読み込み + 自動修正レジストリのヘルパー。
参考資料
notes/rollout/PLAN.md— 設計、カバレッジモデル、フェーズ分け、未解決の質問。reference/delivery-gates.md— Phase C のゲート + 大規模な一括配信のフロー。skills/dynamics/SKILL.md+ そのreference/— 動的な領域:クラス、トリアージ軸、一覧のコントラクト + クエリーインデックスの仕組み、パターンカタログ、パリティレポート(B2/D2)。reference/multilingual.md— 言語ごとのツリー(D3)。reference/operational-learnings.md— 大規模ロールアウトでの注意点(拡張、再公開、検証)。reference/audit-sources.md— 監査ソース → レイヤー → 修正可能性 → 自動修正の対応表。reference/checks.md—rollout:baselineのチェックカタログ。skills/stardust/reference/learnings.md— レポートフェーズで実行ごとの学びを書き込む台帳。skills/migrate/reference/fidelity-tiers.md— Phase C で記録するアーキタイプ/類似ページ/簡易ページの各ティアのコントラクト。skills/migrate/reference/media-reconciliation.md— 画像忠実度リゾルバーの判断表。skills/deploy/SKILL.md— ロールアウトで適用する単一ページ変換の手法。skills/deploy/da-deploy-protocol.md— DA Source API のトランスポート。skills/migrate/SKILL.md—migrated/+_meta.jsonの入力を生成します。schemas/*.schema.json— カバレッジ + 設定のコントラクト。