✅ 完了工程 retest-01-wave3a-server-patchWave 3A: 再診断前のGameSession最小patchを実装し、各cacheの無効化契約とRelay判断telemetryをfocused testで固定する
カテゴリ: impl
正規ID: bingo-capacity-retest/retest-01-wave3a-server-patch
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
採用方針
再診断前に、既知の計測汚染と重複readだけを除く最小patchを入れる。telemetry context、reaction namespace/viewer非依存射影、retention state、product updated_atをinstance cache化し、正本を書いた経路で更新または無効化する。
不変条件
cacheは正本ではない。hibernation後の新instanceは初回readでSQLから再構築する。
reaction transactのcommit成功でnamespace stateを置換し、失敗時は破棄する。purge時は全cacheを消す。
load-staging telemetryはactive capacity receiptがある時だけ有効で、participant、token、秘密値を記録しない。
drawAndJudge object再利用、Worker response passthrough、Relay DOは診断で支配要因が確認されるまで実装しない。
追加観測
mutation queue待ち、WebSocket page送信、recipients/shared frames、response bytes、in-flight participant readを固定dimensionで記録する。
完了証拠
2026-08-01にfocused test付きで実装済み。証跡はdocs/evidence/capacity-retest-wave-3a-2026-08-01.md。負荷試験と正式容量判定は後続ToDoが所有する。
後続工程
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-01-wave3a-server-patch- anchor
- anchor_missing
✅ 完了工程 retest-02-live-reactions-realtimeリアクション即時反映の受入条件を確定し、製品E2E『観戦者が合計1件を見る』を緑にする
カテゴリ: impl
正規ID: bingo-capacity-retest/retest-02-live-reactions-realtime
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
オーナー裁定
reaction集計はメモリのみとし、DO再構築・deployで0へ戻ることを許容する。reaction押下経路のSQL書込はゼロ、永続化は主催者のmute操作だけ。
個人別5秒6回/300ms burst制限と冪等receiptを撤去する。ゲーム全体の毎秒300件windowだけをメモリで残す。
500ms coalesced broadcast(leading + trailing)で{type:"reactions", revision, aggregates}の共有frameを全socketへ送る。clientは揮発revisionで弾かず最新frameを採用する。
悪意ある大量送信の本対策はWorker/edge側であり、今回DO内へ偽の防御を置かない。
実装境界
src/game/live-reactions.mjsを揮発tally+永続moderationへ分離し、worker/game-session.tsから同期永続化を除く。clientはreactions frameでsnapshot内集計を差し替え、未知frame typeを無視する。
受入と現在地
押下数に比例してSQLへ書かない、500msで畳む、muteだけ残る、DO再構築で集計だけ0へ戻ることをfocused testで固定する。本番SHA 2d3c6463af5189b4d79e83bfe6e429fe30218f8fでPOST 200、即時UI反映、別接続snapshot反映、全切断後0復帰まで確認済み。未実施は抽選完走、観戦grant経路、高負荷配信計測。
作業記録
現行Step 6(本番deploy)完了。2d3c646を2026-08-01 05:57Zにbingo.kitepon.devへ配備した。
配備前実測: /healthz buildSha=5e11189(runbookとHANDOFFの a4b731f は追随漏れ。a4b731fは00:33Zに配備されたが01:03Zに5e11189が上書きしていた)。container running/healthy、restart 0。
進行中ゲーム: running 0件・paused 0件・ready 1件(オーナーの未開始ゲーム。削除せず永続stateのまま)・ended 35件・deleted 14件。
rollback tag: bingo-bingo:rollback-20260801T055643Z-pre-2d3c646。
rsync dry-run: 削除4件はすべてec536c4で改名済みの旧Gantt生成物。秘密混入なし。
配備後: /healthz・/readyzとも buildSha=2d3c6463af5189b4d79e83bfe6e429fe30218f8f、ok/ready、bindings=ok、database=ok。container healthy、restart 0、state mount健在。logにEACCES・migration失敗・JWKS/TLS失敗なし。
公開UI実測: smoke用ゲームを作成し参加者として参加、リアクションを実押下。POST /api/games//reactions が3回とも200。500回帰は解消。押下はUIへ即時反映。後から開いた別接続が接続直後のsnapshotで集計を受け取ったので、集計はサーバ側に存在する。全接続が切れた後に開き直すと0へ戻り、裁定1の揮発が本番で実際に起きた。smokeゲームは削除済み。
未実施: 抽選完走、観戦grant経路でのリアクション表示、高負荷下の配信計測(retest-03〜07で扱う)。
安全上表示できない要素を除外しました。
来歴: v1/retest-02-live-reactions-realtime・記録者 kite-mac/claude-opus-5
現行実装手順(この順で進める。1〜4はtreeを緑に保つため1つのcommitで着地させる)
src/game/live-reactions.mjs を新モデルへ差し替える。
永続面は moderation(mutedParticipantIds)だけ。集計・直近イベント・ゲーム全体の窓は
createLiveReactionTally が持つ揮発面。participants / hostMemberships / receipts /
participantWindows を落とす。projectLiveReactions は tally と moderation を合成する。
worker/game-session.ts を配線する。
synchronizeReactionState を削除。reactions.react は mute判定 → tally.react → 配信予約。
reactions.moderate は mute/unmute だけ永続化し、clear は tally.clear。
500ms coalesced broadcast(leading + trailing)で共有frameを全socketへ送る。
app/lib/product-game-client.ts を配線する。
frame.type === "reactions" を取り込み、snapshotのreactionsを差し替える(再取得しない)。
revisionで弾かない(揮発なので0へ戻り得る)。未知frame typeは致命扱いをやめて無視する。
testを作り直す。
live-reactions.test.mjs を新モデルへ。game-session-reactions.test.mjs へ
「押下数に比例してSQLへ書かないこと」「500msで畳むこと」「muteだけ永続すること」
「DO再構築で集計が0に戻り、muteは残ること」を追加する。
製品E2E product-game-flow.spec.ts を緑にする。
本番deployと公開後smoke。配備前gateはdocs/operations/production-deploy-plan.mdに従う。
HANDOFFと同runbookの「本番SHA a4b731f」は実測5e11189とずれているので同時に直す。
来歴: v1/retest-02-live-reactions-realtime・記録者 kite-mac/claude-opus-5
現行オーナー裁定(2026-08-01)で設計を確定した。実測に基づく。
【計測】1,000人・実運用時のreaction state = 711 KiB を1リアクションにつき3 transact書いていた
(約2.1 MiB/件)。内訳は receipts 460.9 / participants 178.7 / participantWindows 53.7 KiB。
永続化が本当に要るのは205 bytes分だけだった。
【裁定1】集計はメモリのみ(案A)。DO再構築で0に戻ることを許容する。
deployのたびに必ず0へ戻る点を説明した上での選択。よってリアクション経路のSQL書込はゼロ。
SQLへ書くのは主催者のmute操作時だけ。
【裁定2】個人別の連打制限(5秒6回・300msバースト)を撤去する。
UIが送信中に全ボタンを無効化しており通常操作では発動しない。サーバ実装は
resume token検証と参加者引き当ての後に判定しており防御になっていない。
ゲーム全体の窓(毎秒300件)はメモリで残す。守る対象はカウンタではなく単一DOの処理枠。
【裁定3】冪等の受領書を撤去する。連打が自由なら再送の二重計上と2回押しが区別できず、
区別する意味が消える。
【配信】500ms間隔・trailing edgeあり。{type:"reactions", revision, aggregates} の
118 bytes共有frameを全接続へ。送信元も送信先も載せない。viewer固有のmute状態は
snapshot側で配る。revisionはメモリのみで0へ戻り得るため、clientはrevisionで弾かず
最新frameを素直に採る。
【非目標】悪意ある大量送信への対策はDO内では成立しない(到着後に安く捨てるだけ)。
本当の対策はWorker/edge側で、今回は手を出さない。「DO内制限で守れている」と書かない。
【受入】製品E2E product-game-flow.spec.ts「カウントダウン・ライブリアクション・匿名観戦検索」
が緑。focused testでmute・throttle・押下数に比例して書き込まないことを固定する。
来歴: v1/retest-02-live-reactions-realtime・記録者 kite-mac/claude-opus-5
note head: 07485fc1da3b095c7c800f99e5b9ced3c520af51e83e27ff2b387c0b27b6e31c
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-02-live-reactions-realtime- anchor
- anchor_missing
✅ 完了工程 retest-03-wave1-generator-clockWave 1(生成器側): 単調時計によるRTTと生成器内処理時間の計測、試験前後20回以上のmidpoint採取を実装する
カテゴリ: impl
正規ID: bingo-capacity-retest/retest-03-wave1-generator-clock
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
背景
Windows生成器の時計がサーバーより約0.92秒進んでいたため、従来の片方向fan-out遅延は正式値にできない。試験を再実行するだけでは同じ不確実性を残す。
実装方針
試験前後それぞれ20回以上、request送信時刻とresponse受信時刻のmidpointを採取する。
最小RTT群からserver offsetと不確かさを算出し、raw RTT、採用sample、補正値をrun artifactへ残す。
RTT、生成器内event処理時間、snapshot attempt時間はwall clockでなく単調時計で測る。
片方向遅延はraw値、offset補正後、offset不確かさを併記し、不確かさを隠した単一値にしない。
max(pre uncertainty, post uncertainty) + abs(post offset - pre offset) > 50msなら正式runを開始・受理せずINVALIDにする。
受入
pre/post各20件以上のsample、選択した最小RTT群、offset、uncertainty、drift、50ms gate判定が一つのbounded artifactから再計算できる。
後続工程
作業記録
現行背景
Windows生成器の時計がサーバーより約0.92秒進んでいたため、従来の片方向fan-out遅延は正式値にできない。試験を再実行するだけでは同じ不確実性を残す。
実装方針
試験前後それぞれ20回以上、request送信時刻とresponse受信時刻のmidpointを採取する。
最小RTT群からserver offsetと不確かさを算出し、raw RTT、採用sample、補正値をrun artifactへ残す。
RTT、生成器内event処理時間、snapshot attempt時間はwall clockでなく単調時計で測る。
片方向遅延はraw値、offset補正後、offset不確かさを併記し、不確かさを隠した単一値にしない。
max(pre uncertainty, post uncertainty) + abs(post offset - pre offset) > 50msなら正式runを開始・受理せずINVALIDにする。
受入
pre/post各20件以上のsample、選択した最小RTT群、offset、uncertainty、drift、50ms gate判定が一つのbounded artifactから再計算できる。
来歴: v1/retest-03-wave1-generator-clock・記録者 codex-desktop/bell
note head: 858b93ad4a12b4d4683a29eb6e7fa4c3fe4d9b7f97f117c03868b9ed313ae84c
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-03-wave1-generator-clock- anchor
- anchor_missing
✅ 完了工程 retest-04-wave1-server-clock-evidenceWave 1(サーバ側): NTP同期状態をrun artifactへ保存し、offset不確かさ50ms gateで正式runの受理可否を判定する
カテゴリ: impl
正規ID: bingo-capacity-retest/retest-04-wave1-server-clock-evidence
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
背景
生成器側のmidpoint補正だけでは、server host自身の同期状態が崩れているrunを正当化できない。両端の時計証拠が必要。
実装方針
run開始前と終了後にserver hostのNTP同期状態、参照先、offset、取得時刻を採取する。
生成器のpre/post midpoint結果と同じrun ID・候補SHAへ束縛して保存する。
生成器側の合成不確かさが50ms超、server側同期証拠欠落、同期外れのいずれかならrunをINVALIDにする。
INVALIDはCorrectness FAILや性能FAILへ混ぜず、正式matrixの母数にも含めない。
credential、host secret、不要な絶対pathはartifactへ含めない。
受入
第三者がartifactだけで「このrunの両端時計が正式判定に使える」と判断でき、欠落時はrun開始前または受理前に止まる。
後続工程
作業記録
現行背景
生成器側のmidpoint補正だけでは、server host自身の同期状態が崩れているrunを正当化できない。両端の時計証拠が必要。
実装方針
run開始前と終了後にserver hostのNTP同期状態、参照先、offset、取得時刻を採取する。
生成器のpre/post midpoint結果と同じrun ID・候補SHAへ束縛して保存する。
生成器側の合成不確かさが50ms超、server側同期証拠欠落、同期外れのいずれかならrunをINVALIDにする。
INVALIDはCorrectness FAILや性能FAILへ混ぜず、正式matrixの母数にも含めない。
credential、host secret、不要な絶対pathはartifactへ含めない。
受入
第三者がartifactだけで「このrunの両端時計が正式判定に使える」と判断でき、欠落時はrun開始前または受理前に止まる。
来歴: v1/retest-04-wave1-server-clock-evidence・記録者 codex-desktop/bell
note head: 16835b843cc640767c85ef6308d6c12721c1427e37bdd35cb2f7ffea79f9c92e
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-04-wave1-server-clock-evidence- anchor
- anchor_missing
✅ 完了工程 retest-05-wave2-vu-artifactsWave 2(採取): 最終抽選後の初回snapshotをimmutableに保存し、VU別の受信・ACK・snapshot・oracle結果をbounded artifactへ残す
カテゴリ: impl
正規ID: bingo-capacity-retest/retest-05-wave2-vu-artifacts
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
背景
前回は最終snapshotが977/1,000で、残る23 VUについて初回失敗と後続retry成功が上書きされ、原因を確定できなかった。
実装方針
最終host commit後、各VUの最初のsnapshot responseをimmutable観測として保存する。
最大10秒のbounded retryを許すが、初回遅延、初回request失敗、同一revisionのhash/oracle差分を消さない。
VUごとに受信最終sequence、連続throughSeq、ACK、snapshot revision/hash/drawnCount、oracle結果、接続状態、未適用数、各HTTP attemptのstatusと時間を保存する。
target revisionはserver artifactの最終host command commit revisionに固定し、異なるrevision同士のhashを比較しない。
同一revisionで一度でもhash/oracle差分が出たVUは、後で一致してもintegrity FAILを維持する。
受入
全1,000 VUについて初回観測と収束時刻を追跡でき、23件のような不一致が再発しても後続retryで原因が消えない。
後続工程
作業記録
現行採取ロジックは完成、k6側の配線だけ残してin-progressのまま置く。
できたもの: scripts/load/p3-01-vu-convergence.mjs と test 15件。
初回observationはretryで上書きされない。
同一revisionでのhash/oracle差分は一度でも出たら粘る。
revisionが違うhashは比較しない(nullにする)。
attempt切り捨ては件数を併記し、切り捨てても初回観測は残る。
構造上の決定: targetは走行中に確定できない。k6はscenario間でJS状態を共有せず、host driverの
最終commit revisionを参加者VUへ渡す経路が無い。参加者が自分のsnapshotから推定すると検証対象で
検証する循環になる。よって生成器は生の観測だけを出し、targetの固定と条件判定はrun後の
replayVuObservationsで行う。再生は記録済みの時間をそのまま使い時計を読み直さない。
残っている配線: scripts/load/p3-01-public.k6.js の finalizeParticipant。現在 readSnapshot を
1回だけ呼び、結果を complete という boolean へ潰している。これがまさに977/1,000の盲点である。
ここを「10秒までのbounded retryを回し、各attemptのsnapshot値と所要時間、transport状態を
そのまま出す」形へ置き換える必要がある。あわせて operator 側で run 後に
replayVuObservations→classifyRunCauses→三層verdict→buildArtifactChecksums を通し、
run directory へ書く配線が要る(Wave 1 の run-clock-evidence.json と同じ位置)。
証拠: docs/evidence/capacity-retest-wave-2-cause-decomposition-2026-08-01.md
来歴: rev-3fe65993c050c93ad913ff0b/retest-05-wave2-vu-artifacts・記録者 kite-mac/claude-opus-5
現行背景
前回は最終snapshotが977/1,000で、残る23 VUについて初回失敗と後続retry成功が上書きされ、原因を確定できなかった。
実装方針
最終host commit後、各VUの最初のsnapshot responseをimmutable観測として保存する。
最大10秒のbounded retryを許すが、初回遅延、初回request失敗、同一revisionのhash/oracle差分を消さない。
VUごとに受信最終sequence、連続throughSeq、ACK、snapshot revision/hash/drawnCount、oracle結果、接続状態、未適用数、各HTTP attemptのstatusと時間を保存する。
target revisionはserver artifactの最終host command commit revisionに固定し、異なるrevision同士のhashを比較しない。
同一revisionで一度でもhash/oracle差分が出たVUは、後で一致してもintegrity FAILを維持する。
受入
全1,000 VUについて初回観測と収束時刻を追跡でき、23件のような不一致が再発しても後続retryで原因が消えない。
来歴: v1/retest-05-wave2-vu-artifacts・記録者 codex-desktop/bell
note head: 89f3216e5f4d8369e2d182ebf7843a9b2bbd10a2982a3fe658fb8f1691d893ce
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-05-wave2-vu-artifacts- anchor
- anchor_missing
✅ 完了工程 retest-06-wave2-cause-classifierWave 2(分類): primary causeを固定7分類で一意に確定する集計器を実装し、secondary conditionを併記する
カテゴリ: impl
正規ID: bingo-capacity-retest/retest-06-wave2-cause-classifier
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
背景
条件flagを並べるだけではprimary causeがrunごとに揺れる。修正先を一枝へ絞るため、分類順を固定する。
実装方針
全condition flagを保持したまま、次の優先順位でprimary causeを一つだけ確定する。
hash-mismatch / oracle-mismatch(targetと同一revision。即integrity FAIL)
snapshot-request-failed
event-not-received
event-not-applied
ack-behind
snapshot-behind
generator-timeout
非primaryの成立条件はsecondary conditionとして残す。
どれにも分類できない場合はunknownとし、unknownが1件でもあるrunを正式判定へ進めない。
分類器は集約処理だけを所有し、観測欠落を推測で補わない。
受入
同じVU artifact集合から常に同じprimary causeが得られ、各分類の境界と優先順をfixtureで固定する。
後続工程
作業記録
現行背景
条件flagを並べるだけではprimary causeがrunごとに揺れる。修正先を一枝へ絞るため、分類順を固定する。
実装方針
全condition flagを保持したまま、次の優先順位でprimary causeを一つだけ確定する。
hash-mismatch / oracle-mismatch(targetと同一revision。即integrity FAIL)
snapshot-request-failed
event-not-received
event-not-applied
ack-behind
snapshot-behind
generator-timeout
非primaryの成立条件はsecondary conditionとして残す。
どれにも分類できない場合はunknownとし、unknownが1件でもあるrunを正式判定へ進めない。
分類器は集約処理だけを所有し、観測欠落を推測で補わない。
受入
同じVU artifact集合から常に同じprimary causeが得られ、各分類の境界と優先順をfixtureで固定する。
来歴: v1/retest-06-wave2-cause-classifier・記録者 codex-desktop/bell
note head: 4555b300ab773feefdb901a5177e513d424346af0047333ec2c53596ccb13be3
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-06-wave2-cause-classifier- anchor
- anchor_missing
✅ 完了工程 retest-07-verdict-aggregatorCorrectness / Product experience / Stressを別々に出す三層verdict集計器と、全artifactのSHA256SUMS生成を実装する
カテゴリ: impl
正規ID: bingo-capacity-retest/retest-07-verdict-aggregator
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
背景
通常利用の体験と極端なstress、stateの正しさを一つのPASSへ丸めると、どの保証が成立したか分からない。
実装方針
correctnessVerdict、productExperienceVerdict、stressVerdictを別々に集約する。
Correctnessはintegrity違反0件かつ最終host commitから10秒以内に全員が正本revision/hashへ一致することを要求する。
Product experienceはevent median≤1秒、p95≤3秒、全員収束≤10秒、再接続収束≤10秒、1,000人登録≤90秒を固定する。
Stressは既存の1秒抽選、5秒fan-out、最終snapshot同時read、再接続嵐、command競合、p50/p95/p99閾値を維持する。
capacityVerdict=PASSは三層すべてPASSの場合だけ。ProductだけPASSならproductUsability=PASS / capacityVerdict=FAILとする。
全artifactについてcanonical一覧とSHA256SUMSを生成する。
受入
同じrunを三層で3秒以内に判読でき、INVALID、FAIL、PASSを混同せず、全入力artifactのdigestを検証できる。
後続工程
作業記録
現行背景
通常利用の体験と極端なstress、stateの正しさを一つのPASSへ丸めると、どの保証が成立したか分からない。
実装方針
correctnessVerdict、productExperienceVerdict、stressVerdictを別々に集約する。
Correctnessはintegrity違反0件かつ最終host commitから10秒以内に全員が正本revision/hashへ一致することを要求する。
Product experienceはevent median≤1秒、p95≤3秒、全員収束≤10秒、再接続収束≤10秒、1,000人登録≤90秒を固定する。
Stressは既存の1秒抽選、5秒fan-out、最終snapshot同時read、再接続嵐、command競合、p50/p95/p99閾値を維持する。
capacityVerdict=PASSは三層すべてPASSの場合だけ。ProductだけPASSならproductUsability=PASS / capacityVerdict=FAILとする。
全artifactについてcanonical一覧とSHA256SUMSを生成する。
受入
同じrunを三層で3秒以内に判読でき、INVALID、FAIL、PASSを混同せず、全入力artifactのdigestを検証できる。
来歴: v1/retest-07-verdict-aggregator・記録者 codex-desktop/bell
note head: 169eb25a99b6f37b15a11a592462d18bc70a3229d5efa7adac9b356c03ccf856
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-07-verdict-aggregator- anchor
- anchor_missing
✅ 完了工程 retest-08-wave4-improved-diagnosticWave 4: 改良後のcold seed A / normal profileで1,000人診断を1回行い、原因分岐表の一枝だけへ進む
カテゴリ: verify
正規ID: bingo-capacity-retest/retest-08-wave4-improved-diagnostic
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
前提
Wave 1/2の観測と三層集約が揃い、Wave 3A patchが候補SHAへ入っていること。このrunは診断であり正式容量PASSへ昇格させない。
実行方針
.11 Windows生成器から.2専用self-hosted stagingへCloudflare Tunnel経由で、cold seed A / normal workload / 1,000人を1回実行する。
同一runをCorrectness / Product experience / Stressの三層で評価する。
原因分類後は、生成器backlog、snapshot read集中、judge commit、Worker serialize、WebSocket backpressure、Relay条件、unknownのうち一枝だけへ進む。
unknown/複合原因なら観測を追加して診断へ戻り、推測修正をしない。
本体修正後は独立oracle、再接続、hibernation、load harnessの関連testを通し、同じprofileを一回だけ再実行して比較する。
停止点
外部Windows生成器、Tunnel、長時間試験は開始前に目的・影響・停止方法を確認し、productionへ負荷を送らない。Relay条件成立時は自動実装せず費用とrollbackを提示する。
前提工程
後続工程
作業記録
現行前提
Wave 1/2の観測と三層集約が揃い、Wave 3A patchが候補SHAへ入っていること。このrunは診断であり正式容量PASSへ昇格させない。
実行方針
.11 Windows生成器から.2専用self-hosted stagingへCloudflare Tunnel経由で、cold seed A / normal workload / 1,000人を1回実行する。
同一runをCorrectness / Product experience / Stressの三層で評価する。
原因分類後は、生成器backlog、snapshot read集中、judge commit、Worker serialize、WebSocket backpressure、Relay条件、unknownのうち一枝だけへ進む。
unknown/複合原因なら観測を追加して診断へ戻り、推測修正をしない。
本体修正後は独立oracle、再接続、hibernation、load harnessの関連testを通し、同じprofileを一回だけ再実行して比較する。
停止点
外部Windows生成器、Tunnel、長時間試験は開始前に目的・影響・停止方法を確認し、productionへ負荷を送らない。Relay条件成立時は自動実装せず費用とrollbackを提示する。
来歴: v1/retest-08-wave4-improved-diagnostic・記録者 codex-desktop/bell
note head: 215b936b0c550353d6ba525753a68f2cbc3ffe1c103aca1676902caae2fe729c
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-08-wave4-improved-diagnostic- anchor
- anchor_missing
✅ 完了工程 retest-09-wave5-tier-matrixWave 5: 100/300/1,000の枠別確認と、最終候補SHAでの正式matrix・60分soakを実行する
カテゴリ: verify
正規ID: bingo-capacity-retest/retest-09-wave5-tier-matrix
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
前提
改良後診断で原因が一枝へ確定し、必要な最小修正と同profile再診断が完了していること。正式matrix中は候補SHA、設定、閾値を固定する。
実行方針
既存normal workloadのjoin時間、1秒抽選、snapshot規則を変えず、参加者数だけ100→300→1,000の順で確認する。
緩いproduct専用profileは作らず、各runから三層verdictを同時に出す。
1,000人normalでCorrectnessとProduct experienceがPASSした場合だけ、既存12 profileのcold 1回・warm 2回と60分soakへ進む。
3 runは平均でなく各run単独で閾値を満たす。
matrix中に実装、設定、閾値を変えた場合は以前のrunを破棄し最初からやり直す。
受入
100/300/1,000の各枠と正式matrix/soakのartifactが同じ候補SHAへ束縛され、上位枠の失敗を下位枠の成功で隠していない。
前提工程
後続工程
作業記録
現行Wave 5枠別確認を実施。100/300人枠は三層PASS、1,000人枠はcorrectness FAIL(参加者3人が
脱落しparticipant-count-mismatch)。計画の進行条件を満たさないため正式12 profile matrixと
60分soakへは進んでいない。
FAILの直接原因はparticipant snapshotのHTTPが"connection reset by peer"で3件失敗し、
該当VUが自らclose(4011)して最終snapshotへ到達できなかったこと。2回連続で再現(999/1000、
997/1000)。DOは当該時刻も平穏(do.incoming 9/s・inflight_reads 10・5xxゼロ・
snapshot p95 62ms)で、Tunnel側のResetStreamが多いことから発生源は試験経路が最有力。
前提として判定側の欠陥2件を先に塞いだ。(1)片方向遅延の補正offsetをstaging側で採っており
外部生成器のズレが補正へ入っていなかった(fan-outが常時負値のままPASSしていた)。
k6自身が試験前後に採る方式へ変更し、負値ならINVALIDにするgateも追加。
(2)観測が届かなかったVUが収束集計の母数から落ち、999/999全収束としてPASSしていた。
missingVuCountをcorrectnessへ接続。今回のFAILはこの修正が捕まえた。
証跡: docs/evidence/capacity-retest-wave-5-tier-2026-08-04.md
次の一手: Tunnelを通さない経路で1,000人を走らせ、RSTの発生源を確定させる。
来歴: rev-3fe65993c050c93ad913ff0b/retest-09-wave5-tier-matrix・記録者 claude/belle
現行前提
改良後診断で原因が一枝へ確定し、必要な最小修正と同profile再診断が完了していること。正式matrix中は候補SHA、設定、閾値を固定する。
実行方針
既存normal workloadのjoin時間、1秒抽選、snapshot規則を変えず、参加者数だけ100→300→1,000の順で確認する。
緩いproduct専用profileは作らず、各runから三層verdictを同時に出す。
1,000人normalでCorrectnessとProduct experienceがPASSした場合だけ、既存12 profileのcold 1回・warm 2回と60分soakへ進む。
3 runは平均でなく各run単独で閾値を満たす。
matrix中に実装、設定、閾値を変えた場合は以前のrunを破棄し最初からやり直す。
受入
100/300/1,000の各枠と正式matrix/soakのartifactが同じ候補SHAへ束縛され、上位枠の失敗を下位枠の成功で隠していない。
来歴: v1/retest-09-wave5-tier-matrix・記録者 codex-desktop/bell
note head: 3ebd66eec28213f14e24e03243373e5b3b5455260c94b59cefe03c0e7528d763
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-09-wave5-tier-matrix- anchor
- anchor_missing
✅ 完了工程 retest-10-capacity-verdict三層verdictを確定し、bingo-serviceのp5-06-prod-capacity-evidenceへ渡す完了証拠を揃える
カテゴリ: verify
正規ID: bingo-capacity-retest/retest-10-capacity-verdict
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
目的
再試験全体の証拠を閉じ、bingo-service/p5-06-prod-capacity-evidenceへ渡せる一つの完了証拠を作る。
集約方針
clock pre/post、offset/uncertainty/drift、VU別収束、固定原因分類、client/server event、oracle diff、runtime telemetry、生成器資源を列挙する。
100/300/1,000、正式12 profile、60分soakを候補SHAと設定へ束縛し、全artifactのSHA256SUMSを検証する。
三層verdictを別々に提示し、三つすべてPASSの場合だけcapacityVerdict=PASSとする。
INVALID run、unknown原因、telemetry欠落、時計証拠欠落が一つでも残れば完了扱いしない。
Relay DO条件が2連続の有効runで成立した場合は、現構成結果、Relay案、月額/従量費上限、rollbackを提示してH承認を待つ。自動実装しない。
受入
第三者が3秒で「何人まで、どの保証が、どのSHAで成立したか」を判断でき、p5-06の完了証拠としてdigest検証できる。
前提工程
作業記録
現行オーナー裁定(2026-08-05): 本ToDoの受入条件を改定する。
改定前は「100/300/1,000の各枠と正式12 profile matrix・60分soakを同一候補SHAへ
束縛し、全artifactのSHA256SUMSを検証する」ことを要求していた。
改定後の受入条件:
1,000人容量は、候補SHA f84e62d において、4 profile(normalConnection / normal /
rosterBrowsing / soak)が各1回PASSしたことと、62分soakがPASSしたことをもって成立
とする。
seed間再現性の確認(3 seed × 4 profile = 12本の正式matrix)は本再試験の範囲外と
する。
100/300人枠の確認(2026-08-03)は当時のSHAで成立しており、1,000人枠と単一SHAへ
束縛しない。
改定理由: 12本を1本の鎖として走らせる構造のため、途中1本の失敗で全体が破棄され
最初へ戻る。5.5時間の走行に対し計測経路(Cloudflare Tunnel)の一過性障害を約1時間に
1回踏むため、完走確率が低い。4回の再走行で見つかった停止要因5件はすべて計測装置側で
あり、製品側の欠陥は0件だった。装置の完走能力が容量主張の成立を阻んでいる状態と
判断し、要求範囲を実測済みの範囲へ合わせる。
完了証拠には、成立した範囲と範囲外にした事項の両方を明記する。数値・判定は改定せず、
実測をそのまま載せる。
来歴: rev-3fe65993c050c93ad913ff0b/retest-10-capacity-verdict・記録者 KaitonoMacBook-Air/claude-opus-5
現行目的
再試験全体の証拠を閉じ、bingo-service/p5-06-prod-capacity-evidenceへ渡せる一つの完了証拠を作る。
集約方針
clock pre/post、offset/uncertainty/drift、VU別収束、固定原因分類、client/server event、oracle diff、runtime telemetry、生成器資源を列挙する。
100/300/1,000、正式12 profile、60分soakを候補SHAと設定へ束縛し、全artifactのSHA256SUMSを検証する。
三層verdictを別々に提示し、三つすべてPASSの場合だけcapacityVerdict=PASSとする。
INVALID run、unknown原因、telemetry欠落、時計証拠欠落が一つでも残れば完了扱いしない。
Relay DO条件が2連続の有効runで成立した場合は、現構成結果、Relay案、月額/従量費上限、rollbackを提示してH承認を待つ。自動実装しない。
受入
第三者が3秒で「何人まで、どの保証が、どのSHAで成立したか」を判断でき、p5-06の完了証拠としてdigest検証できる。
来歴: v1/retest-10-capacity-verdict・記録者 codex-desktop/bell
note head: 3cbdb8ad9e3247d7b47aa8356dcb20c44fca1d162a41d494a2a4e4dc0ca30266
元plan: docs/architecture/capacity-retest-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-capacity-retest/retest-10-capacity-verdict- anchor
- anchor_missing
✅ 完了工程 e2e-01-full-run-blank-pageE2Eフルラン終盤の白紙ページ切断の原因を特定し、恒久策を入れてフルスイート連続2回greenを確認する
カテゴリ: impl
正規ID: bingo-e2e-stability/e2e-01-full-run-blank-page
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
仮説はvinext devサーバーの連続稼働疲弊。devサーバーのメモリ/ハンドル推移を観測して原因を特定し、ビルド済みサーバーでのE2E実行・スイート分割等から恒久策を選ぶ。joinレート制限バケット永続とceremony演出ロック競合は切り分け済み(散文参照)。受入はフルスイート連続2回green。
作業記録
現行2026-08-05: 原因を本番で修正し、実測で判定した。
白紙ページ切断の原因(wrangler ProxyControllerクラッシュ)は、本番起動を直結プロキシ
方式へ切替えて解消。同一刺激(E2Eフルスイート・Tunnel経由22.9分)でクラッシュ
26回→0回、container再起動13回→0回、E2E失敗への502混入7本→0本を実測。
途中、直結転送にwrangler ProxyWorkerのorigin書換規則(MF-Original-URL)が欠けて
いてsameOriginが403になる二次障害を踏み、parity実装+ローカル4行matrix一致の
確認を経て配備した。記録: docs/evidence/production-direct-proxy-deploy-2026-08-05.md
受入(ローカルフルスイート連続2回green)への残作業:
tests/helpers/product-e2e-server.mjs はまだ vinext dev 経由で、クラッシュする
経路の上にいる。E2Eサーバをビルド済みdist+直結起動(scripts/ops/wrangler-direct-dev.mjs)
へ移すのが残りの一手。移行時の既知の罠:
wrangler.e2e.jsonc の main は worker/index.ts で vinext仮想モジュールに依存する
ため素のwranglerではビルド不能。dist/server/index.js を指すE2E用configが要る
.wrangler/state は plugin側wrangler(4.92)の形式。top-level(4.114)で触ると
_cf_ALARM列数差で旧側が読めなくなるため、新しいstate dirを使う
E2E裏口(exactE2eRequest)はhostnameがlocalhost系の時だけ有効。直結起動でも
MF-Original-URLのhostがlocalhostになるため成立する見込みだが要実測
来歴: v1/e2e-01-full-run-blank-page・記録者 KaitonoMacBook-Air/claude-opus-5
現行2026-08-05: 本番実行で原因が判明。旧仮説「vinext devサーバーの連続稼働疲弊」は棄却する。
本スイートを本番(bingo.kitepon.dev、素のnpx wrangler dev)へ向けて流したところ、
vinext devが存在しない本番でも同種の停止が再現した。死因はwranglerのプロキシ層で、
ProxyController内のNetwork connection lost。スタックに製品コードのフレームは無く、
直前にInspectorProxyWorkerのreconnectが出る。同日26回クラッシュ・コンテナ再起動13回、
開始時刻はフルスイート起動と一致。クラッシュ窓でCloudflareが502を返し、ブラウザには
白紙ページが見える。webServerログにエラーが出ないのも、落ちているのがworkerではなく
proxy側だからである。
負荷の見積もりも訂正: disconnect-recovery.spec.tsに1,000 WebSocketのfan-out試験が
2本あり、このスイートは軽くない。
1,000人負荷試験が耐えたのは、ハーネス(p3-01-wrangler-direct.mjs)がProxyControllerを
自前のDirectHttpProxyControllerへ差し替えinspector:falseを強制していたため。
クラッシュする当の部品を経路から外していた。本番はこの差し替えをしていない。
恒久策の候補: (1) 本番およびE2Eの起動をdirect proxy方式へ寄せる(実装はrepo内に既存。
本番の可用性リスクにも同時に効く) (2) inspectorの無効化だけで収まるかを先に切り分ける。
いずれも本番起動の変更を伴う高リスク操作で、着手にはオーナー承認が要る。
散文正本: docs/operations/e2e-suite-stability.md
関連証拠: docs/evidence/p5-06-prod-capacity-evidence-2026-08-05.md 第7節
来歴: v1/e2e-01-full-run-blank-page・記録者 KaitonoMacBook-Air/claude-opus-5
note head: 6380a1a1ac0c8d774c39a8e9f17ee13ac9d9d4fb6bcb6858c5a4c23c8ffd2524
元plan: docs/operations/e2e-suite-stability.md:29 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-e2e-stability/e2e-01-full-run-blank-page- anchor
- digest_mismatch
✅ 完了工程 mgs-00-spike-fetchSpike A: workerd(--local)からの外向きfetch到達性を確認する
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-00-spike-fetch
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
throwawayの最小構成(echo DOを持つshard風worker+fetchするfront風worker)をdocker compose 2コンテナで起動し、front→http://<コンテナ名>:<port>のfetchが通るか確認する。不達時のfallback順: compose固定IP(ipv4_address)→ extra_hosts。TLSなしHTTP fetchがwrangler dev --localで拒否されないことも確認。受入: 可否と、可の場合の1往復あたりのfrontオーバーヘッド概算が文書化されている。
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-00-spike-fetch- anchor
- anchor_missing
✅ 完了工程 mgs-00-spike-ws-proxySpike B: fetchによるWS透過proxyの成立を確認する
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-00-spike-ws-proxy
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
front風workerでfetch(shardUrl, upgrade:websocket)の101 Responseをaccept()せずreturnし、client↔shard DOのフレーム双方向・切断の両側伝播を確認する。不成立時のfallback: frontでclient側accept+shard側WSとJS pump(この場合のper-message CPUコストを実測してPhase 4の限界見積りへ入力)。受入: 可否とfallback要否の判定が文書化されている。
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-00-spike-ws-proxy- anchor
- anchor_missing
✅ 完了工程 mgs-01-routing-key-plumbing裸gameIdをdo_routing_key経由へ是正する(挙動不変)
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-01-routing-key-plumbing
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
敵対的検証で確認済みの壊れ方(prefix焼き込み後、作成initializeが裸gameId名の間違ったDOへ書き込まれシャード側DOは永遠に未初期化)を防ぐ下準備。(1)作成api-router.ts:983-988と作成直後snapshot:1031-1035: initializeGameの入力(game-creation.mjs:597-613)へdoRoutingKeyの配管を追加。(2)join:1803-1814: resolveJoinCode(join-resume.mjs:207-234)の返り値へdoRoutingKey追加。(3)preview:1891: join-resume.mjs:260のadapter署名を変更しrecord.doRoutingKeyを渡す。(4)game-creation.mjs:543のシャード選択はapi-routerから注入する新パラメータにし未注入時はidentity。受入: fake directoryでdo_routing_key≠gameIdでもcreate/join/preview/WS/clone/telemetryの全invokeがdo_routing_key側を使うテスト。既存テスト全green。
前提工程
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-01-routing-key-plumbing- anchor
- anchor_missing
✅ 完了工程 mgs-01-session-routingsession-routing.tsへstub/invokeSessionを統合する
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-01-session-routing
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
worker/session-routing.ts新規。api-router.ts:711-750のstub/invokeSessionとload-control.ts:195-221の同型コピーを統合し、fetchSessionTelemetry(load-control.ts:231)のgameId直キーも是正する。telemetry封筒の有無はoption引数で吸収。受入: GAME_SESSIONS.getがsession-routing.ts 1箇所に収束、既存テスト全green。挙動不変。
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-01-session-routing- anchor
- anchor_missing
✅ 完了工程 mgs-02-integration-testfront+shard構成の結合テストで契約を固定する
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-02-integration-test
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
受入: (a)prefix有無×endpoint有無×shard 5xx/例外のルーティング表をunitテストで固定。(b)ローカルfront+shard1構成でcreate→join→WS→抽選→clone→retention sweepのe2e。(c)shardプロセスkill状態で該当ゲームのAPIが503 GAME_SHARD_UNAVAILABLEを返し、in-process DOに空stateが作られないこと。(d)BINGO_SHARD_IDS未設定の従来構成でe2e全green(dev/vite/e2e回帰なし)。
前提工程
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-02-integration-test- anchor
- anchor_missing
✅ 完了工程 mgs-02-prefix-routingprefixルーティングとシャード割当を実装する
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-02-prefix-routing
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
session-routing.tsへprefix分岐: ^s\\d+\\//マッチ→BINGO_SHARD_ENDPOINTSへHTTP転送(invoke-auth+routing keyヘッダ、WSは透過return)。endpoint未設定→500 GAME_SHARD_MISCONFIGURED、到達不能/5xx→503 GAME_SHARD_UNAVAILABLE。in-process DOへのフォールバック禁止(空DO生成=split-brain)。作成経路はBINGO_SHARD_IDSからhash(gameId) mod Nで決定的に割当しsN/<gameId>をD1へ焼き込み。retention sweepのみ候補ごとにエラー隔離(ログして続行)。worker/env.tsへBINGO_SHARD_IDS/BINGO_SHARD_ENDPOINTS追加。
前提工程
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-02-prefix-routing- anchor
- anchor_missing
✅ 完了工程 mgs-02-shard-workerシャードworker(do-shard.ts)とwrangler.shard.jsoncを作る
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-02-shard-worker
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
GameSession re-export、/readyz(operational-healthのDB必須判定を流用しない)、/do/invoke、/do/socket。/do/invokeへのHMAC署名は必須(DOのinvoke経路自体は無署名で、到達できればinitialize・command・purgeが撃ち放題。x-bingo-internal-socket-authと同型のsignClaims 30秒)。envはSESSION_SECRET/CAPACITY_ENTITLEMENT_PUBLIC_JWK/CAPACITY_ENTITLEMENT_ISSUER/BINGO_BUILD_SHA(前段と同一値必須)/BINGO_DEPLOYMENT_ENVIRONMENT/BINGO_STAGING_HOSTNAME/BINGO_TELEMETRY_4種/BINGO_E2E(_SEED)/BINGO_ANNOUNCER_DURATION_MS。D1・ASSETS・IMAGESなし。DO migrations(new_sqlite_classes)は本番configと同一。
前提工程
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-02-shard-worker- anchor
- anchor_missing
✅ 完了工程 mgs-03-compose-opscompose・起動script・backupをシャード対応にする
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-03-compose-ops
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
start-production.shへBINGO_ROLE=front|shard(shardはD1 migration skip、wrangler.shard.jsonc、内部ポート)。compose.yamlへbingo-shard-N(ports非公開、/readyz healthcheck、volume ./.wrangler-production/state-shard-N)。backup-production.sh/restore-drillを全service・全state dir対応(pathの許可listも更新)。受入: 3コンテナ健全、新旧両形式ゲームのsmoke、backupアーカイブに全state dirが含まれ全serviceが自動復帰。Tunnel/ingress/healthcheck公開面は無変更。
前提工程
後続工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-03-compose-ops- anchor
- anchor_missing
✅ 完了工程 mgs-04-loadtest-topologyp3-01負荷試験基盤をtopology descriptor化する
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-04-loadtest-topology
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
staging-operator.mjsの「workerdちょうど1プロセス」前提(resolveWorkerdProcesses 1078-1124、argv検証1219-1234)を、planが宣言するprocess数と役割の完全一致(front+N shards)へ一般化。attestationのconfigDigestsもrole別に拡張。wrangler.load-staging.app.jsoncへBINGO_SHARD_ENDPOINTS注入(staging内はloopbackポート)。
前提工程
後続工程
作業記録
現行着手前調査の結果(次の担当が再導出しないための記録。2026-08-02)。
現行のload-staging runtimeは「launcher 1本=workerd 1個」を三重に固定している:
p3-01-wrangler-direct.mjs: parseWranglerDirectArgumentsが--localとexact 3個の-cを必須。
runtimeEnvironmentKeysはexact 6 keyで、余分なkeyがあるとentrypointが落ちる。
inspectorをfalseへ落としているため、wrangler dev既定の2個目のworkerd(inspector用)が
生まれない=「workerdちょうど1個」が成立している。
staging-operator resolveWorkerdProcesses: children.length!==1で失敗、workerd 1個・
rolemulti-worker-runtime単一を要求。workerdRoleは--socket-addr=entry=127.0.0.1:0
(direct proxy経由なのでentryはport 0)と--external-addr=loopback=...の形で判定する。
シャードは--portを直接bindするためentry socketがそのportになり、既存の判定では
unknown-workerd-runtimeになる。role判定に per-process の期待portを渡す必要がある。
collectRuntimeTopologyAttestation: children/workerd/plan各1を要求し、
launcher argvの--config+-c合計3・port 8791単一・persist-to単一を固定。
configDigestsは{gateway,app,control}固定。
したがってmgs-04の実装は次の5点になる:
wrangler.load-staging.shard.jsonc を新規作成(wrangler.shard.jsoncのload-staging版。
D1・assets無し、GAME_SESSIONSとmigrations v1、telemetry varsはapp/controlと同型)。
p3-01-wrangler-direct.mjs を front(3 config)と shard(1 config)の2形態対応にし、
BINGO_SHARD_IDは秘密でないのでargv(--shard-id)で受けてprocess.envへ入れる
(env fileのexact 6 key契約を壊さないため)。
buildSelfHostedPlan が plan.processes を [multi-worker-runtime, shard-s1, ...] で返す。
各processにrole・shardId・configDigests(roleごと)・期待portを持たせる。
resolveWorkerdProcesses / collectRuntimeTopologyAttestation を
「planが宣言したprocess数と役割の完全一致」へ一般化する。個数の直書き(1)を
plan由来にし、workerdRoleにrole別の期待argv形を渡す。
wrangler.load-staging.app.jsonc へ BINGO_SHARD_IDS / BINGO_SHARD_ENDPOINTS を
loopback port指定で注入し、buildSelfHostedPlanのconfig契約検査(varsのallowlist・
exactRequiredEnvironmentKeys・hasRuntimeEnvironmentValueInVars)を追随させる。
影響範囲: tests/load/p3-01-staging-operator.test.mjs の
「planはgateway/app/controlを単一multi-worker runtimeで起動する」(443行)と
「単一launcherとWrangler 4.114のdirect workerdを…束縛する」(586行)は前提ごと書き換えになる。
来歴: rev-initial/mgs-04-loadtest-topology・記録者 KaitonoMacBook-Air/claude-opus-5
note head: efe991d1cdb3bd3a611facdc2982aaf5327615d9fca7321904bd0f0da25a59fb
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-04-loadtest-topology- anchor
- anchor_missing
シャード構成で1×1,000と2×1,000を実測する
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-04-measure
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
計測1: 1×1,000をshard経由で流しfront転送オーバーヘッド算出(WS透過proxyでも1,000接続のフレームは前段を通過し続けるため中継コストを分離計測)。計測2(campaign受入): 2×1,000同時で両ゲーム収束・正しさ指標ゼロ違反・front+shard合計CPUが1コア超へ伸び・frontピーク約0.5コア未満。計測3: frontのreq/sあたりコストからN×1,000の理論上限を外挿しevidence化。B案(snapshot応答効率化)はfrontピーク0.5コア超かつプロファイルでsnapshot生成/転送が支配的な場合のみ実装する条件付き項目。
前提工程
後続工程
作業記録
現行Phase 3本測定: run77b(2026-08-03、build 9d874d8、2×1,000同時)。証跡は
docs/evidence/load/run77b-do-telemetry-2026-08-03.md、生データは.2のoutput配下。
成立: 両ゲームjoin 1,000/final_snapshots 1,000/draw_events 60,000、正しさ指標
オール0(oracle_diffs=0×約75k照合/ゲーム、cursor_regressions=0含む)。k6は新wire
(packed判定正本)を独立decoderで復元して照合済み。run77初回はworker死亡で中断
(run75と同型)、再走で成立。両runとも2ゲーム片肺割当(run76=s1、run77b=s2)で
同条件比較が成立。
Phase 1a〜2cの構造改革はDO側で大きく効いた(run76比、配置非依存のtelemetry合計)
judge.commit_us/draw_next: 143,675→38,658us/件(-73%)。総量17.2秒→4.6秒
do.action_us/snapshot: 866→614us/件(-29%)。総量27.9秒→18.8秒
do.action_us/other(join等): -70%(28.2秒→8.4秒)
DO busy合計 約76秒→約35秒(-54%)
トレード: snapshot応答bytes 11.6KB→15.4KB/件(+33%、総+98MB)。B案card省略の
撤去+共有focus 12人分packed同梱の設計どおり
プロセスCPU: 稼働shard med 0.34→0.18 / p95 1.08→0.84。front p95はほぼ不動
(1.02→1.00)——frontはWS透過proxyでsnapshotを生成しないため想定どおり
残る論点2つ(裁定待ち)
campaign受入「frontピーク約0.5コア未満」は本系列では届かない。front側の別の手
(WS中継コスト削減 or front複数プロセス化)に進むか、受入条件を見直すか
応答時間系threshold NG(snapshot_refresh p95 2.2秒等)はrun74/76と同系だが悪化して
見える。fanout medが負値でrun間の時計offset・tunnel日次変動が乗っている疑いが強く、
この面の比較は保留した(DO telemetryはサーバー単独時計で無影響)
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-bell
現行Phase 2c完了: wire刷新——packed生配布・共有snapshot・stateHash全廃(2026-08-03、build a89af61)。
4コミット構成:
5ba727d サーバーwire刷新+クライアント境界。参加者投影はpacked判定正本(judging 91字/人)
を生配布し、card/evaluation/markedPositionsへの展開はapp/lib/snapshot-judging.mjsが実施
(join/claim/resume応答だけ発行点として展開済み形を維持)。snapshotの重量部
(presentation・roster items・static・venue・results)はsharedSnapshotPartsがstateごと
1回組立→全viewer共有(KNOWN_IMMUTABLE_VALUESでoverlayのみ再凍結)。カード可視性
フィルタ撤去(表示制御はapplyCardVisibilityPreferenceへ格下げ)。known.cardDigest省略
(B案)撤去(省略はstaticだけ)。stateHashをwire・state・検証tokenから全廃、results
paginationはsection別binding(standings=resultDigest/他=revision)拘束cursor v2へ
1ff95d1 k6・負荷計測・E2Eヘルパ。k6はpacked独立decoder(decodePackedJudging、本体
非共有)で復元し独立oracleと照合。収束・finalizeのhex64チェック除去(残すと試験が
永久未完)。vu-convergence v2/cause-classifier v2(hash-mismatch分類廃止)/
load-contract v7/browser-probeはrevision+eventSeq+phase比較へ
00742b2 roster.selfのカード合成もクライアントへ移譲(per-viewerに残っていた
projectRosterCardViewの25マス再検証+凍結が消えた)+配布ベンチ追加+AGENTS.md/
domain-data-model.md更新
測定(scripts/bench/snapshot-fanout.mjs、1,000人+会場1、抽選1回の全viewer組立)
d508608(2c前): 212ms/抽選(0.212ms/枚)
00742b2(2c後): 101ms/抽選(0.101ms/枚、-52%)
抽選コマンド本体は5.5〜6.1msで2c前と同水準(ここは対象外)。残りの支配項は
join経路のassertState O(n²)(既知の別課題・スコープ外)
payloadは11.7KB→12.9KB/枚。participant viewerにも共有focus 12人分のpackedが
載るようになった分の増(DO CPU削減とのトレード、オーナー裁定の共有配布どおり)
a89af61 packed純関数をcrypto非依存のpacked-judging.mjsへ分離(重要な罠: client boundary
がauto-judging経由でnode:cryptoをブラウザへ引き込み、build/testはgreenのまま全ページが
実行時に落ちた。検出できるのはE2Eだけ→caveat登録済み)+E2E整備(cardDigest断言撤去・
ceremony演出連鎖に耐える待ち・joinレート制限バケットのrun間掃除)
検証: npm test 761件+tests/load 302件+hibernation+lint+Playwright E2E 32本すべて通過
(フルラン30/32、残り2本は新サーバー単独で通過。フルラン終盤の白紙ページはローカル
devサーバー疲弊の環境問題=別課題)。E2E初回実行はtailパイプでexit code誤認しかけた
(既知caveatどおり)ため、以後パイプなしで確認した。
仕様面の変化(クライアント観測可能):
spectator/participantのpresentation.participantsが全role共通のfocus12人になった
presentation.outcomeParticipantsはwireから消えクライアント導出になった
roster.selfのcardはwireでnull(クライアント合成)
非公開設定のゲームでも他人カードはwire上は届く(表示だけ隠す。オーナー裁定9)
次: Phase 3(検証まとめ+staging 2×1,000 run77でrun76とDO telemetry直接比較)。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-bell
現行Phase 2完了: participants静的化+packed 12行正本化(2026-08-02、build d508608)。
3コミット構成:
05724e8 純関数群(packJudgingRecord/advancePackedJudging/unpackCard/
evaluationFromPacked/markedPositionsFromPacked/readPackedJudging/withPackedStatus、
91字/人固定レイアウト)+最重要固定テスト9本(cardDigestバイト一致・独立oracle
全抽選一致・「1行だけ開き忘れ」変異の必検出)
6d874f3 本体切替。state.judging={participantId: packed}が判定の唯一の正本、
participantsは静的identity(cardId/cardFormat/cardGenerationVersion/cardDigest保持)。
抽選でparticipants配列は参照ごと不動(テストで固定)→保存のfield差分書きで
participants約2.9MBのserializeが消える
d508608 旧v1 stateのPRODUCT_STATE_SCHEMA_RETIRED(409)ゲート。変換fallbackなし
発見した旧実装の非対称: 旧実装は勝者/脱落者の保存済みevaluationを凍結しつつ、
wire投影(markedPositions/evaluation)だけ毎回全量再計算していた。packed化では
全員の判定正本を進め続けることで一致させた(リーチ演出だけ現役の初回リーチに限定)。
測定: 純粋層ベンチ 5.54ms/抽選(1b後5.42msと同水準)。純粋層の残りコストは
engagementのimmutable/freeze walk・投影再構築で、これはPhase 2cの共有snapshot化が
刈る対象。本コミットの本命効果(保存差分・participants serialize消滅)は
worker永続化経路にあり、staging run77(Phase 3)で実測する。
lifecycle投影を静的participantでcache(毎抽選1,000回のnormalizeDisplayName削減)。
762件+load 302件+hibernation green。E2E/型検査/lintはPhase 3で総点検。
次: Phase 2c(wire刷新・整形のクライアント移譲・共有snapshot・stateHashフィールド
撤去とk6/AGENTS.md更新)。計画正本: ~/.claude/plans/320-squishy-nebula.md
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-fable-5
現行Phase 1b完了: stateHash契約の整理と過剰検証機構の削減(2026-08-02、build 3f665aa)。
入れたもの
venue-screen: sync.stateHash(hex64必須)契約とhash chainを撤去し、revision一致+
seq連続性検査へ(9a094e5)。DOM属性は既存data-revisionへ集約
未配線の演出検証器3本(casino/reverse/hybrid-flip presentation .mjs)を削除。
本番からは型参照(typeof import→推論不能でany)のみで、署名済みceremony・
HMAC receipt・hash chainは実行時に一度も走っていなかった。テスト41件も削除
rosterページングcursorを{version, revision, offset}へ、engagement sourceStateHash
材料をrevisionへ(3f665aa)
join-resume.mjsの registerParticipant/resumeParticipant を削除(api-routerは
previewJoinCode/resolveJoinCodeしかimportしない未配線デッドコード)
計画変更2件
wire応答のstateHashフィールド・k6のhash指標・AGENTS.md契約文言の更新は
Phase 2c(wire刷新)でclient・k6・E2Eごと一度にやる。安いtoken(revision由来)は
無害なので残置。二度手間の回避
Phase 2aと2bは統合。card/evaluationをparticipantsから外す作業自体が可変部の
隔離そのもので、分けると同じ読み手50〜100箇所を二度書き換える
測定: 1b後の抽選5.42ms(1a後5.35msから劣化なし)。752件+load302件green。
プロファイル上、残りコストに単独主犯なし(engagement/lifecycleのfreeze walk、
buildStateProjection再構築等に分散)——Phase 2の正本切替が刈る対象。
次スレッドへのバトン: Phase 2(統合版)= participants静的化+packed 12行正本。
新しい形: participants=静的identity(cardId/cardDigest保持、card/evaluation除去)、
judging={participantId: packed文字列}(numbers25+open25+lines12+scalars+
status/firstReach/firstBingo/eliminated/eliminationOrderを固定幅で同梱、約85字/人)
wire互換の投影(card.cells再構成はpacked numbersから。digest(復元card)===保存済み
cardDigestのバイト一致テストが最重要固定)
読み手の書き換えはgrep駆動で: .card/.evaluation/.judgingLines/.status/
.firstReachAtSeq/.firstBingoAtSeq/.eliminatedAtSeq/.eliminationOrder
schemaVersion v2ゲート(assertStateの巨大booleanの前でPRODUCT_STATE_SCHEMA_RETIRED、
旧v1は切り捨て裁定済み)
e2eFixtureCard経路とtests/draw-evaluation-consistency(内部直読み)の更新が必要
計画正本: ~/.claude/plans/320-squishy-nebula.md
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-fable-5
現行Phase 1a: stateHashを版識別tokenへ置換(2026-08-02、build 6a0cdb4)。
state全体(1,000人で約3MB)の正規化+sha256を毎コマンド計算していたstateHashを
digest({gameId, revision, eventSeq})へ置換。revision/eventSeqはlockstepなので
版判定の意味は不変、hex64のままなのでwire・DOM・k6・cursor契約は無変更で
798件+tests/load 302件が全通過した。
実測(draw-profile.mjs、1,000人・60抽選)
draw.next 1回: 12.1ms → 5.35ms(-56%)
join 1,000人: 1,571ms → 653ms(-58%)(joinも毎commitで全量hashしていた)
累積: 27.67ms(4ce37f2)→ 5.35ms = -81%。
失ったもの(オーナー裁定済み): 「同一revisionで中身が違う」破損の検出。
内容の正しさ検証は独立oracle(oracle_diffs==0)が担う。改ざん検出テストは
revision改ざん検出へ書き換え、テスト側独立モデル2箇所を新仕様へ更新。
次: Phase 1b(stateHash契約の撤去、server→venue/client→k6/docsの3コミット)。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-fable-5
現行Phase 0: 判定正本の物理表現ベンチ(2026-08-02、build 8dc2547)。
12行正本方式への移行計画(オーナー裁定: 形にこだわらず「DB処理が最速の形」を採る)の
最初の工程。scripts/bench/judging-representation-bench.mjs で4候補を同一土俵で実測した。
実測(1,000人・60抽選の合計、best of 3、判定遷移974件は4候補で完全一致)
| 候補 | update | persist | read(共有payload) | 合計 |
| B JSコンパクトobject | 1.4ms | 13.8ms | 14.9ms | 30.1ms |
| C JS packed文字列(68字/人) | 4.8ms | 4.3ms | 4.6ms | 13.8ms |
| D SQLite逐行(prepared) | 63.0ms | 0 | 68.4ms | 131.3ms |
| D2 SQLite一括(UPDATE...FROM 1文) | 63.8ms | 0 | 83.7ms | 147.4ms |
採用: C packed文字列。1抽選あたり0.23ms(現行の抽選パイプライン12.1msに対し
判定・保存・payload組立の合計が誤差級になる)。
SQLiteが10倍遅い理由(実測から): prepared statement再利用でも一括UPDATEでも
変わらなかった。支配項はSQL実行そのものではなく、JS⇔native境界での行の材料化
(共有payloadのために毎抽選1,000行×17列をJSオブジェクトへ変換する部分と、
更新前後の対象行読み出し)。workerdのDO SQLiteは同一スレッドの同期APIなので
並列化の利得もない。「テーブルを唯一の正本にすると、読むたびに境界を渡る」が
本質的なコストで、これは実装の巧拙ではなく構造。オーナーの「SQLで一気に」案は
D2として字義通り実装して測った上での棄却であり、推測による棄却ではない。
Bがpersist/readで負ける理由: JSON.stringifyが1,000オブジェクト×17値を毎抽選
歩くため。文字列配列のstringifyはほぼ無料。updateだけはBが最速(1.4ms vs 4.8ms、
文字列は不変なので1人分の作り直しコストが乗る)が、合計でCが勝つ。
保存の前提: DOは既にfield/chunk差分書き(bingo-product-state-fields-v2、
96Ki chunk、参照同一ならserializeスキップ)。ベンチの(b)はこの経路を再現している。
judging fieldは68KB=1chunkで毎抽選書き直しになるが68KB/抽選は誤差。
次: Phase 1a(stateHashを安いtokenへ、wire無変更)。純粋層ベンチ
(scripts/bench/draw-profile.mjs、現行12.1ms/抽選)でbefore/afterを取る。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-fable-5
現行抽選1回のDO側CPU内訳を実測し、47%削った(2026-08-02、build 5c9ab47)。
測り方: 純粋層で1,000人を組み60抽選し、抽選フェーズだけをV8 CPU profilerで
サンプリングした(store cloneは実物に無いコストなので除いた形にした)。
scratchpadのdraw-profile.mjs / read-profile.mjs。
判明した内訳(修正前・抽選1回28.9ms)
| 項目 | self | 実体 |
| 参加者の線形探索 | 29% | applyProductEngagementEventsのnewlyReach判定が参加者数の2乗 |
| engagementのdeep freeze | 17% | immutableが凍結済みtreeを毎回再構築(event最大512件を二度歩く) |
| stateHash(canonical+sha256) | 約47% | state全体の正規化文字列化 |
| evaluateServerCard | 1.5% | 全参加者の全再計算そのもの |
「番号が出るたび全員のリーチ/ビンゴを数え直しているのでは」という見立ては
構造としては当たっていたが、そこは全体の1.5%しかなかった。 12ラインの数え直しを
カウントダウン方式へ変えても抽選CPUは動かない。同じ「全員分の無駄」でも、
効いていたのは判定ではなく (a) 二乗の線形探索 (b) 凍結済みobjectの再構築
(c) 変化しない参加者のobject作り直しによるhash cache失効、の3つだった。
修正3点と効果(累積)
線形探索→Map: 28.9 → 20.6ms(-29%)
immutableが自分の凍らせた値を覚える: 20.6 → 17.1ms(-12%)
評価が動かない参加者はobject同一性を保つ: 17.1 → 15.3ms(-10%)
合計 28.9 → 15.3ms(-47%)
3点目が「変わらない参加者を触らない」という当初の発想が実際に効いた場所。ただし
効き筋は判定の省略ではなく、stateHashのcanonical fragment cacheがfrozen object
identityで引かれるため、作り直すとcard 25マスぶんの正規化文字列が毎抽選失効する
という経路だった。
検証: tests/draw-evaluation-consistency.test.mjs(新規3件)。期待値は本体と
実装を共有しない独立oracle(tools/oracle)だけから作り、毎抽選・全参加者で
評価一致・初回リーチ/ビンゴseq・訂正抽選後の一致・同一性保持を確認する。
同一性判定を緩める変異で3件とも落ちることを確認済み。既存含め798件通過、lint通過。
残っている最大項目はstateHash(現在も約4割)。state全体を毎抽選で正規化文字列
にしてsha256している。fragment cacheは効いているが、変化した参加者ぶんは毎回再計算。
次に削るならここ。あわせてjoinが1,000人で1.58秒(1人1.6ms)で、参加者数に対して
線形以上に伸びている疑いがあり未調査。
射程の注意: これはDO側の削減であって、campaign受入条件が見ているfrontのCPUでは
ない(B案と同じ射程の話)。front p95は本変更では動かない見込み。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-fable-5
現行直前noteの訂正: B案の本来の標的(DO側)を実測した(2026-08-02、run74 vs run76)。
直前のnoteは「frontのCPUは改善しなかった」を結論の位置に置き、DO側を「配置が違うため
比較できない」として未測定のまま残した。これは測る場所を取り違えた報告だった。
shardプロセスのCPU比較は配置差で不能だが、server-events.ndjson の
metric×dimension集計は合計値なので配置に依存せず比較できる。測り直した結果:
| metric(1件あたり) | run74 (c7a7b34) | run76 (01eb27e) | 差 |
| do.response_bytes / snapshot | 15,480 B | 11,597 B | -25.1% |
| do.action_us / snapshot | 962 us | 866 us | -10.0% |
総量では response_bytes が 466.8MB → 356.2MB(-110.6MB)、action_us が
30.4秒 → 27.9秒(snapshot件数は31,620→32,202と増えているのに減少)。
対照が効いている(触っていない処理は動いていない):
judge.commit_us: 17.2秒 / 143,558 → 143,675 us/件
ws.push_us: 2.4秒 / 486 → 469 us/件
変化したのはsnapshotだけで、前提プロファイルで「削るべき」と特定した項目そのもの。
B案はDO側の転送を25%、snapshot処理CPUを10%削っている。
frontが動かなかったことの位置づけ(訂正): 前提プロファイルの根拠だった
do.action_us/snapshot = 30.4秒(最大項目) はDOの指標であって、frontの指標ではない。
frontの仕事はWSフレームの透過proxyとroutingで、snapshotを生成していない。
よってB案でfrontが動かないのは想定どおりであり、B案の失敗ではない。
campaign受入条件「frontピークが概ね0.5コア未満」がfrontを見ているのに対し、
B案はDOを削る施策だという射程の不一致が残る問題であって、frontを下げるには
別の手(WS中継そのもののコスト、またはfrontの複数プロセス化)が要る。
この点は次スレッドで「次の一手」を決めるときの出発点にする。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行B案の実負荷実測(2026-08-02、run76 / build 01eb27e、2×1,000同時)。
run76は成立した: 両ゲームとも join_accepted 1,000 / final_snapshots 1,000 /
draw_events 60,000。正しさ指標(oracle_diffs / state_hash_mismatches / revision_gaps /
duplicate_events / roster_duplicates / missing_state_hashes /
engagement_projection_violations)はすべて0。
B案は実経路で効いた(実測)
snapshot応答の平均文字数: run74 15,068 / 15,199 → run76 11,058 / 11,161
= 26.6%減(純粋層の28.5%と整合)
省略ブロック数の平均 1.55(最大2=static と card の両方)
bingo_snapshot_rehydration_retries = 0件。1,000人×2ゲーム×60抽選の実経路で
復元に一度も失敗していない。k6は本体の投影コードを共有せず独立に復元しており、
復元が壊れていればindependentOracleがカード判定の不一致を出すが、oracle_diffs も0。
frontのCPUは改善しなかった(実測)
| | run74 (c7a7b34) | run76 (01eb27e) |
| front (multi-worker-runtime) | med 0.21 / p95 1.00 / max 1.12 | med 0.36 / p95 1.03 / max 1.14 |
| shard-s1 | med 0.13 / p95 0.66 / max 0.88 | med 0.46 / p95 1.08 / max 1.18 |
| shard-s2 | med 0.12 / p95 0.63 / max 0.86 | 0(空) |
| front RSS max | 2,346MB | 2,399MB |
ただしシャード配置が違うためshard側は比較できない。run76は2ゲームとも s1 へ
割り当たった(DO storage: shard-s1 31MB / shard-s2 124KB)。run74は分散していた
(16MB / 15MB)。割当はゲーム作成時に確定するため制御できない。
front が動かなかったことの意味(解釈): frontの仕事はWSフレームの透過proxyと
routingで、snapshotの生成はDO側にある。snapshot応答bytesを26.6%削ってもfrontの
CPU支配項ではない。campaign受入条件の「frontピークが概ね0.5コア未満」はB案では
達成できない。計測3のN×1,000外挿にとっては、run74の線形近似(front約0.5コア/ゲーム)が
そのまま生きるということでもある。
B案の価値がどこにあるか: 応答bytes(帯域とDO側のシリアライズCPU)であって
front CPUではない。1,000人×60抽選×2ゲームで snapshot 31,620件・平均4KB削減=
約126MBの転送削減に相当する。
運用上の罠を2つ踏んだ(罠DBへprivate記録済み: wrangler-dev-tee-worker-502-401)
node ... | tee log でstdoutをパイプへ繋ぐとwrangler devが無言で終了する。
entrypointは生き続けるので「controlだけ502」「preflightが401」と別の顔で出る。
wrangler-runtime.logは ⎔ Starting local server... で止まり死因が残らない。
ss -ltn | grep 8791 でlistenが無いことを見て初めて分かった。
対処: nohup node ... > log 2>&1 &(パイプを挟まない)。
p3-01-external-generator-cli.mjs は --output-root 配下のresult未生成な
external-generator-request.json を全部拾う。中断したrunのディレクトリが残っていると
古いリクエストを掴み、--games 2 の枠を食って2×1,000が成立しない。
起動前にstale run を output-root の外へ退避する。bridge側の --games 既定は1。
破棄したrun: run75系3本(aborted/へ退避)。clock502・preflight401・
worker-died はすべて上記1が原因。run75-dirty-double-k6 は私がbridgeを中断・再起動して
同じゲームへk6を二度走らせた汚染run(join 542/1,000)。
次: 計測3(N×1,000の理論上限)。frontのreq/sあたりコストをtelemetryから出す。
front p95がゲーム1本あたり約0.5コアでほぼ線形という2点(run72の1×1,000、run74の
2×1,000)に、run76も「2ゲームでfront p95 1.03」として3点目を与える(配置は違うが
frontから見た負荷は同じ2×1,000)。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行B案(snapshot応答の効率化)の実装完了(2026-08-02、build 01eb27e)。
前提の訂正が先にある。 直前のnoteの「rosterは抽選では変わらない/準静的43%」は
推測であって実測ではなかった。1,000人・60抽選を純粋層で回して各ブロックの変化率を
測ると:
| block | 文字数 | 比率 | 抽選ごとの変化率 |
| roster | 5,696 | 39.7% | 93%(55/59) |
| viewer | 2,493 | 17.4% | 27% |
| results | 1,948 | 13.6% | 80% |
| presentation | 1,904 | 13.3% | 100% |
| game+branding+messages+prizeGuide他 | 1,118 | 7.8% | 0% |
roster.itemsはfocus 12人で、compareGeneralFocus(product-session.mjs)がリーチ数と
ビンゴでソートするため抽選のたびに顔ぶれが入れ替わり、itemsにreachCountと
outcomeStatusも入っている。revision一致で省ける真に不変な部分は7.8%しかない。
noteの実装方針のままだとWS/HTTP契約・client・k6・oracleへ波及する工事をして7.8%だった。
実測で見つけた本当の主役: snapshotの26.1%がカードの25マスを2箇所で冗長に
表現しているだけだった。
viewer.participant.card 1,760文字(markedなし)
roster.self.card 1,985文字(markedあり)
両者のcellsの数字は完全に同一(実測で確認)
1マスの表現 {"position":0,"row":0,"column":0,"number":8,"isFree":false} = 58文字。
position以外は添字から導出でき、本質的な情報はnumberひとつ
カードは参加時に確定して二度と変わらない(変わるのはmarkedだけ)
cardDigestは既にsnapshot.viewer.cardDigestにあり、clientもdata-card-digestで使用済み
実装: snapshot要求に known: { cardDigest, staticRevision } を追加。サーバの
計算値と一致した時だけ、カード(viewer.participant.cardをnull、roster.self.cardを
25文字のmarkビット列へ)とgame/branding/prizeGuideを省く。応答に staticRevision と
omitted[] を載せる。
削減(純粋層1,000人の実測): 15,429 → 11,036文字 = 28.5%。
設計上の裁定
省略は一致時だけ。不一致・未申告は必ず全量。clientが嘘のdigestを送っても
一致しなければ全量が返るだけで、古い内容を掴まされる経路がない
revisionとstateHashは動かさない(省略は表現の違いでstateの違いではない)
「変わらない条件」の列挙ではなく内容のdigestで判定する。条件を1つ書き漏らすと
古い内容を配り続けるため
client復元はnormalizeSnapshotの手前で閉じる。埋め戻せない時は黙って欠けたまま
進めず、申告を捨てて1回だけ取り直す
k6は本体の投影コードを共有せず独立に復元する。復元が壊れれば
independentOracle(participant.card, drawnNumbers)がカード判定の不一致として検出する
配管: api-router(?knownCard=&knownStatic=、形式不正は422で止める)→
game-session.ts participant.read → authenticatedSnapshot → projectSnapshotView。
検証: 新規15テスト(tests/snapshot-known-projection.test.mjs 9件、
tests/snapshot-rehydration.test.mjs 6件)。復元結果が全量応答と完全一致すること、
12抽選ぶんmarkが実体と一致すること、控えが無い/digestが食い違う時にincompleteを
立てること、参加者が増えればstaticRevisionが追随して省略されないことを含む。
既存を含め795件全通過、lint通過。
計測上の注意(今回も踏んだ): 擬似時計が1msずつしか進まないとengagementDeliveryに
期限切れcueが溜まり3,525文字(本来17文字)に膨れる。抽選間で時計を実時間相当
(8秒)進めて潰した。この汚染を除くと純粋層14,348文字となりrun74の実測15.5KBと整合する。
次: k6経路を通した実測(計測3と同じrunで削減効果とfront CPUの変化を見る)。
front p95 1.01コアのうちsnapshotがaction_us最大項目(30.4秒)だったので、
bytes 28.5%減がCPUにどう効くかは実測でしか分からない。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行B案(snapshot応答の効率化)の前提プロファイル(2026-08-02、run74の証跡+純粋層の実測)。
B案の条件は両方とも成立した。
条件1「frontピークが0.5コア超」: run74で front p95 1.01 / max 1.12コア。
条件2「プロファイルでsnapshot生成/転送が支配的」: 成立。run74の2ゲーム合計で
do.response_bytes / snapshot = 489MB(31,620件・平均15.5KB)。全応答bytesの92.7%。
次点はresults 20.9MB、other 12.1MBで桁違い。
do.action_us / snapshot = 30.4秒CPU。judge.commit_us(17.2秒)を上回る最大項目。
ws.push_us / page = 2.4秒のみ。fanout受信者366,678件を共有frame 6,324本へ
畳んでいるため、WS配信は既に安い。削るべきはsnapshotであってfanoutではない。
snapshot 15.8KBの内訳(1,000人・60抽選・演出cue非活性、純粋層で実測)
roster 5,669文字 35.9% ← 抽選では変わらない(join/rename/退出のみ)
results 2,742文字 17.4% ← 変わる
viewer 2,561文字 16.2% ← 変わる(自分のカードと判定)
presentation 2,280文字 14.4% ← 変わる
branding 548 / game 523 / engagement 522 / controls 285 / prizeGuide 124 / venue 117
(合計2,119文字 13.4%)← ほぼ変わらない
準静的な部分(roster + branding + prizeGuide + venue + controls ≒ 6,743文字 = 43%)を
「変わっていなければ省く」のがB案の骨子。抽選のたびに変わるのはviewer・results・
presentationだけで、snapshotの約57%。
計測上の注意(実際に踏んだ): 擬似時計(1msずつ進む)で測ると、
engagementDelivery.visualCuesに期限切れのcueが全部残り38,109文字=70.7%に見える。
実runの平均15.5KBと桁が合わないことで気付いた。cue窓を過ぎさせてから測ると
15,800文字となり実測と一致する。時間窓でフィルタされる項目を含む構造を
擬似時計で測る時は、必ず実runの数値と突き合わせる。
実装方針(未着手): snapshot要求へクライアントが保持する準静的ブロックの
revisionを載せ、サーバ側で一致すれば当該ブロックを省いてrevisionだけ返す。
省略はrevision一致時だけなので、名簿の更新が遅れることはない。
ただしWS/HTTP契約・client・k6契約・oracleへ波及するため、変更範囲は小さくない。
stateHashは抽選ごとに変わるため、roster.identityRevisionには使えない
(roster専用のrevisionが要る)。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行計測2(2×1,000同時)の成立版(2026-08-02、run74 / build c7a7b34)。
joinレート制限の3本目を参加コード単位へ変えた後、2×1,000が成立した。
成立の根拠: 2ゲームがs2とs1へ分散(s2/load-697a44b8... / s1/load-9875fbb1...)。
両ゲームとも join_accepted 1,000 / initial_connections 1,000 /
final_snapshots 1,000 / draw_events 60,000(60抽選×1,000人)。k6は2本同時完走
(3m03.6s / 3m04.2s)。生成器はCPU p95 0.25(gate 0.7)・memory 0.52(gate 0.8)で
余力あり=生成器側の飽和ではない。
CPU(cpu_ratio、1.0=1コア)
front: med 0.36 / p95 1.01 / max 1.12(RSS 2,461MB)
shard-s1: med 0.27 / p95 0.68 / max 0.88(650MB)
shard-s2: med 0.26 / p95 0.64 / max 0.86(715MB)
front+shard合計: med 0.90 / p95 2.14 / max 2.55コア
受入条件の照合
両ゲーム収束: 満たす
正しさ指標ゼロ違反: 満たす(oracle_diffs / state_hash_mismatches / revision_gaps /
duplicate_events / roster_duplicates / missing_state_hashes /
engagement_projection_violations すべて0)
front+shard合計が1コアを超えて伸びる: 満たす(p95 2.14 / max 2.55)
frontピークが概ね0.5コア未満: 未達(p95 1.01 / max 1.12)
frontの伸び方(計測1と並べる)
1×1,000(run72): front p95 0.44 / max 0.90、合計 p95 0.97 / max 1.70
2×1,000(run74): front p95 1.01 / max 1.12、合計 p95 2.14 / max 2.55
frontはゲーム1本あたりp95約0.5コアでほぼ線形に増える。WSフレームが透過proxyで
front を通り続けるため、DOをシャードへ出してもfrontのコストは消えない。
B案(snapshot応答の効率化)の条件が成立した。設計文書の条件は
「frontピークが0.5コア超」かつ「プロファイルでsnapshot生成/転送が支配的」。
前者は満たした。後者は未取得で、frontのプロファイル取得が次の一手になる。
兆候はある: snapshot_refresh_latency p95 が 1,349ms / 1,222ms(1×1,000では169ms)、
front RSS 2,461MB(1×1,000では1,384MB)。
残る閾値NG(正しさではなく応答時間): roster_latency p95>750(両ゲーム)、
game2でconvergence/fanout p99>1500。fanout p95はgame1が-176ms(負値)で、
生成器とサーバの時計ずれが残っている。Wave 1のclock補正を当てないと
fanoutの絶対値は判断材料にできない。
計測3(N×1,000の理論上限の外挿)は未実施。現状の2点(1ゲーム/2ゲーム)から
線形近似すると front 1プロセスで約2ゲームが限界に見えるが、2点だけの外挿は弱く、
frontのreq/sあたりコストをtelemetryから出す必要がある。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行計測2(2×1,000同時)の実測結果(2026-08-02、run73 / build 228c3a3)。
2×1,000は成立しなかった。原因はjoinのサービス全体レート制限で、資源ではない。
構成は狙いどおりに出来ていた: 2ゲームがs1とs2へ分散(do_routing_key =
s2/load-5ab159a2... と s1/load-8dcd77bb...)、k6は2本が同時に完走
(2m51.4s / 2m51.5s、各VU 1000/1000起動)。
実際に参加できたのは各ゲーム558人・557人(計1,115人)。
k6 rawのstatus分布に429が3,978件。サーバのruntime logはエラー0件、
FOXはCPU p95 0.22(gate 0.7)・memory 0.46(gate 0.8)で余力あり。
つまりサーバ資源でも生成器でもなく、業務的な429で弾かれている。
原因: src/game/join-resume.mjs の JOIN_RATE_LIMITS.registration.service が
1,000件/60秒で、キーが join-code:registration:service=全ゲーム横断。
1×1,000はちょうど上限に収まるが、2×1,000は約半分が429になる。観測値
(1,115 ≈ 1,000+窓跨ぎ)と一致する。ip=10/10分・networkPrefix=50/10分の
バケットは負荷試験の到達元では効いていない(両ゲームで落ち方がほぼ同一)。
これは負荷試験の作り物ではなく製品の挙動である。現状の実装では、参加登録が
60秒に集中する限り、サービス全体で同時に1,000人しか登録できない。
複数ゲーム同時開催という製品要件と正面から衝突する。
CPU(1,115人ぶんの値であり、2,000人ぶんではない)
front: med 0.02 / p95 0.71 / max 0.97コア(RSS 1,384MB)
shard-s1: p95 0.42 / max 0.60(523MB)、shard-s2: p95 0.43 / max 0.69(503MB)
front+shard合計: p95 1.49 / max 2.13コア
参考 run72(1×1,000、1,000人成立): front p95 0.44 / max 0.90、合計 p95 0.97 / max 1.70
受入条件の照合:
「両ゲーム収束」→ 未達(各558/557人でしか成立していない)
「正しさ指標ゼロ違反」→ 満たす(oracle_diffs / state_hash_mismatches /
revision_gaps / duplicate_events / roster_duplicates / missing_state_hashes /
engagement_projection_violations すべて0)。入れた参加者については壊れていない。
「front+shard合計が1コア超へ伸びる」→ 満たす(p95 1.49 / max 2.13)
「frontピークが概ね0.5コア未満」→ 未達(p95 0.71 / max 0.97)。ただし1,115人での値。
裁定が要る: service バケットをどうするか。
(a) 上限引き上げ(DoS防御の緩和)
(b) ゲーム単位バケットへ変更(ip/networkPrefixの防御は残る。join-codeは既にゲーム特定)
(c) load-staging限定で緩める(本番挙動は変えないが、測定条件が本番と変わる)
この裁定なしに2×1,000の再実測はできない。
副次: 両ゲームともfanout_latency p95が負値(-62ms / -54ms)。生成器と
サーバの時計ずれ。1×1,000(run72)では正値だったので、2実行同時での
clock probe取得タイミングの問題の可能性がある。未調査。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行計測1(1×1,000をシャード経由)の実測結果と、その前に潰した3つの欠陥(2026-08-02)。
実測が成立したことの根拠: D1のdo_routing_key = s1/load-8817c0ffe2ef24ac40f8462f679d624a、
game DOのSQLite(7.8MB)はshard-s1のpersist dirに存在。front単体ではない。
run72 / build ffe63ac / cold seed A / normal / 1,000人 / 外部生成器(FOX)。
CPU(cpu_ratio、1.0=1コア)
run72 シャード構成: front med 0.05 / p95 0.44 / max 0.90(RSS 1,211MB)、
shard-s1 med 0.11 / p95 0.57 / max 0.85(RSS 685MB)、shard-s2は0(割当なし・RSS 70MB)
run68 front単体(build 0b11e3f、同条件): front med 0.18 / p95 0.74 / max 1.11(RSS 1,277MB)
→ DOをシャードへ出すとfront CPUはp95 0.74→0.44(約-40%)、max 1.11→0.90。
front+shard合計はp95で約1.01コアとなり、転送のぶん総CPUは約37%増える。
WSフレームは透過proxyでfrontを通り続けるため、frontのコストは消えない。
campaign受入の「frontピーク約0.5コア未満」はp95では満たすがmaxでは満たさない。
latency(すべて閾値内): join p95 77ms / fanout p95 263ms(閾値750) / ws_open p95 201ms /
snapshot_refresh p95 169ms / roster p95 118ms / reconnect p95 246ms。
未解決: 1,000人中1人がunexpected errorで脱落し、draw_events 59,940/60,000・
final_snapshots 999/1000・ready_frames 1,998/2,000でthreshold NG。原因未特定。
この計測の前に潰した欠陥(いずれも「エラーを出さずに別構成を測る」形)
remote entrypointがshardConfig/shardTopologyを持たず、シャードを起動しない(commit 0b11e3f)
load-controlのcreateFixtureがselectRoutingKeyを渡さず、全fixtureが前段DOへ載る(9f3ba21)
シャードIDがapp/controlへ届かない。wranglerの--varはmulti-config devの先頭configだけ、
process.envはsecrets.requiredへ宣言した名前だけが渡る(d24bd0c)
BINGO_SHARD_ENDPOINTSがapp configだけにあり、controlからの転送が引けない(ffe63ac)
1回目の実測はruntime topology attestationがVALIDのまま前段単体を測っていた。起動形の検査だけでは
「起動したが載っていない」を検出できないため、fixture応答のdoRoutingKeyを宣言topologyと
突き合わせるガード(SHARD_PLACEMENT_MISMATCH)を入れた。実際にこれが2回目を止めた。
次: 計測2(2×1,000同時)はharness拡張が要る(fixture 2本・k6 2実行の同時駆動・
両ゲームぶんの収束集計)。計測3は計測2の結果からの外挿。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行実行経路の確認結果(2026-08-02、実機で確認)。
シャード構成の設定検証はhost上でPASSした。 .2へrelease相当をrsyncし、
.wrangler/load-stagingを/home/kite/Developer/bingo-load-staging/stateへsymlinkしたうえで
p3-01-staging-operator.mjsへ--shard-ids s1,s2を渡し、'self-host設定検証: PASS'を得た。
mgs-04-loadtest-topologyのplan・config契約は実configの上でも成立している。
(この作業dirは検証後に撤去済み。tunnelは502=ingressは生きておりoriginだけ不在。)
未実装の穴: 実測の正規runnerはp3-01-staging-operator.mjsのmain()ではなく
p3-01-remote-entrypoint.mjsである。理由:
operatorのmain()はexternalGeneratorをexecuteSelfHostedへ渡さない(--external-generatorは
operator側のCLIには存在しない)。外部生成器(FOX)を使う実測はremote entrypoint経由だけ。
remote entrypointはconfiguration objectを自前で組み立てる(370-400行)。
そこにshardConfig/shardTopologyが無いため、このまま実測するとシャードは1台も起動せず、
従来の単一process構成を測ることになる。
remote entrypointはattestCleanRelease(git clean HEAD)とPLAYWRIGHT_BROWSERS_PATHの
固定toolsetを要求し、秘密値は自前でephemeral生成する(stdin JWKは不要)。
よって実測環境はrsyncコピーではなくgit cloneが要る。
したがってmgs-04-measureの最初の一歩は「remote entrypointへshard topologyを通す」
(--shard-idsまたは既定値でshardConfig/shardTopologyをconfigurationへ載せる)ことになる。
その後: 計測1(1×1,000をshard経由)は現行harnessで可能。計測2(2×1,000同時)は
fixture 2本・k6 2実行の同時駆動と両ゲームぶんの収束集計が要る(前ノートの通り)。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
現行着手前の前提確認(2026-08-02、実測)。
到達性: Macから .2(staging、/home/kite/Developer/bingo-load-staging 有り・過去runのstate有り)と
FOX(k6生成器、ssh windows-workstation)の両方へ到達できる。.2→.11 のSSHは不可なので、
p3-01-external-generator-bridge.mjs の記載どおりbridgeはMacで動かす。hostにk6は無い。
秘密値(SESSION_SECRET・P-256 private JWK)はstaging閉域でのみ使われるため、run毎に
新規生成でよい=オーナー保持の秘密待ちにはならない。
未解決の設計課題: 現行harnessは1 runにつき1ゲームしか駆動しない。
p3-01-staging-operator.mjs:920が /v1/fixture を1回呼び、p3-01-public.k6.js:38,766,1042 は
単一の BINGO_GAME_ID を必須にして『同一game』を表明する。campaignの受入条件である
2×1,000同時にはharness側の拡張(fixture 2本・k6 2実行の同時駆動・両ゲームぶんの収束集計)が要る。
計測1(1×1,000をshard経由)は現行harnessのままで実行できるので、そこから入るのが順序として自然。
来歴: rev-initial/mgs-04-measure・記録者 KaitonoMacBook-Air/claude-opus-5
note head: 727b2d70a68ded59324a89351fbd6dba65145ef5fab3362acee0749410990e3f
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-04-measure- anchor
- anchor_missing
本番rolloutとsmokeを行う(オーナー承認ゲート)
カテゴリ: main
正規ID: bingo-multi-game-scale/mgs-05-rollout
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
デプロイ(.deploy.envへBINGO_SHARD_*追加)→smoke: (a)旧形式ゲームの閲覧/WS継続 (b)新規ゲームをシャード数ぶん作成しdo_routing_keyのprefix分布確認、各ゲームでjoin+WS+抽選1回 (c)shard1を意図的にstop→該当ゲームのみ503・他ゲーム無影響→start→復帰 (d)backup手動1回。rollback条件: シャード上にゲームが出来た後24h(join code TTL)は旧構成へ戻さない。既存ゲームは最悪61日で自然排水。
前提工程
元plan: docs/architecture/multi-game-scale.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-multi-game-scale/mgs-05-rollout- anchor
- anchor_missing
✅ 完了工程 prize-results-emphasisプレイ中順位と最終結果で景品を主役として表示する
カテゴリ: implementation
正規ID: bingo-prize-results-emphasis/prize-results-emphasis
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
既存の awards、branding.prizes、prizeGuide をクライアントで結合する。新しい獲得瞬間演出は追加せず、プレイ中は順位順を維持して受賞行を強調し、最終結果は受賞者を先頭へ分離する。公開面から受け渡し運用情報を隠し、主催者面だけに残す。会場面は終了後のみ結果を主表示へ上げる。focused test、lint、build、responsive browser QA、本番smokeを受入証跡に含める。
元plan: docs/prize-results-emphasis-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-prize-results-emphasis/prize-results-emphasis- anchor
- anchor_missing
✅ 完了工程 p0-01-reverse-tiebreak逆ビンゴで最後の候補が同時脱落した場合の勝者決定ルールを決める(5.4節の逆向き優先条件案を裁定)
カテゴリ: owner
正規ID: bingo-service/p0-01-reverse-tiebreak
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L56 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-01-reverse-tiebreak- anchor
- anchor_missing
✅ 完了工程 p0-02-card-visibility他人のカードの公開範囲を決める(常時公開/ビンゴ後のみ/非公開。初期設定候補は常時公開)
カテゴリ: owner
正規ID: bingo-service/p0-02-card-visibility
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L67 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-02-card-visibility- anchor
- anchor_missing
✅ 完了工程 p0-03-account-policy参加者アカウントの要否を決める
カテゴリ: owner
正規ID: bingo-service/p0-03-account-policy
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L73 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-03-account-policy- anchor
- anchor_missing
✅ 完了工程 p0-04-identity-policy参加者名の重複およびなりすまし対策を決める
カテゴリ: owner
正規ID: bingo-service/p0-04-identity-policy
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L74 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-04-identity-policy- anchor
- anchor_missing
✅ 完了工程 p0-05-free-cap-behavior30人無料・31人目以降の動作を決める
カテゴリ: owner
正規ID: bingo-service/p0-05-free-cap-behavior
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-05-free-cap-behavior- anchor
- anchor_missing
大人数利用の価格と課金方法を決める(100円/24時間案は保留。3節の確認事項を含む)
カテゴリ: owner
正規ID: bingo-service/p0-06-pricing
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L7 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-06-pricing- anchor
- anchor_missing
✅ 完了工程 p0-07-data-retentionゲームデータの保存期間を決める
カテゴリ: owner
正規ID: bingo-service/p0-07-data-retention
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L8 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-07-data-retention- anchor
- anchor_missing
✅ 完了工程 p0-08-draw-correction-policy誤抽選の訂正可能時点、取消event、順位・景品の再計算範囲、監査履歴を裁定する
カテゴリ: owner
正規ID: bingo-service/p0-08-draw-correction-policy
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L9 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-08-draw-correction-policy- anchor
- anchor_missing
✅ 完了工程 p0-09-late-join-policy途中参加時の過去抽選反映、即時当選、順位資格、無料枠計数を裁定する
カテゴリ: owner
正規ID: bingo-service/p0-09-late-join-policy
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L10 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p0-09-late-join-policy- anchor
- anchor_missing
✅ 完了工程 p1-01-stack-decisionフロントエンド、バックエンド、データベース、リアルタイム配信方式を決める(vinext/Cloudflare構成を検証の上で確定)
カテゴリ: design
正規ID: bingo-service/p1-01-stack-decision
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L11 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-01-stack-decision- anchor
- anchor_missing
✅ 完了工程 p1-02-authz-boundary主催者、参加者、観戦者の権限境界を設計する
カテゴリ: design
正規ID: bingo-service/p1-02-authz-boundary
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L12 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-02-authz-boundary- anchor
- anchor_missing
ゲーム、カード、抽選、判定、順位、景品のデータモデルを設計する
カテゴリ: design
正規ID: bingo-service/p1-03-data-model
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L13 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-03-data-model- anchor
- anchor_missing
✅ 完了工程 p1-04-oracle-invariants本体とは独立した判定モデルと、ゲーム状態の不変条件を定義する(12.1節の不変条件を含む)
カテゴリ: design
正規ID: bingo-service/p1-04-oracle-invariants
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L14 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-04-oracle-invariants- anchor
- anchor_missing
最大1,000人の擬似参加者を動かせるゲームシミュレーターを作る
カテゴリ: impl
正規ID: bingo-service/p1-05-simulator
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L15 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-05-simulator- anchor
- anchor_missing
✅ 完了工程 p1-06-failure-capture失敗シード、操作履歴、最小再現ケースを保存できるようにする
カテゴリ: impl
正規ID: bingo-service/p1-06-failure-capture
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L16 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-06-failure-capture- anchor
- anchor_missing
✅ 完了工程 p1-07-judge-tests-first自動判定と同時ビンゴ優先処理のテストを先に作る
カテゴリ: impl
正規ID: bingo-service/p1-07-judge-tests-first
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L17 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-07-judge-tests-first- anchor
- anchor_missing
✅ 完了工程 p1-08-art-direction通常、逆、ハイブリッド各モードのアートディレクションを決める
カテゴリ: design
正規ID: bingo-service/p1-08-art-direction
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L18 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-08-art-direction- anchor
- anchor_missing
✅ 完了工程 p1-09-visual-prototypeカード、主要画面、反転演出の高品質プロトタイプを作る
カテゴリ: impl
正規ID: bingo-service/p1-09-visual-prototype
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L19 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-09-visual-prototype- anchor
- anchor_missing
✅ 完了工程 p1-10-av-sync-policy音楽、効果音、モーションの同期方針を決める
カテゴリ: design
正規ID: bingo-service/p1-10-av-sync-policy
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L20 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-10-av-sync-policy- anchor
- anchor_missing
✅ 完了工程 p1-11-load-test-spec1,000人負荷試験の条件と計測項目を決める
カテゴリ: design
正規ID: bingo-service/p1-11-load-test-spec
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L21 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-11-load-test-spec- anchor
- anchor_missing
✅ 完了工程 p1-12-ops-recovery障害時の復旧方法と監視項目を決める
カテゴリ: design
正規ID: bingo-service/p1-12-ops-recovery
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L22 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-12-ops-recovery- anchor
- anchor_missing
✅ 完了工程 p1-13-payment-failure-modelprovider中立の決済状態機械、署名失敗、冪等性、取消・返金、枠解放失敗の検証行列を設計する
カテゴリ: design
正規ID: bingo-service/p1-13-payment-failure-model
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L23 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p1-13-payment-failure-model- anchor
- anchor_missing
ゲーム作成と主催者権限
カテゴリ: impl
正規ID: bingo-service/p2-01-game-create
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L24 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-01-game-create- anchor
- anchor_missing
URL/QR/期限付き短い参加codeによる参加と安全な参加者復帰を実装し、code衝突と総当たりを防ぐ
カテゴリ: impl
正規ID: bingo-service/p2-02-join-resume
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L25 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-02-join-resume- anchor
- anchor_missing
✅ 完了工程 p2-03-card-generationカード生成と表示(サーバー生成・改ざん不可)
カテゴリ: impl
正規ID: bingo-service/p2-03-card-generation
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L26 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-03-card-generation- anchor
- anchor_missing
✅ 完了工程 p2-04-draw-realtime抽選とリアルタイム同期
カテゴリ: impl
正規ID: bingo-service/p2-04-draw-realtime
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L27 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-04-draw-realtime- anchor
- anchor_missing
✅ 完了工程 p2-05-auto-judgingリーチ/ビンゴの自動判定(サーバー正本・独立モデルと照合)
カテゴリ: impl
正規ID: bingo-service/p2-05-auto-judging
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L28 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-05-auto-judging- anchor
- anchor_missing
✅ 完了工程 p2-06-tiebreak-lottery同時ビンゴの優先判定と最終抽選(5.2節の選択式ルール)
カテゴリ: impl
正規ID: bingo-service/p2-06-tiebreak-lottery
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L29 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-06-tiebreak-lottery- anchor
- anchor_missing
✅ 完了工程 p2-07-reverse-mode逆ビンゴの脱落、生存順位、観戦、最終勝者判定
カテゴリ: impl
正規ID: bingo-service/p2-07-reverse-mode
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L30 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-07-reverse-mode- anchor
- anchor_missing
ハイブリッドモードの反転順位、脱落、通常側/生存側の景品設定(反転は一度だけ確定)
カテゴリ: impl
正規ID: bingo-service/p2-08-hybrid-mode
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L31 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-08-hybrid-mode- anchor
- anchor_missing
✅ 完了工程 p2-09-prize-config景品設定(単独順位・順位範囲・飛び賞)
カテゴリ: impl
正規ID: bingo-service/p2-09-prize-config
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L32 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-09-prize-config- anchor
- anchor_missing
✅ 完了工程 p2-10-roster-card-view参加者一覧と他人のカード閲覧
カテゴリ: impl
正規ID: bingo-service/p2-10-roster-card-view
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L33 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-10-roster-card-view- anchor
- anchor_missing
✅ 完了工程 p2-11-venue-screen会場スクリーン
カテゴリ: impl
正規ID: bingo-service/p2-11-venue-screen
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L34 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-11-venue-screen- anchor
- anchor_missing
✅ 完了工程 p2-12-lobby-admission待機室、受付締め切り、途中参加設定
カテゴリ: impl
正規ID: bingo-service/p2-12-lobby-admission
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L35 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-12-lobby-admission- anchor
- anchor_missing
✅ 完了工程 p2-13-draw-controls抽選の開始、自動進行、一時停止、再開、終了、訂正/取消を実装し、再送・重複確定を防止する
カテゴリ: impl
正規ID: bingo-service/p2-13-draw-controls
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L36 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-13-draw-controls- anchor
- anchor_missing
✅ 完了工程 p2-14-casino-presentation通常モードのカジノ風カードと演出(6.1節・6.4節の品質条件)
カテゴリ: impl
正規ID: bingo-service/p2-14-casino-presentation
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L37 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-14-casino-presentation- anchor
- anchor_missing
✅ 完了工程 p2-15-reverse-presentation逆ビンゴのシリアスなカードと演出(6.2節)
カテゴリ: impl
正規ID: bingo-service/p2-15-reverse-presentation
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L38 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-15-reverse-presentation- anchor
- anchor_missing
✅ 完了工程 p2-16-hybrid-flip-presentationハイブリッドモードの画面、カード、音響の反転演出(6.3節)
カテゴリ: impl
正規ID: bingo-service/p2-16-hybrid-flip-presentation
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L39 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-16-hybrid-flip-presentation- anchor
- anchor_missing
✅ 完了工程 p2-17-prize-handover-results景品受け渡しと結果表示
カテゴリ: impl
正規ID: bingo-service/p2-17-prize-handover-results
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L40 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-17-prize-handover-results- anchor
- anchor_missing
✅ 完了工程 p2-18-rehearsal-mode予行演習モード
カテゴリ: impl
正規ID: bingo-service/p2-18-rehearsal-mode
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L41 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-18-rehearsal-mode- anchor
- anchor_missing
✅ 完了工程 p2-19-cohost-takeover共同主催者と主催者切断時の引き継ぎ
カテゴリ: impl
正規ID: bingo-service/p2-19-cohost-takeover
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L42 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-19-cohost-takeover- anchor
- anchor_missing
✅ 完了工程 p2-20-engagement-featuresリーチ演出、同時判定実況、最終抽選roulette、紙吹雪、景品残人数表示を実装する
カテゴリ: impl
正規ID: bingo-service/p2-20-engagement-features
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L43 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-20-engagement-features- anchor
- anchor_missing
✅ 完了工程 p2-21-free-cap-enforcement30人上限のサーバー側強制(参加登録数基準)
カテゴリ: impl
正規ID: bingo-service/p2-21-free-cap-enforcement
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L44 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-21-free-cap-enforcement- anchor
- anchor_missing
✅ 完了工程 p2-22-participant-lifecycle名前変更、退出、再参加禁止、重複名識別、安全な本人復帰を実装する
カテゴリ: impl
正規ID: bingo-service/p2-22-participant-lifecycle
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L45 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-22-participant-lifecycle- anchor
- anchor_missing
✅ 完了工程 p2-23-live-reactions絵文字リアクション、rate制限、主催者moderationを実装する
カテゴリ: impl
正規ID: bingo-service/p2-23-live-reactions
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L46 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-23-live-reactions- anchor
- anchor_missing
✅ 完了工程 p2-24-announcer-countdown抽選番号読み上げ、選択音声、効果音、会場countdownを同期cueとして実装する
カテゴリ: impl
正規ID: bingo-service/p2-24-announcer-countdown
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L47 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-24-announcer-countdown- anchor
- anchor_missing
✅ 完了工程 p2-25-spectator-discovery参加者検索、リーチ一覧、順位、お気に入り、待ち番号公開設定、獲得カード振り返りを実装する
カテゴリ: impl
正規ID: bingo-service/p2-25-spectator-discovery
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L48 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-25-spectator-discovery- anchor
- anchor_missing
✅ 完了工程 p2-26-game-templates-export過去ゲーム保存・複製、参加者と結果の出力、参加者事前登録を実装する
カテゴリ: impl
正規ID: bingo-service/p2-26-game-templates-export
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L49 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-26-game-templates-export- anchor
- anchor_missing
✅ 完了工程 p2-27-host-messaging-audit主催者の祝福messageと改ざん困難な操作履歴を実装する
カテゴリ: impl
正規ID: bingo-service/p2-27-host-messaging-audit
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L50 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-27-host-messaging-audit- anchor
- anchor_missing
✅ 完了工程 p2-28-theme-prize-branding背景・theme・景品画像・企業logo・主催者brand表示の基本customizeを実装する
カテゴリ: impl
正規ID: bingo-service/p2-28-theme-prize-branding
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L51 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-28-theme-prize-branding- anchor
- anchor_missing
✅ 完了工程 p2-29-real-device-presentation-qa3mode×smartphone・PC・会場×音声・mute×reduced-motionの実機品質行列を完走し証拠化する
カテゴリ: verify
正規ID: bingo-service/p2-29-real-device-presentation-qa
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L52 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-29-real-device-presentation-qa- anchor
- anchor_missing
✅ 完了工程 p2-30-product-e2e-integration製品routeをサーバー正本serviceへ接続し、3modeの実ゲーム完走E2Eと機能網羅表を証拠化する
カテゴリ: impl
正規ID: bingo-service/p2-30-product-e2e-integration
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/phase-2-gate-followup-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-30-product-e2e-integration- anchor
- anchor_missing
✅ 完了工程 p2-31-roster-lifecycle-product参加者一覧・検索・他者カード閲覧と、名前変更・退出・再参加禁止を含む参加者管理を製品API/UIへ接続する
カテゴリ: impl
正規ID: bingo-service/p2-31-roster-lifecycle-product
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/phase-2-product-surface-followup-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-31-roster-lifecycle-product- anchor
- anchor_missing
✅ 完了工程 p2-32-rehearsal-cohost-product予行演習と、共同主催者の招待・操作・切断時引継ぎを主催者製品面へ接続する
カテゴリ: impl
正規ID: bingo-service/p2-32-rehearsal-cohost-product
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/phase-2-product-surface-followup-cutover.md#L7 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-32-rehearsal-cohost-product- anchor
- anchor_missing
✅ 完了工程 p2-33-engagement-spectator-product盛り上げ機能、ライブリアクション、司会カウントダウン、観戦・参加者発見を製品API/UIへ接続する
カテゴリ: impl
正規ID: bingo-service/p2-33-engagement-spectator-product
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/phase-2-product-surface-followup-cutover.md#L8 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-33-engagement-spectator-product- anchor
- anchor_missing
✅ 完了工程 p2-34-host-tools-branding-productテンプレート保存・複製、事前登録、CSV出力、主催者メッセージ・監査、テーマ・ロゴ・景品画像を主催者製品面へ接続する
カテゴリ: impl
正規ID: bingo-service/p2-34-host-tools-branding-product
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/phase-2-product-surface-followup-cutover.md#L9 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p2-34-host-tools-branding-product- anchor
- anchor_missing
✅ 完了工程 p3-02-roster-render-optimization参加者一覧とカード閲覧の表示最適化(検索・ページ分割・仮想表示)
カテゴリ: impl
正規ID: bingo-service/p3-02-roster-render-optimization
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L54 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p3-02-roster-render-optimization- anchor
- anchor_missing
✅ 完了工程 p3-03-disconnect-recovery-test同時接続中の切断と復帰試験
カテゴリ: verify
正規ID: bingo-service/p3-03-disconnect-recovery-test
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L55 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p3-03-disconnect-recovery-test- anchor
- anchor_missing
✅ 完了工程 p3-04-mass-tiebreak-test多数の同時ビンゴ時の順位および景品処理試験
カテゴリ: verify
正規ID: bingo-service/p3-04-mass-tiebreak-test
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L57 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p3-04-mass-tiebreak-test- anchor
- anchor_missing
✅ 完了工程 p3-05-duplicate-request-guard主催者の連打、再送、複数タブに対する重複処理防止
カテゴリ: impl
正規ID: bingo-service/p3-05-duplicate-request-guard
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L58 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p3-05-duplicate-request-guard- anchor
- anchor_missing
✅ 完了工程 p3-06-authority-grants観戦・会場grantの発行、fragment一回引換、version・expiry正本、失効時WebSocket切断を実装する
カテゴリ: impl
正規ID: bingo-service/p3-06-authority-grants
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/phase-3-authority-grant-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p3-06-authority-grants- anchor
- anchor_missing
✅ 完了工程 p3-07-websocket-admission-scale分散clientで1,000同時WebSocket接続・配信・長履歴再接続を実証する
カテゴリ: impl
正規ID: bingo-service/p3-07-websocket-admission-scale
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/phase-3-websocket-transport-scope-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p3-07-websocket-admission-scale- anchor
- anchor_missing
✅ 完了工程 p4-01-psp-selection決済採用時はPSPを選定し、無料β時は非採用scopeを証拠化する
カテゴリ: owner
正規ID: bingo-service/p4-01-psp-selection
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L59 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p4-01-psp-selection- anchor
- anchor_missing
✅ 完了工程 p4-02-viability-check決済採用時は少額決済の採算を確認し、無料β時は需要検証条件を証拠化する
カテゴリ: owner
正規ID: bingo-service/p4-02-viability-check
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L60 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p4-02-viability-check- anchor
- anchor_missing
✅ 完了工程 p4-03-paid-tier-impl決済採用時は有料枠と有効期間を実装し、無料β時は非適用をserver側で固定する
カテゴリ: impl
正規ID: bingo-service/p4-03-paid-tier-impl
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L61 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p4-03-paid-tier-impl- anchor
- anchor_missing
✅ 完了工程 p4-04-webhook-idempotency決済採用時は署名検証と冪等webhookを実装し、無料β時は決済入口が無いことを検証する
カテゴリ: impl
正規ID: bingo-service/p4-04-webhook-idempotency
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L62 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p4-04-webhook-idempotency- anchor
- anchor_missing
✅ 完了工程 p4-05-payment-failure-verify決済採用時は二重決済・失敗・取消・返金を検証し、無料β時は非適用証拠で閉じる
カテゴリ: verify
正規ID: bingo-service/p4-05-payment-failure-verify
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L63 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p4-05-payment-failure-verify- anchor
- anchor_missing
✅ 完了工程 p4-06-upgrade-flow決済採用時は31人目のupgrade導線を実装し、無料β時は明示的な上限案内を実装する
カテゴリ: impl
正規ID: bingo-service/p4-06-upgrade-flow
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L64 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p4-06-upgrade-flow- anchor
- anchor_missing
✅ 完了工程 p5-01-prod-environment本番環境を構築する
カテゴリ: release
正規ID: bingo-service/p5-01-prod-environment
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L65 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-01-prod-environment- anchor
- anchor_missing
bingo.kitepon.dev のDNSとTLSを設定する(DNS変更はオーナー操作)
カテゴリ: owner
正規ID: bingo-service/p5-02-dns-tls
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L66 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-02-dns-tls- anchor
- anchor_missing
✅ 完了工程 p5-03-backup-monitoringバックアップ、監視、エラー通知を設定する
カテゴリ: release
正規ID: bingo-service/p5-03-backup-monitoring
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L68 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-03-backup-monitoring- anchor
- anchor_missing
利用規約、プライバシー表示、問い合わせ導線を用意する
カテゴリ: release
正規ID: bingo-service/p5-04-legal-pages
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L69 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-04-legal-pages- anchor
- anchor_missing
✅ 完了工程 p5-05-prod-smoke-game本番で少人数の実ゲームを完走する
カテゴリ: verify
正規ID: bingo-service/p5-05-prod-smoke-game
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L70 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-05-prod-smoke-game- anchor
- anchor_missing
✅ 完了工程 p5-06-prod-capacity-evidence本番で負荷試験または同等の容量証拠を確認する
カテゴリ: verify
正規ID: bingo-service/p5-06-prod-capacity-evidence
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L71 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-06-prod-capacity-evidence- anchor
- anchor_missing
✅ 完了工程 p5-07-prod-payment-smoke決済採用時は本番決済smoke、無料β時は非採用scope証拠を記録する
カテゴリ: verify
正規ID: bingo-service/p5-07-prod-payment-smoke
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
作業記録
現行2026-08-07: Stripeを決済事実の正本とし、D1をAPI量・遅延削減用の認可投影とする方式へ切替。commit a65790c467f48524145531b7837167fb8b473913を本番3サービスへ配備しhealth/ready/公開料金ページsmoke成功。Checkout完了時の直接照合、署名Webhook重複排除・現在状態投影、解約直後反映を実装。通常の課金表示・ゲーム作成・開始はD1だけを読む。定期照合・手動再確認はなし。実¥100支払と本番PayPay表示は未実施のため、このToDoはactiveのまま。証拠: docs/evidence/stripe-local-projection-cutover-2026-08-07.md
来歴: rev-277b36089ee9055cda4ea084/p5-07-prod-payment-smoke・記録者 codex-desktop/belle-root
現行課金利用可否をD1資格コピーからStripe現在値の毎回照会へ変更。課金画面・有料ゲーム作成・開始直前でCheckout/Subscriptionを直接確認し、24時間・支払済みInvoice・返金・429 fail-closedを検証。focused 75、Playwright 3、full regression 739、tsc/build成功。実Stripe APIの展開付きGETは本番secretで両方200。実100円決済とPayPay実表示は未実施のためtaskはactiveのまま。証拠: docs/evidence/stripe-live-authority-predeploy-2026-08-07.md
来歴: rev-277b36089ee9055cda4ea084/p5-07-prod-payment-smoke・記録者 local/codex-root
現行全購入の安定ログイン本人ID切替を本番受理した。配備SHA 12e923a39b354b4ad84d0a3d86a001444e4eac5b。料金表は公開、全購入と契約管理は人間のCloudflare Access account必須とし、guest/host Cookieとservice identityを拒否する。選択プランは同一タブでログイン後に一度だけ復元する。関連71 test、料金E2E 3件、lint/build、独立反証、health/ready、3 container、匿名billing API 3経路401、旧guest paid/資格/subscription 0件を確認した。実際の100円支払いによるWebhook・資格発行とPayPay実表示は未実施のため本ToDoはactiveのまま維持する。証跡: docs/evidence/billing-stable-login-cutover-2026-08-07.md、Decision: docs/adr/0019-billing-stable-login-cutover-acceptance.md。
来歴: rev-277b36089ee9055cda4ea084/p5-07-prod-payment-smoke・記録者 codex/root
現行全購入を安定したCloudflare Access本人IDへ結び付ける切替を同一ToDoへ統合する。料金表は公開のまま、全購入でログイン必須、選択プランは同一タブでログイン後に復元する。guest Cookieと主催者Cookieはbilling認可に使わない。既存guest注文はpending 7件、資格・Subscription 0件。focused test、独立反証、push、本番配備、匿名API拒否smokeまで親が直列実行し、実課金smokeは別途未完のまま維持する。Decision: docs/adr/0018-billing-requires-stable-login.md。
来歴: rev-277b36089ee9055cda4ea084/p5-07-prod-payment-smoke・記録者 codex/root
現行Stripe固定商品カタログ切替を本番受理した。配備SHA 108408aef267bb7284dda14242f770126819d2b4。5 Product・18 Price全件、関連11 test、lint/build、料金E2E、health/ready、3 container、未払いCheckoutのProduct/Price/lookup_key一致を確認し、Sessionはexpired/unpaidへ清掃した。実際の100円支払いによるWebhook・資格発行とPayPay実表示は未実施のため、本ToDoはactiveのまま維持する。証跡: docs/evidence/stripe-product-catalog-cutover-2026-08-07.md、Decision: docs/adr/0017-stripe-product-catalog-cutover-acceptance.md。
来歴: rev-277b36089ee9055cda4ea084/p5-07-prod-payment-smoke・記録者 codex/root
現行Stripe商品カタログ移行を本ToDoへ統合する。4人数枠Product×24時間・30日・365日Priceと、24時間差額アップグレードProduct×6 Priceを版付きlookup_keyで作成する。CheckoutはPrice ID指定へ移行し、Webhook・利用権・返金・期間末解約を維持する。実決済・AuctionBOT変更・料金期間変更は対象外。focused test、lint、build、push、rollback保全、本番配備、無課金Checkout生成、Stripe再読込で受け入れる。同一repoとStripeカタログが密結合するため親が直列実行し、並行writerは使わない。
来歴: rev-277b36089ee9055cda4ea084/p5-07-prod-payment-smoke・記録者 codex/root
note head: 0cec4ae3b9b7d06355baef7dc9f29fcb3159ef3659163918cbc5fc0bf80c47ed
元plan: .lattice/todo/source-ledger/bingo-service-v2-cutover.md#L72 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-07-prod-payment-smoke- anchor
- anchor_missing
✅ 完了工程 p5-08-retention-deletion30日保持・期限切れ自動削除・削除依頼の実行経路を実装して検証する
カテゴリ: implement
正規ID: bingo-service/p5-08-retention-deletion
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/launch-handoff-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-08-retention-deletion- anchor
- anchor_missing
✅ 完了工程 p5-09-backup-restore-drillバックアップを隔離環境へ復元し、完全性とRPO/RTOを検証する
カテゴリ: verify
正規ID: bingo-service/p5-09-backup-restore-drill
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/launch-handoff-cutover.md#L7 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-09-backup-restore-drill- anchor
- anchor_missing
✅ 完了工程 p5-10-final-release-deployオーナー承認後、最終feature SHAを本番へ一度だけ配備してrollbackまで確認する
カテゴリ: owner
正規ID: bingo-service/p5-10-final-release-deploy
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/launch-handoff-cutover.md#L8 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-10-final-release-deploy- anchor
- anchor_missing
✅ 完了工程 p5-11-prod-worker-runtime本番containerをWorkers binding供給runtimeへ是正し、公開経路のAPI疎通を証拠化する
カテゴリ: implement
正規ID: bingo-service/p5-11-prod-worker-runtime
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/prod-runtime-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-11-prod-worker-runtime- anchor
- anchor_missing
✅ 完了工程 p5-12-realtime-cursor-defect参加者socketがEVENT_CURSOR_AHEADで拒否される欠陥を直し、ブラウザE2Eの完走を回復する
カテゴリ: implement
正規ID: bingo-service/p5-12-realtime-cursor-defect
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/realtime-cursor-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-12-realtime-cursor-defect- anchor
- anchor_missing
✅ 完了工程 p5-14-unified-bgm-header-design共通BGMヘッダー設計を敵対的検証し、音声所有権と公開ページ範囲を確定する
カテゴリ: design
正規ID: bingo-service/p5-14-unified-bgm-header-design
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/unified-bgm-header-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-14-unified-bgm-header-design- anchor
- anchor_missing
✅ 完了工程 p5-15-unified-bgm-header-implementation共通BGMヘッダー、実周波数ビジュアライザー、曲名出典リンクを実装しブラウザ受入する
カテゴリ: impl
正規ID: bingo-service/p5-15-unified-bgm-header-implementation
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/unified-bgm-header-cutover.md#L7 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-15-unified-bgm-header-implementation- anchor
- anchor_missing
✅ 完了工程 p5-16-live-game-ux-remediation実ゲーム相当の体験抽選、開始前カード交換、横長参加画面を一体で実装し、実ブラウザ受入する
カテゴリ: impl
正規ID: bingo-service/p5-16-live-game-ux-remediation
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/live-game-ux-cutover-v2.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-16-live-game-ux-remediation- anchor
- anchor_missing
✅ 完了工程 p5-17-host-game-deletion-ui主催者ゲーム削除UIを正規削除APIへ接続し、残置smokeゲームを本番で削除する
カテゴリ: impl
正規ID: bingo-service/p5-17-host-game-deletion-ui
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/host-game-deletion-ui-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-17-host-game-deletion-ui- anchor
- anchor_missing
✅ 完了工程 p5-18-presentation-ux-polishPC参加画面の空白を解消し、ビンゴ・脱落演出とトップ体験導線を磨く
カテゴリ: impl
正規ID: bingo-service/p5-18-presentation-ux-polish
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/presentation-ux-polish-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-18-presentation-ux-polish- anchor
- anchor_missing
✅ 完了工程 p5-19-host-console-ux-redesign主催者コンソールを状態と使用頻度で再構成し、景品設定と運営導線を実ブラウザ受入する
カテゴリ: impl
正規ID: bingo-service/p5-19-host-console-ux-redesign
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
元plan: .lattice/todo/source-ledger/host-console-ux-redesign-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p5-19-host-console-ux-redesign- anchor
- anchor_missing
✅ 完了工程 p6-01-billing-contract24時間枠、1時間猶予、購入・アップグレード・返金契約を正本化する
カテゴリ: design
正規ID: bingo-service/p6-01-billing-contract
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
後続工程
元plan: .lattice/todo/source-ledger/stripe-billing-cutover.md#L8 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p6-01-billing-contract- anchor
- anchor_missing
✅ 完了工程 p6-02-stripe-entitlementsStripe Checkout、署名Webhook、冪等な利用権台帳を実装する
カテゴリ: impl
正規ID: bingo-service/p6-02-stripe-entitlements
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/stripe-billing-cutover.md#L9 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p6-02-stripe-entitlements- anchor
- anchor_missing
✅ 完了工程 p6-03-game-expiry-enforcement作り置き禁止、新規参加締切、1時間後の通常終了をゲーム正本で強制する
カテゴリ: impl
正規ID: bingo-service/p6-03-game-expiry-enforcement
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/stripe-billing-cutover.md#L10 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p6-03-game-expiry-enforcement- anchor
- anchor_missing
✅ 完了工程 p6-04-billing-ui-legal料金購入UI、利用規約、プライバシー表示を課金契約へ合わせる
カテゴリ: impl
正規ID: bingo-service/p6-04-billing-ui-legal
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
元plan: .lattice/todo/source-ledger/stripe-billing-cutover.md#L11 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p6-04-billing-ui-legal- anchor
- anchor_missing
✅ 完了工程 p6-05-test-mode-checkoutStripe test modeでカード・walletとWebhook付与を通し確認する
カテゴリ: verify
正規ID: bingo-service/p6-05-test-mode-checkout
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
前提工程
後続工程
作業記録
現行2026-08-08: オーナー承認により、Google Pay実機表示は端末・ブラウザ・Wallet適格性に依存する本番wallet受入としてp6-06へ移管する。p6-05は全12プランE2E、実Stripe test Webhook→D1投影、Apple Pay実表示、PayPay test表示を証拠として受理する。受理正本: docs/adr/0024-phase-6-test-checkout-acceptance.md
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-05-test-mode-checkout・記録者 codex-desktop/root
現行2026-08-08: Stripe test Checkoutをテストカードで完了し、checkout.session.completed実配送→/api/stripe/webhook 200→D1注文paid→利用権active→billing status 100人枠まで確認。Apple Payはin-app BrowserとmacOS Chromeで表示、PayPayも買い切りtest Checkoutに表示。証拠: docs/evidence/stripe-test-webhook-delivery-2026-08-08.md。残りはGoogle Pay適格端末・Google Wallet設定済み環境での実表示だけ。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-05-test-mode-checkout・記録者 codex-desktop/root
現行2026-08-08工程分離: PayPayの表示・決済確認はp6-07-paypay-live-followupへ移管。本ToDoはカード・Apple Pay・Google PayとWebhook付与だけを所有する。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-05-test-mode-checkout・記録者 codex-desktop/root
現行2026-08-08: KITE BINGO test mode(acct_1U1EzY55aH9JpMa5)で全12料金プランE2Eを実行し、12/12成功。実Stripe test APIで24時間4件のPaymentIntent/Charge、月額・年額8件のSubscription/paid Invoiceを作成し、D1利用権投影後に全12ゲームの作成上限・開始・抽選・終了を確認。24時間4枠は100/300/500/1000人ちょうどと+1人拒否を確認。Checkoutは12件すべてexpired/unpaid、Subscriptionは8件すべてcanceled、livemode=false。証跡: outputs/stripe-all-plans-e2e.json、設計: docs/testing/stripe-all-plans-e2e-2026-08-07.md。Stripe公式上Checkout画面は自動テスト防止対象のためAPIシミュレーションへ分離。PayPayは24時間Checkout Sessionのpayment_method_types存在まで、wallet端末表示と実Webhook配送は未確認なのでp6-05はactiveのまま。
来歴: rev-277b36089ee9055cda4ea084/p6-05-test-mode-checkout・記録者 codex-desktop/root
現行オーナー承認によりStripe test mode限定の全12プランE2Eを開始。sk_test_必須・livemode=false必須・live拒否を実装し、各プランのCheckout→D1利用権→上限ゲーム作成→開始/抽選/終了、24時間4枠の上限+1拒否を受入条件とする。BingoアカウントのCLI再認証待ち。
来歴: rev-277b36089ee9055cda4ea084/p6-05-test-mode-checkout・記録者 codex-desktop/belle-root
note head: 346049013d1466117d2d741e3671593257a53ee5855fa8f11f6fccac2f1bbb9e
元plan: .lattice/todo/source-ledger/paypay-followup-cutover.md#L6 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p6-05-test-mode-checkout- anchor
- anchor_missing
✅ 完了工程 p6-06-live-activation-release法定表示とStripe本番設定を承認後に確定し、カード・walletの本番決済smokeまで完了する
カテゴリ: release
正規ID: bingo-service/p6-06-live-activation-release
前提工程
後続工程
作業記録
現行2026-08-08受入訂正: 開始時note sequence 15で追加した『Google Pay適格端末での実表示』は、正式ToDoの『カード・walletの本番決済smoke』より強い条件だった。Apple Payの実表示・100円実決済でwallet smokeは成立。Stripe live Payment Method Configuration pmc_1U1F0455aH9JpMa5KQA7mdpuはcard/Apple Pay/Google Payがすべてavailable=true・preference on。Google Payの表示は適格端末・対応browser・Wallet設定に依存するため、実機表示を本工程の阻害条件から外し、本番有効化を受理する。オーナーは同日サービスインを裁定。PayPayはavailable=falseのためp6-07だけに残す。受入ADRはdocs/adr/0025-phase-6-live-activation-acceptance.md。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-06-live-activation-release・記録者 codex-desktop/root
現行2026-08-08 本番Apple Pay 100円smokeをオーナー本人の試験精算としてStripe Dashboardから全額返金。refund=re_3U23cW55aH9JpMa50ODRNoa9 succeeded、charge ch_3U23cW55aH9JpMa502PymNdJ refunded=true/amount_refunded=100、理由=requested_by_customer。Webhook evt_3U23cW55aH9JpMa509FAERWV (charge.refunded) を本番が処理し、order_e0c7ae56-9abc-4631-a317-f41287bcae7f と ent_order_e0c7ae56-9abc-4631-a317-f41287bcae7f は refunded。料金画面も有効枠なし・無料30人へ復帰。これは一般ユーザー向け自動返金ではなく、運営判断による本番試験精算。公開中の規約・特商表示は利用者都合の原則返金不可、期間末解約、重複請求/サービス障害のみ返金対象で裁定と一致。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-06-live-activation-release・記録者 codex-desktop/root
現行2026-08-08 live smoke成功: Chromeから100人24時間100円をApple Payで実決済。Checkout cs_live_a1eb5...=complete/paid、PaymentIntent pi_3U23cW55aH9JpMa50YD3rjbK=succeeded、Charge ch_3U23cW55aH9JpMa502PymNdJ=paid・wallet apple_pay。Webhook evt_1U23cY55aH9JpMa5juWMwSfZを本番D1が受理し、order_e0c7ae56-9abc-4631-a317-f41287bcae7f=paid、100人利用権が2026-08-09 06:20:37 UTCまでactive。料金画面も最大100人を表示。本番ゲーム5242ba32-4194-4d15-ab88-276c20c11126をparticipant_limit=100・当該entitlement紐付けで作成成功。全額返金は不可逆なH操作のためオーナー承認待ち。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-06-live-activation-release・記録者 codex-desktop/root
現行2026-08-08 preflight: Stripe live acct_1U1EzY55aH9JpMa5はcharges/payouts/details有効、card_payments active、PayPay pending。live Webhook endpointは有効かつ7イベント設定済み。12本番Priceと差額6Priceは金額・周期一致。公開の料金/特商法/規約/Privacy/Contactとトップ導線を実表示確認。production container healthy/restart 0、live key/whsec注入、D1 migration 0008・課金投影table確認。100人24時間100円のlive Checkout cs_live_a157... を作成し、商品・金額・特商法リンク・card/Apple Pay設定を確認。Google Payはautoだが現Apple環境では非表示。実課金の支払う操作でH停止中。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-06-live-activation-release・記録者 codex-desktop/root
現行2026-08-08開始: p6-06はカード・Apple Pay・Google Payの本番開通を所有する。Google Payは適格端末での実表示を本工程で確認する。PayPay本番開通はp6-07へ分離済みで、本工程・サービスインを阻害しない。課金を伴わないlive設定・法定表示・Webhook経路監査を先行し、最小100円の実課金確定操作はH停止点としてオーナーへ引き渡す。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-06-live-activation-release・記録者 codex-desktop/root
現行2026-08-08工程分離: 本ToDoはカード・Apple Pay・Google Payの本番開通のみを所有する。PayPayの実表示・決済smokeはp6-07-paypay-live-followupへ移管し、PayPay審査待ちは本ToDoの完了を阻害しない。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-06-live-activation-release・記録者 codex-desktop/root
現行2026-08-08台帳監査: 現行の本番決済smokeは本ToDoだけが所有する。p5-07はPhase 5無料β公開時の非採用scope証拠で完了へ戻し、重複管理を解消した。開始条件はp6-05完了後。残作業は法定表示・Stripe本番設定の最終確認、オーナーによる実課金直前承認、最小額の本番決済、実Webhook・利用権・ゲーム作成確認、必要な取消/返金、PayPay実表示確認。
来歴: rev-277b36089ee9055cda4ea084/p6-06-live-activation-release・記録者 codex-desktop/root
note head: f7a465a8edddd3d222285e568b306ea287b083ecbd5adb871c4f68c8106ca180
元plan: .lattice/todo/source-ledger/paypay-followup-cutover.md#L7 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p6-06-live-activation-release- anchor
- anchor_missing
☐ 未着手工程 p6-07-paypay-live-followupPayPay承認後、買い切りCheckoutの実表示と本番決済smokeを完了する
カテゴリ: verify
正規ID: bingo-service/p6-07-paypay-live-followup
ready frontierの一員です。現在の唯一の着手候補です。
並列可否: 未検査です。競合が無いのではなく、まだ判定していません。このplanには独立性の記録がまだありません。宣言を書いて lattice todo independence compile --plan bingo-service --input <ref> を通すと判定できます。
前提工程
作業記録
現行2026-08-08分離時点でStripe live capability paypay_payments=pending。p6-06-live-activation-release完了後、Stripe承認を待って買い切りCheckoutの実表示と本番決済smokeを確認する。サブスクリプションはPayPay対象外。
来歴: rev-1c0fcd5a08ae8aab8fbbb16f/p6-07-paypay-live-followup・記録者 codex-desktop/root
note head: 296a101cbf3ed5fce0caede20e11ee18d6486cea10a17c24f1b42572071adcfc
元plan: .lattice/todo/source-ledger/paypay-followup-cutover.md#L8 — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-service/p6-07-paypay-live-followup- anchor
- anchor_missing
✅ 完了工程 social-card-releaseX・Open Graphの大画像カードを実装して本番配備する
カテゴリ: implementation
正規ID: bingo-social-card/social-card-release
登録済みの前提工程はありません。図だけではdispatch可否を判定しません。
完走済みのため既定の図には描いていません。左上の「完走済み」バッジを押すと、このページ内で表示できます。
設計メモ
公開トップへcanonical、Open Graph website、Twitter summary_large_imageを絶対URLで設定する。黒・金・カジノ調の1200×630 SVG原稿と配信用PNGを追加し、focused test、lint、build、独立監査、本番3サービスの同一SHA配備、Twitterbotによる公開後smokeを受入証跡に含める。
元plan: docs/social-card-plan.md — 行対応を確認できないため、本文位置との対応は表示していません
開発者向け診断
- canonical ref
bingo/bingo-social-card/social-card-release- anchor
- anchor_missing