AI Landing Page Lab — 修正指示リスト
Date: 2026-08-30
Reviewer: 植木拓海 / Claude
対象状態: src/lp-model.js (8/27 17:42), src/main.jsx src/runtime-prompt.js (8/30 11:02)
このリストは2026-08-30時点のレビュー原本であり、完了状態の正本ではありません。2026-08-31時点の実装状況、二層画像版、最新QA、未解決事項は docs/CURRENT_STATUS.md を参照してください。
前提
上流設計(docs/production-pipeline.md, docs/wf-layout-principles.md, src/runtime-prompt.js のプロンプト)は水準以上。
問題は 設計を出力に接続していないこと。特に exportHtml() が全設計情報を破棄している。
WF側のレイアウトカタログを拡張する前に、A群を閉じること。
優先度: P0=商品として成立しない / P1=検証に入れない / P2=品質 / P3=整合
A. 出力HTML(src/lp-model.js:598 exportHtml)— P0
全セクションが small + h1 + p + proof + a.cta の同一マークアップで出力されている。
| ID | 症状 | 修正 | 完了条件 |
|---|
| A1 | layoutVariant type content asset implementation layout userQuestion role を一切使っていない | wireframe-layouts.js の型解決と WireframeSectionBody の分岐を exportHtml に移植し、型ごとのマークアップを実装 | 40型カタログの各型が固有のDOM構造を出力する。同一構造の連続が0 |
| A2 | <form> が存在しない。全CTAが href="#contact"(最終セクション=ただのテキストブロック) | form-panel / form-split / hero-form を実データで実装。送信先・完了後表示・入力時間を明記 | 出力HTMLに動作する <form> が1つ以上あり、CVが完了できる |
| A3 | 各セクションに <h1> → 12〜22個 | h1はheroのみ。以降は h2/h3 | 出力HTMLの h1 が厳密に1つ |
| A4 | 画像がラウンドロビン visuals[index % visuals.length]。imageBrief と無関係 | セクションIDと生成画像を1:1で紐付け | FV用画像がFAQに出ない。imageBriefを持つセクションだけが画像を持つ |
| A5 | 画像srcが signedUrl 直リンク。期限切れで納品物が自壊する | エクスポート時に画像を取得しzip同梱、相対パス参照へ書き換え | ネットワーク遮断状態でzipを展開しても画像が表示される |
| A6 | 全画像 alt="" | imageBrief.subject から意味のあるaltを生成。装飾画像のみ空alt | 情報を持つ画像のaltが0件でない |
| A7 | font-family:Arial,'Noto Sans JP' でWebフォント未読込。トンマナ3案の書体指定が出力に届かない | 選択トーンの type(極太ゴシック/明朝/可変欧文)に対応するWebフォントを読み込む。日本語を先に指定 | 3トーンで書体が実際に変わる |
| A8 | 日本語組版が壊れる:letter-spacing:-.07em / line-height:.94 / word-break・overflow-wrap 指定なし | 日本語見出しは letter-spacing .01em 前後、line-height 1.3〜1.4。overflow-wrap:anywhere を全体に | 375/390/414px で横スクロール0、見出しの不正折返し0 |
| A9 | OGP / Twitter card / JSON-LD / canonical / favicon なし。description が sections[0].body 直 | 全て出力。description は専用生成 | 主要メタタグが揃う |
| A10 | ボタン表記「HTML / CSS / JSをダウンロード」だがJSは出力されず、zipでもなく画像も同梱されない | zip出力(index.html / assets/ / images/ / README / 設計書 / 変更履歴)に変更 | ボタン表記と成果物が一致 |
| A11 | section:nth-child(4n+3) の機械的色反転、.no の巨大装飾数字 | 背景反転はセクションの役割で決定。装飾数字は削除 | 自らの quality-gate.md「装飾だけの面積を使わない」に適合 |
| A12 | min-height:72vh × 最大22セクション=スクロール紙芝居 | 情報量に応じた高さ。min-height は hero と cta のみ | 20セクション時の総高が現行比40%減 |
| A13 | sections[] 空 / tone.palette 3色未満でクラッシュ | 防御的デフォルトを実装 | 空入力でも例外を投げない |
| A14 | 個人情報の取扱い・プライバシーポリシー導線なし | フォーム設置時は同意チェックと取扱い表示を必須出力 | 日本のBtoBリード獲得LPとして公開可能な状態 |
| A15 | 計測タグ(GA4 / 広告 / CV計測)の差し込み口なし | 計測ID入力欄とタグ出力を実装 | CV計測が設定できる |
| A16 | nav にアンカーナビもロゴもない(リンク1本のみ) | セクションアンカーナビ+ロゴ枠 | ページ内回遊が可能 |
B. 事業導線 — P0
| ID | 症状 | 修正 | 完了条件 |
|---|
| B1 | ログイン / アカウントが無い | メールリンク認証など最小構成 | 別端末で続きから再開できる |
| B2 | 決済が無い。customer-validation-kit.md に価格(9,800 / 24,800 / 39,800円)まで書いてあるのに受け取れない | 決済連携(実装のみ。課金開始はApproval必須) | 有料エクスポートが技術的に成立 |
| B3 | 保存が localStorage のみ(STORAGE_KEY = "landing-page-studio:v5")。端末変更・キャッシュ削除で全消失 | サーバー永続化 | ブラウザを変えても案件が残る |
| B4 | 自プロダクトのLPにフォームが無い(ドッグフーディングしていない) | 自分のツールで自分のLPを作り、フォームでリードを取る | 問い合わせが受けられる |
| B5 | metrics.json 全ゼロ、hypotheses.json 両方UNTESTED、顧客接触ゼロ | customer-validation-kit.md の5問を既知3社に当てる(外部送信はApproval必須) | H1/H2に観測データが入る |
C. ヒアリング — P1
docs/adaptive-interview.md の設計思想に対し、実装は固定12問。
C-1. ドキュメントとの乖離
| ID | 症状 | 修正 | 完了条件 |
|---|
| C1 | when を持つ質問が0件で分岐が機能していない。ドキュメント記載のCV別分岐(資料DL→情報段階・営業接触への警戒 / デモ→決裁構造・価格開示 / トライアル→開始負荷・初回成功体験 / セミナー→日時・登壇者・定員)が1つも未実装 | goal に応じた分岐質問を実装 | goalを変えると出題内容が実際に変わる |
| C2 | invalidates 未実装。rewindAnswers は直前1問を消すだけで、矛盾する下流回答と生成物を再評価しない | 依存グラフを定義し、上流変更時に下流回答と生成物を無効化 | goal変更で traffic/proof の回答と既存構成が再評価される |
| C3 | needsConfirmation(AIが資料から推測した要確認項目)を受信して保存しているが画面に一度も表示していない(main.jsx:1598 で set、参照0件) | 「資料から推測した項目」を確認UIとして提示し修正可能にする | 推測項目がユーザー検証を通る |
C-2. 欠落している必須項目
| ID | 欠落 | なぜ必須か |
|---|
| C4 | 価格の実数値 | price は「見せ方」しか聞いていない。プロンプトは「価格情報があれば必ず反映」と命令するが渡す値が存在しない |
| C5 | 証拠の中身(実績数値・事例本文・顧客の声の原文・出典) | proof は「種類」しか聞いていない。捏造禁止なので証拠セクションが全て「要確認」で埋まる |
| C6 | フォーム項目・送信先・送信後の挙動 | A2が作れない直接原因 |
| C7 | ブランド資産(ロゴ・指定フォント・カラー・使用可能な写真・素材権利) | トンマナ3案が案件に接続しない。A7の前提 |
| C8 | 競合URL / 既存LPのURL | auditWireframe が answers.competition を参照しているがそんな質問が存在せず、チェックが常に空振り |
| C9 | 法務・業種規制(景表法・薬機法・特商法)・NGワード | 公開できない出力になる |
| C10 | 計測(GA4 / 広告タグ / CV定義)・公開先ドメイン | 「流入経路から設計する」と言いながら計測が出力に無い。事業仮説の「独自ドメイン公開」も未取得 |
| C11 | 正式表記(社名・サービス名・商標・敬称) | 誤記のまま公開される |
| C12 | 除外ターゲット / 言ってはいけないこと | 「対象外顧客」セクションが作れない |
C-3. 実装バグ
| ID | 症状 | 修正 |
|---|
| C13 | optional質問をスキップすると文字列 "未定" が回答として保存されプロンプトに混入する | null を保存し、プロンプト側で欠落として扱う |
| C14 | 進捗バーは completed / active.length、ラベルは completed + 1 / active.length でオフバイワン | 表記を統一 |
| C15 | multiPicked が質問切替時にリセットされない(continueMultiple 内でのみ空配列化) | 質問変更時にリセット |
| C16 | 単一選択のたびに setTimeout(commit, 320) の人工ディレイ。12問で約4秒の純損失 | 削除または120ms以下に短縮 |
D. 生成の堅牢性 — P1
| ID | 症状 | 修正 | 完了条件 |
|---|
| D1 | parseLpResult はセクション数が12〜22の範囲外なら即例外。リトライも修復もない | 範囲外は自動リトライ(最大2回)→ それでも外れたら不足を提示して部分採用 | 11セクション返却でユーザーがエラーだけを見る状態を解消 |
| D2 | parseHeadlineResult(3件未満)/ parseToneResult(3件でない)も件数不一致で即例外 | 同上 | 生成失敗率を計測し記録 |
| D3 | mergeTargetedSections は対象sectionIdが生成結果に無いと例外を投げ、生成物を全破棄 | id正規化+近似マッチ、失敗時は該当コメントのみスキップ | id名の揺れでコメント反映が全滅しない |
| D4 | 部分再生成で「指定外は変更するな」と指示しつつ sections配列全体を返させ、ドリフトを検証していない | 返却後に非対象セクションをハッシュ比較し、差分があれば元の値へ戻す | 無関係セクションの無断変更が0 |
| D5 | clean() が改行を全てスペースに潰すため、資料の段落・箇条書き構造が失われた状態でLLMへ渡っている | 改行を保持(制御文字のみ除去) | 資料の見出し構造がプロンプトに残る |
| D6 | sourceText を9,000字でサイレント切り捨て。通常のサービス紹介資料は超える | チャンク分割 or 事前要約。切り捨て時はユーザーへ明示 | 20,000字の資料で欠落が起きないか、起きたら通知される |
| D7 | トーンのパレット不正値を全て #111111 に置換するため、3案が同色になり得る | 不正時はリトライ。フォールバックは案ごとに別色 | 3案のパレットが必ず相互に異なる |
| D8 | 画像生成ポーリングが最大120回×2200ms=4.4分。進捗表示はattempt数から算出したフェイク | 実ジョブ進捗を返す。タイムアウトを短縮し中断可能に | 進捗表示が実態と一致、キャンセルできる |
| D9 | p_request_id を毎回 crypto.randomUUID() で生成しており冪等性がない。リトライで二重にジョブが積まれ生成枠を消費 | クライアント側で安定したリクエストIDを生成 | 同一リクエストの再送でジョブが増えない |
| D10 | reviseSection が指示文をそのまま body に代入する実装のまま残っている(「もっと短く」で本文が「もっと短く」になる)。現在未使用 | 削除するか、LLM再生成へ置換 | デッドコード0 |
E. セキュリティ / コスト — P0(公開前必須)
| ID | 症状 | 修正 | 完了条件 |
|---|
| E1 | api/generate-page.js に認証もレート制限も無い。URLを知っている誰でもLLMジョブを投げられ、制限はサービス全体の LLM_DAILY_JOB_LIMIT のみ。一人が回すと全ユーザー分の枠が消える | セッション単位のレート制限+認証 | 匿名の連続実行が遮断される |
| E2 | api/design-images.js が ai-banner エンジンへの完全無認証プロキシ。誰でも無料で画像生成できる | 認証必須化 | 無認証リクエストが401 |
| E3 | sourceText / instruction がプロンプトへ素通し。</source> を含む文書でプロンプトを乗っ取れる=タダでLLMを使う穴 | デリミタのエスケープ、または構造化入力へ変更 | 注入テストが通らない |
| E4 | error.message をそのままクライアントへ返している(内部構造が漏れる) | ユーザー向けメッセージへマップ | 内部情報が露出しない |
F. UI / デザイン — P2
※ 検証スクショは 8/27 00:01 版。現行ビルドで再撮影して再判定すること。
| ID | 症状 | 修正 |
|---|
| F1 | FVの下半分が空(1280×1400のうち下750pxが白紙) | 情報密度を上げ、成果物の予感を見せる |
| F2 | 最重要入力である資料アップロードが右上の小さな点線ボックス。質問カードが主役になっている | 「資料を入れると勝手に埋まる」を主役に |
| F3 | 選択カードの図版(DOC/TALK/PLAY/LIVE)が意味を伝えず、4枚とも同図形の色違い。自らの color-system.md「装飾だけの面積を使わない」に違反 | 現行版で修正済みか再確認 |
| F4 | H1の禁則処理が壊れる(「増やしたい行/動は?」) | 日本語の折返し制御 |
| F5 | SP横スクロールが残っている。browser-qa-2026-08-27.md は修正済みと記載しているが、証跡の sp-390-fixed.png 自体が見出し・カード・ヘッダーの切れを示している | 390/375/414px で再検証 |
| F6 | word-break:break-all を使用(日本語では誤り)。overflow-wrap:anywhere と混在 | overflow-wrap:anywhere に統一 |
| F7 | 選択カード4枚に Action/System/Attention/Success を1色ずつ当てており、color-system.md で定義した色役割が最初の画面で崩壊 | 色は状態を表す用途に限定 |
| F8 | AUTO SAVED 表示の実体は localStorage のみ。過剰な安心を与えている | B3の解決まで表記を弱める |
| F9 | <button> の内側に <input type="file"> を置いている(不正なHTMLネスト、キーボード操作とスクリーンリーダーが壊れる) | <label> + input 構成へ |
G. コード品質 / 運用 — P2
| ID | 症状 | 修正 |
|---|
| G1 | product-v3.css が45KBで74行(1行数千文字)。人間もAIも差分レビューできない | 整形し、責務ごとに分割 |
| G2 | agents/*/workspace/ が .gitignore:17 で除外=製品コードがバージョン管理外。ロールバック手段がアプリ内の localStorage 版履歴だけ | workspace配下のソースをgit管理対象へ |
| G3 | 未使用CSSが並存(styles.css / studio-v2.css / art-direction.css / product-v3.css / runtime.css) | 使用中以外を削除 |
| G4 | QAの自己申告と証跡が食い違っている(F5)。放置すると以降の全報告が信用できなくなる | QA手順に「証跡画像を再度開いて自分で判定する」を必須化し、AGENTS.md に明記 |
H. ドキュメント整合 — P3
| ID | 症状 | 修正 |
|---|
| H1 | docs/adaptive-interview.md が実装と乖離(C1/C2) | 実装に合わせるか、実装をドキュメントに合わせる。どちらか明記 |
| H2 | docs/quality-gate.md の Accessibility / Performance / Conversion を出力が満たしていない(A2/A3/A6/A14) | 出力を基準に合わせる |
| H3 | docs/browser-qa-2026-08-27.md に事実と異なる記載(F5) | 再検証のうえ訂正 |
着手順
- E1 / E2 / E3 — 公開する前に塞ぐ。放置するとコストが漏れる
- A1 / A2 / A3 / A5 — 納品物が商品になる最低ライン。特にA5は返金事故になる
- C3 / C4 / C5 / C6 — 出力を埋めるための入力。ここが無いとAの改修が空回りする
- D1 / D3 / D4 — 生成の失敗率とドリフトを潰す
- B5 — 顧客接触。実装と並行して開始する
- 残り
WFレイアウトカタログのさらなる拡張は、A1が閉じるまで停止すること。 設計と納品物の乖離を広げるだけになる。
2026-08-30 追加QA対応
| ID | 状態 | 生成器側の対応 | 証跡 |
|---|
| A17 SPナビ | 解消 | ネイティブ details / summary のセクション目次を追加 | evidence/after/mobile-nav-interaction.json |
| A18 FV天端 | 解消 | hero-formのコピーとフォームを上端揃え | evidence/after/sections/1280/01-hero.png |
| A19 eyebrow重複 | 解消 | hero連番を廃止し、重複時は対象読者へ置換 | 同上 |
| A9残 OGP画像 | 解消 | og:image / twitter:image を絶対URL出力し、publicUrl 注入に対応 | output/real-e2e/index.html |
| A20 画像なしセクションの重なり | 解消 | 画像が存在する場合だけ負のmarginを使う重ねレイアウトを生成 | evidence/after/sections/*/{02,08,14}-*.png |
17セクション × 4幅の最終判定は docs/browser-qa-2026-08-30.md を正とする。