既存 comparator-cron.yml (STEP 1696 land、 daily 22:30 UTC / 07:30 JST の 4 gauge auto-refresh) を 3 point 追記:
plugin_census を 5 本目 gauge として 同列追加 (snapshot / run / change 判定 / commit / failure upload の 全 5 経路)dist-renderer/data/comparator/ mirror 生成 + 同一 commit に 含める (STEP 1815 addendum で 発見 の 「mirror 不在で SPA fallback」 系統問題 の 恒久予防)scripts/generate-tools-index.ts を workflow 内で 実行、 public/tools/index.html + dist-renderer/tools/index.html + public/sitemap.xml を 同一 commit に 追加、 独立 trigger として tools index staleness も changed=true 判定既存 4 gauge (freshness / harvest-lag v01+v02 / feed-cadence) と 同型 の 経路:
# snapshot loop に 追加 for f in freshness harvest-lag harvest-lag-v02 feed-cadence plugin-census; do ... done # 実行 step - name: Run comparator plugin-census (STEP 1826, multi-registry HTTP, ~10s) run: npm run comparator:plugin-census # change 判定 loop も 5 gauge # commit の git add に plugin-census-latest.json 追加 (source + dist-renderer 両方) # failure artifact upload も plugin-census 追加
probe は 5 registry (npm×3 + openvsx + wordpress + drupal + crates.io control) で HTTP、 世界を変更する 呼出は 皆無、 polite header pinned in registry-probe.ts。 daily 07:30 JST 実行 で 前日 07:30 との delta を per-probe で 記録、 検査票 v2 (STEP 1815) fingerprint で edit vs world change 判別。
/data/comparator/*.json 5 URL 全てが _headers の no-cache rule を 通過しつつ 実体は SPA fallback (index.html) を 配信していた。 dist-renderer/data/comparator/ が 存在せず、 _redirects の /* → /index.html 200 が unknown path を 吸収。 addendum commit 75f7d9d19 で 1 回 mirror を land したが、 cron の 次 refresh で source が 動いても mirror は 動かず、 手動 mirror + commit の 負担 が 恒久 残る 構造。
本 STEP で mirror 生成 を workflow の 「新 step」 として embed、 gauge 再生成 → mirror 生成 → change 判定 → commit の 順で source と mirror を 同一 commit に 束ねる。 blast radius は 既存 4 gauge cron と 同等、 STEP 1802 bake sync gate と同型の 「焼いた copy が 原本から 静かに ずれる」 pattern の 予防。
- name: Mirror data + tools index into dist-renderer (STEP 1826)
run: |
mkdir -p dist-renderer/data/comparator
for f in freshness harvest-lag harvest-lag-v02 feed-cadence plugin-census; do
src="data/comparator/${f}-latest.json"
if [ -f "$src" ]; then
cp "$src" "dist-renderer/data/comparator/${f}-latest.json"
fi
done
if [ -f public/tools/index.html ]; then
mkdir -p dist-renderer/tools
cp public/tools/index.html dist-renderer/tools/index.html
fi
scripts/generate-tools-index.ts が どの npm script (dev:build 等) にも 組み込まれておらず、 tool page 追加時 に 手動 run が 必要。 藤本さん独立確認で 「377 vs 380 gap」 として 発見、 STEP 1814+1815 land 直後 も 反映漏れ。 手動 fix commit d6cb9ab61 で 応急 fix したが 恒久 対策 未実装 だった。
- name: Regenerate tools index (STEP 1826)
run: npx tsx scripts/generate-tools-index.ts
# change 判定 で tools index staleness も 独立 trigger:
if [ "$after_idx" != "$prev_idx" ]; then
changed=true
summary="${summary}tools-index "
fi
# commit の git add に:
public/tools/index.html
dist-renderer/tools/index.html
public/sitemap.xml
gauge 変化 が ゼロ でも tools index が 前日 と 異なれば commit trigger、 「gauge 静穏 + tool page 追加のみ」 の 日 も 24h floor で 反映保証。
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/comparator-cron.yml'))"
→ parsed OK, 15 steps (元 11 → 15)
npm run test:step1826
→ 25 passed, 0 failed
# 実 workflow trigger:
gh workflow run "Comparator Gauge Daily Refresh" (manual、 藤本さん judgment 待ち)
または scheduled 2026-09-07 07:30 JST で 自動 fire
dist-renderer/data/** が source (data/comparator/** or public/data/**) と バイト一致 しなければ fail する CI gate。 STEP 1802 bake sync gate と 完全 同型、 workflow 側 の 過失 (mirror 忘れ / 部分 mirror) を PR 段階 で catchscripts/research-radar/inspection-tail.ts を 走らせて 検査票 v2 md も 同一 commit に、 は 本 STEP に 含めず。 daily-radar.ts (local ReiResearchRadar 06:30 JST) が 別経路 で 生成、 workflow 07:30 JST で mirror だけ 更新すると 検査票 の fingerprint が 前日 gauge を 参照する 不整合。 別 STEP 判断待ち# scheduled 2026-09-07 07:30 JST or manual trigger の 直後: curl -s https://rei-aios.pages.dev/data/comparator/plugin-census-latest.json | jq '.generatedAt' curl -s https://rei-aios.pages.dev/tools/index.html | grep -oE "step-181[45]" # 期待: # generatedAt 07:30 JST 直後 に 更新 # tools/index.html に step-1814 + step-1815 が 含まれる # workflow log で 「Mirror data + tools index into dist-renderer」 step が successful