---
name: dev-build-git-add-protocol
description: "dev:build 実行後の commit では必ず `git add -A dist-renderer/assets/` を含めること. selective stage は vite chunk hash rotation 時に SPA Failed to fetch を生む."
metadata: 
  node_type: memory
  type: feedback
  originSessionId: f3963f63-e0c0-4ff9-8d81-c0fb14dcb6f8
---

# dev:build 後の git add 永続 protocol

## Rule

`npm run dev:build` を実行した turn で commit を作る時は、 **必ず `git add -A dist-renderer/assets/`** を含めること. app-*.js / index.html / 個別 component file の selective stage **だけ** は禁止.

**Why**: vite は dev:build ごとに動的 import chunk file (mermaid.core / lib / mermaid-parser.core / wavedrom / katex / Pyodide 関連) の hash を rotation 再生成する. app-*.js (entry bundle) は新 hash chunks を参照するため、 chunks を stage し忘れると **HTML が参照する chunk が deploy 先 (CF Pages) に存在しない** ⇒ user side で `Failed to fetch dynamically imported module` の site outage が発生する.

**How to apply**: dev:build を実行した turn では git commit 前に **必ず** 以下 protocol を順守する:

1. `git status dist-renderer/assets/ --short | grep -c "^??"` で untracked chunks 数を確認
2. `git status dist-renderer/assets/ --short | grep -c "^ D"` で deleted chunks 数を確認
3. **両者が non-zero** なら hash rotation event 観測 → `git add -A dist-renderer/assets/` 強制
4. `git diff --staged --stat | grep -E "mermaid|lib-D|wavedrom|katex"` で critical chunks 含有 verify
5. ↑ 1-4 完了後に commit

## 観測 incident (累積 2 例)

| date | commit | scope | hash rotation 規模 | user impact |
|---|---|---|---|---|
| 2026-05-15 | STEP 1146 `a59701fa` "EMERGENCY site outage fix — dist-renderer/assets/ chunked deps unblocked" | 初回 incident, .gitignore `!app-*.js` のみ exception で chunk 全 ignore されていた pattern. .gitignore 修正 + 包括 stage で fix | unknown | full site outage |
| 2026-05-18 | `0e878dd0` "fix(spa-chunk-hash): mermaid + lib chunk hash rotation を stage — Circuit Showcase Failed to fetch 解消" | 2 回目 incident, .gitignore は正しく `!*.js` allow だったが、 私 (Claude) が前 commit 6bd3df4b で `git add app-Bhf0J7LT.js` の selective add 実行 → 60 chunks untracked のまま deploy | 61 deletions + 61 untracked = symmetric rotation | Circuit Showcase ②④⑤⑦⑧ section で Failed to fetch (5 section 同時 broken) |

★ **同 root cause で 3 日間隔で再発** = systemic anti-pattern, memory 永続記録必須.

## Detection heuristics

dev:build 後の `git status dist-renderer/assets/ --short` で以下 pattern が出たら **絶対に selective add でなく `-A`**:

```
 D dist-renderer/assets/mermaid.core-XXXX.js   ← 旧 hash
?? dist-renderer/assets/mermaid.core-YYYY.js   ← 新 hash
 D dist-renderer/assets/lib-XXXX.js
?? dist-renderer/assets/lib-YYYY.js
 D dist-renderer/assets/chunk-ZZZZ.js
?? dist-renderer/assets/chunk-WWWW.js
... (50+ files in similar pairs)
```

**symmetric D + ?? pairs** が 30+ あれば 100% hash rotation event. 一括 `-A` stage が唯一 safe な response.

## Related memory + protocol

- [[site-coverage-map]] — CLAUDE.md `docs/SITE_COVERAGE_MAP.md` 「実装 ≠ 反映」 永続原則 entry point の sibling protocol (dev:build chain は SITE_COVERAGE_MAP update と同 stage で chunk add 必須)
- [[auto-managed-file-conflict-protocol]] — auto-managed file は Edit 禁止 (script 経由) の sibling rule. dev:build artifacts (dist-renderer/) は auto-managed なので **直接 Edit でなく `git add -A` で transparent stage**
- [[no-rush-publication]] — 急がず ゆっくりと: hash rotation event を見逃さないために commit 前 git status check は必須 1 step

## Anti-anti-pattern (Antipattern #5 balance)

「だから dev:build 自体を避けるべき」 は誤った over-reaction. dev:build は site visible update に required tool で、 避けると site が古くなる. **dev:build 実行 + 直後 `git add -A` 包括 stage の 2 step が正解 protocol**. dev:build 回避は Antipattern #5 (過度の reject 警戒).

## Sub-incident: Cloudflare edge cache corruption (1 年 stuck) — 2026-05-19 観測

`git add -A` を順守しても **Cloudflare edge cache の corruption により別 layer の問題が発生する** ことが判明 (2026-05-19 incident).

### 症状

- 藤本さん browser が `mermaid.core-BS35Vb8N.js` で Failed to fetch 継続
- local + git + GET response 全て正常 (33,214 bytes valid JS)
- **HEAD response のみ `Content-Length: 32` で stuck** + `CF-Cache-Status: HIT` + `Age: 24,888 秒 (~7 時間)` + `Cache-Control: immutable, max-age=31536000`

### 原因

Deploy race window (中間状態) 中に missing chunk が一時的に SPA fallback (32 bytes) を返却 → CF edge が **immutable, max-age=31536000** で 32 bytes response を cache → 実 file deploy 後も cached 32-byte HEAD が **1 年間 stuck**.

browser modern ES module loader は HEAD response の Content-Length を信頼するため、 GET は valid content 返すが import は 32 bytes として失敗する.

### Detection

```bash
# HEAD vs GET の Content-Length 不一致を確認
curl -sI https://rei-aios.pages.dev/assets/<chunk>.js | grep -i content-length
curl -sv https://rei-aios.pages.dev/assets/<chunk>.js -o /tmp/check.js 2>&1 | grep -iE "content-length"
wc -c /tmp/check.js
# HEAD Content-Length != actual file size = CF cache corruption 確定
```

### Remediation

優先順位:

1. **User side (即効)**: Browser「サイトデータを完全消去」 (DevTools → Application → Storage → Clear site data) OR incognito window. **hard refresh だけでは不足** — immutable cache のため.
2. **Server side (永続)**: Cloudflare dashboard → rei-aios.pages.dev → Caching → **Purge Everything** (CF API token あれば automation 可能).
3. **Long-term prevention (trade-off あり)**: `_headers` の `/assets/*` を `immutable, max-age=31536000` から `max-age=86400, must-revalidate` 等の **shorter cache + revalidation** に変更. 但し 正常時の performance 低下.

### Why this matters

CF edge cache corruption は **`git add -A` protocol を完璧に順守しても発生する** 別 layer の問題. dev:build 後の deploy が成功しても、 deploy race window 中の transient state を edge cache が永続化する risk が常にある.

**永続防止**: deploy 後 5-10 分の verification window を取り、 主要 chunk の HEAD Content-Length と GET Content-Length を比較. 不一致なら即座に CF purge 検討.

## Related Incidents Timeline

| date | commit | scope | root cause | user impact |
|---|---|---|---|---|
| 2026-05-15 | STEP 1146 `a59701fa` | .gitignore `!app-*.js` のみ exception で chunk 全 ignore | full site outage |
| 2026-05-18 | `0e878dd0` | selective `git add` (chunks untracked のまま deploy) | Circuit Showcase ②④⑤⑦⑧ 5 section Failed to fetch |
| 2026-05-19 | (browser-side fix) | CF edge cache が deploy race window 中 32-byte SPA fallback を immutable 1 年 cache → HEAD response stuck | 藤本さん browser のみ stuck (cleared with site data delete) |

★ **3 incidents in 4 days** = systematic anti-pattern. 3 layer 防衛が必要:
- Layer 1: .gitignore で chunks allow (STEP 1146 fix)
- Layer 2: `git add -A dist-renderer/assets/` 順守 (STEP 1156-followup-37 fix)
- Layer 3: CF edge cache verification + browser data clear protocol (STEP 1156-followup-46 fix)
