📄 スマートグラス×リアルタイム役判定 リリース仕様書 のサブページ / INDEX / 対象: camera-ai.html(実物デモ)

📱 iPhone Web牌認識テスト — camera-ai.html スクリプト検証と改善計画

iPhone Safari + getUserMedia + onnxruntime-web で実施した実機牌認識テストのスクリプト(539行)を、5系統監査 → 改善統合 → 3レンズ敵対的検証(29クレーム) → 確定計画の全工程で検証。
検証中に本番モデル欠落(約1ヶ月間の無検知停止)を発見し、復旧まで完了した。

📅 2026-07-26 作成 🤖 マルチエージェントワークフロー 10 agents(5監査+統合+3検証+確定) 🎯 対象: docs-site/camera-ai.html(全539行・行番号突合済)
🗓 「いつまでに何をやればいいか」だけ知りたい方へ: 本レポートの実行計画を日付・担当・図解に落とした 図解ロードマップ(別ページ) を用意しました。識別方式の変更(YOLOX 載せ替え・KEEP 投票再設計・赤5の構造判定)も牌画像つきで図解しています。
49
監査指摘(CAM/INF/POST/UX/WEB の5系統)
8
CRITICAL — うち1件は本番停止を現認・復旧済
25
MAJOR(精度・安定性・運用に直結)
29
敵対的検証クレーム(needs_fix 15 → 全件計画に反映)
約9h
次のテストセッションまでに入れる確定8項目の工数
復旧済
本番モデル 10.6MB を過去デプロイから回収・再配信

🚨 最重要 — 検証中に発見した本番停止インシデント(復旧済み)

本番の models/mahjong_yolov8n.onnx は約1ヶ月前から欠落しており、camera-ai.html は新規アクセスで全停止状態だった。
モデル URL は HTTP 200 で text/html(SPA フォールバック)を返すため、HTTP コード監視では検出不能。onnxruntime は「protobuf parsing failed」を出し「カメラ開始」は永久に無効のままだった。
項目事実(デプロイメント履歴の実査で確定)
最後の正常配信デプロイ bb8bf7a0(コミット 9c0b7f4「CFデモ堅牢化」・約1ヶ月前)— 10,572,743 bytes / application/octet-stream
欠落発生同日の後続デプロイ 03036a0a 以降。原因: *.onnx.gitignore 対象でローカル docs-site/models/ に実体がなく、wrangler pages deploy(ローカル直アップロード)がモデル無しのマニフェストを配信した(本日 2026-07-26 のレポート追加デプロイ 2 回も同様に欠落を継承)
実機テストへの含意直近1ヶ月内のテストで認識が動いていた場合はブラウザキャッシュの旧モデルによるもの。新しい端末・シークレットモード・キャッシュ削除後は一切動かない状態だった。テスト結果の解釈時はこの点を考慮すること
復旧(2026-07-26 実施済)過去デプロイ bb8bf7a0 から ONNX 回収(SHA256 907d12d5…ba440429・先頭バイト 0x08=protobuf 確認)→ docs-site/models/ 配置 → 再デプロイ → 本番が application/octet-stream 10.6MB を返すことを確認
再発防止(P0-H)①日次ヘルスチェック: content-type が text/html なら notify.py 経由で LINE/デスクトップ通知 ②pdca-cycle.py の a1 自動デプロイ直前に docs-site/models/*.onnx 実体 assert(無ければ中断+通知) ③デプロイ検証を curl -w "%{content_type}" 方式に(HTTP コードでは検出不能のため)。mercari-text-copy の18日間無検知インシデントと同型の穴

この欠落は監査(INF-5)が構造リスクとして予言し、敵対的検証(impact レンズ)が「現在すでに停止中」と現認、確定計画で P0-0(即時復旧)に格上げされた — 多段検証が機能した実例。

目次

  1. 対象スクリプトの現状仕様
  2. iOS 実機で判明した重要事実(Web調査)
  3. 5系統監査の主要指摘(49件)
  4. 敵対的検証(29クレーム)の反映
  5. 確定改善計画 P0〜P3
  6. 次のテストセッションまでに入れる8項目(コード付き)
  7. iPhone 実機テストプロトコル(毎回同条件)
  8. 親仕様(スマートグラス版)との接続

§1 対象スクリプトの現状仕様

getUserMedia({facingMode:'environment', width:1280, height:720})   … L455(720p固定)
  → video(playsinline muted) → ガイド枠ROI切り出し(gw/13*1.7 の横長帯) … L278
  → 512×512 letterbox → onnxruntime-web 1.20.1(jsdelivr CDN・webgpu→wasm・numThreads=1)… L157/L266-275
  → decode(38クラス [1,42,5376] 決め打ち)→ NMS(IoU 0.45)… L293-303
  → 3モード: フリー / 13枠KEEP投票(minVotes6・agree0.62・conf0.48・streak4)/ 6枚スキャン蓄積 … L178/L188
  → 和了牌タップ → tenpai/score.js 役判定(ツモ・門前・子・東場東家 固定)… L259/L331/L388
駆動: rAF + setTimeout 20ms の常時全速ループ(静止検知なし)… L432-453

正しく実装されている点(検証で confirmed): ROI の videoWidth 基準座標換算、object-fit:cover のタップ逆変換(L470-475)、loopToken による多重 rAF 防止、pre canvas の willReadFrequently、NMS の隣接牌誤抑制が起きにくい設計、conf スライダー。土台は健全で、問題は iOS 実機運用への耐性・テスト計測・フィードバック還流の3領域に集中している。

§2 iOS 実機で判明した重要事実(2026年7月・Web調査+出典付き)

#事実camera-ai への影響
WEB-1iOS 26 Safari で WebGPU がデフォルト有効(WWDC25 発表・2025年秋出荷)。iOS 18 系は Feature Flag 止まりで既定無効ユーザーの iPhone が iOS 26 か 18 かで EP(webgpu/wasm)も速度も別物になる。テスト記録に OS バージョンと EP を必ず残す必要
WEB-2iOS 26.3 Safari の WebGPU は連続約500推論でページごとクラッシュする既知 issue(onnxruntime#27584。YOLO のカメラ検出で再現・Chrome では再現せず)20ms 間隔の常時ループでは数分で500回に到達。「しばらく使うと落ちる」現象の第一容疑。スロットリング+定期セッション再生成が必要(有効性は実機ゲートで判定)
WEB-3onnxruntime-web の最新は 1.27.0(2026-06)。使用中の 1.20.1 は約7バージョン遅れ。さらに WebKit 26 では JSEP ビルドの wasm モードが CPU 400%+/メモリ14GB+ に暴走する既知 issue(#26827・1.20.0〜1.23.2 で再現、非JSEP の ort.min.js は正常)現構成は ort.webgpu.min.js(JSEP)で wasm フォールバックも同バンドル — iOS 26 で WebGPU 初期化に失敗して wasm に落ちた端末がこのバグを踏む。navigator.gpu の有無で webgpu/非JSEP を出し分ける二段ロードへ変更すべき
WEB-4WebNN の Safari 実装は見込みなし(WebKit の立場は No signal)。ANE(Neural Engine)はブラウザから使えない高速化投資は WebGPU 安定化に集中。ANE が必要ならネイティブ化(親仕様の Unity アプリ)という判断材料
WEB-5iOS 16.3+ で背面カメラ(広角/超広角/望遠)を enumerateDevices で個別選択可。zoom は Safari 17+ 対応。torch/focusMode は実用上期待不可。「720p 上限」情報は 2018 年由来で古く、実上限は track.getCapabilities().width.max の実測が確実現在の 1280×720 固定(L455)は引き上げ余地。超広角は接写に強く「6枚寄せスキャン」と相性が良い。iPhone 主カメラの最短撮影距離(約15〜20cm)より寄るとピンボケ — ズーム活用で「離して寄せる」へ
WEB-6requestVideoFrameCallback は iOS 15.4+ で利用可setTimeout+rAF ループより適切(同一フレームの二重推論を排除、フレームドロップ計測も可能)
WEB-7Cloudflare Pages の _headers で COOP/COEP を配れば SharedArrayBuffer が有効化でき wasm マルチスレッド化(numThreads 4)が可能。ただし CDN スクリプトは CORP 制約に掛かるため ort 一式の自ホストが前提wasm 推論 200〜400ms → 最大3倍高速化の余地(要実機 A/B)。スコープは /camera-ai.html/vendor/* に限定(全パス適用は train-capture 等の外部リソースを壊す — 検証で確定)
WEB-8iPhone ブラウザでの YOLO 実測ベンチ公開事例はほぼ皆無外部データに頼れない — 自前テレメトリ(EP・median ms・UA を feedback 送信)が唯一の道。field_val_map50=null の解消と同根

§3 5系統監査の主要指摘(49件から抜粋)

3.1 CRITICAL 8件

ID指摘根拠(行)
INF-5モデルがローカル不存在+gitignore で再デプロイ即404(→実際に本番停止が現実化・復旧済)。404時も protobuf 生エラー表示のみで復帰不能。webgpu 失敗時に 12MB を二重フェッチL269-275 / .gitignore:26 / models/ 実査
CAM-1jsdelivr CDN が単一障害点 — ort 読込失敗で module 全体が ReferenceError 死し、サンプル・オンボーディング含む全ボタンが無反応(HUD は「モデル読込中…」のまま無言)L157 / L266 / L486-536(未到達)
WEB-1iOS 26 で WebGPU デフォルト有効(→ EP が OS 依存で分岐。テスト記録に必須)webkit.org WWDC25
WEB-2iOS 26.3 WebGPU の連続約500推論クラッシュ(→常時ループでは数分で到達)onnxruntime#27584
POST-1KEEP 校正が「ちょうど13牌検出フレーム」を要求 — 実機の低 recall では永久に固定されず、12真+1誤検出の瞬間に誤校正が恒久汚染L217
POST-2誤ロックしたスロットの個別訂正手段がない(全リセットのみ)— テスト完走率を直撃L228 / L244 / L530-533
UX-1feedback-worker への送信が皆無 — 誤認識データが PDCA(新規feedback≥30 で再学習)に一切還流せず、field_val_map50=null が永遠に埋まらない全539行に fetch なし / feedback-worker/src/index.js は受け皿実装済
UX-2スキャン蓄積に牌クラスの訂正 UI がない(✕削除のみ)— モデルが系統的に誤読する牌が出るとテストが13枚完成前に破綻L523-528 / L397-403

3.2 MAJOR 25件(領域別の要点)

領域主要指摘
iOS ライフサイクル(CAM-2/3/4/5)画面ロック・アプリ切替からの復帰処理ゼロ(visibilitychange / track ended / Wake Lock すべて不使用)→ 復帰後は凍結映像に「認識中」表示のまま。「📸確定」が video.pause() を呼ばず枠と映像がズレて和了牌タップが不正確。getUserMedia エラーは英語生文言のみで復旧手順に辿り着けない(旧 live-demo.html にあったガードの退行)
カメラ品質(CAM-6/7)「6枚に寄せて」誘導が主カメラの最短撮影距離(約15〜20cm)と衝突しピンボケ入力を誘発(zoom capability 未活用)。ガイド帯は 13枚前提固定(gw/13*1.7)で、6枚スキャン時は牌の上下約44%が ROI 外にクロップされ「寄せるほど悪化」する逆説(512×512 入力の有効面積はわずか13%)
推論性能(INF-3/4/6)wasm はメインスレッド直列実行(proxy 未設定)で 1推論 200〜400ms の UI ブロック+発熱→スロットリング。webgpu の実行時故障(run 時例外・誤出力)にフォールバックなし。COOP/COEP 未配備で numThreads=1 固定(2.5〜3倍の高速化余地が未着手)
投票・後処理(POST-3〜8)x座標のみの枠割当は手ブレ・パンで全枠が隣にズレて投票汚染。投票に減衰なし(初期誤投票が永続)。KEEP.conf=0.48 が UI スライダーと独立の隠し閾値。赤5(0m)⇔通常5(5m)のフリッカーで投票キーが分裂しロック不能。SCAN_CONF=0.5 は参照ゼロの死に定数で安定判定(5フレーム)も➕ボタン活性に反映されず誤追加し放題。class-agnostic NMS のみで同一牌の重複箱が二重カウント
テスト運用(UX-3/4/5)EP・モデル版・conf% が画面に出ず「どのモデルで何%正解したか」を記録できない。正解率の記録手段ゼロ。点数計算はツモ・門前・子・東場東家固定で実戦と一致しない(「東の刻子は2飜つくのに子計算」という矛盾既定も)

MINOR 16件は確定計画の P2 群(0z 可視化・dims 検証・セーフエリア・✕44px 化・fps EMA・サンプルデモの蓄積保護 等)に反映。全指摘は行番号付きでワークフロー成果物に保存済み。

§4 敵対的検証(29クレーム)— needs_fix 15件の反映

改善バックログを「実装可能性」「効果」「後方互換・リスク」の3レンズで検証。confirmed 14 / needs_fix 15(refuted 0) — 全 needs_fix を確定計画に反映した。主要な修正:

レンズ指摘反映
impact「本番は現在すでに停止中」を現認。models URL は 200+text/html を返し、res.ok でも curl の HTTP コードでも検出できないP0-0(即時復旧)に格上げ・実施済み。検出は content-type + 先頭バイト検査に変更
impactヘルスチェックと PDCA 自動デプロイ(a1)のモデル同梱保証が欠落 — a1 が走るたびモデルを消す構造P0-H 新設(日次 content-type 監視+デプロイ前 assert)
feasibility復帰処理のスニペットが running=true を戻さず「恒久凍結」を作り込む/frozen 中の復帰で pause が解除され確定状態が壊れるuserStarted フラグ分離+frozen 維持分岐に書き直し(§6 #3)
feasibility150ms スロットリングは500回到達を約100秒に延ばすだけで対策にならない。セッション再生成での回避も未実証10分実機検証を「有効性判定ゲート」に格上げ。無効時の代替(wasm 張替え/再読込誘導)を計画に内包
feasibilitywasm proxy は WebGPU EP と併用不可(ORT 公式)。テンソル再利用と transfer が非互換(2フレーム目に detached)proxy=true は ep==='wasm' 確定後のみ+テンソル再利用と排他制御
feasibility / regression_headers /* 全適用は train-capture.html(Google Fonts)・live-demo.html(jsdelivr)・yolo-roboflow.html(mermaid CDN)を COEP で破壊スコープを /camera-ai.html/vendor/* に限定+他ページ回帰確認を検証項目化
impact / regressionフィードバック自動送信の自己ラベル(モデル予測)が pull-feedback.py の 20% field-val 恒久昇格を汚染=精度計測の自作自演。L143「端末内処理・送信なし」の約束を破る後方非互換。worker は meta を黙って破棄payload に auto:true 必須+auto の val 昇格除外。送信はオプトイン UI(既定 OFF・初回確認)+文言更新。worker の meta パススルー改修を工数に内包
regressionKEEP を14枠化すると maybeKeepScore が15枚を scoreHand に渡し採点全損(CSS も13列固定)slots は13本維持、余剰1枚は割当除外して和了牌候補として提示のみ(UI 無改修設計に固定)
regression点数条件バーで seatWind=東+isDealer 自動セットにするとサンプルデモの点数ラベルが親計算に化けるsampleDemo は子・ツモ固定 opts、UI 既定は子、自動セットは明示操作時のみ

§5 確定改善計画 P0〜P3(検証反映済み)

#項目工数
P0-0本番モデル欠落の復旧 — ✅ 2026-07-26 実施済み(bb8bf7a0 から回収→配置→再デプロイ→content-type 検証)0.5h(済)
P0-H再発防止: 日次 content-type ヘルスチェック(notify.py 連携)+ pdca-cycle a1 デプロイ前の *.onnx 実体 assert0.7h
P0-1fetch 読込+content-type/先頭バイト検査+session.inputNames[0] 使用+二重フェッチ排除1.5h
P0-2ort undefined ガード(CDN 死亡時もサンプル/オンボーディング生存)→ 本修正は vendor/ 自ホスト0.2h+2h
P0-3カメラライフサイクル: wakeLock+visibilitychange 復帰(running 復元・frozen 維持・userStarted 分離)+track ended 監視+連打ガード1h
P0-4150ms スロットリング+400回ごとセッション再生成(iOS 26 実機10分の有効性判定ゲート付き)1h
P0-5 / P0-6確定時 video.pause()(タップ座標ズレ解消)/ getUserMedia ガード+e.name 別の日本語復旧案内0.5h
P0-7guideRect の scanMode 分岐(6枚時の上下44%クロップ解消)+縦持ち下限0.3h
P0-8KEEP 校正の複数フレーム化(直近10フレーム最頻値)+14検出許容(slots 13本維持・余剰は和了牌候補)1.5h
P0-9フィードバック送信(worker meta パススルー改修+オプトイン UI+auto:true+val 昇格除外+文言更新)— Phase D(jitaku 日次タスク)完了が Do 着火の前提3.5h
P0-10model-meta.json+version/EP 常時表示+cache-bust1h
P0 計約13.5h

P1(精度・速度 — 計約14.6h)

NMS 2段閾値+IoA 包含抑制 / KEEP.conf の confThr 連動+保留理由表示 / 投票リングバッファ化(N=20)/ 枠割当のグローバルシフト補正+1対1マッチング / スキャン品質ゲート(SCAN_CONF を confThr 連動で復活+除外枚数表示)/ ウォームアップ推論+実行時 wasm フォールバック / wasm proxy 化(ep 確定後のみ)/ ort 1.27.0 化+非JSEP/webgpu 二段ロード / COOP/COEP(スコープ限定)/ zoom スライダー+1080p / requestVideoFrameCallback 化 / テンソル再利用 / imageSmoothingQuality A/B

P2(テスト効率 — 計約8.3h)/ P3(将来)

P2: ロック済みスロット個別訂正+手動パレット(訂正ペアは最高品質の学習データとして送信)/ conf%+実効 fps EMA+セッションサマリ JSON(log-ml-progress.py 直貼り形式)/ 点数条件バー(ツモ/ロン・親/子・リーチ・ドラ)/ 0z 可視化 / dims 検証 / セーフエリア / ✕44px 化 / サンプルデモ蓄積保護。 P3: 2段ガイド(7+7)/ レンズ切替 / torch / camera-core.js 切り出し(グラス版と共通化)/ OffscreenCanvas。

§6 次のテストセッションまでに入れる8項目(計約9h・コード付き)

#0(✅実施済)本番復旧+同梱保証の残り

モデル復旧は完了。残り: pdca-cycle.py a1 直前の docs-site/models/*.onnx 実体 assert+日次ヘルスチェック(P0-H・0.7h)。

#1 モデル読込の故障検出+version 表示+cache-bust(2h)

let ep='wasm', modelBuf=null, META={version:'unknown'};
(async()=>{
  try{ META=await (await fetch('models/model-meta.json',{cache:'no-store'})).json(); }catch(e){}
  const res=await fetch(`models/mahjong_yolov8n.onnx?v=${META.version}`);
  const ct=res.headers.get('content-type')||'';
  modelBuf=new Uint8Array(await res.arrayBuffer());
  if(!res.ok || ct.includes('text/html') || modelBuf[0]===0x3C /* '<'=HTML */ || modelBuf.length<1e6){
    hud.textContent=`モデル未配置(${ct||'不明'})— models/ 配置後に再デプロイしてください`; return; }
  try{ session=await ort.InferenceSession.create(modelBuf,{executionProviders:['webgpu']}); ep='webgpu'; }
  catch(e){ session=await ort.InferenceSession.create(modelBuf,{executionProviders:['wasm']}); }
  hud.textContent='準備OK ('+ep+')'; document.getElementById('start').disabled=false;
})();
// L439: session.run({[session.inputNames[0]]: meta.tensor})
// L451: `${dt.toFixed(0)}ms | ${META.version} | ${ep}` を常設表示

#2 ort undefined ガード(0.2h)

L266 以降の ort 依存コードを if(typeof ort==='undefined') で包み、CDN 死亡時も L486-536 の UI バインド(サンプル/オンボーディング)を生存させる。本修正(vendor/ 自ホスト)は次サイクル。

#3 カメラライフサイクル堅牢化(1h)— 検証反映版

let track=null, wl=null, userStarted=false;
async function reqWL(){ try{ wl=await navigator.wakeLock.request('screen'); }catch(e){} }
async function startCam(){
  if(running) return;                                  // 連打ガード
  if(!navigator.mediaDevices?.getUserMedia){ hud.textContent='カメラAPI非対応(httpsで開いてください)'; return; }
  try{ const s=await navigator.mediaDevices.getUserMedia({...});
    track=s.getVideoTracks()[0];
    track.addEventListener('ended',()=>{ running=false;
      hud.textContent='カメラが停止しました — カメラ開始を再タップ';
      document.getElementById('start').textContent='カメラ開始'; });
    video.srcObject=s; await video.play(); running=true; frozen=false; userStarted=true; reqWL();
    /* 既存 UI 更新 */ startLoop();
  }catch(e){ /* #5 の e.name 分岐 */ }
}
document.addEventListener('visibilitychange', async()=>{
  if(document.hidden){ running=false; return; }         // 推論のみ停止
  if(!userStarted) return;
  await reqWL();                                        // 非表示で自動解放されるため再取得
  if(!track || track.readyState==='ended'){ await startCam(); return; }
  if(frozen) return;                                    // 確定状態は維持(pause も解除しない)
  await video.play().catch(()=>0);
  running=true; startLoop();                            // ★復元してから再開(恒久凍結の防止)
});

#4 スロットリング+セッション再生成 — 有効性判定ゲート付き(1h)

L452 の 20150。推論成功側に 400 回ごとの session.release() → 再 create(失敗時は wasm 張替え)。iOS 26 実機で10分連続稼働してクラッシュ回避を判定 — 無効なら (a) 400回ごと wasm 張替え (b) 再読み込み誘導へ即切替(スロットリング単体は500回到達を約100秒に延ばすだけ)。

#5 確定 pause+エラー分岐(0.5h)

toggleFreeze に frozen ? video.pause() : video.play().catch(()=>0)。catch は e.name で分岐: NotAllowedError→「アドレスバー左の「ぁあ」→Webサイトの設定→カメラ→許可 後に再読み込み」/ NotReadableError→「他のアプリがカメラ使用中」。

#6 guideRect の scanMode 分岐(0.3h)

function guideRect(W,H){ const gw=W*0.94, per=scanMode?6:13;
  let gh=Math.min(H*0.62, gw/per*1.7);
  if(H>W) gh=Math.max(gh, H*0.25);          // 縦持ち下限
  return [(W-gw)/2,(H-gh)/2,gw,gh]; }

6枚スキャン時の牌上下約44%クロップを解消。修正前後で平均 conf を比較記録。

#7 フィードバック送信 — 訂正フラグ込み版(3.5h)

次点(KEEP を本格テストするなら先行必須): P0-8 — 直近10フレーム最頻値校正+14検出時は slots 13本のまま余剰1枚を和了牌候補として提示(1.5h)。

§7 iPhone 実機テストプロトコル(毎回同条件・1セッション約15分)

固定条件

項目規定
端末機種名・iOS バージョンを毎回記録(iOS 26=webgpu / 18=wasm で速度が別物)
同一セットの実物牌。基準手牌3種を固定: A=タンヤオ形(萬筒中心)/ B=索子7枚以上(1s・9s 含む=既知の弱点)/ C=字牌4種以上
並べ方緑マット上・理牌済み・牌同士は接触・1列水平・ガイド枠内
照明室内天井灯(逆光・直射・影かぶりなし)。毎回同じ部屋・同じ時間帯。低照度テストは別枠で明示
距離スキャン蓄積=牌から約20cm(それ以上寄るとピンボケ=最短撮影距離割れ)/ KEEP 13枚=約35〜40cm。手持ちは肘を机につけて固定
事前確認HUD のモデル version と EP を読み上げ記録(旧キャッシュなら無効テスト — リロードで更新確認)。フィードバック送信トグル ON

手順

  1. 起動確認(1分): カメラ開始 → HUD「version | ep | ms」を記録。エラー時は文言をそのまま記録
  2. スキャン蓄積(手牌A→B・各約3分): 6枚ずつ➕で13枚蓄積 → 和了牌タップ → 点数表示。記録: ✕削除した誤認識の牌名と正解・conf 不足除外枚数・➕回数
  3. 13枠KEEP(手牌B・約4分): 全枠ロックまでの秒数・誤ロック枠(枠番号・誤/正)・校正が始まらない場合はその時間
  4. 確定+タップ(1分): 📸確定 → 端末を意図的に少し動かす → タップした牌が正しく和了牌になるか(#5 の検証)
  5. 耐久(2分以上): 放置して自動ロックしないこと(wakeLock)/ ホーム→復帰で推論再開(#3)を各1回
  6. 送信確認(1分): 送信件数 → 後刻 R2 / pdca-state.json で突合

記録項目(毎セッション必須 → log-ml-progress.py へ時刻付きで)

有効テストの3条件: version が最新・EP 記録あり・feedback 送信成功 — を満たすもののみ Δ比較に採用。満たさないものは理由付きで参考値ログに。

§8 親仕様(スマートグラス版)との接続

この iPhone Web テストは、親仕様(スマートグラス×リアルタイム役判定 リリース仕様書)の Phase 0「一人称 field mAP 初計測」の前段をなす実機評価装置である。以下の改善は将来のグラス版(Unity/C#)にそのまま持ち越される共通資産になる:

本レポートの改善グラス版仕様での対応物
SG共通 静止検知ゲート+推論間引き(P1-7 サブ項目)イベント駆動推論(§4.2 — 電力 1/30 削減の中核)
SG共通 KEEP 投票の再設計(複数フレーム校正・リングバッファ・2次元割当)バースト7フレーム多数決+KEEP 再チューニング(M-2)
SG共通 誤認識の訂正 UX(スロット個別訂正・クラスパレット)誤判定時 UX(§7 — 「?」マーカー+訂正)
SG共通 計測基盤(EP/version/median ms のテレメトリ)性能目標の実測ゲート(T-1/T-6/T-7)
SG共通 フィードバック送信(auto フラグ+訂正ペア)PDCA 還流(§7 — 30件で再学習トリガ)
guideRect のモード分岐 → P3 の 2段ガイド(7+7)手牌 ROI 抽出の一人称対応(M-13 の画角整合)
優先順位の指針: まず #0〜#7(約9h)で「テストが毎回成立し・結果が数値で残り・誤認識が学習に還流する」状態を作る → テストプロトコル初回実施で field 精度の一次データを取る → その結果(と P0-4 の有効性判定)で P1 の着手順を決める。Phase D(jitaku-pc1 の日次タスク登録)は #7 と並行で完了させること。