---
name: feedback-dist-renderer-dual-html-sync-protocol
description: "vite build 後、 dist-renderer/app.html + dist-renderer/index.html **両方** の bundle reference を同時 update commit 必須。 片方漏れると CF Pages トップページが blank になる (2026-07-11 実発生 incident 教訓)。 [[feedback-index-html-bundle-sync]] の dual sync 拡張。"
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 51f819cd-c0d3-444d-92fa-83a843e19d5b
---

# dist-renderer/index.html + app.html **両方** の bundle reference dual sync 永久 protocol (2026-07-11 確立)

## Rule

vite build (`npx vite build`) 実行後、 commit + push する前に **必ず 以下 2 file 両方の bundle reference を確認 + 同時 update**:

- `dist-renderer/app.html`
- `dist-renderer/index.html`

**両方が 同じ新 bundle hash** (例: `app-Dm4q5JXO.js`) を reference していることを実測 verify してから commit。

## Why

**Root cause**: CF Pages は `dist-renderer/_redirects` の `/*  /index.html  200` rule で 全 path を **`dist-renderer/index.html`** に fallback する SPA routing。 つまり:

- **トップページ (`https://rei-aios.pages.dev/`) は `dist-renderer/index.html` を serve**
- **`dist-renderer/app.html` は 別 endpoint** (直 URL `/app.html` は redirect 308)

vite build は `dist-renderer/app.html` を primary output として更新するが、 **`dist-renderer/index.html` は自動更新されない** (2 file が build 後に手動 sync 必要な状態)。 片方だけ commit すると CF Pages 上 index.html が古い bundle reference を保持 → 削除済 bundle URL に fetch → SPA fallback で HTML 返却 → browser JS 期待で HTML 受信 → dynamic import failed → **トップページが blank**。

## How to apply

vite build 後の commit 前 sanity check (毎回 mandatory):

```bash
# 両方 file の bundle reference を実測 grep
grep -oE "app-[a-zA-Z0-9]+\.js" dist-renderer/app.html
grep -oE "app-[a-zA-Z0-9]+\.js" dist-renderer/index.html

# → 両方が同じ hash であることを目視確認
# 不一致なら sed で index.html を app.html に合わせる:
sed -i "s|app-OLD_HASH\.js|app-NEW_HASH.js|g" dist-renderer/index.html

# git status で両方が staged されていることを確認
git status --porcelain | grep -E "dist-renderer/(app|index)\.html"
```

**git status で `D dist-renderer/index.html` (working tree 削除、 未 stage) が出た場合の対処**:

```bash
# GitHub HEAD から復元 (working tree 削除は誤削除の可能性)
git checkout HEAD -- dist-renderer/index.html
# その後 bundle reference を新 hash に update
sed -i "s|app-OLD_HASH\.js|app-NEW_HASH.js|g" dist-renderer/index.html
git add dist-renderer/index.html
```

## 2026-07-11 実発生 incident 詳細

**背景**: STEP 1275-1281 の Chang paradigm coverage arc の site 反映 commit `51966e688` (Chang Paradigm Coverage page 新設)。

**症状**: 藤本さん 「https://rei-aios.pages.dev/ トップページが開かない」 実報告 (site page 追加 commit push 完了直後)。

**Root cause 実測 (5 分特定)**:

1. **`npx vite build`** で新 bundle `app-Dm4q5JXO.js` 作成、 旧 `app-yY3UoLoY.js` は `git rm` rename tracked で削除
2. commit `51966e688` で `dist-renderer/app.html` は新 bundle reference に更新
3. **しかし `dist-renderer/index.html` は同 commit で更新漏れ** — ローカル working tree 削除 (`D` in git status) で 未 stage、 GitHub HEAD には 古い version (`app-yY3UoLoY.js` reference) が retain
4. CF Pages `_redirects /* /index.html 200` で `dist-renderer/index.html` を serve、 削除済 bundle URL に fetch → SPA fallback HTML 返却 → browser JS 期待で HTML 受信 → dynamic import failed → **blank page**
5. 藤本さん 実 browser で 「トップページ 開かない」 実報告 (Rei は curl で 実測 diagnose 必要)

**修正 (commit `fb3f6c341`, 1 file +1/-1 line, 5 分以内 復旧)**:

```bash
git checkout HEAD -- dist-renderer/index.html
sed -i 's/app-yY3UoLoY\.js/app-Dm4q5JXO.js/g' dist-renderer/index.html
git add dist-renderer/index.html
git commit -m "Site: dist-renderer/index.html bundle sync fix ..."
git push origin main
```

CF Pages redeploy 完了確認 (Bash `run_in_background` + `until` loop で automated wait):

```bash
until curl -s "https://rei-aios.pages.dev/?t=$(date +%s)" | grep -q "app-Dm4q5JXO"; do
  sleep 5
done
echo "DEPLOY_COMPLETE: top page references new bundle app-Dm4q5JXO.js"
```

## 前身 protocol との差分

[[feedback-index-html-bundle-sync]] は既存の bundle sync protocol だが、 **単一 file only** の focus。 本 protocol は:

- **`dist-renderer/app.html` + `dist-renderer/index.html` 両方** の dual sync 強制
- **CF Pages `_redirects` の SPA fallback behavior** の明示化 (root = index.html serve)
- **`D` in git status (working tree 削除、 未 commit)** 検出時の `git checkout HEAD --` 復元手順
- **CF Pages redeploy 完了 wait automation** (Bash run_in_background + until loop)

[[feedback-index-html-commit-required-protocol]] とも複合適用。

## Prevention checklist (毎回 vite build 後 mandatory)

- [ ] `grep -oE "app-[a-zA-Z0-9]+\.js" dist-renderer/app.html` で新 hash 確認
- [ ] `grep -oE "app-[a-zA-Z0-9]+\.js" dist-renderer/index.html` で **同 hash であることを実測**
- [ ] `git status --porcelain | grep -E "dist-renderer/(app|index)\.html"` で **両方 staged** 確認
- [ ] `D dist-renderer/index.html` (未 stage 削除) が出たら `git checkout HEAD --` で復元 + hash update
- [ ] commit + push 後、 `curl -s https://rei-aios.pages.dev/ | grep -oE "app-[a-zA-Z0-9]+\.js"` で deploy 結果 verify
- [ ] deploy lag があれば `until` loop で automated wait (max 5-10 min)

## Related

- [[feedback-index-html-bundle-sync]] 前身 protocol (単一 file focus)
- [[feedback-index-html-commit-required-protocol]] vite 後 commit mandatory
- [[feedback-deploy-verify-http-200-plus-content-grep-required]] HTTP 200 + grep verify discipline
- [[feedback-deploy-verify-violation-same-day-2026-06-05]] 前 incident 実例
- [[project-session-2026-07-11-collatz-chang-coverage-arc]] 本 protocol 確立の直接原因 session
- commit `51966e688` (トップページ壊れた commit) + `fb3f6c341` (fix commit) の pair reference
- dist-renderer/_redirects の `/*  /index.html  200` fallback rule
