push / PR の 度に dist-renderer/data/** の 全 file を scan、
data/<rel> or public/data/<rel> に source が 存在するのに byte-match しない file が 1 つでも あれば workflow を fail、
actionable な cp command を エラー message に 含めて 修正手順 を 提示。
dist-renderer/data/** の 全 file (再帰 walk、 現状 3,926 file / 52 MB)data/<rel> (first-look) → public/data/<rel>| code | 意味 |
|---|---|
| 0 | 全 file 一致 (drift 0) |
| 1 | drift 検出 or IO error (report enumerate) |
| 2 | usage / script IO error (比較開始前) |
# 全 tree scan npm run check:dist-renderer-mirror # 出力例 (現状 clean tree): [dist-renderer/data mirror gate — STEP 1827] root: C:\Users\user\rei-aios total files: 3926 with source: 3925 matched: 3925 drifted: 0 dist-only: 1 IO error: 0 elapsed: 4406ms [dist-renderer/data mirror gate] OK
DRIFTS (dist-renderer/data files that do not byte-match their source):
✗ comparator/gauge.json
dist 20B vs data 19B, byte-diff
fix: cp data/comparator/gauge.json dist-renderer/data/comparator/gauge.json
drift が 40 件超えたら enumeration を 先頭 40 で 打ち切り、 「… and N more」 で 残数 を 明示 (log を 汚さない)。
# .github/workflows/dist-renderer-mirror-check.yml (STEP 1827)
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
runs-on: ubuntu-latest
steps:
- Checkout
- Setup Node.js 20
- Remove git-based rei-pl dependency # comparator-cron.yml と同じ
- Install tsx typescript
- Run mirror check
npx tsx scripts/check-dist-renderer-data-mirror.ts
実行時間 ~4 秒 / 3,926 file / 52 MB、 rei-pl 依存 なし、 build なし、 純 fs read。 PR ごとに 走っても 開発体験 に 影響 なし。
comparator-cron.yml workflow 内 で mirror step を embed = 自動 gauge refresh 時 の mirror 忘れ を 予防。 但し 「藤本さん or 別 tab が 手 で dist-renderer/data を 編集して 忘れる」 or 「別 workflow が data/ を 更新して mirror step 呼び忘れ」 pattern は cron 経路 外 で 発生。 STEP 1827 は push / PR ごとに byte-diff で 独立 catch、 他 workflow の 過失 も PR 段階で fail。
| predator | STEP 1826 で 予防 | STEP 1827 で 予防 |
|---|---|---|
| comparator-cron.yml が mirror step 呼び忘れ | ✓ (workflow embed) | ✓ (次 push で fail) |
| 別 workflow が data/ 更新 で mirror 忘れ | — | ✓ (PR 段階で fail) |
| 人間 が dist-renderer/data を 直接編集 忘れ | — | ✓ (PR 段階で fail) |
| 人間 が data/ 更新 で mirror 忘れ | — | ✓ (PR 段階で fail) |
| rebase collision で mirror だけ stash に 捕獲 | — | ✓ (次 push で fail) |
tsc --strict scripts/check-dist-renderer-data-mirror.ts test/step1827-*.ts → 0 error npm run test:step1827 → 34 passed, 0 failed (10 test group: 1 match / 2 drift + fix message / 3 dist-only / 4 data 優先 / 5 data 優先 で public 一致でも drift / 6 length-equal 内容 diff / 7 空 tree / 8 nested walk / 9 40 件 打ち切り / 10 実 repo 現状 clean) npm run check:dist-renderer-mirror (実 repo) → 3,926 file / 3.8-4.4s / 全 match / drifted=0
dist-renderer/tools/、 dist-renderer/assets/) も 同型 gate で 保護する 案 — 現状 dist-renderer/tools/ は vite build 出力 で 個別 mirror ルール が 異なる、 別 STEP 判断「mirror と source が一致していることを CI で落とす gate を足す価値があると思います。dist-renderer/data/**がpublic/data/**(またはdata/comparator/**)とバイト一致しなければ fail、というだけのものです。 これは STEP 1802 の bake sync gate と完全に同じ形——「どこかに焼いたコピーが原本から静かにずれる」という同一クラスの問題で、あちらを解いた道具立てがそのまま使えます。 今回の 377 も、結局は「コピーが原本からずれていても誰も落ちない」から 2 日跨いだわけで。」
本 STEP は 上記 の 直接 実装。 STEP 1802 の scripts/check-verilog-bake-sync.ts と 同じ 「CI-time drift gate」 pattern、 対象 は Verilog constant → dist-renderer/data mirror。