← 一覧に戻る

pocket-museum

GitHub ↗ Python 最終push: 2026/8/18 21:27

WIP(現在進行中)

Work In Progress

このプロジェクトで現在進行中の作業と、過去のスナップショットを記録する。

現在の状況

今どこまで進んだか:

  • 特集公開と休眠復帰のお知らせ通知を iOS に実装(2026-08-18): ローカル通知のみで完結する設計(FCM・バックグラウンド同期なし)。特集公開=publish_at の現地19:00に1本、休眠復帰=最終起動から 7/21/60 日後の現地19:00に3本(起動のたびに貼り直すデッドマンズスイッチ)。発火は端末の暦の壁時計で組むので深夜に鳴らない。マイに「特集のお知らせ」トグル(既定ON・毎朝リマインダと独立)。文言5キー×9言語は Codex でレビュー済み(指摘5件すべて反映)。詳細は DECISIONS 4件
  • 1.0.3 / build 10 を TestFlight へアップロード済み(2026-08-18): processingState=VALID / internalBuildState=IN_BETA_TESTING で内部テスターがインストール可能。輸出コンプライアンスは自動クリア。まだ実機での確認は未実施
  • iOS 1.0.2 は公開済み(2026-08-18 08:13 JST。jp/us とも 1.0.2)
  • Android は Play 審査中(2026-08-17 23:07 提出。通常7日以内=8/24 前後が目安。キルスイッチ 9/8 に対し余裕あり)
  • YouTube の著作権通知は旧動画由来で実害なし(8/18 切り分け済み)。利用規約ページ・フェルメール特集無料開放・Play 提出物は前スナップショット参照

次に何をするか:

  1. TestFlight 実機で 1.0.3 を確認: マイ画面に「特集のお知らせ」が既定ONで出るか / 毎朝の通知を OFF にしてもお知らせが独立して残るか。通知の発火そのものは日付が先なので待っても鳴らない → 見るなら ⓐ端末の日付を7日進める(進めた後にアプリを開くと貼り直されるので開く前に待つ)ⓑpublish_at 入りコンテンツを本番 CDN へ(通知コードがあるのは build 10 だけなので一般ユーザーには影響しない)
  2. Play 審査結果の確認 → 承認後: 一時的なアプリ名 (unreviewed) の解消・ストアページ確認・実機での製品版動作確認
  3. Android への通知機能の後追い実装(Play 審査の結果が出てから。文言は xcstrings 正本から生成スクリプトで展開できる)
  4. 両OS公開が揃ったら: PR TIMES 骨子 → 9月中旬配信 / Devpost に Google Play URL 追記(〜9/30)
  5. AdMob 開通チェーン(iOS・ストア掲載リンク。アカウント再審査の結果メール待ち)
  6. GA4 定点観測(notification_opened の kind 別が新たに見られる)/ asc-submission-check.mjs に配信国チェック追加(軽作業・持ち越し)

詰まっていること・未決事項:

  • ドイツ語の du / Sie がアプリ全体で割れている: 既存の通知プライマー文言が Sie、別の既存文言が du。Codex の見解は「静かな日常系アプリなら du に統一」。今回追加した5件は du/Sie 中立なので影響なし。既存分の統一は別タスク
  • 配布 export の署名は毎回ひと手間要る: 署名専用キーチェーンに WWDR 中間証明書が無く errSecInternalComponent になる。復旧手順は DEVLOG 2026-08-18 21:07 参照(検索リスト再設定 → WWDR import → set-key-partition-list → export → 検索リストを login のみに戻す)。ナレッジ化は未実施
  • DEBUG のログ出力: refreshNotifications がフォアグラウンドのたびに [PMNotifications] pending: を出す。Release には影響しないが要否は未判断
  • (継承)ASC の MCP 既定キーは別チーム(RAMANU は AuthKey_8M2SWG78S6.p8)/ 同一タイトルの YouTube 動画3本の通知判別 / ASC 審査待ち中編集の制約 / AD_ID 有無のローカル検証は信用しない / Play Console 操作の型 / PR TIMES 支払い・実購入実機・マウリッツハイス Commons 限定・レオナルド帰属精査は前スナップショット参照

過去のWIPアーカイブ

(新しい「現在の状況」を書く前に、古いものをここに追記でアーカイブする。新しいものが上)

2026-08-18 21:07 時点より前のスナップショット(2026-08-18 09:40作成分)

今どこまで進んだか:

  • iOS 1.0.2 が公開済み(2026-08-18 08:13 JST 公開・09:40 確認): jp / us とも version 1.0.2、What's New は9言語の「フェルメール特集を無料開放」。特集の恒久無料開放と一覧の無料公開中バッジがユーザーに届いた状態
  • Android は Play 審査中(2026-08-17 23:07 に19件を送信。通常7日以内・キルスイッチ 9/8 に対し余裕あり)
  • YouTube の著作権ブロック通知は旧動画由来で実害なし(2026-08-18 切り分け済み): 8/18 05:48 の通知は初代 Q62huvtjorg 宛(Studio リンクで確定)。Shipaton/Devpost に載っている現行 oPT_g_lx5v0 は公開・全世界再生OK・Devpost は Submitted 維持。ブロック中は限定公開の旧2本のみで、削除せず放置で確定(DECISIONS 参照)
  • 利用規約ページ新設 / フェルメール特集無料開放 / 8言語レビュー / Play 提出物登録は前スナップショット参照

次に何をするか:

  1. Play 審査結果の確認(通常7日以内。承認されると自動で全世界公開)→ 公開確認後: 一時的なアプリ名 (unreviewed) の解消・ストアページ確認・実機での製品版動作確認
  2. 両OS公開が揃ったら: PR TIMES 骨子 → 9月中旬配信 / Devpost に Google Play URL 追記(〜9/30)
  3. AdMob 開通チェーン(iOS・ストア掲載リンク。アカウント再審査の結果メール待ち)
  4. GA4 定点観測 / asc-submission-check.mjs に配信国チェック追加(軽作業・持ち越し)
  5. 任意の持ち越し: 削除ページへの保持期間明記 / Play 審査リジェクト時は指摘対応

詰まっていること・未決事項:

  • **ASC の MCP 既定キーは別チーム(thomsons)**で Pocket Museum(6792521728)は 404 → iOS のストア公開状態は iTunes Lookup で確認する
  • 同一タイトルの YouTube 動画が3本あるため、今後の著作権通知はメール本文の Studio リンクの動画 ID で宛先を判別する(旧2本宛なら無視でよい)
  • (継承)ASC 審査待ち中編集の制約 / AD_ID 有無のローカル検証は信用しない / Play Console 操作の型 / Publishing API edit 失効 / 実 Chrome ファイル選択の cliclick 経路 / YouTube 新動画サムネ・Devpost ギャラリー旧デザイン / PR TIMES 支払い・実購入実機・マウリッツハイス Commons 限定・レオナルド帰属精査は前スナップショット参照

2026-08-18 09:40 時点より前のスナップショット(2026-08-17 23:15作成分)

今どこまで進んだか:

  • Android 版を Play 審査に提出(2026-08-17 23:07 頃): 製品版リリース 4 (1.0.0)(UI磨き込み5件 + 無料公開中バッジ + Paywall 利用規約リンク入り)・配信国176か国・掲載9言語・全申告の19件を審査送信。「審査中の変更」に遷移済みで、クイックチェック完了後に自動で審査へ(確認タイマー仕込み済み)。審査目安は通常7日以内・キルスイッチ 9/8 に対し約3週間の余裕。直前ブロッカー「広告ID申告不完全」は Firebase Analytics の AD_ID 自動マージが原因と判明し「使用する(分析・広告マーケ)」で解消(DATA_SAFETY.md 訂正済み・DECISIONS 参照)
  • 利用規約ページを新設・公開(2026-08-17): https://ramanu.co.jp/pocket-museum/terms/ (ja/en・company-operation 04733d8)。Android Paywall に利用規約リンク追加(iOS と同じ3リンク並び・iOS は stdeula 維持)。Play 掲載文9言語にも利用規約行を追記して API 再登録済み
  • iOS 1.0.2 は審査提出済み(2026-08-17 20:29・AFTER_APPROVAL): 承認後自動公開・操作不要。詳細は前スナップショット参照
  • フェルメール特集無料開放 / 8言語レビュー / Play 提出物登録は前スナップショット参照

次に何をするか:

  1. Play 審査結果の確認(通常7日以内。承認されると自動で全世界公開 = 管理対象の公開オフのため)→ 公開確認後: 一時的なアプリ名 (unreviewed) の解消・ストアページ確認・実機での製品版動作確認
  2. iOS 1.0.2 の審査結果確認(承認後は自動公開)
  3. 両OS公開が揃ったら: PR TIMES 骨子 → 9月中旬配信 / Devpost に Google Play URL 追記(〜9/30)/ AdMob 開通チェーン(iOS・ストア掲載リンク)
  4. GA4 定点観測 / asc-submission-check.mjs に配信国チェック追加(軽作業・持ち越し)
  5. 任意の持ち越し: 削除ページへの保持期間明記 / Android 審査リジェクト時は指摘対応(プロモコード用意は不要と判断済み)

詰まっていること・未決事項:

  • ASC の審査待ち中編集: releaseType は PATCH 可・whatsNew は取り下げ必要(auto-memory asc-direct-access に記録済み)
  • AD_ID 有無のローカル検証は信用しない: merged_manifests 中間ファイルと Play 側の最終マージ結果が一致しなかった(正は Play の提出前チェック)
  • (継承)Play Console 操作の型 / Publishing API edit 失効 / 実 Chrome ファイル選択の cliclick 経路 / YouTube 新動画サムネ・Devpost ギャラリー旧デザイン / PR TIMES 支払い・実購入実機・マウリッツハイス Commons 限定・レオナルド帰属精査は前スナップショット参照

2026-08-17 23:15 時点より前のスナップショット(2026-08-17 22:02作成分)

今どこまで進んだか:

  • iOS 1.0.2 を審査提出(2026-08-17 20:29): build 9 = 特集一覧の「無料公開中」バッジ。What's New は9言語「フェルメール特集を無料開放いたしました。」。releaseType=AFTER_APPROVAL(承認後自動公開・操作不要)。提出後チェックで課金取りこぼしなし。バージョン更新は d4f8074
  • フェルメール特集を恒久無料開放(2026-08-17): 9言語 access=open + 両OSの一覧カードに無料公開中バッジ実装(Pro 非表示)。R2 反映済みで既存アプリはゲート解除済み。iOS のバッジは 1.0.2 から、Android は次リリースから(929db85
  • 特集8言語の全文レビュー完了(2026-08-17): 訳者と別モデルの Claude 言語別8並列で ja と全文対読 → 高中低74件修正・revision 2 で本番反映(70e7b75)。結果正本は レビュー結果_特集記事8言語全文レビュー.md。今後の月次フローの検収工程に組み込む
  • Shipaton 動画差し替え / Play 提出物登録完了は前スナップショット参照

次に何をするか:

  1. iOS 1.0.2 の審査結果確認(承認後は自動公開。前回実績は提出から1日弱)
  2. Android 製品版リリースの作成 → 審査送信(〜9月上旬提出目標・キルスイッチ 9/8): AAB の版判断が先 — バッジ入り最新 main で versionCode 4 を作るか、実購入E2E 検証済みの versionCode 3 のまま出すか
  3. 提出前判断: Android Paywall の ToS リンク要否 / 審査用 Play プロモコードの用意要否 / 削除ページへの保持期間明記(任意)/ 未検証項目(ピンチ実指・ダブルタップ復帰)
  4. AdMob 開通チェーン(iOS)/ PR TIMES 骨子 / GA4 定点観測(持ち越し)/ asc-submission-check.mjs に配信国チェック追加(軽作業)

詰まっていること・未決事項:

  • ASC の審査待ち中編集: releaseType は PATCH 可・whatsNew は取り下げ必要(auto-memory asc-direct-access に記録済み)
  • (継承)Play Console 操作の型 / Publishing API edit 失効 / 実 Chrome ファイル選択の cliclick 経路 / YouTube 新動画サムネ・Devpost ギャラリー旧デザイン / PR TIMES 支払い・実購入実機・マウリッツハイス Commons 限定・レオナルド帰属精査は前スナップショット参照

2026-08-17 22:02 時点より前のスナップショット(2026-08-17 18:53作成分)

今どこまで進んだか:

  • Shipaton デモ動画の Content ID ブロックを解消(2026-08-17 18:53): Naxos 申し立てで全世界ブロックされた 7BoL3VbVYIQ を限定公開に降格し、BGM を Night Snow(YT オーディオライブラリ・帰属表示不要)に差し替えた新動画 oPT_g_lx5v0 を公開(著作権チェック通過)。Devpost の Video URL も差し替え済みで SUBMITTED / 5/5 steps 維持。App Store プレビュー動画の BGM は現状維持で確定(DECISIONS 2件参照)。動画正本は ~/ichirokisanuki/pocket-museum-video/pocket-museum-daily-art-demo-shipaton2026-v2.mp4
  • Play 提出物の登録完了(2026-08-17 16:18): 掲載9言語 + スクショ + アプリのコンテンツ 9/9 申告 + ストア設定まで完了、「必要なすべての情報を指定しました」を9言語で確認済み。詳細は前スナップショット参照
  • 並行セッション分: フェルメール特集の恒久無料開放 + 一覧の無料公開中バッジ(929db85。詳細はそのセッションの記録へ)
  • iOS 1.0.1 公開済み / Android 実装・実購入E2E・プライバシーポリシー両OS化は前スナップショット参照

次に何をするか:

  1. 製品版リリースの作成 → 審査送信: AAB を製品版トラックへ + 配信国選択 → 公開の概要から「審査のために送信」(〜9月上旬提出目標・キルスイッチ 9/8。残り約3週間)
  2. 提出前判断: Android Paywall の ToS リンク要否 / 審査用 Play プロモコードの用意要否(ログインの詳細で「全機能アクセス可」チェックが必須だったため。手順テキストには fail-open の実態を明記済み)/ 削除ページへの保持期間明記(任意)/ 未検証項目(ピンチ実指・ダブルタップ復帰)
  3. AdMob 開通チェーン(iOS)/ PR TIMES 骨子 / GA4 定点観測(持ち越し)
  4. scripts/asc-submission-check.mjs に配信国チェック追加(軽作業・再発防止)

詰まっていること・未決事項:

  • Play Console 操作の型が確立: テキスト=ref→form_input / チェック類=input.click() / 選択と保存は別ティック / 保存確認は「変更を保存しました」トースト / 連絡先は「保存して公開」→「承認して公開」の2段(詳細は DEVLOG 16:18)。テスター系チップ入力だけは You の実キー必須のまま
  • Publishing API の edit は短時間で失効・commit には「未公開のアプリの編集、削除」権限が必要
  • 実 Chrome のファイル選択は cliclick 経路で確立(ダイアログ表示4秒待ち + frontmost 確認必須。auto-memory youtube-video-swap-ops 参照)
  • YouTube 新動画(oPT_g_lx5v0)のサムネイル既定のまま / Devpost サムネイル・ギャラリー3枚は旧デザイン(保留中)
  • (持ち越し)PR TIMES 支払いは銀行振込のみ / iOS 実購入検証は実機 iPhone 14 / マウリッツハイス画像は Commons 限定 / レオナルド帰属精査

2026-08-17 18:53 時点より前のスナップショット(2026-08-17 16:18作成分)

今どこまで進んだか:

  • Play 提出物の登録が完了(2026-08-17): ストア掲載9言語(テキスト正本 store-assets/play-listing/LISTING.md・広告記述は iOS 同文維持)+ スクショ 9:16 版9ロケール×6枚(store-assets/screenshots/android/)+ feature graphic + アイコン512 を Publishing API で一括登録・commit 済みscripts/play-upload-listing.mjs。SA に「ストアでの表示の管理」「未公開のアプリの編集」権限を追加)。アプリのコンテンツ 9/9 申告完了(レーティング ESRB 13+/PEGI 3・データセーフティ送信・広告はい・対象年齢13+ ほか)。ストアの設定(カテゴリ=教育・連絡先)も公開済み。公開の概要で9言語すべて「必要なすべての情報を指定しました」を確認
  • プライバシーポリシーを両OS対応に改定・デプロイ済み(2026-08-17): Google Play 課金/解約 + データ削除リクエスト章(#data-deletion)を ja/en に追加(company-operation e0db059)。Play のデータセーフティ削除用 URL・プライバシーポリシー URL に設定済み
  • Android 実購入E2E 完了(2026-08-17 06:03): 購入・復元・トライアル表記の3点検証済み。環境は auto-memory android-play-e2e-setup 参照
  • iOS 1.0.1 公開済み / メディア9言語化 / Android 実装・課金チェーンは前スナップショット参照

次に何をするか:

  1. 製品版リリースの作成 → 審査送信: AAB を製品版トラックへ + 配信国選択 → 公開の概要から「審査のために送信」(〜9月上旬提出目標・キルスイッチ 9/8。残り約3週間)
  2. 提出前判断: Android Paywall の ToS リンク要否 / 審査用 Play プロモコードの用意要否(ログインの詳細で「全機能アクセス可」チェックが必須だったため。手順テキストには fail-open の実態を明記済み)/ 削除ページへの保持期間明記(任意)/ 未検証項目(ピンチ実指・ダブルタップ復帰)
  3. AdMob 開通チェーン(iOS)/ PR TIMES 骨子 / GA4 定点観測(持ち越し)
  4. scripts/asc-submission-check.mjs に配信国チェック追加(軽作業・再発防止)

詰まっていること・未決事項:

  • Play Console 操作の型が確立: テキスト=ref→form_input / チェック類=input.click() / 選択と保存は別ティック / 保存確認は「変更を保存しました」トースト / 連絡先は「保存して公開」→「承認して公開」の2段(詳細は DEVLOG 16:18)。テスター系チップ入力だけは You の実キー必須のまま
  • Publishing API の edit は短時間で失効・commit には「未公開のアプリの編集、削除」権限が必要
  • YouTube 新動画・Devpost サムネイル既定のまま / Devpost ギャラリー3枚は旧デザイン(保留中)
  • (持ち越し)PR TIMES 支払いは銀行振込のみ / iOS 実購入検証は実機 iPhone 14 / マウリッツハイス画像は Commons 限定 / レオナルド帰属精査

2026-08-17 16:18 時点より前のスナップショット(2026-08-17 06:03作成分)

今どこまで進んだか:

  • Android 実購入E2E 完了(2026-08-17): Play Console で内部テスター+ライセンステスター登録(ichirokisanuki@gmail.com・リスト名「内部テスター」)→ opt-in → Play Store 入りエミュレータ pm-playstore(Pixel 6・API 35)で 購入・復元・トライアル表記の3点すべて検証。購入はテスト決済(Test card)→ アプリ即時解錠 → RC に entitlement pro 到達。復元は pm clear 後の自動復元(RC Android は明示操作不要)。トライアル→有料の自動更新もテスト時間圧縮(3分/30分)で観測。E2E は英語UIで実施=「en ロケール表示」も実質カバー。環境と落とし穴は auto-memory android-play-e2e-setup と DEVLOG 06:03 参照
  • iOS 1.0.1 は公開済み(2026-08-17 READY_FOR_DISTRIBUTION): 詳細は前スナップショット参照
  • ストア掲載メディア9言語化・Shipaton 動画刷新・Android 実装・課金外部チェーンは前スナップショット参照(変更なし)

次に何をするか:

  1. Play 提出物: ストア掲載9言語 / スクショ(iOS 9言語の流用リサイズ)/ データセーフティ / コンテンツレーティング → 〜9月上旬提出・キルスイッチ 9/8
  2. 提出前判断: Android Paywall の ToS リンク要否 / 残る未検証項目(ピンチ実指・ダブルタップ復帰)
  3. AdMob 開通チェーン(iOS)/ PR TIMES 骨子 / GA4 定点観測(持ち越し)
  4. scripts/asc-submission-check.mjs に配信国チェック追加(軽作業・再発防止)

詰まっていること・未決事項:

  • Play Console のテスター系チップ入力は合成キー不可(CDP/JS とも不発)→ You の実キー入力で確定する運用(招待フォーム制約と同根)
  • YouTube 新動画のサムネイル・Devpost サムネイルは既定のまま / Devpost ギャラリー3枚は旧デザイン(保留中)
  • (持ち越し)Android Paywall の ToS リンク要否 / PR TIMES 支払いは銀行振込のみ / iOS 実購入検証は実機 iPhone 14 / マウリッツハイス画像は Commons 限定 / レオナルド帰属精査

2026-08-17 06:03 時点より前のスナップショット(2026-08-17 02:39作成分)

今どこまで進んだか:

  • iOS 1.0.1 を公開(2026-08-17 READY_FOR_DISTRIBUTION): 審査承認を確認 → 公開前に配信国175か国の維持をチェック(1.0.0 の配信国ゼロ事故の再発なし)→ appStoreVersionReleaseRequests API で手動公開。ストア反映は最大数時間。これで 1.0.1 チェーン(カード撤去 + メディア9言語 → 審査 → 公開)は完結
  • ストア掲載メディアの多言語化は完了済み: スクショ9ロケール×6枚 + プレビュー動画9本を ASC 登録済み。コピー正本は store-assets/screenshots/COPY_REVIEW.mdstore-assets/app-previews/VIDEO_COPY_REVIEW.md
  • Shipaton デモ動画も壁背景版に刷新済み: YouTube 新URL 7BoL3VbVYIQ(旧は限定公開)・Devpost 更新済み。制作一式は ~/ichirokisanuki/pocket-museum-video/(git 外)と store-assets/app-previews/
  • Android 実装・課金外部チェーンは前スナップショット参照(変更なし)

次に何をするか:

  1. Android 内部テスターの設定 → Play Store 入り端末で実購入E2E(持ち越し)
  2. Play 提出物: ストア掲載9言語 / スクショ(iOS 9言語の流用リサイズ)/ データセーフティ / コンテンツレーティング → 〜9月上旬提出・キルスイッチ 9/8
  3. AdMob 開通チェーン(iOS。1.0.1 公開でストア掲載リンクの前提は継続)/ PR TIMES 骨子 / GA4 定点観測(持ち越し)
  4. scripts/asc-submission-check.mjs に配信国チェック追加(軽作業・再発防止)

詰まっていること・未決事項:

  • YouTube 新動画のサムネイルは自動生成のまま(旧動画のカスタムサムネ相当を作るなら make_thumb.py 参照)/ Devpost のサムネイルも既定のまま
  • Devpost のギャラリー画像3枚(store-assets/shipaton/assets/)は旧デザインのまま。「フレームなしスクショ」の必須チェックに抵触しうるため壁背景版への差し替えは保留中
  • (持ち越し)実購入E2E は Play Store 入り端末必須 / Play Console 招待フォームは Claude 側から操作不可 / Android Paywall の ToS リンク要否 / Android 未検証項目(ピンチ実指ほか)/ PR TIMES 支払いは銀行振込のみ / iOS 実購入検証は実機 iPhone 14 / マウリッツハイス画像は Commons 限定 / レオナルド帰属精査

2026-08-17 02:39 時点より前のスナップショット(2026-08-16 08:03作成分)

今どこまで進んだか:

  • iOS 1.0.1 を審査提出(2026-08-16 WAITING_FOR_REVIEW・releaseType=MANUAL)。中身: build 8(コレクションの地域別 acquired/total カード撤去。DECISIONS 参照)+ 新機能テキスト9言語 + ストアスクショ9ロケール×6枚 + App プレビュー動画9ロケール(886x1920・24.5秒)。承認されても自動公開されない → 公開操作が必要
  • ストア掲載メディアの多言語化が完了: スクショは Codex 生成 → Claude 検品でレンダバグ2件(NewYork.ttf ハイフン不描画 / SFNS 15px スペース潰れ)を修正して ASC 登録。プレビュー動画は統一デザイン9本を検証(仕様・デコード・fr/pt ハイフン描画)して登録。コピー正本は store-assets/screenshots/COPY_REVIEW.mdstore-assets/app-previews/VIDEO_COPY_REVIEW.md(レビュー結果込み)
  • Shipaton デモ動画も壁背景版に刷新済み: YouTube 新URL 7BoL3VbVYIQ(旧は限定公開)・Devpost 更新済み。制作一式は ~/ichirokisanuki/pocket-museum-video/(git 外)と store-assets/app-previews/
  • Android 実装・課金外部チェーンは前スナップショット参照(変更なし。今回カード撤去のみ反映済み)

次に何をするか:

  1. 1.0.1 の審査結果確認 → 承認後に手動公開(reviewSubmission cb6ca13d
  2. Android 内部テスターの設定 → Play Store 入り端末で実購入E2E(前スナップショットから持ち越し)
  3. Play 提出物: ストア掲載9言語 / スクショ(iOS 9言語が揃ったので流用リサイズが容易に)/ データセーフティ / コンテンツレーティング → 〜9月上旬提出・キルスイッチ 9/8
  4. AdMob 開通チェーン(iOS)/ PR TIMES 骨子 / GA4 定点観測(持ち越し)

詰まっていること・未決事項:

  • YouTube 新動画のサムネイルは自動生成のまま(旧動画のカスタムサムネ相当を作るなら make_thumb.py 参照)/ Devpost のサムネイルも既定のまま
  • Devpost のギャラリー画像3枚(store-assets/shipaton/assets/)は旧デザインのまま。「フレームなしスクショ」の必須チェックに抵触しうるため壁背景版への差し替えは保留中
  • ASC の 02 スクショ用ラベルは受蔵番号を AIC 正式 1954.326 に統一済み(旧 80607 は API のオブジェクトID だった)
  • (持ち越し)実購入E2E は Play Store 入り端末必須 / Play Console 招待フォームは Claude 側から操作不可 / Android Paywall の ToS リンク要否 / Android 未検証項目(ピンチ実指ほか)/ PR TIMES 支払いは銀行振込のみ / iOS 実購入検証は実機 iPhone 14 / マウリッツハイス画像は Commons 限定 / レオナルド帰属精査

2026-08-16 08:03 時点より前のスナップショット(2026-08-15 18:08作成分)

今どこまで進んだか:

  • Android の課金の外部チェーンが全部つながった(2026-08-15。コード変更なし): Play Console のアプリ作成〜内部テスト公開〜サブスク2種の作成・有効化〜RC への商品登録(前スナップショット参照)に加えて、購入検証の認証情報リアルタイム通知まで開通した
    • 購入検証: 専用SA revenuecat-play@pocket-museum-d060f.iam.gserviceaccount.com を新規作成(Subnote 用SAの流用はせず鍵を分離。DECISIONS 参照)→ Play Android Developer API 有効化 → Play Console でポケット美術館限定のアプリ権限4つ → 鍵を ~/.config/android/pocket-museum-play-sa.json(600・git 外)に発行 → RC にアップロード → validate-app-credentials が3チェックすべて valid
    • リアルタイム通知(RTDN): Pub/Sub API 有効化 + SA に roles/pubsub.admin → トピック projects/pocket-museum-d060f/topics/pocket-museum-play-rtdn 作成 + Google の通知送信元に Publisher → RC「Connect to Google」でサブスクリプション自動生成 → Play Console の収益化のセットアップにトピック名を登録・有効化 → テスト通知が RC に届くところまで実データで確認
  • Android 版の実装はすべて完了(前スナップショット参照。画面・課金・通知・プライマー・Analytics 実ログ検証・オフライン画像・アイコン・共有テストベクタ両OS通過。広告+UMP は後回し枠)
  • 署名済み AAB: cd android && JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" ./gradlew :app:bundleRelease(鍵は ~/.config/android/
  • App Store 公開済み / Shipaton 応募済み / 画像配信・R2 等は前スナップショット参照

次に何をするか:

  1. 内部テスターの設定 → 実購入E2E: メーリングリスト作成 → opt-in リンク → Play Store 入りの端末でインストール → 購入・復元・トライアル表記の確認(テスターはテスト決済扱い)
  2. Play 提出物: ストア掲載9言語 / スクショ(store-assets の iOS 素材流用リサイズ)/ データセーフティ / コンテンツレーティング → 審査提出(〜9月上旬目標・キルスイッチ 9/8)
  3. AdMob 開通チェーン(iOS) / PR TIMES 骨子(9月中旬両OS配信目標)/ GA4 定点観測ほか(前スナップショット参照)
  4. (後回し枠)Android の広告+UMP / 自前 ToS ページの要否判断

詰まっていること・未決事項:

  • 実購入E2E には Play Store 入りの端末が必要(kowai16k は Google APIs イメージなので BILLING_UNAVAILABLE のまま)
  • Play Console の権限は API 反映まで数分かかる。RC の検証が insufficient permissions で落ちても権限不足とは限らず、SA 自身で Purchases API をダミートークンで叩いて 400 Invalid Value なら権限OK / 401・403 なら不足で切り分ける
  • Play Console のユーザー招待フォームは Claude 側から入力・送信できない(アクセス権付与にあたるため権限判定でブロック)。値を pbcopy で用意して You に渡す運用
  • Play Console のアプリ作成フォームは「パッケージ名使用済み」の一過性誤判定がある(再試行で通る・既知)
  • Android Paywall に「利用規約」リンクなし(自前 ToS ページを作るか Play 提出前に判断)
  • Android 未検証: ズームのピンチ実指 / ダブルタップでフィット復帰 / en ロケール表示(エミュレータ手動で)
  • エミュレータの DB は検証用の擬似獲得14件入り・システムロケール ja-JP(ともに意図的)
  • Devpost の Growth Fund チェック未確認 / サムネイル既定の青のまま / PR TIMES 支払いは銀行振込のみ / スクショ残7ロケール
  • (従来から継続の未決)iOS 課金の実購入検証は実機 iPhone 14 / 買い切り再検討は実測後 / マウリッツハイス画像は Commons 限定 / レオナルド帰属は Fable チェック時に精査 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-08-15 18:08 時点より前のスナップショット(2026-08-15 16:00作成分)

今どこまで進んだか:

  • Play Console が開通し課金チェーンの配線が完成(2026-08-15。コード変更なし): アプリ「ポケット美術館」作成(package jp.co.ramanu.pocketmuseum・ja-JP・無料)→ 内部テストリリース 1 (1.0.0) 公開(署名済み AAB・Play App Signing 有効・審査不要)→ サブスク2種を作成・有効化pm_pro_monthly=monthly ¥300 / pm_pro_yearly=yearly ¥1,500+free-trial 7日無料・新規のみ。177地域一括換算。2本立て構造は DECISIONS 参照)→ RC に Play 商品登録・entitlement pro / offering default アタッチ完了。アプリの offerings エラーが構成エラー→ BILLING_UNAVAILABLE(エミュレータに Play が無いだけ)に変化 = 配線完了を確認
  • Android 版の実装はすべて完了(前スナップショット参照。画面・課金・通知・プライマー・Analytics 実ログ検証・オフライン画像・アイコン・共有テストベクタ両OS通過。広告+UMP は後回し枠)
  • 署名済み AAB: cd android && JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" ./gradlew :app:bundleRelease(鍵は ~/.config/android/
  • App Store 公開済み / Shipaton 応募済み / 画像配信・R2 等は前スナップショット参照

次に何をするか:

  1. RC の Play サービスアカウント認証情報(実購入検証に必須): Cloud Console でサービスアカウント作成 → Play Console「ユーザーと権限」で招待(財務データ閲覧+アプリ権限)→ RC ダッシュボードに JSON アップロード → validate-app-credentials で確認
  2. 内部テスターの設定 → 実購入E2E: メールリスト作成 → opt-in リンク → Play Store 入りの実機/エミュレータでインストール → 購入・復元・トライアル表記の確認(テスターはテスト決済扱い)
  3. Play 提出物: ストア掲載9言語 / スクショ(store-assets の iOS 素材流用リサイズ)/ データセーフティ / コンテンツレーティング → 審査提出(〜9月上旬目標・キルスイッチ 9/8)
  4. AdMob 開通チェーン(iOS) / PR TIMES 骨子(9月中旬両OS配信目標)/ GA4 定点観測ほか(前スナップショット参照)
  5. (後回し枠)Android の広告+UMP / 自前 ToS ページの要否判断

詰まっていること・未決事項:

  • Play の実購入E2Eは RC のサービスアカウント認証情報が無いと検証で落ちる(上記1が先)。購入テスト端末も Play Store 入りが必要(kowai16k は Google APIs イメージで BILLING_UNAVAILABLE)
  • Play Console のアプリ作成フォームは「パッケージ名使用済み」の一過性誤判定がある(再試行で通る・既知)
  • Android Paywall に「利用規約」リンクなし(自前 ToS ページを作るか Play 提出前に判断)
  • Android 未検証: ズームのピンチ実指 / ダブルタップでフィット復帰 / en ロケール表示(エミュレータ手動で)
  • エミュレータの DB は検証用の擬似獲得14件入り・システムロケール ja-JP(ともに意図的)
  • Devpost の Growth Fund チェック未確認 / サムネイル既定の青のまま / PR TIMES 支払いは銀行振込のみ / スクショ残7ロケール
  • (従来から継続の未決)iOS 課金の実購入検証は実機 iPhone 14 / 買い切り再検討は実測後 / マウリッツハイス画像は Commons 限定 / レオナルド帰属は Fable チェック時に精査 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-08-15 16:00 時点より前のスナップショット(2026-08-15 08:04作成分)

今どこまで進んだか:

  • Android 版の実装がすべて完了(2026-08-15。後回し枠の広告+UMP を除く): 画面移植(c459b63)→ 課金(ba9367f)→ 通知・アイコン・署名AAB・今日の1枚本格化(0eb5b8d)→ Analytics(2c63244)→ オフライン画像(e68460b)→ 通知プライマー+共有テストベクタ(0a9db7c。各機能ともエミュレータE2E検証済み(Analytics は実ログ・オフラインは機内モード・プライマーは全ステップ・テストベクタは両OS240ケース通過)
  • 計測が両OS合流状態で本稼働: google-services.json 配置済み。イベント正本 docs/analytics-events.md 準拠・RC への App Instance ID 連携込み
  • 署名済み AAB がビルド可能: 鍵は git 外 ~/.config/android/。Play Console にアプリを作れば即アップロード可能
  • RC の Play 側: アプリ appebb22cf191goog_ キー配線済み・entitlement pro 共有。残るは Play Console 商品作成 → RC 登録のみ
  • 正本データによる両OS整合が完成: ① 文言 xcstrings ② Analytics イベント md ③ 抽選テストベクタ。iOS にテストターゲット PocketMuseumTests を新設

次に何をするか: 1. Play Console にアプリ作成 → AAB → サブスク作成 → RC 登録 → サービスアカウント → 実購入E2E 2. Play 提出物 3. AdMob 開通チェーン(iOS) 4. PR TIMES 骨子 5. 広告+UMP / ToS 要否(後回し枠)

詰まっていること・未決事項: Play Console アプリ作成は手作業 / Paywall に利用規約リンクなし / ピンチ実指・ダブルタップ復帰・en 未検証 / エミュレータは擬似獲得14件+ja-JP(意図的)/ Devpost・PR TIMES・スクショ残・従来の未決は変わらず

2026-08-15 08:04 時点より前のスナップショット(2026-08-15 07:20作成分)

今どこまで進んだか:

  • Android 版はストア提出に必要な機能がほぼ揃った(2026-08-15): 画面移植(4画面+ズーム c459b63)→ 課金(RC Play アプリ + PurchaseProvider + Paywall ba9367f)→ 通知・アダプティブアイコン・リリース署名 + 今日の1枚本格化(0eb5b8d まで完了。エミュレータでロック状態のゲート表示・フェイルオープン開放(広告CTA→fallback チケット→全文+注記)・通知の実配達まで E2E 検証済み
  • 署名済み AAB がビルド可能: アップロード鍵は git 外 ~/.config/android/pocket-museum-upload.keystore(properties 同所・build.gradle は無いマシンで未署名フォールバック)。./gradlew :app:bundleReleaseapp/build/outputs/bundle/release/app-release.aabPlay Console にアプリを作れば即アップロード可能
  • RC の Play 側: アプリ appebb22cf191・公開キー goog_ 配線済み・entitlement pro は iOS と共有。残るは Play Console 側の商品作成 → RC 商品登録のみ
  • Android 土台 / App Store 公開済み / Shipaton 応募済みは前スナップショット参照
  • (変化なし)画像配信高速化 / TestFlight 内部テスト / 本番R2 1,200点版 / support@ / PR TIMES 企業登録済み・本体未着手

次に何をするか:

  1. Play Console にアプリ作成(You の手作業・API 不可) → AAB → サブスク作成 → RC 商品登録 → 実購入E2E
  2. Android 残実装: Analytics 送信 / オフライン画像保存 / 通知プライマー / 共有テストベクタ(広告+UMP は後回し枠)
  3. Play 提出物 4. AdMob 開通チェーン(iOS) 5. PR TIMES 骨子ほか

詰まっていること・未決事項:

  • Play Console のアプリ作成は手作業 / Paywall に利用規約リンクなし / ピンチ実指・ダブルタップ復帰・en ロケール未検証 / エミュレータは擬似獲得14件+ja-JP(意図的)/ Devpost・PR TIMES・スクショ残・従来の未決は変わらず

2026-08-15 07:20 時点より前のスナップショット(2026-08-15 06:44作成分)

今どこまで進んだか:

  • Android 画面移植が完了(2026-08-15 c459b63: コレクション(地域別進捗・訪問の記録)・作品詳細(額装・解説ゲート・お気に入り・シェア・誤訳報告・メタデータ)・特集(一覧+記事+ロック帯)・マイ(お気に入り)+ 全画面ズームビューア(ピンチ・ダブルタップ・スワイプ閉じ)を iOS 正本から移植。骨格はタブごと NavHost + SaveableStateHolder(タブ切替後もスタック保持)、ズームはルート直上オーバーレイ。エミュレータ(ja)で全画面の動作確認済み。解説ゲートは広告SDK未導入のためフェイルオープン(当日獲得分のみ fallback チケット・過去分は再試行案内)
  • Android 課金の実装が完了(2026-08-15 ba9367f: RC に Play アプリ「Pocket Museum (Play Store)」(appebb22cf191)作成 → 公開キー goog_nBblHhdeVDuvFDIJMCMcKxciFHq を build.gradle に配線。purchases-android 10.16.2 / PurchaseProvider 境界 + PaywallSheet 移植 / isPro は購読ストリーム連動(変化でゲート即再評価)。entitlement pro は iOS と共有。RC バックエンド通信は開通済みで、offerings エラーは「Play 商品未登録」のみ = Paywall はグレースフルに再試行表示(想定どおり)
  • Android 土台(前スナップショット参照): Kotlin + Compose 単体 / targetSdk 36 / データ層移植済み / 文言は xcstrings → strings_generated.xml 生成(9言語・ドリフト検知)
  • App Store 公開済み・初インストール発生 / Shipaton 応募完了(〜10/1 編集可)は前々スナップショット参照
  • (変化なし)画像配信高速化 / TestFlight 内部テスト / 本番R2 1,200点版 / support@ / PR TIMES 企業登録済み・本体未着手

次に何をするか:

  1. Play Console にアプリ作成(You の手作業・API 不可) → AAB 内部テストにアップロード → サブスク作成 → RC に Play 商品登録・アタッチ → サービスアカウント認証情報 → 実購入E2E
  2. Android 残実装: 通知 / Analytics 送信 / オフライン画像保存 / アダプティブアイコン / 抽選ロジックの共有テストベクタ
  3. AdMob 開通チェーン(iOS) 4. PR TIMES 骨子 5. GA4 定点観測ほか

詰まっていること・未決事項:

  • Play Console のアプリ作成は API 不可の手作業 / Android Paywall に利用規約リンクなし / Android 未実装: 通知・オフライン画像・Analytics・広告+UMP・アダプティブアイコン / ズームのピンチ実指・ダブルタップ復帰・en ロケール未検証 / エミュレータのロケール ja-JP のまま / Devpost・PR TIMES・スクショ残・従来の未決は変わらず

2026-08-15 06:44 時点より前のスナップショット(2026-08-15 05:54作成分)

今どこまで進んだか:

  • Android 版の開発に着手(2026-08-15): 技術選定 = Kotlin + Jetpack Compose 単体で確定(KMP 不採用・DECISIONS 参照)。android/ に土台を新規作成(AGP 8.11.1 / Kotlin 2.2.0 / Room / Coil / targetSdk 36=9月提出の Play 要件 / applicationId は iOS と同一 jp.co.ramanu.pocketmuseum)。データ層(SyncEngine・DeckEngine・StoryGate・Room スキーマ)を iOS から移植し、エミュレータ(AVD kowai16k = Pixel 6・API 35)で本番CDN同期 → seed抽選 → 今日の1枚表示 → ウェルカム特典の解説全文まで動作確認済み(en/ja 両ロケール)。ビルドは cd android && JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" ./gradlew :app:assembleDebug
  • 両OS整合の仕組み(DECISIONS「正本データで担保」参照): ① 文言 = xcstrings 正本 → scripts/xcstrings_to_android.py + 対応表 android/l10n/xcstrings-map.json で生成(128キー×9言語・過不足はエラー停止のドリフト検知)② Analytics = docs/analytics-events.md 正本(16イベント・dedupe 規則まで明文化)③ 抽選ロジックの共有テストベクタは Android テスト整備時に
  • App Store 公開済み・初インストール発生 / Shipaton 応募完了(〜10/1 編集可・素材は store-assets/shipaton/)は前スナップショット参照
  • (変化なし)画像配信高速化 / TestFlight 内部テスト / 本番R2 1,200点版 / support@ / PR TIMES 企業登録済み・本体未着手

次に何をするか:

  1. Android 画面移植の続き: コレクション・作品詳細(ズーム含む)・特集・マイ。文言は生成済み strings_generated.xml を使う
  2. Android 課金: RevenueCat プロジェクトに Play アプリ追加 → goog_ 公開キー取得・配線 → PurchaseProvider + Paywall 移植(entitlement pro は iOS と共有)
  3. AdMob 開通チェーン(iOS): 再審査結果の確認 → ストア掲載リンク設定 → 広告のアプリ審査 → 配信開始確認
  4. PR TIMES プレスリリース骨子(promo-expert 壁打ち)+ 横長メイン画像 → 9月中旬に両OSで配信目標(キルスイッチ 9/8)
  5. インストール・GA4 定点観測 / scripts/asc-submission-check.mjs への availability チェック追加 / リリース後継続タスク・Devpost 任意課題(前スナップショット参照)

詰まっていること・未決事項:

  • RevenueCat の Android 用公開キー(goog_)が未取得(RC に Play アプリ未作成)
  • Android 未実装: 通知・オフライン画像保存・Analytics 送信・広告+UMP(広告は後回し可 = フェイルオープン設計)・アダプティブアイコン(現状は legacy PNG)
  • 検証エミュレータのシステムロケールを ja-JP に変更したまま(意図的。en 検証時は戻す)
  • Devpost の Growth Fund チェック未確認 / サムネイル既定の青のまま / PR TIMES 支払いは銀行振込のみ / スクショ残7ロケール
  • (従来から継続の未決)課金の実購入検証は実機 iPhone 14 / 買い切り再検討は実測後 / マウリッツハイス画像は Commons 限定 / レオナルド帰属は Fable チェック時に精査 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-08-15 05:54 時点より前のスナップショット(2026-08-15 04:34作成分)

今どこまで進んだか:

  • App Store 公開済み・初インストール発生(8/11 の配信国復旧後に反映、8/15 に You がインストール発生を確認)
  • Shipaton 2026 に応募完了(2026-08-15 SUBMITTED): 初公開 8/7 が提出期間(7/31〜9/30)内で資格適合。提出物 = 英文ストーリー + デモ動画1:12(YouTube 公開 https://www.youtube.com/watch?v=Q62huvtjorg )+ フレームなしスクショ3枚 + アイコン + RC project ID proj8f670edd。カテゴリは HAMM 本命 + Design + Catvertising。締切 10/1 15:45 JST まで Devpost 上で編集可。素材とドラフトは store-assets/shipaton/
  • プロモ素材にコンテンツ規模数字(作品数・美術館数)を入れない方針を決定(DECISIONS・auto-memory 保存済み)
  • Android 開発は初速実測(D30 目安)まで見送りと決定
  • Release ビルド(build 6 相当)を再ビルドして 17e に導入済み(動画撮影用・DEBUG 欄なし)
  • (変化なし)画像配信高速化 / TestFlight 内部テスト / Debug も本番CDN / scripts/asc-submission-check.mjs / 本番R2 1,200点版 / seed抽選 / support@ / PR TIMES 企業登録済み・本体未着手

次に何をするか:

  1. Android 版の開発着手(2026-08-15 方針転換・DECISIONS 参照): 技術選定(Kotlin/Compose vs KMP)から。〜9月上旬 Play 審査提出 → 9月中旬 両OSで PR TIMES。キルスイッチ 9/8。Play Console 法人アカウントは開設済み(You 確認)
  2. AdMob 開通チェーン(再審査結果の確認 → ストア掲載リンク設定 → 広告のアプリ審査 → 配信開始確認)← 次セッションで着手
  3. PR TIMES プレスリリース骨子(promo-expert 壁打ち)+ 横長メイン画像(1920×1280以上)→ 9月中の配信で Shipaton のトラクション作りを兼ねる(Grand Prize/HAMM は 〜9/30 の伸びが審査材料)
  4. インストール・GA4 の定点観測を習慣化
  5. scripts/asc-submission-check.mjs に配信国(availability)存在チェックを追加(再発防止・小タスク)
  6. リリース後継続: Fable 残985 / 特集の月次フロー / スクショ残7ロケール / 計測のリリース後改善7件(DEVLOG 2026-07-29)/ rewarded 実機確認 / EEA フォーム確認
  7. (任意)Devpost サムネイル 3:2 差し替え / Growth Fund チェックの最終判断(非拘束・締切まで変更可)

詰まっていること・未決事項:

  • Devpost の Growth Fund チェックを入れたかは未確認(You の最終操作次第。編集画面で確認可能)
  • Devpost のプロジェクトサムネイルが既定の青画像のまま(3:2 画像を作れば差し替え可)
  • PR TIMES: 支払いは銀行振込のみ(詳細は 2026-07-26 スナップショット参照)
  • スクショの残ロケール(en 以外の7言語)は未制作
  • (従来から継続の未決)課金の実購入検証は実機 iPhone 14 / 買い切り再検討は実測後 / マウリッツハイス画像は Commons 限定 / レオナルド帰属は Fable チェック時に精査 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-08-15 04:34 時点より前のスナップショット(2026-08-11 16:44作成分)

今どこまで進んだか:

  • 1.0.0 (build 6) は審査承認済み(2026-08-07)→ 配信国ゼロ事故を復旧し、ストア反映待ち(2026-08-11 16:44): 承認後も「App Storeから削除済み」表示で一度も公開されていなかった。原因は appAvailability(配信国)リソースが存在しないこと=API 提出だと配信国未設定のまま審査を通過してしまう罠(Apple の取り下げではない。診断の詳細は DEVLOG 2026-08-11 参照)。8/11 に POST /v2/appAvailabilities全175か国の availability を作成し復旧(available=175 検証済み)。影響は公開が4日遅れただけで実害なし
  • ストア反映を監視中: iTunes Lookup (JP) を2分間隔でポーリング(掲載検知で通知)。反映確認がとれたら「公開後タスク」が解禁される
  • 審査承認の内訳: バージョン + サブスクグループ + 月額 + 年額の4アイテムすべて承認(審査提出2件とも COMPLETE)。build 6 = 計測修正 + Crashlytics + 画像最適化 + 通知プライマー変更
  • (変化なし)画像配信高速化(Cache Rule + thumb)/ TestFlight 内部テスト開通 / Debug も本番CDN / scripts/asc-submission-check.mjs / 本番R2 1,200点版 / seed抽選 / en-US名 Daily Art / support@ 開通 / 配布署名の二段構え / PR TIMES 企業登録済み・本体未着手

次に何をするか:

  1. ストア掲載の確認(監視の検知後、実ページと検索露出を確認)
  2. scripts/asc-submission-check.mjs に配信国(availability)存在チェックを追加(再発防止・小タスク)
  3. 公開後: AdMob 再審査結果の監視 → ストア掲載リンク設定 → 広告のアプリ審査 → 配信開始確認
  4. プレスリリース骨子(promo-expert に壁打ち)+ 横長メイン画像(1920×1280以上、縦長スクショ流用不可)→ 配信は App Store 公開後
  5. リリース後: Fable 残985 の順次チェック → 差し替え / 特集の月次フロー(型=ja 執筆 → Codex 翻訳)/ スクショ残7ロケール / 計測のリリース後改善7件(Codex レビュー指摘、DEVLOG 2026-07-29 参照)/ rewarded 経路の実機手動確認 / EEA フォームの実表示確認

詰まっていること・未決事項:

  • App Store への実反映がまだ(8/11 16:44 時点。availability 作成から数分〜数時間かかる場合がある)
  • PR TIMES: 配信は公開後 / 支払いは銀行振込のみ(詳細は 2026-07-26 スナップショット参照)
  • スクショの残ロケール(en 以外の7言語)は未制作(ja/en-US のみ登録。iPhone 専用のため iPad 版は不要)
  • (従来から継続の未決)課金の実購入検証は実機 iPhone 14 / 買い切り再検討は実測後 / マウリッツハイス画像は Commons 限定 / レオナルド帰属は Fable チェック時に精査 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-08-11 16:44 時点より前のスナップショット(2026-07-29 13:03作成分)

今どこまで進んだか:

  • 1.0.0 (build 6) を審査提出済み・審査待ち(2026-07-29 12:53): 提出は4アイテム(バージョン + サブスクグループ + 月額 + 年額)で、すべて WAITING_FOR_REVIEW を API 確認済み。承認後は自動公開(AFTER_APPROVAL)。build 6 = build 3 の内容 + 計測修正(dedupe/RC連携/context)+ Crashlytics + 画像最適化(thumb化・リトライ)+ 通知プライマー変更。build 1〜5 は使わない。初回提出はバージョンのみでサブスクが漏れる事故未遂があり、取り下げ→合体→再提出で回収(DECISIONS 参照)
  • 提出設定の最終確定: 配信権(サードパーティコンテンツを含む)/ 価格(無料・基準国日本)/ カテゴリ(教育×ライフスタイル)/ プライバシー詳細9タイプ(クラッシュデータ追加)/ 年齢制限の socialMedia 新質問(期限9/7)も回答済み。※7/20 の「価格登録済み」記録は誤りだった(実際は未設定→今回設定)
  • 画像配信が高速化: Cloudflare Cache Rule「content-cdn-cache」稼働で cf-cache-status HIT・1枚約50ms(従来は常時 MISS で0.6〜1.0秒)。アプリ側は枠内=thumb / 全画面=full + 失敗時自動リトライ
  • TestFlight 内部テスト開通: 内部グループ「内部テスト」(全ビルド自動配信)+ info@ テスター登録済み。build 6 配信中
  • Debug ビルドも本番CDN 参照に変更(LAN IP 直書き運用を廃止。ローカル差し替え検証時のみ一時的に戻す)
  • 再発防止の道具: scripts/asc-submission-check.mjs(審査提出の課金取りこぼし検出)。汎用版は ~/cdev/knowledge/asc-review-submission-iap-check.md
  • (変化なし)本番R2 1,200点版 / seed抽選 / en-US名 Daily Art / support@ 開通 / 配布署名の二段構え / PR TIMES 企業登録済み・本体未着手

次に何をするか:

  1. 審査結果待ち(リジェクト時は Resolution Center を確認して対応)
  2. 公開後: AdMob 再審査結果の監視 → ストア掲載リンク設定 → 広告のアプリ審査 → 配信開始確認
  3. TestFlight で build 6 の体感確認(Cache Rule + thumb 化の効果。任意)/ rewarded 経路の実機手動確認 / EEA フォームの実表示確認(任意・公開後でも可)
  4. プレスリリース骨子(promo-expert に壁打ち)+ 横長メイン画像(1920×1280以上、縦長スクショ流用不可)→ 配信は App Store 公開後
  5. リリース後: Fable 残985 の順次チェック → 差し替え / 特集の月次フロー(型=ja 執筆 → Codex 翻訳)/ スクショ残7ロケール / 計測のリリース後改善7件(Codex レビュー指摘、DEVLOG 2026-07-29 参照)

詰まっていること・未決事項:

  • PR TIMES: 配信は公開後 / 支払いは銀行振込のみ(詳細は 2026-07-26 スナップショット参照)
  • スクショの残ロケール(en 以外の7言語)は未制作(ja/en-US のみ登録。iPhone 専用のため iPad 版は不要)
  • (従来から継続の未決)課金の実購入検証は実機 iPhone 14 / 買い切り再検討は実測後 / マウリッツハイス画像は Commons 限定 / レオナルド帰属は Fable チェック時に精査 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-07-29 13:03 時点より前のスナップショット(2026-07-28 12:38作成分)

今どこまで進んだか:

  • 1.0.0 が審査提出可能・build 3 まで完了(2026-07-27 17:19): ASC に build 1(旧デッキ・旧宛先)/ build 2(seed抽選)/ build 3(seed抽選 + support@ + 特集英語名 Editorial。提出はこれを選ぶ)。スクショ ja/en-US 各5枚・App Review 情報(連絡先+Review Notes)・掲載文9言語・価格・プライバシー申告まで登録済み。1.0.0 は PREPARE_FOR_SUBMISSION ※価格は実際には未設定だったことが 7/29 に判明
  • 本番R2 1,200点版 / seed抽選 / support@ / Fable リリース後実施 / 配布署名 / PR TIMES(詳細は下の 2026-07-28 12:38 時点スナップショット=当時の記述と同一のため省略)
  • en-US ストア名 = Pocket Museum: Daily Art(2026-07-28 に Masterpieces から再変更・ASC 反映済み)

次に何をするか: 1. build 3 を 1.0.0 に紐付けて審査提出(You の操作) 2以降は 7/29 の「現在の状況」とほぼ同一のため省略

詰まっていること・未決事項: 実機の配信URLが LAN IP 直書き(→ 7/29 に本番CDN化で解消)ほかは 7/29 の「現在の状況」と同一

2026-07-28 12:38 時点より前のスナップショット(2026-07-27 20:23作成分)

今どこまで進んだか:

  • 1.0.0 が審査提出可能・build 3 まで完了(2026-07-27 17:19): ASC に build 1(旧デッキ・旧宛先)/ build 2(seed抽選)/ build 3(seed抽選 + support@ + 特集英語名 Editorial。提出はこれを選ぶ)。スクショ ja/en-US 各5枚・App Review 情報(連絡先+Review Notes)・掲載文9言語・価格・プライバシー申告まで登録済み。1.0.0 は PREPARE_FOR_SUBMISSION
  • 本番R2 が 1,200点版に切替済み(2026-07-27): deck v2(deck.json 削除→全面組み直し。作家近接80→34件・新規200点の1年目到達 0→62点)+ stories×9言語 + featured 9言語(20:23 残り7言語を Codex 翻訳・検収して配信済み。DECISIONS 参照)。7/15 検証用1,000点版は置き換え済み。看板作品(真珠の耳飾りの少女ほか)が配信対象に入った
  • 「今日の1枚」は個人別seed抽選(build 2〜): 全ユーザー共通の固定順カーソルを廃止(DECISIONS 2026-07-27)。作家3日除外・DEBUG は PM_DECK_SEED で再現可・DeckCursor テーブルは残置(削除は iCloud 設計確定後)
  • en-US ストア名 = Pocket Museum: Masterpieces(確定・ASC 反映済み。他8言語は「毎日の芸術」系のまま変更なし)→ 2026-07-28 に Daily Art へ再変更(このスナップショットの直後)
  • support@ramanu.co.jp 開通: 受信=Cloudflare Email Routing(→Gmail 転送)、送信=Gmail send-as。テスト受信確認済み。AppConfig.supportEmail 差し替え済み(build 3 同梱)→ 長年の未決「誤訳報告の宛先が仮アドレス」が解消
  • Fable チェックはリリース後に順次実施と決定(残985。完走はリリース条件から外した)
  • 配布署名の道具立てが確立: 証明書/プロファイルは ASC API 発行済み、資材(p12・鍵・署名用キーチェーン)は ~/.config/asc/pocket-museum-dist/ に退避。アーカイブ=自動署名 + export=手動配布署名の二段構え(DEVLOG 2026-07-27 参照)
  • PR TIMES は企業登録済み(ID 187992)・プレスリリース本体は未着手(配信は App Store 公開後)

次に何をするか: (2026-07-28 の「現在の状況」と同一のため省略)

詰まっていること・未決事項: (2026-07-28 の「現在の状況」と同一のため省略)

2026-07-27 17:19 時点より前のスナップショット(2026-07-26 15:12作成分)

今どこまで進んだか:

  • PR TIMES の企業登録〜企業ページ整備が完了(2026-07-26 15:12): 企業ID 187992。日曜11:21に申請 → 約2時間20分で審査承認(13:43)→ 本登録完了。企業プロフィールに企業説明155字・ロゴ250×250・カバー画像1920×450 を登録し公開ページに反映済み。代表電話番号(個人携帯)は削除して公開ページで「-」を実確認。無料枠(スタートアップチャレンジ)は「日本国内の株式会社」限定なので合同会社ラマヌは原則対象外 → 従量課金 1配信3万円(税別)が既定線。ブランド資産は ~/cdev/company-operation/output/brand/(ロゴはサイトのインラインΣを PIL で描画、カバーは Codex ImageGen で Σ反復+中央抜き)
  • (以下は 2026-07-22 09:28 時点から変化なし)ストア用スクショ ja・6.9インチ全5枚完成 / 拡大鑑賞のピンチズームバグ修正済み / 17e の検証状態 / UMP 実装済み・EEA 実表示未確認 / サブスク審査スクショ登録済み / 通知プレパーミッション・レビュー促進実装済み / AdMob 再審査中 / dist は1,200点版・R2 本番は7/15検証用のまま / ASC 9言語掲載済み / Fable 215/1,200

次に何をするか:

  1. プレスリリースの骨子(ニュース価値の軸決め=1,200点/毎日1枚/9言語/パブリックドメインのどれを主役にするか。promo-expert に壁打ちさせる想定)
  2. プレスリリースのメイン画像(推奨 横1920×縦1280以上。縦長のストア用スクショは流用できないので横長を新規制作)
  3. スクショの他ロケール(en ほか8言語)と iPad 13インチの展開要否を判断 → ASC へスクリーンショット登録
  4. Fable チェック再開(残985)→ 完走後に pm deckpm exportpm upload
  5. rewarded 経路の手動確認
  6. EEA フォームの実表示確認(実機 + UMP テストデバイスか公開後 EEA)
  7. en-US ストア名接尾辞の再決断(リリース前)

詰まっていること・未決事項:

  • PR TIMES の配信は App Store 公開後(本文に実ストアURLを入れるため)。スタートアップチャレンジの適用状態は管理画面のダッシュボードで確認できるので、対象外と出た場合のみ問い合わせる(文面は作成済み・送信保留中)
  • PR TIMES の支払いは銀行振込のみ・クレジット決済不可(配信日の当月末締め → 翌月初3営業日以内に請求書メール → 翌月末までに振込・手数料自己負担)。GMOあおぞらからの振込と freee 側の処理が必要
  • スクショの多言語展開: 見開き・各シートのコピーは ja 前提。en 展開時は翻訳+Codex 再生成が必要(マスター見開きの文言差し替え)
  • (2026-07-20 21:34 時点と同一の未決)課金の実購入検証は実機 iPhone 14 / 買い切り再検討 / en-US ストア名 / Review Notes に14枚・広告・Pro 記載 / マウリッツハイス画像は Commons 限定 / レオナルド帰属精査 / AdMob 再審査監視 / 誤訳報告の宛先 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-07-26 15:12 時点より前のスナップショット(2026-07-22 09:28作成分)

今どこまで進んだか:

  • ストア用スクリーンショット(ja・6.9インチ)全5枚が完成(2026-07-22 09:28): 構成=見開き2枚(accent-arch「名画をひらく」/「次の一枚が」)+03今日の一枚(光琳・金地の白い芥子)+04拡大鑑賞(実ピンチズーム画面×ルーペ)+05コレクション。特集シートなしの5枚で確定(DECISIONS)。全て 1320×2868 検証済み・store-assets/screenshots/(ギャラリー preview/index.html)。見開きの確定デザインは You が Codex 直接対話で制作、実画面素材・分割・検証は Claude の分業。残: 他ロケール/iPad 展開の要否判断と ASC 登録
  • 拡大鑑賞のピンチズームバグ修正(2026-07-22): dismissPan が2本指を拾ってズームと衝突 → 1本指限定+ピンチ開始時キャンセル等で修正、シミュレータ実ズーム確認済み(DEVLOG 参照)
  • 17e の検証状態: 日送りで収蔵37作品・今日=7/22実日付・Pro トグルは再起動で OFF に戻る。LAN IP 192.168.1.5(project.yml 更新済み)
  • (以下は 2026-07-20 21:34 時点から変化なし)UMP 実装済み・EEA フォーム実表示は未確認 / サブスク審査スクショ登録済み / 通知プレパーミッション・レビュー促進実装済み / AdMob 再審査中 / dist は1,200点版・R2 本番は7/15検証用のまま / ASC 9言語掲載済み / Fable 215/1,200

次に何をするか:

  1. スクショの他ロケール(en ほか8言語)と iPad 13インチの展開要否を判断 → ASC へスクリーンショット登録
  2. Fable チェック再開(残985)→ 完走後に pm deckpm exportpm upload
  3. rewarded 経路の手動確認
  4. (任意)ストア説明文への特集追記(9言語)
  5. EEA フォームの実表示確認(実機 + UMP テストデバイスか公開後 EEA)
  6. en-US ストア名接尾辞の再決断(リリース前)

詰まっていること・未決事項:

  • スクショの多言語展開: 見開き・各シートのコピーは ja 前提。en 展開時は翻訳+Codex 再生成が必要(マスター見開きの文言差し替え)
  • (2026-07-20 21:34 時点と同一の未決)課金の実購入検証は実機 iPhone 14 / 買い切り再検討 / en-US ストア名 / Review Notes に14枚・広告・Pro 記載 / マウリッツハイス画像は Commons 限定 / レオナルド帰属精査 / AdMob 再審査監視 / 誤訳報告の宛先 / simctl defaults の注意(詳細は下のアーカイブ参照)

2026-07-22 09:28 時点より前のスナップショット(2026-07-20 21:34作成分)

今どこまで進んだか:

  • 広告のローンチ前対応が決着(2026-07-20 21:34): ATT なし + EU 配信 + UMP を決定(DECISIONS 参照)→ AdConsent 実装(EEA では広告表示直前にフォーム・拒否/失敗はフォールバック・マイに EEA 限定「広告のプライバシー設定」)→ AdMob コンソールで GDPR メッセージ「Pocket Museum GDPR」公開(en+7言語・Do not consent あり・EEA/UK/CH のみ・再審査中でも作成できた)。非EEA 広告経路の無傷は検証済み。残: EEA フォームの実表示確認(シミュレータはジオデバッグ無視で notRequired になるため実機か公開後 EEA で)
  • サブスク審査用スクリーンショット完了(2026-07-20 21:34): Paywall 実写 1170×2532 を ASC API で両商品に登録 → pm_pro_monthly/pm_pro_yearly とも READY_TO_SUBMIT(MISSING_METADATA 解消)。ストア関連の残りはアプリ本体スクリーンショットのみ
  • 通知プレパーミッション実装済み(2026-07-20 19:53、d2f2ba7: 起動時1回きりの3ステップ(自前促し→iOS ダイアログ→時刻設定/マイ誘導)。「あとで」は許可機会温存。Codex レビュー4件反映(enable ロールバック・リマインダ操作の直列化・時刻設定中のスワイプ禁止・ScrollView 化)。シミュレータE2E済み
  • レビュー促進ソフトアスク実装済み(2026-07-20 19:53、設計 4f51ff3 → 実装 a286a94: 同意型二段構え=初回同意→アプリ内星ダイアログ / 2回目以降→write-review ページ。資格=獲得7日・契機は特集読了と作品詳細クローズ(お気に入り追加は除外決定)・再訴求45日→60日で通算3回・同意後は再提示なし・他モーダルと同一セッション抑制。マイに常設リンク+Analytics 6イベント。仕様の正本は discussions/2026-07-20-review-prompt.md。シミュレータE2E済み(実機での星ダイアログ実動作と、公開後の write-review ページ到達は未確認=公開後に自然解消)
  • AdMob アカウント却下 → 原因切り分け → 再送信済み(2026-07-20 11:30): 却下対象は法人アカウント pub-7837692984627105(受取人格は個人アカウントと別で重複違反ではないことを実地確認)。本命原因はアプリ未公開でストア掲載にリンクできずコンテンツ確認不能と推定。再審査中。公開初日から広告が出ないのは仕様上不可避で、フォールバック(無料開放)が働くためローンチブロッカーではない
  • 月例特集が完成(2026-07-20 11:07、器+1本目+E2E): pm featured check + export、原稿は pipeline/data/featured/(ja 正本)、4タブ目「特集」+ 言語別同期、ぼかし帯+Pro CTA、Analytics 3イベント実証済み。1本目「フェルメール、窓辺の光」執筆済み。詳細は 11:07 スナップショット参照
  • ローカル dist/ は 1,200点版に再生成済み。R2 本番は 7/15 検証用(1,000点)のまま。実アップロードは Fable 完走後(特集1本目も同じ流れで本番に乗る)
  • プライバシーポリシー・R2 配信・ASC サブスク9言語・app-ads.txt は完了済み(04:19 スナップショット参照)
  • ASC ストア掲載情報は9言語登録済み(2026-07-20 別セッションで実施・同日 ASC API で実在確認): name・サブタイトル・説明・キーワード・プロモ文の全9言語。プライバシーポリシーURLは ja=ja版・他8言語=/privacy/en/。年齢制限 12+・App プライバシー詳細も公開済み。ただし説明文は特集への言及なし(追記するなら9言語分)。ストア関連の残りはスクリーンショット2種(サブスク審査用 + アプリ本体の各言語×デバイスサイズ)
  • Fable チェックは 215/1,200 完了(残985)。今日は進んでいない
  • LAN IP を 192.168.1.3 に更新済み(project.yml Debug、2026-07-20 再更新)

次に何をするか:

  1. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行 → pm exportpm upload で本番配信に差し替え(特集1本目もこの流れで本番に乗る
  2. ストア用スクリーンショット制作(アプリ本体・9言語×デバイスサイズ・ASO設計込み。サブスク審査用は 2026-07-20 完了: Paywall スクショ 1170×2532 を ASC API で両商品に登録 → pm_pro_monthly/pm_pro_yearly とも READY_TO_SUBMIT。MISSING_METADATA 解消済み)
  3. rewarded 経路の手動確認(実広告を手で閉じてチケット付与 source=ad を1回見れば完全)
  4. (任意)ストア説明文への特集の追記(9言語。掲載情報自体は登録済み・下記参照)
  5. ローンチ前の広告残タスク: ATT なし + EU 配信 + UMP は 2026-07-20 決定・アプリ側実装済み・AdMob コンソールの GDPR メッセージも同日公開済み(「Pocket Museum GDPR」・en+7言語・Consent/Do not consent/Manage options・EEA/UK/CH のみ表示・ポリシーURL=/privacy/en/。アカウント再審査中でも作成できた)。残: EEA フォームの実表示確認。シミュレータは PM_UMP_DEBUG_EEA=1 でもジオデバッグが無視され notRequired になる(AdConsent の DEBUG ログで status/formStatus を出力可)ため、実機 + UMP テストデバイスID登録か、公開後の EEA 実配信で確認する。公開後は AdMob のストア掲載リンク → アプリ審査 → 配信開始確認(再審査の結果メール info@ramanu.co.jp 宛も監視。7/20 再送信済み)
  6. 特集の残運用課題: 翻訳制作の範囲確定(当面 ja のみは決定済み・いつ広げるか)/ ローンチ前バッファ本数 / 月次制作フロー
  7. (任意)サンドボックスのトライアル→課金転換の観測 / 月額プランの購入E2E

詰まっていること・未決事項:

  • en-US のストア名「Pocket Museum: Daily Art」の接尾辞をリリース前に再決断する(2026-07-20 保留): 「daily art」検索は競合 DailyArt(Moiseum)のブランドに乗った形で、誤入手→低評価リスクあり。候補は「Art History」(26字・カテゴリ定番検索語・第一候補)/「Paintings」/「Famous Art」/「Classic Art」。サブタイトル「One masterpiece, every day」が daily 概念を担うためタイトルから外しても検索の穴は小さい。他8言語は一般語翻訳のため変更不要。当面は Daily Art のまま
  • 課金の実購入検証はシミュレータ不可・実機 iPhone 14 で行う(サンドボックステスターは applesandboxtester1@ramanu.co.jp / JPN)。実機の検証インストールは freeStoryCount=0 ピン留めの特殊状態(Pro 有効・素の状態を試すときは入れ直し)
  • 買い切りの再検討発動(実測データが揃ってから)/ 特集の翻訳拡大時期・バッファ本数(実装形と ja のみ制作は 2026-07-20 決定済み)
  • App Store 審査対策: Review Notes に 14枚・広告・Pro の関係を記載する(レンタルモデル決定の付帯事項)。ストア文言の「永久収蔵」は作品に限定
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • AdMob アカウントは 2026-07-20 却下 → 同日再送信で再審査中。アカウント承認 + 公開後のストアリンク + アプリ審査が揃うまで実広告は配信されない(その間は unavailable → フォールバックで当日全文無料開放、実害なし)
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml の debug、現在 192.168.1.3)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ
  • シミュレータの UserDefaults を外から操作するときは simctl spawn defaults write を使わない(コンテナ外のデバイスレベル plist に書かれて二重状態になる)。シャットダウン中にコンテナ内 plist を plutil で直接編集する(DEVLOG 2026-07-20 19:53 参照)

2026-07-20 21:34 時点より前のスナップショット(2026-07-20 19:53作成分・要約)

  • 通知プレパーミッション実装済み(d2f2ba7・Codex レビュー4件反映・E2E済み)/ レビュー促進ソフトアスク実装済み(設計 4f51ff3 → 実装 a286a94・E2E済み・仕様の正本は discussions/2026-07-20-review-prompt.md)
  • AdMob 却下→再送信で再審査中 / 月例特集完成(11:07)/ ローカル dist 1,200点版・R2 は 7/15 検証用のまま / ASC ストア掲載9言語登録済み(説明文に特集言及なし)/ Fable 215/1,200 / LAN IP 192.168.1.3
  • 次にやること: Fable 再開 / 審査用スクリーンショット2種 / rewarded 手動確認 / ATT・UMP 方針決め / 特集運用課題
  • 未決に「ATT を出すか / EU 配信の有無」を含む(→ 21:34 に決着)。ほかの未決事項は 21:34 時点とほぼ同一

今どこまで進んだか:

  • AdMob アカウント却下 → 原因切り分け → 再送信済み(2026-07-20 11:30): 却下対象は法人アカウント pub-7837692984627105info@ramanu.co.jp、お支払いプロファイルは組織 RAMANU LLC・確認済み)で、app-ads.txt / Release ビルドの ID と一致。個人の稼働中アカウント(別 pub ID)とは受取人格が別で重複違反ではないことを実地確認。本命原因はアプリ未公開でストア掲載にリンクできずコンテンツ確認不能と推定。ポリシー準拠チェック → 再送信済み
  • 月例特集が完成(2026-07-20 11:07、器+1本目+E2E): パイプラインは pm featured check 新設 + export が content/featured/{lang}.json を出力。原稿は pipeline/data/featured/(Git 管理下・ja 正本)、記事単位 access 属性で全開放特集にも対応。アプリは4タブ目「特集」+ featured-v1 マイグレーション + 言語別同期。ロック表現はぼかしサムネ帯(radius 1)+ Pro CTA。Analytics 3イベント実証済み
  • 1本目「フェルメール、窓辺の光」執筆済み(intro+7節+結び、ヒーロー=真珠の耳飾りの少女)
  • ローカル dist/ は 1,200点版に再生成済み。R2 本番は 7/15 検証用(1,000点)のまま。実アップロードは Fable 完走後
  • プライバシーポリシー・R2 配信・ASC サブスク9言語・app-ads.txt は完了済み(04:19 スナップショット参照)
  • ASC ストア掲載情報は9言語登録済み(別セッションで実施・ASC API で実在確認): 全9言語の name・サブタイトル・説明・キーワード・プロモ文。説明文は特集への言及なし。残りはスクリーンショット2種
  • Fable チェックは 215/1,200 完了(残985)
  • LAN IP を 192.168.1.83 に更新済み(project.yml Debug)

次に何をするか: Fable チェック再開 → pm deck/export/upload / 審査用スクリーンショット / rewarded 手動確認 / (任意)説明文への特集追記 / ATT・UMP 方針 / 特集の翻訳範囲・バッファ / (任意)課金転換観測

詰まっていること・未決事項: 11:30 時点と同一(課金実機検証・買い切り再検討・ATT/EU・Review Notes・マウリッツハイス画像・レオナルド帰属・AdMob 再審査・LAN IP 直書き・誤訳報告宛先)

2026-07-20 11:30 時点より前のスナップショット(2026-07-20 11:07作成分)

今どこまで進んだか:

  • 月例特集が完成(2026-07-20 11:07、器+1本目+E2E): パイプラインは pm featured check 新設 + export が content/featured/{lang}.json を出力(参照切れは export 停止・upload は自動対象)。原稿は pipeline/data/featured/Git 管理下・ja 正本)、記事単位 access 属性(preview/open)で全開放特集にも対応。アプリは4タブ目「特集」(一覧→記事)、featured-v1 マイグレーション、言語別同期 + ja フォールバック。ロック表現はぼかしサムネ帯(radius 1)+「この先、あと N 作品がつづきます」+ Pro CTA(広告なし・記事内完結・ヒーロー画像は一覧カード専用)。Analytics 3イベント(featured_preview_completed の dedupe 含む)を実ログで実証、英語UIの ja フォールバックも確認済み。実装形と ja のみ制作の決定は DECISIONS 2件参照
  • 1本目「フェルメール、窓辺の光」執筆済み(intro+7節+結び、ヒーロー=真珠の耳飾りの少女)。既存単体解説と矛盾しない書き下ろし
  • ローカル dist/ は 1,200点版に再生成済み(特集の参照に必要)。R2 本番は 7/15 検証用(1,000点)のまま。pm upload --dry-run で featured/ja が差分に載ることは確認済み、実アップロードは Fable 完走後
  • プライバシーポリシー・R2 配信・ASC サブスク9言語・app-ads.txt は完了済み(04:19 スナップショット参照)
  • Fable チェックは 215/1,200 完了(残985)。今日は進んでいない
  • LAN IP を 192.168.1.83 に更新済み(project.yml Debug)

次に何をするか:

  1. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行 → pm exportpm upload で本番配信に差し替え(特集1本目もこの流れで本番に乗る
  2. 審査用スクリーンショット登録(MISSING_METADATA 解消。特集画面もスクショ候補に)
  3. rewarded 経路の手動確認(実広告を手で閉じてチケット付与 source=ad を1回見れば完全)
  4. ja のストア掲載情報作成(アプリ名・サブタイトル・説明等。あわせて ja プライバシーポリシーURL設定。説明文で特集に触れる)
  5. ローンチ前の広告残タスク: ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー(app-ads.txt は完了)
  6. 特集の残運用課題: 翻訳制作の範囲確定(当面 ja のみは決定済み・いつ広げるか)/ ローンチ前バッファ本数 / 月次制作フロー
  7. (任意)サンドボックスのトライアル→課金転換の観測 / 月額プランの購入E2E

詰まっていること・未決事項:

  • 課金の実購入検証はシミュレータ不可・実機 iPhone 14 で行う(サンドボックステスターは applesandboxtester1@ramanu.co.jp / JPN)。実機の検証インストールは freeStoryCount=0 ピン留めの特殊状態(Pro 有効・素の状態を試すときは入れ直し)
  • 買い切りの再検討発動(実測データが揃ってから)/ 特集の翻訳拡大時期・バッファ本数(実装形と ja のみ制作は 2026-07-20 決定済み)
  • ATT を出すか(公開したプライバシーポリシーは「ATT 不要求」前提で記述済み。出す方針に変えるなら文面も更新)/ EU 配信の有無(UMP 要否が決まる。ストア配信自体は全175地域で設定済み、広告同意だけの問題)
  • App Store 審査対策: Review Notes に 14枚・広告・Pro の関係を記載する(レンタルモデル決定の付帯事項)。ストア文言の「永久収蔵」は作品に限定
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml の debug、現在 192.168.1.83)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ

2026-07-20 11:07 時点より前のスナップショット(2026-07-20 04:19作成分)

今どこまで進んだか:

  • プライバシーポリシー公開済み(2026-07-20 04:19、ローンチブロッカー解消): 日本語(正本) https://ramanu.co.jp/pocket-museum/privacy/ + 英語 /en/(コーポレート Pages、company-operation/website/ から wrangler deploy)。AppConfig.privacyPolicyURL 差し替え済み(77b1ae9)・ASC en-US の privacyPolicyUrl 設定済み。ja ストア掲載情報は未作成 → 作成時に ja 版URLを設定
  • R2 本番配信が開通(2026-07-20 04:19): R2 有効化($0/月)→ バケット pocket-museum-content(APAC)→ pm upload 実装(boto3・md5/ETag差分同期・Cache-Control: manifest 60s / JSON 5min / 画像 7d)→ 検証用 dist 2,012ファイル/712MB アップロード済み → content.ramanu.co.jp 接続。project.yml Release は本番URLに差し替え済み。iPhone 17 シミュレータの Release 新規インストールで本番URL同期E2E成功。認証は ~/.config/r2/pocket-museum.env(バケット限定トークン)。今の配信内容は検証用(1,000点・7/15 dist)。本番は Fable 完走後に pm deck → pm export → pm upload で置き換え
  • ASC 残タスクを消化: サブスク表示名・説明が全9言語完了(残り7言語を一括登録、訳語は xcstrings と統一)。app-ads.txt を https://ramanu.co.jp/app-ads.txt に公開し、ASC 1.0.0 en-US の supportUrl/marketingUrl も ramanu.co.jp に設定(AdMob クローラ経路開通)。商品側の残件は審査用スクリーンショットのみ
  • サンドボックス実購入E2E・Firebase Analytics・実バグ2件修正は完了済み(02:54 スナップショット参照)
  • Fable チェックは 215/1,200 完了(残985)。今日は進んでいない
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す

次に何をするか:

  1. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行 → pm exportpm upload で本番配信に差し替え
  2. 審査用スクリーンショット登録(MISSING_METADATA 解消。Paywall UI は確定済みなので実施可能)
  3. rewarded 経路の手動確認(実広告を手で閉じてチケット付与 source=ad を1回見れば完全)
  4. ja のストア掲載情報作成(アプリ名・サブタイトル・説明等。あわせて ja プライバシーポリシーURL設定)
  5. ローンチ前の広告残タスク: ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー(app-ads.txt は完了)
  6. (任意)サンドボックスのトライアル→課金転換の観測 / 月額プランの購入E2E

詰まっていること・未決事項:

  • 課金の実購入検証はシミュレータ不可・実機 iPhone 14 で行う(サンドボックステスターは applesandboxtester1@ramanu.co.jp / JPN)。実機の検証インストールは freeStoryCount=0 ピン留めの特殊状態(Pro 有効・素の状態を試すときは入れ直し)
  • 買い切りの再検討発動(実測データが揃ってから)/ 月例特集の制作体制(9言語対応の範囲、ローンチ前バッファ本数、プレビュー編集規律のテンプレ化)
  • ATT を出すか(公開したプライバシーポリシーは「ATT 不要求」前提で記述済み。出す方針に変えるなら文面も更新)/ EU 配信の有無(UMP 要否が決まる。ストア配信自体は全175地域で設定済み、広告同意だけの問題)
  • App Store 審査対策: Review Notes に 14枚・広告・Pro の関係を記載する(レンタルモデル決定の付帯事項)。ストア文言の「永久収蔵」は作品に限定
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml の debug、現在 192.168.1.5)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ

2026-07-20 04:19 時点より前のスナップショット(2026-07-20 02:54作成分)

今どこまで進んだか:

  • サンドボックス実購入E2Eが完了(2026-07-20 02:54、実機 iPhone 14 で全経路開通): 月額の StoreKit 伝播を確認(Paywall 2プラン+「7日間無料」表記)。シミュレータは実購入不可(サインイン後キャンセル扱いになる既知の制限)と判明し実機に切替。サンドボックステスター applesandboxtester1@ramanu.co.jp(JPN、パスワードは You 管理)で購入成功、RevenueCat に entitlement pro active / trialing / sandbox / JP を確認。円表示(¥1,500/年・¥300/月)も実機で確認済み
  • 実バグ2件を発見・修正(39531e7: まっさらな初回インストールで manifest の free_story_count が一切効かず内蔵既定値14で固定される問題(SyncEngine のピン留めが AppState 行存在前提+bootstrap と handleForeground の獲得レース)。ピン留めを SyncEngine で行ごと作成+フォールバック確定を「最初の獲得発生時点」に遅延して構造的に解消。サーバからウェルカム枚数を調整する機能がこれで新規ユーザーにも効く
  • Firebase Analytics 導入完了(b41b130、アプリ側+外部+検証): PMAnalytics 境界+8イベント(featured_* 2種は特集実装時)+ユーザープロパティ free_count/deck_version。firebase-ios-sdk 12.16.0。外部は Firebase プロジェクト pocket-museum-d060f(GA=Default Account for Firebase、Gemini オフ)+ iOS アプリ登録+ GoogleService-Info.plist 配置済み。実イベント送信(story_gate_action{pro} / paywall_viewed{gate_today})をデバッグログで実証、DebugView 利用可能
  • チケット prune を「失効後7日保持」に変更(ticket_expired_gate_viewed 検出用。DECISIONS 2026-07-20)
  • RevenueCat/ASC 外部セットアップ・アプリ側課金実装・価格体系は完了済み(01:20 以前のスナップショット参照)。ASC MCP は別アカウントを見る点に注意(ramanu へは AuthKey_8M2SWG78S6.p8 で直接 API)
  • Fable チェックは 215/1,200 完了(残985)。今日は進んでいない
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す。dist の manifest.json は free_story_count=14

次に何をするか:

  1. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行
  2. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  3. rewarded 経路の手動確認(実広告を手で閉じてチケット付与 source=ad を1回見れば完全)
  4. プライバシーポリシーページ作成(ローンチブロッカー)
  5. ローンチ前の広告残タスク: app-ads.txt / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー
  6. 提出前の ASC 残り: 審査用スクリーンショット登録(MISSING_METADATA 解消)/ サブスクのストア表示名の残り7言語
  7. (任意)サンドボックスのトライアル→課金転換の観測 / 月額プランの購入E2E

詰まっていること・未決事項:

  • プライバシーポリシーURLがプレースホルダhttps://pocket-museum.invalid/privacy)。Paywall 表示と ASC 申請の両方で実ページが必要なローンチブロッカー(AppConfig.privacyPolicyURL で差し替え)
  • 課金の実購入検証はシミュレータ不可・実機 iPhone 14 で行う(サンドボックステスターは applesandboxtester1@ramanu.co.jp / JPN)。実機の検証インストールは freeStoryCount=0 ピン留めの特殊状態(Pro 有効・素の状態を試すときは入れ直し)
  • 買い切りの再検討発動(実測データが揃ってから)/ 月例特集の制作体制(9言語対応の範囲、ローンチ前バッファ本数、プレビュー編集規律のテンプレ化)
  • ATT を出すか(eCPM は上がるがプライバシー印象とトレードオフ)/ EU 配信の有無(UMP 要否が決まる。ストア配信自体は全175地域で設定済み、広告同意だけの問題)
  • App Store 審査対策: Review Notes に 14枚・広告・Pro の関係を記載する(レンタルモデル決定の付帯事項)。ストア文言の「永久収蔵」は作品に限定
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.1.5)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ

2026-07-20 02:54 時点より前のスナップショット(2026-07-20 01:20作成分)

今どこまで進んだか:

  • RevenueCat / ASC の外部セットアップが完了(2026-07-20 01:20、実価格表示まで開通): RevenueCat に App Store アプリ(app5291deeaf4)+ 商品 pm_pro_monthlypm_pro_yearly を作成し entitlement pro / offering default に紐付け済み。公開SDKキーを project.yml PM_REVENUECAT_API_KEY へ配線済み。ASC は bundle ID 登録(9UPTQ5B2Z6)→ アプリレコード Pocket Museum: Daily Art(Apple ID 6792521728 / en-US / SKU pocketmuseum)→ サブスクグループ「Pocket Museum Pro」+ 商品2つ(¥300/¥1,500 JPN ベース+均等化で全175地域、年額に7日無料イントロオファー、en-US/ja 表示名)まで構築済み。In-App Purchase Key S5S7WUD6JY(Subnote と共通)+ ASC API キー 8M2SWG78S6 を RevenueCat に登録済み(両方 configured: true)。Paywall に StoreKit 実価格「年額 $9.99/年」の表示を確認済み(US ストアフロント)。Paid Apps 契約は有効と You 確認済み
    • 残: 月額 pm_pro_monthly のサンドボックス StoreKit 伝播待ち(年額は約30分で出現、月額は未伝播のため Paywall に年額のみ表示中)。年額の「7日間無料」表記も伝播待ち。両商品の状態は審査用スクリーンショット未登録による MISSING_METADATA(サンドボックスの妨げではない・提出時までに登録)
    • 注意: 接続済み app-store-connect MCP は別アカウント(thomsons 系)を見ている。ramanu チームへは ~/.config/asc/AuthKey_8M2SWG78S6.p8(issuer は subnote/.mcp.json)で直接 API を叩く(DEVLOG 01:20 参照)
  • RevenueCat課金のアプリ側実装は完了済み(2026-07-20 00:13): PurchaseProvider 境界、AppModel.isPro 購読ストリーム連動、Paywall は StoreKit 実価格・トライアル適格性・購入/復元。xcstrings 97キー×8言語
  • bundle ID は jp.co.ramanu.pocketmuseum(2026-07-20 確定)。iPhone 17 Pro と実機 iPhone 14 には旧 bundle のアプリが残存(17 Pro は並行セッション使用中+元データ保険で温存)
  • 検証環境はシミュレータ iPhone 17e(課金検証はここで。17 Pro は並行セッションと取り合いになるため)
  • 価格体系は最終決定済み(2026-07-19、月¥300/年¥1,500・7日トライアルは年額のみ・レンタルモデル。DECISIONS 4件)
  • Phase 2(アプリ本体)は完了済み。残るスタブ境界は iCloud(ProgressSyncProvider)のみ
  • Fable チェックは 215/1,200 完了(残985)。今日は進んでいない
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す。dist の manifest.json には free_story_count=14 を追記済み

次に何をするか:

  1. サンドボックス実購入E2E: 月額の StoreKit 伝播を確認してから実施(シミュレータ購入にはサンドボックステスターアカウントが必要になる場合あり)。トライアル表記の表示確認も同時に
  2. Firebase Analytics 導入(ファネル型イベント10種+ユーザープロパティ。購読状態の正本は RevenueCat、2026-07-19 決定)
  3. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行
  4. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  5. rewarded 経路の手動確認(実広告を手で閉じてチケット付与 source=ad を1回見れば完全)
  6. ローンチ前の広告残タスク: app-ads.txt / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー
  7. 提出前の ASC 残り: 審査用スクリーンショット登録(MISSING_METADATA 解消)/ サブスクのストア表示名の残り7言語

詰まっていること・未決事項:

  • プライバシーポリシーURLがプレースホルダhttps://pocket-museum.invalid/privacy)。Paywall 表示と ASC 申請の両方で実ページが必要なローンチブロッカー(AppConfig.privacyPolicyURL で差し替え)
  • 買い切りの再検討発動(実測データが揃ってから)/ 月例特集の制作体制(9言語対応の範囲、ローンチ前バッファ本数、プレビュー編集規律のテンプレ化)※市場別価格は「JPN ベース+均等化」で決着(DECISIONS 2026-07-20)
  • ATT を出すか(eCPM は上がるがプライバシー印象とトレードオフ)/ EU 配信の有無(UMP 要否が決まる。ストア配信自体は全175地域で設定済み、広告同意だけの問題)
  • App Store 審査対策: Review Notes に 14枚・広告・Pro の関係を記載する(レンタルモデル決定の付帯事項)。ストア文言の「永久収蔵」は作品に限定
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.0.146)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ

2026-07-20 01:20 時点より前のスナップショット(2026-07-20 00:13作成分)

今どこまで進んだか:

  • RevenueCat課金のアプリ側実装が完了(2026-07-20、シミュレータE2E+Releaseビルド検証済み): PurchaseProvider 境界(本番=RevenueCatPurchaseProvider / キー未設定Debug=即席スタブ)、AppModel.isPro が購読ストリーム連動(変化で表示中ゲート即再評価)、Paywall は StoreKit 実価格・トライアル適格性表示(消化済みは即時課金表示)・購入/復元・自動更新注記・EULA/プライバシーポリシーリンク。xcstrings は 97キー×8言語。識別子規約は DECISIONS 2026-07-20 参照(entitlement pro / offering default / 商品ID案 pm_pro_monthlypm_pro_yearly
  • bundle ID を jp.co.ramanu.pocketmuseum に変更(2026-07-20、DECISIONS 参照): スキャフォールド以来の com.ichirokisanuki.pocketmuseum は個人風の決め打ちだったため、法人リリース(info@ramanu.co.jp / チーム 9HZW92277N = 当初から正しい)に合わせて修正。project.yml 書き換え→xcodegen→17e 再ビルド、テストDB・オフライン画像は新コンテナへ移行済み(収蔵18作品・ゲート表示を実機確認)。旧 bundle のアプリは 17e から削除済み、iPhone 17 Pro と実機 iPhone 14 には旧アプリが残存(17 Pro は並行セッション使用中+元データ保険で温存。旧コンテナのバックアップはスクラッチパッドにも有り)
  • RevenueCat 外部セットアップが進行中(2026-07-20): アカウント(info@ramanu.co.jp)+プロジェクト「Pocket Museum」作成済み。オンボーディングで entitlement pro / Default offering(Monthly・Yearly の2つ、Lifetime は削除)を設定済み。公式 MCP(https://mcp.revenuecat.ai/mcp)を pocket-museum プロジェクトの local スコープに登録し、OAuth 認証済み(Pocket Museum プロジェクト限定・Read & Write)。→ 次セッションで MCP から: App Store アプリ設定作成(bundle ID jp.co.ramanu.pocketmuseum)/ offering・パッケージ・商品IDの確認調整(pm_pro_monthlypm_pro_yearly)/ 公開SDKキー appl_... 取得 → project.yml PM_REVENUECAT_API_KEY へ配線・実SDK切替検証
  • ASC に本アプリのレコードは未登録と確認(MCP list_apps)。ASC 側(Paid Apps 契約・アプリレコード・サブスク商品2つ・In-App Purchase Key)は You の作業として未着手
  • 検証環境をシミュレータ iPhone 17e に複製(テストDB・オフライン画像・Preferences 込み。並行セッションが iPhone 17 Pro を Subnote 検証で使うため取り合い回避。今後の課金検証は 17e)
  • 価格体系は最終決定済み(2026-07-19、月¥300/年¥1,500・7日トライアルは年額のみ・レンタルモデル。DECISIONS 4件)
  • Phase 2(アプリ本体)は完了済み。残るスタブ境界は iCloud(ProgressSyncProvider)のみ
  • Fable チェックは 215/1,200 完了(残985)。今日は進んでいない
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す。dist の manifest.json には free_story_count=14 を追記済み

次に何をするか:

  1. RevenueCat / ASC 外部セットアップ(You の作業): ① RevenueCat アカウント+プロジェクト作成 → 公開SDKキー(appl_...)を project.yml の PM_REVENUECAT_API_KEY へ(入れれば実SDKに自動切替) ② ASC アプリレコード作成 + Paid Apps 契約・銀行・税務の有効化 ③ サブスクグループ+商品2つ(pm_pro_monthly ¥300 / pm_pro_yearly ¥1,500+7日無料イントロオファー) ④ RevenueCat で entitlement pro・offering default(annual/monthly)設定 + ASC の In-App Purchase Key 登録 → 完了後にサンドボックス実購入E2E(Claude 側で実施可)
  2. Firebase Analytics 導入(ファネル型イベント10種+ユーザープロパティ。購読状態の正本は RevenueCat、2026-07-19 決定)
  3. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行
  4. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  5. rewarded 経路の手動確認(実広告を手で閉じてチケット付与 source=ad を1回見れば完全)
  6. ローンチ前の広告残タスク: app-ads.txt / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー

詰まっていること・未決事項:

  • プライバシーポリシーURLがプレースホルダhttps://pocket-museum.invalid/privacy)。Paywall 表示と ASC 申請の両方で実ページが必要なローンチブロッカー(AppConfig.privacyPolicyURL で差し替え)
  • 買い切りの再検討発動(実測データが揃ってから)/ 市場別価格ローカライズの具体テーブル(ASC 商品作成時に確定)/ 月例特集の制作体制(9言語対応の範囲、ローンチ前バッファ本数、プレビュー編集規律のテンプレ化)
  • ATT を出すか(eCPM は上がるがプライバシー印象とトレードオフ)/ EU 配信の有無(UMP 要否が決まる)
  • App Store 審査対策: Review Notes に 14枚・広告・Pro の関係を記載する(レンタルモデル決定の付帯事項)。ストア文言の「永久収蔵」は作品に限定
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.0.146)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ

2026-07-20 00:13 時点より前のスナップショット(2026-07-19 23:42作成分)

今どこまで進んだか:

  • 価格体系が最終決定(2026-07-19、三者議論3ラウンド + expert壁打ち。DECISIONS 4件): 月額¥300 / 年額¥1,500(7日トライアルは年額のみ・既定選択)。買い切りはローンチ非搭載・予告もなし(D30/D90等の実測後に年額4年分目安で再検討)。解説アクセスはレンタルモデルに転換(旧「広告で永久開放」を supersede): 最初の14作品=ウェルカム特典で永久無料、以降は「広告1本=その作品の解説の24時間チケット」、Pro=契約中すべて広告なし。特集は恒久的な冒頭プレビュー(導入+1作品目無料、広告開放なし)。Firebase Analytics 導入方針も確定(正本は RevenueCat)。全記録は .devnotes/discussions/2026-07-19-pricing-final.md
  • レンタルモデルのゲート実装 + Paywall刷新が完了(同日実装・シミュレータE2E検証済み): story_unlock 廃止→storyTicket(24hチケット、端末限定・prune)、ゲートは storyGate 純関数、free_story_count は manifest 配信値を初回起動でピン留め(現在14)。フォールバックは当日分のみ救済+注記表示、過去分は再試行案内。CTA「広告1本で、この解説を24時間読む」/「7日間Proを試す」並列、残り2枚予告あり。Paywall は 2プラン・¥300/¥1,500・新文言。xcstrings は 86キー×8言語
    • 残: rewarded 経路の最後だけ手動確認(実テスト広告の「報酬を獲得しました」までは確認済み。広告を手で閉じてチケット付与(source=ad)を1回見れば完全)
  • Phase 2(アプリ本体)は完了済み。残るスタブ境界は iCloud(ProgressSyncProvider)のみ
  • Fable チェックは 215/1,200 完了(残985)。今日は進んでいない
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す。dist の manifest.json には free_story_count=14 を追記済み(pm export も出力するよう改修済み)
  • シミュレータは検証用に DB を書き換え済み + 今回の日送りテストで獲得17件(うち未来日あり。実機は無変更)

次に何をするか:

  1. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行
  2. StoreKit(RevenueCat)実装 + Firebase Analytics 導入(価格決着済み。表示価格は StoreKit の適格性・ローカライズ価格を正に。トライアル消化済みユーザーは即時課金表示へ切替)
  3. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  4. ローンチ前の広告残タスク: app-ads.txt / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー
  5. rewarded 経路の手動確認(上記)

詰まっていること・未決事項:

  • 買い切りの再検討発動(実測データが揃ってから)/ 市場別価格ローカライズの具体テーブル(StoreKit実装時に確定)/ 月例特集の制作体制(9言語対応の範囲、ローンチ前バッファ本数、プレビュー編集規律「1作品目まで=問い、2作品目以降=答え」のテンプレ化)
  • ATT を出すか(eCPM は上がるがプライバシー印象とトレードオフ)/ EU 配信の有無(UMP 要否が決まる)
  • App Store 審査対策: Review Notes に 14枚・広告・Pro の関係を記載する(レンタルモデル決定の付帯事項)。ストア文言の「永久収蔵」は作品に限定
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する(収集元拡大調査の結論。詳細は discussions 参照)
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.0.146 に更新済み 2026-07-19)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ。報告メールの自動入力欄と件名は日本語固定(開発者向け)、UI と冒頭説明のみ9言語

2026-07-19 23:42 時点より前のスナップショット(2026-07-19 20:38作成分)

今どこまで進んだか:

  • Phase 2(iOSアプリ本体)の実装が完了(2026-07-19): 最後の2項目だった String Catalog 9言語 + オフライン画像保存を実装・検証済み
    • String Catalog: Resources/Localizable.xcstrings(85キー×8言語、キー=日本語原文・基準言語 ja)+ InfoPlist.xcstrings(アプリ名 ja=ポケット美術館 / 他=Pocket Museum)。ja/en/zh-Hans のシミュレータ実表示で検証済み。UI文字列を追加したら xcstrings に8言語を手で追記する運用
    • オフライン画像: ImageStore が獲得済み作品の thumb+full を自動ディスク保存(獲得時+起動時バックフィル+prune)。機内モードでも全画面表示OKを検証済み。表示は StoredAsyncImage(AsyncImage は全廃)
    • 副産物: museumName を7館×9言語に修正(旧3館のままだった)
  • アプリアイコン(真珠の耳飾りの少女)・図鑑1,200点化・AdMobリワード広告・ローカル通知は完了済み(〜2026-07-17)。残るスタブ境界は iCloud(ProgressSyncProvider)のみ
  • Fable チェックは 215/1,200 完了(残985)。並行セッションが少しずつ進行中
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す
  • シミュレータは検証用に DB を書き換え済み(firstLaunchDay=2026-06-01。実機は無変更)

次に何をするか:

  1. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行
  2. 価格体系の再評価(買い切り¥3,000の位置づけ。保留中)→ 決着後に StoreKit(Pro課金)実装。Paywall の価格表記は ¥ハードコードなので StoreKit 接続時に実価格表示へ
  3. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  4. ローンチ前の広告残タスク: app-ads.txt / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー
  5. フォールバック開放(当日作品×広告unavailable)が無言で開く点の UX 検討(アラートを出すか)

詰まっていること・未決事項:

  • 価格体系(買い切り¥3,000の位置づけ)/ 特集当月分を無料の味見にするか / 無料全文期間の日数(14日基準、7/14/30でA/B)/ 月例特集の制作体制(9言語対応の範囲)
  • ATT を出すか(eCPM は上がるがプライバシー印象とトレードオフ)/ EU 配信の有無(UMP 要否が決まる)
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する(収集元拡大調査の結論。詳細は discussions 参照)
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.0.146 に更新済み 2026-07-19)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ。報告メールの自動入力欄と件名は日本語固定(開発者向け)、UI と冒頭説明のみ9言語

2026-07-19 20:38 時点より前のスナップショット(2026-07-17 02:36作成分)

今どこまで進んだか:

  • アプリアイコンが完成(2026-07-17): 「真珠の耳飾りの少女」の無改変顔クロップ(確定 crop box (328, 0, 4095, 3767)、出自は Wikimedia Commons = アプリ内画像と同一経路)。iOS 18 ダーク/ティンテッド外観対応、シミュレータ実表示で User 承認済み。経緯は .devnotes/discussions/2026-07-16-app-icon-artwork.md(三者議論2ラウンド+実寸比較。いったんゴッホ自画像に決定→収録実現で変更)
  • 図鑑が1,200点に拡大(2026-07-17 受け入れ): 収集元4館追加(CMA / NGA / ゲティ / マウリッツハイス、計7館)+ 追加200点の9言語解説生成済み。受け入れ検証クリア(9言語×1,200件、既存1,000点無変更、トーン一致)。調査・実装は並行セッション+Codex(.devnotes/discussions/2026-07-16-collection-source-expansion.md
  • AdMobリワード広告・ローカル通知は実装済み(2026-07-16、E2E検証済み)。アプリは訪問駆動デッキ仕様で実機動作中。残るスタブ境界は iCloud(ProgressSyncProvider)のみ
  • Fable チェックは 215/1,200 完了(残985)。並行セッションが少しずつ進行中
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す
  • シミュレータは検証用に DB を書き換え済み(firstLaunchDay=2026-06-01。実機は無変更)

次に何をするか:

  1. Fable チェック再開(残985、毎日100作品目安)。看板作品を含む新200点の優先チェックを検討 → 完走後に pm deck 本実行
  2. 価格体系の再評価(買い切り¥3,000の位置づけ。保留中)→ 決着後に StoreKit(Pro課金)実装
  3. Phase 2 残り: String Catalog 9言語 / オフラインDL(アイコンは完了)
  4. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  5. ローンチ前の広告残タスク: app-ads.txt / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー
  6. フォールバック開放(当日作品×広告unavailable)が無言で開く点の UX 検討(アラートを出すか)

詰まっていること・未決事項:

  • 価格体系(買い切り¥3,000の位置づけ)/ 特集当月分を無料の味見にするか / 無料全文期間の日数(14日基準、7/14/30でA/B)/ 月例特集の制作体制(9言語対応の範囲)
  • ATT を出すか(eCPM は上がるがプライバシー印象とトレードオフ)/ EU 配信の有無(UMP 要否が決まる)
  • マウリッツハイス公式サイトの高解像度DLは非商用限定。同館の画像は Wikimedia Commons 経由に限定して運用する(収集元拡大調査の結論。詳細は discussions 参照)
  • クリーブランド「聖母子」のレオナルド帰属はメタデータ通りか Fable チェックで要精査
  • Release の実広告は AdMob 側の反映待ちの可能性。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.1.3)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー + xcodebuild -allowProvisioningUpdates で解決済み(DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ

2026-07-17 02:36 時点より前のスナップショット(2026-07-16 19:51作成分)

今どこまで進んだか:

  • AdMobリワード広告の実導入が完了(2026-07-16): Google Mobile Ads SDK 13.6.0(SPM)+ AdMobRewardedAdProvider(スタブ境界差し替え)。本番アプリID・リワードユニットID発行・反映済み。Debug=テストユニット / Release=本番ユニットの二段構え、ユニットID空ならSDK不起動→当日フォールバックの安全弁つき。シミュレータE2E検証済み(テスト広告→報酬→全文解錠 source=ad
  • ローカル通知が完了(2026-07-16): 毎朝の「今日の1枚」リマインダ(デフォルト8:00、マイでトグル+時刻変更)。許可リクエストはトグルON時のみ。E2E検証済み(登録→配達→バナー実写)
  • アプリは訪問駆動デッキ仕様で実機動作中。残るスタブ境界は iCloud(ProgressSyncProvider)のみ
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す
  • Fable チェックは一時停止中(205/1,000 完了)
  • シミュレータは検証用に DB を書き換え済み(firstLaunchDay=2026-06-01 で14日無料窓が切れた状態 = 広告ゲートを即試せる。実機は無変更)

次に何をするか:

  1. Fable チェック再開(毎日100作品目安、残り795)→ 完走後に pm deck 本実行
  2. 価格体系の再評価(買い切り¥3,000の位置づけ。保留中)→ 決着後に StoreKit(Pro課金)実装
  3. Phase 2 残り: String Catalog 9言語 / アプリアイコン(ローカル通知は完了)
  4. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  5. ローンチ前の広告残タスク: app-ads.txt / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー
  6. フォールバック開放(当日作品×広告unavailable)が無言で開く点の UX 検討(アラートを出すか)

詰まっていること・未決事項:

  • 価格体系(買い切り¥3,000の位置づけ)/ 特集当月分を無料の味見にするか / 無料全文期間の日数(14日基準、7/14/30でA/B)/ 月例特集の制作体制(9言語対応の範囲)※広告SDK選定は AdMob に決着(DECISIONS 参照)
  • ATT を出すか(eCPM は上がるがプライバシー印象とトレードオフ)/ EU 配信の有無(UMP 要否が決まる)
  • Release の実広告は AdMob 側の反映待ちの可能性(登録直後は数時間〜数日)。未配信の間は unavailable→フォールバックで動くので実害なし
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.1.3)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー(~/.config/asc/AuthKey_8M2SWG78S6.p8)+ xcodebuild -allowProvisioningUpdates で解決済み(詳細は DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ
  • アプリアイコン未設定(ホーム画面で真っ白。早めに作りたい)

2026-07-16 19:51 時点より前のスナップショット(2026-07-16 08:10作成分)

今どこまで進んだか:

  • 訪問駆動デッキ移行が完了(2026-07-16): Codex の実装を受け入れ検証し、受け入れ基準6項目すべてクリア(pm deck 決定性 / export / 獲得サイクル / 全文ゲート+広告スタブ+フォールバック / コレクション=獲得済みのみ表示 / 旧概念残骸ゼロ)。シミュレータと実機(iPhone 14)の両方で動作確認済み
  • ユーザー向け呼称を「朱印帳」→「コレクション」に変更(ローカライズ容易性。「収蔵 N 作品」表記は残す)
  • アプリは新仕様で実機動作中: 訪問駆動デッキ・出会い無料・全文は広告かPro・コレクションは獲得済みのみ。広告と iCloud はスタブ境界(RewardedAdProvider / ProgressSyncProvider)
  • 検証用の deck.json / dist は生成済み(Git 管理外)。本番デッキは Fable チェック完走後に deck.json を消してから pm deck で作り直す(残すと接頭辞として固定される)
  • Fable チェックは一時停止中(205/1,000 完了)

次に何をするか:

  1. Fable チェック再開(毎日100作品目安、残り795)→ 完走後に pm deck 本実行
  2. 価格体系の再評価(買い切り¥3,000=年額2年分は買い切り誘導が強すぎる指摘あり。保留中)
  3. Phase 2 残り: ローカル通知 / String Catalog 9言語 / アプリアイコン
  4. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)
  5. フォールバック開放(当日作品×広告unavailable)が無言で開く点の UX 検討(アラートを出すか)

詰まっていること・未決事項:

  • 価格体系(買い切り¥3,000の位置づけ)/ 特集当月分を無料の味見にするか / 無料全文期間の日数(14日基準、7/14/30でA/B)/ 広告SDKの選定 / 月例特集の制作体制(9言語対応の範囲)
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml、現在 192.168.1.3)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • CLI 実機署名は ramanu アカウントの ASC キー(~/.config/asc/AuthKey_8M2SWG78S6.p8)+ xcodebuild -allowProvisioningUpdates で解決済み(詳細は DEVLOG 2026-07-16 08:10)
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ
  • アプリアイコン未設定

2026-07-16 08:10 時点より前のスナップショット(2026-07-16 04:50作成分)

今どこまで進んだか:

  • カレンダーモデルの結論が出た(2026-07-16 鼎談、全8ラウンド): 共通カレンダー廃止 → 訪問駆動デッキ(月別サブデッキ12本、その日初めて開いたときだけ1枚獲得)。マネタイズも刷新: 「出会いは無料、解説全文は広告かPro」(全館アクセス廃止・遡り7日無料+極ロック廃止・図鑑=朱印帳化・初回14日は全文無料)。全記録は .devnotes/discussions/2026-07-16-calendar-model.md、決定2件は DECISIONS.md 参照
  • Codex への実装依頼書を作成済み: 実装依頼_訪問駆動デッキ移行.md(リポジトリ直下)。pm deck 新設 / アプリデータ層(DeckEntry・acquisition・story_unlock)/ UI改修(TodayView 2段構成・図鑑=朱印帳・ArchiveViewロック全廃・Paywall文言)/ 受け入れ基準6項目。広告SDKと CloudKit はスタブ境界でスコープ外
  • Phase 2(iOSアプリ)は実機動作中(現状は旧仕様のまま: 共通カレンダー・遡りロック・図鑑全点表示)
  • Fable チェックは一時停止中(205/1,000 完了)

次に何をするか:

  1. Codex に実装依頼書を渡して実装させる → 完了後にこちらでレビュー・検証(codex-qa-loop 候補)。依頼書末尾の「質疑」セクションに Codex の質問が溜まる方式
  2. 価格体系の再評価(買い切り¥3,000=年額2年分は買い切り誘導が強すぎる指摘あり。保留中)
  3. Fable チェック再開(毎日100作品目安)→ 完走後に pm deck を実行してデッキ生成
  4. Phase 2 残り: ローカル通知 / String Catalog 9言語 / アプリアイコン
  5. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)

詰まっていること・未決事項:

  • 価格体系(買い切り¥3,000の位置づけ)/ 特集当月分を無料の味見にするか / 無料全文期間の日数(14日基準、7/14/30でA/B)/ 広告SDKの選定 / 月例特集の制作体制(9言語対応の範囲)
  • 実機の配信URLが Mac の LAN IP 直書き(project.yml の PM_CONTENT_BASE_URL)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ
  • アプリアイコン未設定 ※「カレンダー --start のローンチ日確定待ち」はデッキ転換で消滅

2026-07-16 04:50 時点より前のスナップショット(2026-07-16 02:25作成分)

今どこまで進んだか:

  • Phase 2(iOSアプリ)着手・実機で動作中: app/ に SwiftUI / iOS 17+ / XcodeGen / GRDB 7 の雛形。manifest sha256 差分同期 → SQLite キャッシュの データ層が完成
  • 実装済み画面: 今日の1枚(モックのトーン再現)/ 図鑑1,000点 / 作品詳細(メタデータ・所蔵館リンク・CC0)/ 誤訳報告(mailto、ID・言語自動埋め込み)/ 全画面ズームビューア(横向き対応・スワイプ閉じ・✕トグル)/ お気に入り(マイに一覧)/ 遡りアーカイブ(7日無料+朱印「極」ロック)/ ペイウォール骨組み(確定価格、決済はPhase 3)
  • pm export 実装済み: R2 と同一レイアウトの data/dist/(manifest+content+images)。開発中は python3 -m http.server 8787 --bind 0.0.0.0(dist/ 配下)で配信し、Debug ビルドは Mac の LAN IP を向く(app/README.md 参照)
  • CDN時刻補正実装済み(端末日付変更対策、DECISIONS 2026-07-15)
  • Fable チェックは一時停止中(205/1,000 完了、アプリ優先の判断)

次に何をするか:

  1. Phase 2 残り: ローカル通知 / String Catalog 9言語 / オフラインDL
  2. 今日の1枚のカレンダーモデルの結論(共通カレンダー維持 or インストール日起点の個人化。順番モデルは季節・記念日連動を失うため保留中。遡りは共通前提で実装済みなので変えるなら早めに)
  3. Fable チェック再開(毎日100作品目安)+ チェック済み205作品への it/ko/pt/zh-Hans 追いチェック
  4. pm upload(R2、wrangler / Cloudflare 認証が必要 ← You に依頼)。dist/ を上げるだけの状態

詰まっていること・未決事項:

  • 実機の配信URLが Mac の LAN IP 直書き(project.yml の PM_CONTENT_BASE_URL)。Wi-Fi 変更時は ipconfig getifaddr en0 で更新して xcodegen 再生成
  • 誤訳報告の宛先が仮アドレス(AppConfig.supportEmail)。ローンチ前に専用アドレスへ
  • アプリアイコン未設定。カレンダーの --start はローンチ日確定後に再生成

2026-07-16 02:25 時点より前のスナップショット(2026-07-14 02:08作成分)

今どこまで進んだか:

  • 解説9言語×1,000件がすべて生成完了(全言語 ja と ID 完全一致を 2026-07-14 に検証済み)。Codex バックエンドの冪等再実行が失敗分も回収
  • Fable 最終チェック体制が稼働: 1作品=1サブエージェント集中型(8並列・完了通知駆動)。205作品×5言語(ja/en/es/fr/de)チェック済み、平均90.2点、修正35作品71件は data/stories/revisions.jsonl(72行)に全履歴あり。コスト実測 $1.03/作品(API単価換算、サブエージェント実測)
  • チェック済みレコードは story_quality: ai_reviewed + review{score,reviewer,reviewed_at,notes} + revision 付き。ja原文の事実誤り(画像と食い違う記述)が205作品中10作品で見つかり全言語修正済み——品質リスクの主因は翻訳より原文

次に何をするか:

  1. 残り795作品の Fable チェックを毎日100作品目安で消化(消費量が大きいため。1回約100分・$103相当/100作品)。9言語一括に切り替えるか5言語+追いチェック維持かは次回判断
  2. チェック済み205作品への it/ko/pt/zh-Hans 追いチェック
  3. 人力監修(カレンダー365件×日英 → human_reviewed)。pm dashboard がレビューUI
  4. pm upload(R2+マニフェスト)← wrangler / Cloudflare 認証が必要(You に依頼)

詰まっていること・未決事項:

  • R2 は Cloudflare 認証待ち。カレンダーの --start はローンチ日確定後に再生成
  • チェックの視覚的事実照合はエージェントが美術館公式画像を取得できた場合のみ確実。残り795作品でも原文事実誤りが約5%出る前提でスケジュールする

2026-07-14 02:08 時点より前のスナップショット(2026-07-13 18:45作成分)

今どこまで進んだか:

  • Phase 1 は「収集 → キュレーション → 画像 → 365日カレンダー → 日本語解説1,000件」まで完了
  • 解説生成は Codex CLI(サブスク枠・追加費用ゼロ)が既定バックエンドpm generate、Claude APIバッチは --backend api)。ja は平均327字・仕様逸脱ゼロ・全件 ai_generated
  • 成果物(いずれもGit管理外): data/stories/ja.jsonl(解説1,000件)、data/curated/calendar.json(365日割当、開始日は仮の2026-10-01)、data/curated/selection.jsonldata/images/
  • You が pm dashboard(選定作品+多言語解説のHTMLレビューUI)を実装中(cli.py + pm/dashboard.py)

次に何をするか:

  1. en を pm generate --lang en --limit 5 で翻訳品質確認
  2. 良ければ8言語×1,000件を夜間実行(--lang en,es,fr,de,it,pt,ko,zh-Hans、4並列で約11時間見込み)
  3. 人力監修(カレンダー365件×日英 → human_reviewed)。dashboard がレビューUIになる想定
  4. pm upload(R2+マニフェスト)← wrangler / Cloudflare 認証が必要(You に依頼)

詰まっていること・未決事項:

  • R2 は Cloudflare 認証待ち(wrangler 未導入)。カレンダーの --start はローンチ日確定後に再生成が必要

2026-07-13 18:45 時点より前のスナップショット(2026-07-12作成分)

今どこまで進んだか:

  • Phase 1 は「収集 → キュレーション → 画像処理」まで完了。選定1,000点(西洋600/日本250/その他150)すべてに WebP 2解像度(thumb 800px / full 2400px、計709MB)が生成済み
  • 成果物: pipeline/data/curated/selection.jsonl(スコア・地域付き選定リスト)、pipeline/data/images/{source}-{id}/(画像)、いずれもGit管理外
  • curate→images は自動差し替えループ(実寸不足・画像URL切れは次点と交代)。有名画家ティア表は pipeline/pm/artists.py で調整可能
  • 品質検証済み: 夜警・牛乳を注ぐ女・神奈川沖浪裏・ゴッホ寝室など有名作の存否チェック通過、西洋枠の下限もラ・トゥール級

次に何をするか:

  • 解説生成バッチ(pm generate): Claude API・9言語・story_quality 管理 ← ANTHROPIC_API_KEY が必要(You に依頼)
  • R2アップロード+マニフェスト(pm upload)← wrangler / Cloudflare 認証が必要
  • 365日配信カレンダー(pm calendar)← 外部依存なし、先行可能

詰まっていること・未決事項:

  • 解説生成と R2 は認証情報待ち。カレンダー生成から先に進められる

2026-07-12 01:11 時点のスナップショット

今どこまで進んだか:

  • Phase 1 の収集工程が完了。pipeline/ に Python CLI pm(uv 管理)を実装し、3館フルランで 44,792件 の正規化メタデータを収集済み(Met 13,554 / AIC 26,359 / Rijksmuseum 4,879。data/raw/*.jsonl、Git管理外)
  • 母集団の分布は西洋60% / 日本28% / その他11%で目標比率とほぼ一致。Wikidataリンク25%、館ハイライト420件、AIC画像の97%が長辺2000px以上
  • 収集は冪等・再開可能(追記式JSONL + スキップ台帳)。Met の持続的403で約250件のみ未回収だが、pm collect met 各プールを再実行すれば自動再試行される

次に何をするか:

  • pm curate 実装: 知名度(Wikidataリンク・館ハイライト)・地域バランス(重み 60:25:15)・画質のスコアリングで1,000点選定
  • その後: 解説生成バッチ(9言語・story_quality 管理)→ 画像処理(WebP 2解像度)→ R2アップロード+マニフェスト → 365日カレンダー

詰まっていること・未決事項:

  • なし。AIC の知名度プロキシは Wikidata が無いため is_boostedhas_not_been_viewed_much・作家名で代替する必要あり(curate 設計時に対応)

2026-07-11 17:54 時点のスナップショット

今どこまで進んだか:

  • 仕様確定フェーズ完了。引き継ぎ.md の未決事項6件を 2026-07-11 にすべて確定(アプリ名・言語セット・キュレーション比率・買い切り仕様・誤訳報告UI・Android時期。詳細は DECISIONS.md)
  • 名称・商標チェック完了。「ポケット美術館」はアプリ名として使用可。英語名は "Pocket Museum" 単体が既存アプリと完全一致のため "Pocket Museum: Daily Art" 等の複合名にする
  • 実装は未着手

次に何をするか:

  • Phase 1 着手: pipeline/ サブディレクトリにPythonで収集スクリプト(Met / AIC / Rijksmuseum の3館API)から。CLI体裁は intelligence-bank の ib コマンドの流儀に合わせる

詰まっていること・未決事項:

  • なし(将来の再検討事項は ROADMAP「いつか」参照: 防衛商標出願、グッズ展開時の第16類被り)

ROADMAP(計画)

ロードマップ

今週

  • Shipaton 2026 応募(2026-08-15 SUBMITTED。デモ動画・スクショ・英文ストーリー一式は store-assets/shipaton/。締切 10/1 15:45 JST まで編集可)

  • Shipaton デモ動画を美術館壁背景に刷新(2026-08-16: YouTube 新URL 7BoL3VbVYIQ・旧は限定公開・Devpost 更新済み)

  • ストア掲載メディアの9言語化(2026-08-16: スクショ6枚×9ロケール + App プレビュー動画9本を ASC 登録。コピー正本は COPY_REVIEW.md / VIDEO_COPY_REVIEW.md)

  • iOS 1.0.1 審査提出(2026-08-16 WAITING_FOR_REVIEW。build 8 = コレクションの地域別カード撤去 + メディア9言語。releaseType=MANUAL)

  • 1.0.1 承認後の手動公開(2026-08-17: 審査承認確認 → 配信国175か国維持を確認 → API で公開 → READY_FOR_DISTRIBUTION)

  • フェルメール特集の恒久無料開放 + 無料公開中バッジ + 8言語全文レビュー74件修正(2026-08-17 本番反映済み。レビュー結果正本は レビュー結果_特集記事8言語全文レビュー.md)

  • iOS 1.0.2 審査提出(2026-08-17 WAITING_FOR_REVIEW。build 9 = 特集一覧の無料公開中バッジ。What's New「フェルメール特集を無料開放」9言語・releaseType=AFTER_APPROVAL で承認後自動公開)

  • iOS 1.0.2 の審査結果確認(2026-08-18 08:13 JST 公開を確認。jp/us とも version 1.0.2・What's New 9言語どおり)

  • 特集公開・休眠復帰のお知らせ通知を iOS に実装(2026-08-18: ローカル通知のみ・現地19:00・毎朝リマインダと独立した「特集のお知らせ」トグル既定ON。文言9言語は Codex レビュー済み。DECISIONS 4件参照)

  • iOS 1.0.3 / build 10 を TestFlight へアップロード(2026-08-18: VALID / IN_BETA_TESTING。Delivery UUID 6f5ac1b7)

  • TestFlight 実機で 1.0.3 の通知まわりを確認(トグルの表示と独立動作。発火を見るなら端末の日付送りか publish_at 入りコンテンツの配信)

  • Android へ通知機能を後追い実装(Play 審査の結果が出てから。文言は xcstrings 正本から生成)

  • AdMob 開通チェーン(再審査確認 → ストア掲載リンク → アプリ審査 → 配信開始確認)

  • Shipaton トラクション作り: PR TIMES 骨子 → 9月中配信(Grand Prize/HAMM は 〜9/30 の伸びが審査材料)

  • AdMob 承認が出たら: X(田沢垢)で報告投稿 → note に PR 記事(リリース+Shipaton 文脈。チャネル戦略どおり note 集約)。X 発信を継続するなら Devpost の #BuildInPublic 欄に投稿リンクを後追い追記(締切まで編集可)

  • Phase 1: 収集スクリプト(Met / AIC / Rijksmuseum の3館API、44,792件収集完了 2026-07-12)

  • Phase 1: pm curate — スコアリングで1,000点選定(2026-07-12)

  • Phase 1: pm images — 画像処理(WebP 2解像度、1,000点分709MB生成完了 2026-07-12)

  • Phase 1: pm calendar — 365日配信カレンダー生成(2026-07-13、記念日13件一致・地域比率60:26:15を検証済み)

  • Phase 1: pm generate 実装 + 日本語マスター解説1,000件生成(2026-07-13、Codex CLI既定・平均327字・逸脱ゼロ)

  • Phase 1: 解説の8言語展開(2026-07-14 全8言語×1,000件完走、全言語 ja と ID 完全一致を検証済み)

  • Phase 1: Fable 最終チェック 残り985作品(毎日100作品目安、$1.03/作品・約100分/100作品。215/1,200 完了)※2026-07-27 決定: 完走はリリース条件から外しリリース後に順次実施(チェック済み分は随時 pm upload で差し替え。DECISIONS 参照)

  • App Store 審査提出(2026-07-29 完了: 1.0.0 は build 6(計測修正+Crashlytics+画像最適化+通知プライマー変更)で提出。サブスク2種+グループを同一提出に含めて 12:53 に審査待ち。取りこぼし検証は scripts/asc-submission-check.mjs)→ 2026-08-07 審査承認(配信国ゼロ事故で公開されず → 8/11 復旧・反映待ち。DECISIONS 参照)

  • scripts/asc-submission-check.mjs に配信国(availability)存在チェックを追加(2026-08-11 の事故の再発防止)

  • Phase 1: チェック済み215作品への it/ko/pt/zh-Hans 追いチェック

  • 収集元拡大: 4館追加(クリーブランド/NGA/ゲティ/マウリッツハイス、計7館)で図鑑を1,200点化 + 追加200点の9言語解説生成(2026-07-17 受け入れ検証クリア。調査・実装は並行セッション+Codex)

  • Phase 2: アプリアイコン(真珠の耳飾りの少女の無改変顔クロップ、iOS 18 ダーク/ティンテッド対応、2026-07-17 実装・承認)

  • Phase 2: 今日の1枚のカレンダーモデルの結論(2026-07-16 鼎談全8ラウンドで確定: 訪問駆動デッキ + 「出会い無料・全文は広告かPro」。DECISIONS 2件参照)

  • Phase 2: Codex による訪問駆動デッキ移行の実装(実装依頼_訪問駆動デッキ移行.md)→ 受け入れ基準6項目クリア・実機動作確認・呼称「コレクション」に変更(2026-07-16)

今月

  • Android 版の開発(2026-08-15 方針転換・DECISIONS 参照): 鑑賞コア+サブスク優先で実装 → 〜9月上旬に Play 審査提出。広告+UMP は後回し可(フェイルオープン設計)。キルスイッチ: 9/8 までに提出見込みなしなら PR TIMES を iOS 単独で切り離し

    • 技術選定 = Kotlin + Jetpack Compose 単体で確定(2026-08-15・DECISIONS 参照)
    • 土台構築 + データ層移植(SyncEngine/DeckEngine/StoryGate/Room)+ 今日の1枚がエミュレータで動作(2026-08-15、targetSdk 36)
    • 文言の仕組み: xcstrings → strings.xml 生成(9言語・ドリフト検知つき。2026-08-15)
    • 画面移植: コレクション / 作品詳細(ズーム)/ 特集 / マイ(2026-08-15 完了・エミュレータ ja で全画面動作確認済み。ズームビューア含む)
    • 課金: RC に Play アプリ追加 → goog_ キー → PurchaseProvider + Paywall(2026-08-15 実装完了・RC 通信開通。entitlement pro は iOS と共有)
    • 課金の外部チェーン前半(2026-08-15 完了): Play Console アプリ作成 → AAB 内部テスト公開 → サブスク2種作成・有効化(¥300/¥1,500・年額のみ7日無料)→ RC 商品登録・entitlement/offering アタッチ(配線完了は BILLING_UNAVAILABLE への変化で確認)
    • 課金の外部チェーン後半: RC の Play サービスアカウント認証情報は 2026-08-15 完了(専用SA 新規作成 + アプリ限定権限4つ + 鍵を ~/.config/android/ に発行 → RC 登録、validate-app-credentials 3/3 valid。あわせて RTDN も接続しテスト通知の到達を確認。DECISIONS 参照)→ 2026-08-17 内部テスター設定 + 実購入E2E 完了(内部テスター/ライセンステスター登録 → opt-in → pm-playstore エミュレータで購入・復元・トライアル表記の3点検証。auto-memory android-play-e2e-setup 参照)
    • 通知(毎朝リマインダ + マイの設定UI。2026-08-15 実配達まで検証済み)/ アダプティブアイコン(同日)/ 今日の1枚画面の本格化(額装+ゲートCTA、同日)
    • 署名鍵 + AAB: アップロード鍵を ~/.config/android/ に生成・署名済み AAB ビルド確認(2026-08-15。Play Console 作成後すぐアップロード可)
    • Analytics 送信(2026-08-15 完了: Firebase Android アプリ登録 + 16イベント配線・実ログ検証済み・両OS合流状態)/ オフライン画像保存(同日・機内モード検証済み)/ 通知プライマー(同日・全ステップE2E済み)
    • 抽選ロジックの共有テストベクタ(2026-08-15 完了: docs/test-vectors 正本240ケース・iOS テストターゲット新設・両OS通過)
    • Play 提出物: ストア掲載9言語 / スクショ / データセーフティ / コンテンツレーティング(2026-08-17 全登録完了: 掲載9言語+スクショ 9:16 版162枚+FG+アイコンを Publishing API 一括登録・アプリのコンテンツ 9/9 申告・レーティング ESRB 13+/PEGI 3・カテゴリ教育・連絡先公開。プライバシーポリシー両OS化+削除章もデプロイ済み。DECISIONS 2件参照)
    • 製品版リリースの作成 → 審査送信(2026-08-17 23:07 完了): 製品版 4 (1.0.0)・配信国176か国・掲載9言語・全申告の19件を送信、「審査中の変更」に遷移。直前ブロッカー「広告ID申告不完全」は「使用する」修正で解消(DECISIONS 参照)。キルスイッチ 9/8 より3週間前倒しで提出達成
    • 提出前判断(2026-08-17 決着): ToS = 自前利用規約ページ新設 + Paywall リンク + 掲載文追記で対応(DECISIONS 参照)/ プロモコード = 不要と判断して送信 / 削除ページの保持期間明記 = 任意のまま持ち越し
    • Play 審査結果の確認(通常7日以内。承認で自動公開 → 一時的アプリ名解消・ストアページ・実機動作を確認)
  • PR TIMES 配信は両OS揃えて9月中旬目標 → 配信後 Devpost に Google Play URL 追記(〜9/30)

  • Phase 1 残り: 人力監修(human_reviewed への昇格。※デッキ転換により対象を再定義する必要あり — 旧「カレンダー365件×日英」の枠は廃止。pm dashboard をレビューUIに)

  • Phase 1 残り: R2アップロード(2026-07-20 完了: R2有効化・バケット pocket-museum-contentpm upload 実装・検証用 dist 712MB 配信・content.ramanu.co.jp 開通・Release 向き先差し替え・シミュレータE2E済み。本番デッキは Fable 完走後に差分アップロードで置き換え → 2026-07-27 本番を1,200点+deck v2+特集ja/en に差し替え完了)

  • Phase 2 着手: iOSアプリ(SwiftUI)雛形、マニフェスト同期+SQLiteキャッシュ層(2026-07-15、XcodeGen+GRDB・実機動作)

  • Phase 2: 今日の1枚 / 図鑑 / 作品詳細(誤訳報告mailto・ズームビューア含む)(2026-07-15)

  • Phase 2: お気に入り / 遡りアーカイブ(7日無料+朱印ロック)/ ペイウォール骨組み / CDN時刻補正(2026-07-15)

  • Phase 2: ローカル通知(毎朝の「今日の1枚」リマインダ、デフォルト8:00・マイで変更可。2026-07-16 E2E検証済み)

  • Phase 2 残り: String Catalog 9言語 / オフラインDL(2026-07-19 実装完了。ja/en/zh-Hans 実表示+機内モード動作をシミュレータ検証済み)

今四半期

  • ドイツ語の du / Sie をアプリ全体で統一する(既存の通知プライマー文言が Sie、別の既存文言が du。Codex の見解は du 寄せ。2026-08-18 に発見)

  • Phase 2 完了: 今日の1枚 / 図鑑 / 作品詳細 / ローカル通知 / String Catalog 9言語(2026-07-19 全項目実装済み。残るスタブ境界は iCloud のみ = Phase 3)

  • Phase 3: RevenueCat課金 + WidgetKit + ASO 9言語 + App Store申請

  • Phase 3: RevenueCat課金のアプリ側実装(PurchaseProvider境界・Paywall実価格化・トライアル適格性表示・購入/復元。2026-07-20 シミュレータE2E+Releaseビルド検証済み。識別子規約は DECISIONS 参照)

  • Phase 3: RevenueCat/ASC 外部セットアップ(2026-07-20 完了: RC アプリ+商品作成・SDKキー配線 / ASC アプリレコード Apple ID 6792521728 + サブスク商品2つ×175地域+7日無料イントロ / In-App Purchase Key・ASC API キーの RC 登録 / Paywall 実価格表示まで開通。DEVLOG 01:20 参照)

  • Phase 3: サンドボックス実購入E2E(2026-07-20 完了: 実機 iPhone 14 で購入成功、RevenueCat に entitlement pro active / trialing / sandbox / JP を確認。シミュレータは実購入不可の制限判明・以後の課金実購入検証は実機で。テスター applesandboxtester1@ramanu.co.jp。副産物で free_story_count が新規インストールに効かない実バグ2件を発見・修正)

  • 提出前: サブスク審査用スクリーンショット登録(2026-07-20 完了: Paywall 実写 1170×2532 を ASC API で両商品に登録、pm_pro_monthly/pm_pro_yearly とも READY_TO_SUBMIT に遷移・MISSING_METADATA 解消)※ストア表示名は全9言語完了

  • 提出前: ストア用スクリーンショット制作(2026-07-27 完了: ja を実画面化(ガイドライン2.3.3対応)+ en-US 5枚新規制作、両ロケール ASC 登録済み。iPhone 専用(TARGETED_DEVICE_FAMILY=1)のため iPad 版は不要。en 以外の7言語ロケールは未制作=公開後の任意課題)

  • ローンチ告知: PR TIMES の企業登録〜企業ページ整備(2026-07-26 完了: 日曜申請→約2h20mで審査承認・本登録済み・企業ID 187992。企業説明155字+ロゴ250×250+カバー1920×450 を公開、代表電話番号の公開は削除。無料枠は株式会社限定で合同会社は原則対象外=従量課金3万円税別が既定線。DECISIONS 参照)

  • ローンチ告知: プレスリリース本体の制作(骨子=ニュース価値の軸決めは promo-expert に壁打ち / メイン画像は横1920×1280以上を新規制作=縦長ストアスクショは流用不可 / 配信は App Store 公開後)

  • リリース前: en-US ストア名の接尾辞を再決断(2026-07-27 に Masterpieces で一旦決着 → 2026-07-28 に「Pocket Museum: Daily Art」へ再変更で最終決着。コンセプト伝達優先。DECISIONS 参照)

  • ローンチ前: プライバシーポリシーページ作成(2026-07-20 完了: https://ramanu.co.jp/pocket-museum/privacy/ 日英2ページ公開、AppConfig 差し替え+ASC en-US 設定済み。ja ストア掲載情報の作成時に ja 版URLも設定する)

  • Phase 3: リワード広告SDKの実導入(AdMob 13.6.0 に決定・スタブ差し替え・本番ID反映・E2E検証まで完了 2026-07-16。フォールバック=広告取得不可時はその日の全文を無料開放、実装済み)

  • Phase 3 残り: 広告のローンチ前対応(2026-07-20 決着: ATT なし + EU 配信 + UMP 実装 + AdMob の GDPR メッセージ「Pocket Museum GDPR」公開。app-ads.txt も完了済み。残は EEA フォームの実表示確認のみ=実機か公開後の EEA 実配信で。DECISIONS 参照)

  • 公開後: AdMob アカウント承認 + ストア掲載リンク(2026-07-20 新規申請が却下 → 原因はアプリ未公開によるコンテンツ確認不能と推定・同日再送信済み。承認 → リンク → アプリ審査が揃うまで実広告なし = フォールバック無料開放で運用)

  • Phase 3: iCloud同期(CloudKit。獲得集合=和集合・カーソル=同一deckVersion内最大値でマージ)

  • 価格体系の最終決定(2026-07-19 三者議論3Rで決着: 月額¥300/年額¥1,500・買い切りローンチ非搭載・解説はレンタルモデル=最初の14作品無料+広告1本で24時間チケット・特集は冒頭プレビュー。DECISIONS 4件参照。同日にゲート実装+Paywall刷新までE2E検証済み)

  • Phase 3: Firebase Analytics 導入(2026-07-20 完了: PMAnalytics 境界+8イベント+ユーザープロパティ free_count/deck_version、firebase-ios-sdk 12.16.0。プロジェクト pocket-museum-d060f 作成・iOS アプリ登録・plist 配置・実イベント送信検証済み。featured_* 2種は特集実装時に追加)

  • 通知プレパーミッション(起動時プライマー1回きり・許可機会温存型。2026-07-20 実装・Codex レビュー4件反映・シミュレータE2E済み。DECISIONS 参照)

  • レビュー促進(同意型ソフトアスク: 初回=星ダイアログ/2回目以降=write-review ページ + マイの常設リンク + Analytics 6イベント。2026-07-20 三者議論4Rで設計決着→実装・シミュレータE2E済み。仕様の正本は discussions/2026-07-20-review-prompt.md、DECISIONS 参照)

  • 月例特集の実装(2026-07-20 完了: pm featured check + export/upload 配信の器・4タブ目「特集」・featured-v1 同期・ぼかし帯+Pro CTA のゲート・Analytics 2イベント・1本目「フェルメール、窓辺の光」7節執筆・シミュレータE2E。言語範囲は「当面 ja のみ制作・器は9言語」で決着。DECISIONS 2件参照)

  • 月例特集の制作運用の残り(ローンチ前バッファ本数 / 月次制作フロー。翻訳範囲は 2026-07-27 に「リリース時から9言語制作」で決着=1本目は9言語配信済み・型は ja 執筆 → 実装依頼_特集記事7言語翻訳.md 形式で Codex 翻訳。編集規律「1作品目まで=問い、2作品目以降=答えと展開」は1本目でテンプレ実証済み。検収は2026-08-17 決定の「別モデル・言語別並列・全文対読」レビューを組み込む=1本目で型実証済み)

いつか

(いつかやりたいこと・アイデアストック)

  • 防衛的な商標出願(「ポケット美術館」第9類+第41類、数万円規模)— アプリが軌道に乗ったら。先行出願 商願2026-039383(ポケットミュージアム、第16類)とは非類似で共存登録の公算大
  • グッズ展開(ポストカード・画集等)をやる場合は第16類の先行出願と被るため商標を再検討
  • 買い切り(永久パス)の再検討 — D30/D90継続率・月額→年額移行率・広告LTV・解約理由が実測できたら。価格目安は年額4年分程度、「Pro完全同等」原則は維持(2026-07-19 決定の再検討条件)
  • Android 版の開発 — D30 実測で判断(2026-08-15 同日中に方針転換 → 「今月」へ前倒し。DECISIONS 参照)

DECISIONS(意思決定)

意思決定記録

このプロジェクトで下した重要な意思決定を記録する。 最新が上に来る。


2026-08-18: お知らせ通知はローカル通知で実装し、FCM とバックグラウンド同期は採らない

背景: 「特集を追加したら通知したい、ただし深夜に送りたくない、地域で出し分けられるか」という要望。選択肢は ①端末が先出しの publish_at を見てローカル通知を予約する案 ②FCM を導入してサーバから配信する案 の2つ。深夜回避は①なら端末の暦で組むだけで構造的に解決し、②はタイムゾーン別トピックの波状送信が要る。

決定: ①のローカル通知で実装する。バックグラウンド同期(BGAppRefresh)も入れない。

理由: 特集は月次・低頻度で「今すぐ見て」の即時性がない。②はプッシュトークンの扱いでプライバシーポリシー・データセーフティ・ASC プライバシー詳細の再申告が要る可能性があり、Android が Play 審査中の時期に触るコストに見合わない。①は先出し(配信日の1〜2週間前にマニフェストへ載せる)にすれば「その期間に一度でもアプリを開けば予約が入る」で足り、毎朝リマインダで毎日開く導線がある以上バックグラウンド同期は保険にすぎない。しかも iOS の BGAppRefresh は使わないアプリほど走らないため、掘り起こしたい休眠層には構造的に効かない。FCM は「その日のうちに開いてほしい告知」が必要になった時点で再検討する。

2026-08-18: 通知トグルは2本構成にし「特集のお知らせ」を既定ONにする

背景: 当初「毎朝リマインダ」1本ですべての通知を統括する案で進めかけたが、You から「毎朝リマインダを OFF にしている人にもお知らせは届かせたい」と要望。しかし1本のままそれを実現すると、ユーザーがお知らせを止める手段が「OS 設定でアプリの通知を全部 OFF」しか無くなる。

決定: マイの通知セクションを「毎朝の通知」と「特集のお知らせ」の2トグルにし、後者は全ユーザー既定ONで入れる。お知らせ側は毎朝リマインダのトグルと独立し、システムの通知許可のみを条件に配信する。

理由: 望んだ挙動(毎朝OFF × お知らせON)が既定で実現し、かつ切る手段も残る。1本構成だと毎朝リマインダごと通知を落とされるリスクがあり、毎朝リマインダはこのアプリのコア導線なのでそこを壊すのが最大の損失。トグル説明文は You 判断で不要とし、ラベル1行のみにした(副次的に、翻訳が3〜4倍に膨らむ fr/pt の折り返し問題も消えた)。

2026-08-18: 休眠復帰通知は特集にも特定の作品にも紐づけない

背景: 当初は休眠通知の本文にも最新の特集タイトルを載せ、タップで特集タブへ送る実装にしていた。You から「休眠は特集とか特定の絵画と結びつけるものじゃない」と指摘。

決定: 休眠復帰通知(7/21/60日)は本文なしのタイトル1行のみとし、userInfo にも記事 ID を持たせない。タップは通常起動(=「今日」タブ)に任せる。特集公開の通知だけが本文に記事タイトルを載せ、特集タブへ遷移する。

理由: 休眠復帰の目的は「戻ってきてもらうこと」であって特定コンテンツの宣伝ではない。特集を出しにすると、その特集に関心がない人には空振りになる。実装面でも latestFeatured クエリと FeaturedRef 型が不要になり簡潔になった。文面も「またゆっくり、絵の前に」→ 今日の1枚、と遷移先と意味が一致する。

2026-08-18: 通知タイトルは全言語32字以内に収める

背景: 9言語の通知タイトルで、ドイツ語が原文の3〜4倍の長さになる。バナーでの折り返し・省略の挙動が不明だった。

決定: 実測に基づき、全言語の通知タイトルを32字以内に収める運用ルールとする。長さ検証は xcrun simctl push に任意文字列のペイロードを流して行う。

理由: 実測で de 40字は語中で …zur… と切れ、37字は収まった(境界は38前後)。ただし検証機 iPhone 17 は 402pt 幅で、deploymentTarget iOS 17 なら 375pt 幅の端末も対象に入るため、安全側に32字とした。simctl push はアプリのコード変更もビルドも要らずバナーの見え方だけ確認できるので、以後この検証はこの手段で行う。

2026-08-18: 申し立てを受けた旧デモ動画2本は削除せず限定公開のまま残す

背景: Naxos の Content ID 申し立てで初代 Q62huvtjorg と2代目 7BoL3VbVYIQ が全世界ブロックになり、同じ件名のブロック通知が2日連続で届いた。どちらも既に限定公開へ降格済みで、Shipaton/Devpost に載っているのは BGM 差し替え済みの oPT_g_lx5v0(公開・再生可)。

決定: 旧2本は削除も異議申し立てもせず、限定公開のまま放置する。今後同じ件名の通知が来ても、Studio リンクの動画 ID が旧2本なら無視する。

理由: ブロックは限定公開の旧動画に閉じていて外部導線もなく、実害がない(YouTube 自身も「制限に問題がなければそのままで可」と案内)。削除は不可逆で、得られるのは通知停止だけ。申し立ての履歴を残しておく方が、後で経緯を確認したり異議を出す必要が生じたときに有利。

2026-08-17: Play 提出は自前の利用規約ページを新設して行う(iOS は Apple 標準 EULA 維持)

背景: 提出前判断として「Android Paywall の ToS リンク要否」が残っていた。Play には Apple の stdeula に相当する標準 EULA がなく、なしでも提出は可能だった。

決定: ramanu.co.jp/pocket-museum/terms/(ja/en)を新設し、Android の Paywall に利用規約リンクを追加(iOS と同じ3リンク並び)、Play 掲載文9言語にも利用規約行を追記して提出する。iOS は Apple 標準 EULA(stdeula)のまま変更しない。

理由: You 判断で「なしで提出」より先に整備する方を選択。サブスクの自動更新・解約・返金の条件を自社文書で明示でき、審査・ユーザー問い合わせの両面でリスクが減る。iOS を stdeula から自前 ToS に切り替えるのは審査済み構成を崩すため見送り。

2026-08-17: 広告 ID 申告は「使用する(分析、広告・マーケティング)」に修正(同日申告方針の部分修正)

背景: 同日朝の申告方針では広告 ID を「使用しない」とした(ローカルの merged_manifests 中間ファイルに AD_ID 権限が見えなかったため)。しかし審査送信直前のクイックチェックが「AAB のマニフェストに com.google.android.gms.permission.AD_ID が含まれている」と検出し、申告不整合で送信がブロックされた。

決定: 広告 ID 申告を「使用する」・用途は「分析」「広告、マーケティング」に修正して送信する。マニフェストから権限を除去する道は採らない。

理由: Firebase Analytics のライブラリマニフェストが AD_ID 権限を自動マージしており、権限が実在する以上「使用する」が事実に即す。AdMob 導入予定・広告=はいの先行申告とも整合し、導入時の再申告も不要になる。教訓: AD_ID 有無はローカル中間ファイルでなく Play 側の実測が正。

2026-08-17: フェルメール特集を恒久無料開放する(access=open の初適用)

背景: 特集は「導入+1作品目無料・以降 Pro」の恒久プレビュー方式(2026-07-19 決定)で運用してきたが、プロモとして特定の特集を無料開放できる枠が欲しくなった。

決定: 2026-08 フェルメール特集を記事属性 access=open で恒久的に全文開放し、一覧カードに「無料公開中」バッジ(Pro には非表示)を追加。今後の特集も記事単位の JSON 指定だけで開放できる。

理由: 設計時から用意していた access 属性の初適用で、端末状態を持たず配信データのみで反映できる。時限式は採らず恒久を既定にする(時限にしたければ配信データの差し替えで表現できるため、アプリ側に時間依存ロジックを持ち込まない)。

2026-08-17: 特集翻訳の検収に「別モデル・言語別並列・全文対読」レビューを組み込む

背景: 特集7言語翻訳の検収は機械検証+一部言語の冒頭目視のみで、es/fr/it/pt は本文を人手で一度も読まないまま公開されていた。無料開放で全ユーザーが全言語・全文を読める状態になり露出が上がった。

決定: 翻訳納品後の検収に、訳者(Codex/GPT)と別モデル(Claude)による言語別並列の全文対読レビュー(観点: 誤訳/訳調/用語、UI 訳語との一致照合を含む)を組み込む。今回8言語で高中低74件を検出・修正した。

理由: 構造検証・タイトル訳語一致の機械チェックを通過していても、視覚的事実の誤り(ペンを止め→置き等)・非成立連語・機能名の UI 不一致は全文対読でしか検出できなかった。訳者と同じモデルの自己レビューより別モデルの方が検出力が期待できる。

2026-08-17: iOS 1.0.2 から承認後自動公開(AFTER_APPROVAL)にする

背景: 1.0.0/1.0.1 は releaseType=MANUAL で、承認後に API から手動公開する運用だった。

決定: 1.0.2 は AFTER_APPROVAL(審査承認後に自動公開)へ変更(審査待ち中に PATCH で変更可能なことを実証済み)。

理由: You 指示。今回は公開タイミングを制御する理由がなく、承認即公開でよい。手動公開の待ち工程が1つ減る。

2026-08-17: デモ動画の差し替えBGMは YouTube オーディオライブラリ音源にする

背景: Shipaton デモ動画が Naxos の Content ID 申し立て(「月の光」の商用録音・上野真 演奏との一致判定)で全世界ブロックされ、審査員が視聴できない状態になった。選択肢は ①BGM差し替え+再アップ ②異議申し立て ③該当区間ミュート。

決定: YouTube オーディオライブラリの「Night Snow」(Asher Fulero・YouTube ライセンス・帰属表示不要) に差し替えて新規アップロード(新ID oPT_g_lx5v0)。旧動画は削除せず限定公開に降格。

理由: YT 公式提供音源は Content ID 申し立てが構造的に発生しない。別の PD 録音への差し替えはクラシックの演奏類似による再誤検知リスクが残り、異議申し立ては応答に最大30日かかり締切(10/1)に対して分が悪い。同曲維持(旧ライブラリの Wahneta Meixsell 版)は削除済みで不可、Gymnopedie No 2 (Kevin MacLeod) は CC-BY で帰属表示が必要なため見送り。

2026-08-17: App Store プレビュー動画の BGM は現状維持

背景: App Store 用プレビュー動画(24秒×9言語)も同じ「月の光」音源(Wikimedia Commons 由来)を使っており、権利上は YouTube でブロックされた録音と同じ論点を抱える。

決定: 差し替えず現状維持(You 決定)。

理由: Apple は Content ID 型の自動照合を行わず、ブロックの実害が出ていない。実害が生じた場合は同じ Night Snow を使い build_ja.sh の BGM 差し替えのみで再生成できる体制を確保済み(音源は src/night-snow-ytal.mp3 に保存)。

2026-08-17: Play ストア掲載物は Publishing API 一括管理方式にする(SA 権限を拡張)

背景: Play Console への掲載登録は 9ロケール×3枠のスクショだけで27回超のファイルダイアログ操作(物理クリック必須)になり、手作業では時間も失敗リスクも大きかった。

決定: 既存の RC 用 SA revenuecat-play@ にアプリ限定で「ストアでの表示の管理」(自動付帯でポリシー申告管理)と「未公開のアプリの編集、削除」を追加し、scripts/play-upload-listing.mjs で 9言語テキスト + 全画像を Google Play Developer API(edits/listings/images)で一括登録する方式を正とする。テキスト正本はリポジトリの store-assets/play-listing/LISTING.md

理由: API なら再現可能で今後の掲載更新にも使い回せる。ブラウザ手作業は約30回の物理アップロード操作が必要で非現実的だった。SA 新設は Play Console の招待フォーム制約(Claude 操作不可)に当たるため、既存 SA の権限拡張(同一アプリ内・公開権限なし)を選択。「未公開のアプリの編集」権限は説明文に「Google Play でアプリを公開することはできません」とあり、commit 403 の解消に必要だったことを実測で確認。

2026-08-17: Play の申告方針(削除リクエスト=はい・広告=先行申告・対象年齢13+・カテゴリ=教育)

背景: Play 提出に必要なデータセーフティ・コンテンツレーティング等の申告で、実装の実態(広告 SDK 未搭載・アカウント機能なし)とストア表示・将来計画の間で選択が必要だった。

決定: ① データ削除リクエストは「はい」で申告し、プライバシーポリシーに削除リクエスト章(#data-deletion)を新設して受け皿にする(ja/en 両ページ・両OS対応化も同時に実施)② 広告は AdMob 未搭載のまま「はい」で先行申告(IARC・広告ラベルとも)③ 対象年齢は 13-15/16-17/18+ ④ カテゴリは iOS と同じ「教育」。

理由: ① 対応コストは削除 API 実行のみで、ストア表示「削除をリクエストできます」の信頼感が勝る ② 掲載文に広告の記述を残す決定(iOS 同文)との整合と、AdMob 導入時の再申告の二度手間回避。「広告を含む」ラベルが先に出る代償は許容 ③ ESRB 13+ 相当の内容(美術ヌード・歴史画の暴力)と iOS 12+ に整合し、13歳未満を含めないことで子ども向けポリシーの対象外を維持 ④ iOS のカテゴリ決定(2026-07-29 教育×ライフスタイル)を踏襲。


2026-08-16: コレクションの地域別 acquired/total カードをアプリからも撤去

背景: プロモ素材に規模数字を入れない方針(2026-08-15 決定)の一方、アプリ内のコレクション画面には地域別の全体母数(西洋 720 / 日本 300 / その他 180)が「7/720」形式で常時表示されており、ストアスクショ経由でも露出していた。

決定: 地域別進捗カードを iOS / Android の両方から削除する(build 8 / 1.0.1 に同梱)。所蔵数の表示(「収蔵 N 作品」)は残す。

理由: カードの本質は全体母数の予告であり、コレクションを「上限ありの図鑑コンプ」として枠づけてしまう。「出会いの記録」として見せる設計と、規模数字を約束しない方針の両方に反する。分母だけ消して所蔵内訳を残す案は情報価値が薄く不採用。

2026-08-15: Play の購入検証用サービスアカウントはアプリ専用に作り、権限もアプリ単位に絞る

背景: RevenueCat の購入検証にはサービスアカウントの鍵が要る。Ramanu のデベロッパーアカウントには既に Subnote 用の revenuecat-play@subnote-ab213... がアカウント権限(全アプリ対象)で登録済みで、鍵ファイルも手元にあった。これを流用すれば Play Console 側の作業ゼロで即完了できる状態だった。

決定: 流用せず、ポケット美術館の GCP プロジェクト pocket-museum-d060f に専用サービスアカウント revenuecat-play@pocket-museum-d060f... を新規作成する。Play Console 側の権限もアカウント権限ではなくアプリ権限で、ポケット美術館だけに4つ(アプリ情報の閲覧 / アプリの品質情報の閲覧 / 売上データの表示 / 注文と定期購入の管理)を付与する。鍵は ~/.config/android/pocket-museum-play-sa.json(git 外・600、アップロード鍵と同じ場所)。

理由: 鍵を共有すると、Subnote 側で鍵をローテートまたは失効させたときにポケット美術館の購入検証が黙って壊れる。エラーは購入時にしか出ないので発見が遅れ、実害が売上に直結する。You は多数のアプリを並行運用しているため、この巻き添えは十分起こりうる。追加コストは Play Console での招待1回分だけで、その保険料としては安い。権限をアプリ単位に絞ったのも同じ理由で、片方の鍵が漏れたときの影響範囲を1アプリに閉じ込める。RC 公式ドキュメントはアカウント権限を案内しているが、アプリ権限でも購入検証・カタログ読み取りの3チェックすべてが valid になることを実地で確認した。

2026-08-15: Play のサブスクは iOS 商品IDと1:1の「2本立て」構造にする

背景: Google Play のサブスク構造は「1つの定期購入に複数ベースプラン」が推奨形だが、iOS(ASC)は pm_pro_monthly / pm_pro_yearly の独立商品2つで構築済み。RevenueCat のパッケージに両ストア商品を対応付ける際の構造を決める必要があった。

決定: Play も独立サブスク2本(pm_pro_monthly にベースプラン monthlypm_pro_yearly にベースプラン yearly + オファー free-trial)とし、iOS の商品IDと1:1対応にする。RC の商品識別子は pm_pro_monthly:monthly / pm_pro_yearly:yearly。7日無料は年額のみ・適格性は「新規ユーザーの獲得」(= iOS のイントロオファー未消化と同義)。

理由: RC の offering パッケージ($rc_monthly / $rc_annual)へ両ストアの商品を並べる構造が対称になり、運用時に iOS と Android の商品を同じ名前で追える。1サブスク複数ベースプラン形は Play 単体では綺麗だが、iOS 側と非対称になり RC 上の対応関係が読みにくくなる。プラン数2つでは複数ベースプランの利点(アップグレード動線の一元化)も効かない。

2026-08-15: 両OSの整合は共有コードではなく「正本データ」で担保する

背景: Android 版を iOS 版とほぼ同じ見た目・仕様にする仕組みの要否を検討した。KMP 不採用によりコード共有はないため、放置すると文言・計測・ロジックが独立に変化してズレる。

決定: ズレの実害が大きい領域だけを「正本データ+生成/参照」で守る。① 文言・翻訳 = iOS の Localizable.xcstrings を9言語の正本とし、scripts/xcstrings_to_android.py + 対応表 android/l10n/xcstrings-map.json で Android の strings_generated.xml を生成(過不足はエラー停止のドリフト検知つき。実施済み)② Analytics = docs/analytics-events.md を正本とし両実装が準拠(実施済み)③ 決定的ロジック(splitmix64 抽選・ゲート判定)= 共有テストベクタを両OSのテストで検証(Android テスト整備時に実施)。デザイントークンは Theme.swift 正本+Android 側コメント参照、画面仕様は iOS 実装を正本として移植時にファイル冒頭で参照明記(いずれも運用ルールのみで仕組み化しない)。

理由: 文言は再翻訳コストと文言差異、Analytics は GA4 で両OSが同一イベントに合流するためズレると気づかずファネルが壊れる、ビット演算移植は静かに挙動が変わる——の3つは実害が大きく機械的に防げる。一方で画面仕様の別文書化は二重管理でロットする。操作系は OS 慣習を優先し「同じブランド・同じ情報設計、ネイティブな操作系」を保つ。

2026-08-15: Android 版の技術スタックは Kotlin + Jetpack Compose 単体(KMP 不採用)

背景: 前決定(Android 版を PR TIMES 前に出す)で技術選定が持ち越しになっていた。候補は Kotlin/Compose 単体 vs KMP。

決定: Kotlin + Jetpack Compose のネイティブ単体で新規実装する。既存 iOS 版には一切手を入れない。

理由: iOS アプリ本体は Swift 36ファイル・約5,100行と小さく、共有して得するロジック量が少ない。KMP は既存 iOS 版(GRDB ベース)の共有モジュール載せ替え=作り直しが発生し、動いている iOS 版に回帰リスクを持ち込むうえ、iOS を触らないなら共有の意味がない。SwiftUI と Compose は宣言的UIとして構造がほぼ1:1で写せ、RevenueCat / Firebase / AdMob も Android ネイティブ SDK が素直に使える。〜9月上旬 Play 提出(キルスイッチ 9/8)の工期に対して最小リスク。正本はコンテンツパイプライン側(配信仕様・manifest)にあるためアプリロジックの二重管理コストは限定的。

2026-08-15: Android 版を PR TIMES 配信前に出す方針へ転換(同日の見送り判断を supersede)

背景: 同日朝に「D30 実測まで見送り」と決定したが、You から ① Google Play Console の法人アカウントは開設済み(最大のリードタイム要因が消滅)② PR TIMES は一発モノなので両OS揃えて配信したい、の2点が提示された。

決定: PR TIMES 配信日から逆算して Android 版を開発する。〜9月上旬に Play 審査提出(鑑賞コア + サブスク優先。広告+UMP は後回し可 = フェイルオープン設計により広告なしでも出せる)→ 9月中旬に両OSで PR TIMES 配信 → 〜9/30 に Devpost へ Google Play URL を追記(Shipaton 提出物の強化・Android も期間内リリースで資格内)。キルスイッチ: 9/8 頃までに Play 審査提出の見込みが立たなければ、PR TIMES は iOS 単独で切り離して 9月中旬に配信する(Shipaton のトラクション窓 〜9/30 を Android 遅延の巻き添えにしない)。技術選定(Kotlin/Compose 単体 vs KMP)は次セッションで検討。

理由: プレスリリースの到達の相当部分は Android ユーザーで、一発モノの価値最大化には両OS対応が効く。開設済みの Play アカウント + 使い回せる資産(コンテンツパイプライン・R2/CDN・RevenueCat プロジェクトに Play アプリ追加で entitlement pro 共有)で工期リスクが下がった。「D30 実測待ち」の慎重論は、配信日という先約ビジネス判断に劣後させる。ただしキルスイッチで下振れを限定する。

2026-08-15: Android 開発は初速データ実測まで見送り(※同日中に上の決定で supersede)

背景: リリース後の運用選択肢(Android 開発 / Shipaton 応募 / iOS プロモ)の優先順位を決める必要があった。

決定: Android 版は今は作らない。D30 前後の継続率・課金転換の実測で「このコンテンツはリテンションする」と確認できてから投資判断する。

理由: SwiftUI アプリのため移植は実質作り直しで最も重い選択肢。Shipaton は iOS 版だけで応募資格が成立しており、今 Android を作る追加メリットがない。買い切り再検討と同じ「実測後」の箱に入れるのが自然。

2026-08-15: プロモ素材にコンテンツ規模の数字(作品数・美術館数)を入れない

背景: Shipaton デモ動画のエンドカードに「1,200 works · 7 museums · 9 languages」と入れたところ、You から作品数・美術館数は入れないでほしいと修正指示。

決定: 動画・カード・スクショコピーなど今後のプロモ素材では規模数字を既定で使わない。Devpost 応募文からも除去(美術館は代表館名の部分列挙に変更)。9 languages・無料14作品・7日トライアルなど「仕組み・条件の数字」は対象外。App Store 説明文の既存記載は別判断(現状維持)。

理由: 数は変動しうるうえ、規模を約束として見せたくない You の意向。auto-memory にも保存済み。

2026-08-15: Shipaton 2026 のカテゴリ戦略(HAMM 本命・Catvertising は AdMob 明記で応募)

背景: Devpost の Additional info でカテゴリ別説明欄への記入有無を決める必要があった。

決定: HAMM(レンタルモデルの収益設計)を本命に、Design・Catvertising の説明欄も記入して応募。Catvertising は「RevenueCat Ads 必須」の可能性があるため AdMob 利用を明記(選外になっても損はない)。#BuildInPublic(SNS 発信履歴なし)・Influencer(生産性/栄養/ヨガ/キャリア/ゲームのみで該当なし)・スポンサー枠(OneSignal/Replit/Layers/Stripe/Kotlin/Noise/Galaxy)は見送り。

理由: 記入は無料で選外リスクしかない一方、無記入はその賞の審査対象外になる。要件 SDK が明確に別のものだけ見送るのが期待値最大。

背景: 8/7 の審査承認後も App Store に掲載されず、ASC が「App Storeから削除済み」表示になっていた。調査で appAvailability リソース自体が存在しない(配信国ゼロ)ことが原因と判明。API 経由の提出は、Web UI なら強制される配信国設定ステップを未設定のまま素通りできてしまう(7/29 のサブスク取りこぼし事故未遂と同根)。

決定: POST /v2/appAvailabilities で全175か国 + availableInNewTerritories: true(新規追加国も自動的に配信対象)を一括設定して復旧。今後は配信国の存在確認(GET /v1/apps/{id}/appAvailabilityV2 が 200 を返すこと)を提出前チェックに加え、scripts/asc-submission-check.mjs にも組み込む。

理由: 9言語対応の世界向けアプリで配信国を絞る理由がなく、サブスク商品も175地域で価格設定済みのため全世界が整合的。この事故はエラーも通知も出ず「公開されないだけ」で気づきにくいので、課金アイテム同梱チェックと同様に機械検証で防ぐ。

2026-07-29: 通知プライマーは「2枚目の獲得時」に表示する(初回起動直後を廃止)

背景: 通知プレパーミッションが初回起動の直後(今日の1枚を見る前)に出る実装で、アプリの価値を体験する前に許可を求める形になっていた。

決定: 初回セッションでは出さず、2枚目の獲得(=初めての再訪問)以降の獲得処理で判定し、1.2秒の一呼吸を置いてから表示する。同一セッションで他モーダルを見せた場合はスキップ(レビュー促進と同じ抑制ルール)。一度きり表示は従来通り。

理由: 「毎日新しい1枚が届く」を実感した直後が「届いたら知らせましょうか?」の文脈として最も自然で承諾率も高い。弱点(初日で離脱した人には出ない)は、価値体験前に断られるコストより小さいと判断。レビュー促進で確立した同意型・ポジティブ契機の設計原則を通知にも揃えた。

2026-07-29: 画像配信の最適化方針(Cache Rule 必須・枠内は thumb・3階層化は見送り・Debug も本番CDN)

背景: TestFlight で画像表示が1枚あたり体感1〜2秒。実測で cf-cache-status が常に MISS=R2 カスタムドメインは Cache Rule を作らないとエッジキャッシュが一切効かないことが判明(7/15 の配信開始以来この状態だった)。

決定: ①Cloudflare に Cache Rule(content.ramanu.co.jp→キャッシュ対象、Edge TTL はオリジンの Cache-Control 7日に従う)を常設 ②枠内表示(今日の1枚・作品詳細・特集ヒーロー)は thumb(800px)、full(2400px) は全画面ズーム専用 ③画像取得失敗時は2秒→4秒で最大2回自動リトライ ④small(400px) を足す3階層化は v1.1 へ見送り ⑤Debug ビルドも本番CDN を参照(LAN IP 直書き運用を廃止。ローカル差し替え検証時のみ一時的に戻す)。

理由: 律速は画像サイズではなく1リクエストごとのオリジン往復(0.6〜1.0秒)で、Cache Rule 1本で50ms級に解消(実測 HIT)。thumb 化は転送量1/10で、800px→900px 表示の軽微アップスケールは額装内では知覚困難。3階層化はパイプライン再生成+再アップの規模に対して効果がコレクション格子の数十KB削減に留まるため提出を遅らせる価値がない。

2026-07-29: 審査提出は課金アイテムの同梱をチェッカーで検証する運用にする

背景: 1.0.0 の初回審査提出がバージョンのみで、サブスク2種が「提出準備中」のまま取り残されていた(You が提出後に発見)。そのまま通ると「アプリは公開されるのに課金が未審査=購入不可」の事故だった。ASC は「バージョン」と「課金アイテム」が別アイテムで、バージョン単独でも提出できてしまい、初回サブスク=同一提出必須の告知も薄い。

決定: 提出の前後に scripts/asc-submission-check.mjs(開いている提出と課金アイテムの状態を突き合わせ、取りこぼしを警告)を実行する運用にする。汎用版と罠・復旧手順は ~/cdev/knowledge/asc-review-submission-iap-check.md に保存。今回は提出を取り下げ→4アイテム(バージョン+グループ+月額+年額)に合体→再提出で回収済み。

理由: この事故はクラッシュもエラーも出ず「ペイウォールのプラン取得が空」になるだけで、公開後まで気づきにくい。UI の目視(サブスクが「審査待ち」に変わったか)だけに頼らず機械検証を挟む。新規アプリの初回提出で毎回踏み得るためナレッジ化してクロスプロジェクトで再利用する。

2026-07-29: Crashlytics をリリース前に導入する

背景: 7/28 時点の構成は Firebase Analytics のみで、クラッシュ監視は Xcode Organizer(ユーザーが共有に同意した分のみ)頼みだった。

決定: FirebaseCrashlytics を build 5 から同梱(dSYM アップロードの postBuildScript 込み)。ASC プライバシー詳細に「クラッシュデータ」(関連付けなし・トラッキングなし)を追加申告。

理由: リリース直後こそクラッシュの検知速度が重要で、導入コストは依存追加+ビルドスクリプトのみ(コード変更ゼロ)。申告も1タイプ追加で済み、トラッキングなしの整合は崩れない。

2026-07-29: App Store カテゴリは「教育(プライマリ)× ライフスタイル(セカンダリ)」

背景: 審査提出時にプライマリカテゴリ未設定が発覚(7/20 登録セッションの取りこぼし。配信権・価格も同様で、いずれも API で即時設定した)。

決定: プライマリ=教育、セカンダリ=ライフスタイル。

理由: 美術解説で学ぶアプリという実態に合致し、競合 DailyArt と同型。教育カテゴリはファミリー/学習層の信頼も得やすい。エンタメは激戦区で埋没リスクが高い。

2026-07-28: en-US ストア名を「Pocket Museum: Daily Art」に戻す(前日の Masterpieces 確定を supersede)

背景: 2026-07-27 に競合 DailyArt(Moiseum)との誤認回避を主目的に「Pocket Museum: Masterpieces」へ確定・ASC 反映していたが、審査提出前に再考した。

決定: en-US のストア名を「Pocket Museum: Daily Art」(24字)に変更する。サブタイトル「One masterpiece, every day」と他8言語の名前は変更しない。ASC 反映済み(1.0.0 は PREPARE_FOR_SUBMISSION のため、このまま提出に乗る)。

理由: 「毎日1枚の名画」というアプリの核が名前から伝わることを、DailyArt との誤認リスクよりも優先した。誤認・検索面の懸念(2026-07-27 エントリ参照)は認識した上での、コンセプト伝達優先の判断。

2026-07-27: 特集記事はリリース時から9言語制作する(「当面 ja のみ」を supersede)

背景: 2026-07-20 に「特集記事は当面 ja のみ制作(器は9言語・ja フォールバック)」と決めていたが、未翻訳言語のユーザーには特集タブに日本語記事がそのまま表示される。en は 7/27 に翻訳済みで、残り7言語をリリース前に埋めるかが論点だった。

決定: 1本目「フェルメール、窓辺の光」を残り7言語(de/es/fr/it/pt/ko/zh-Hans)も翻訳し、リリース時から9言語で配信する。翻訳は Codex 分業(依頼書 実装依頼_特集記事7言語翻訳.md)で、作品タイトルは既存解説の訳語と一致させる。

理由: 特集は Pro の主訴求コンテンツで、ローカライズ済み言語のユーザーに日本語記事が出る状態は課金導線の品質として不揃い。翻訳コストは Codex サブスク枠で小さく(1本×7言語・当日完了)、R2 配信のみで反映されるためリリースブロッカーにもならない。月次の制作フローも「ja 執筆→7+en 翻訳」で型化できる。

2026-07-27: 「今日の1枚」を個人別seed抽選に移行(全ユーザー共通の固定順カーソルを廃止)

背景: 固定順デッキ(2026-07-16 鼎談決定)は全ユーザーが同じ並びをほぼ同じ位相でたどるため、知り合い同士や SNS 投稿で翌日以降の作品が事前に分かり、発見体験が予告編化する。また deck v2 で組み直しても、1か月約100件に対し1日1作品の消化では各月の先頭約30%しか1年目に到達せず、看板作品の一部が2〜4年目配置になる構造問題が残った。

決定: 月プールの残り(未獲得分)から (端末seed, 日付, 月) の splitmix64 決定的ハッシュで毎日抽選する方式に変更。seed は最初の獲得時に生成し appState.deckSeed に永続化(マイグレーション seeded-draw-v1)。直近3日の獲得作家は候補から除外し、除外で候補が空になる場合は制約を解除。スター間隔の編集的保証は失われるが、月例特集が名画との出会いを保証する役割を担う。DeckCursor テーブルは互換のため残置。build 2 以降に搭載。

理由: 季節適合と地域比率は月プール構造で保たれ、抽選は seed+日付+残りプールの決定的関数なのでテスト可能性も維持される=2026-07-16 に端末側ランダムを退けた理由(非決定・編集品質喪失)には抵触しない。開始位相ずらしやブロック内シャッフルの折衷案と比較し、実装が最も素直で「誰かの今日を知っても自分の明日は予測できない」を完全に満たす本方式を採った。将来 CloudKit に seed を載せれば複数端末の同日同着も成立する。

2026-07-27: en-US ストア名は「Pocket Museum: Masterpieces」(Daily Art を放棄)

背景: 2026-07-20 から保留していた en-US 名の接尾辞問題。「Daily Art」は競合 DailyArt(Moiseum)との誤認・誤入手→低評価リスクがあった。第一候補は「Art History」だった。

決定: en-US のストア名を「Pocket Museum: Masterpieces」(27字)にする。他8言語は「毎日の芸術」系の一般語訳のまま変更しない(DailyArt は英語ブランドで非英語圏の誤認リスクなし)。

理由: US ストアの実検索調査で、DailyArt が art history / paintings / art gallery 等カテゴリ主要語のほぼ全てで1位=接尾辞をどう変えても検索流入は奪えず、改名の目的は誤認回避に絞られると判明。「masterpieces」は上位に美術鑑賞アプリが不在の空白地帯で、サブタイトル「One masterpiece, every day」・説明文と一直線になる。第一候補だった Art History は「Art History & Painting - Artly」と正面衝突。「Daily ○○」は量産アプリの命名パターン(実在5本確認)で埋没する。ユーザー案「Daily Masterpieces」は33字で上限超過かつ既存アプリと衝突。

2026-07-27: Fable チェック完走をリリース条件から外す(リリース後に順次実施)

背景: 従来計画は「Fable チェック残985点を完走 → pm deck → export → upload で本番差し替え → リリース」で、R2 本番が 7/15 検証用1,000点のまま止まる依存関係になっていた。特集英訳や deck 修正の本番反映も同じ pm upload に縛られていた。

決定: Fable チェック(残985点)はリリース後に順次実施し、未チェック解説を含む1,200点版を本番配信してリリースする。チェック済み分の差し替えはリリース後に随時 pm upload で行う。

理由: コンテンツは R2 配信でアプリ更新なしに差し替え可能なため、品質改善を公開後に回してもユーザー影響は限定的。support@ の誤訳報告導線も整い、実ユーザーからの品質フィードバックループが機能する。リリースを先に出す価値(審査・AdMob 承認・PR TIMES 配信がすべて公開待ち)がチェック完走を待つ価値を上回る。

2026-07-26: Pocket Museum のローンチ告知に PR TIMES を使う(従量課金3万円を払う前提)

背景: 2026-07-16 に subnote のローンチ広報を設計した際、「PR TIMES は使わない(無料枠の条件確認もしない)」で決着していた。今回 Pocket Museum のローンチで改めて出したいという意向があり、方針を分岐させるかを判断する必要があった。あわせて、無料枠(スタートアップチャレンジ)の対象条件が「日本国内の株式会社」限定で合同会社ラマヌは原則対象外と判明し、実費3万円(税別)が発生する前提になった。

決定: Pocket Museum に限り PR TIMES を使う。無料枠が取れなかった場合も従量課金 1配信3万円(税別)を払って配信する。配信は App Store 公開後。企業ページには X @tazawa_works を掲載しない。

理由: subnote での「使わない」判断は工数対効果(期待値は被リンク+GEO面のみ)に基づくもので、プロダクトごとに再評価してよい性質のもの。Pocket Museum は自信作でプロダクトとしての訴求力が違うため、3万円を投じる価値があると判断した。企業ページのビジネスカテゴリに「アート・カルチャー」を入れて美術・文化系の記者に届く枠を確保しており、この領域はプレスリリースが機能しやすい。X を載せないのは、@tazawa_works が開発者個人の一人称アカウントで、会社の公式面から個人アカウントへ送客する形を避けたかったため(bio 側で会社との紐付けは既に公開しているので、情報としての欠落はない)。

2026-07-22: App Store スクリーンショットは ja・6.9インチ全5枚構成(特集シートなし)

背景: ストア掲載用スクリーンショットの構成を確定する必要があった。当初の Claude 案(金の巨大数字・サロン掛け等)は「静・格」に合わず不採用で、最終デザインは You が Codex と直接対話して確定した。

決定: 見開き2枚(accent-arch トーン: 「名画をひらく。世界がひろがる。」/「次の一枚が、あなたを待っている。」)+ 03今日の一枚 + 04拡大鑑賞(実ピンチズーム画面)+ 05コレクション の全5枚。特集タブのシートは作らない。

理由: 最初の2枚の見開き連結でフックを作り、「毎日届く→細部まで読む→集める」の3枚で物語が完結する。特集は当面 ja のみ運用で訴求の普遍性が弱く、枚数を絞って1枚あたりの質を保つ方が良い。深緑×金×明朝のアプリ実装トーンをストアでも統一する。

2026-07-20: 広告のローンチ前対応 — ATT なし + EU 配信 + UMP 同意フロー

背景: ローンチ前に ATT ダイアログの要否と EU(EEA/UK)配信の可否を決める必要があった。EEA で AdMob 広告を出すには Google 認定 CMP(実質 UMP)の同意フローが必須。

決定: ATT は要求しない(公開済みプライバシーポリシーと ASC の「トラッキングなし」申告を維持)。EU 配信は継続し、UMP の同意フローをアプリに実装(EEA では広告表示直前にフォーム提示・拒否/失敗時は既存フォールバック=当日無料開放へ)。AdMob コンソールに GDPR メッセージを公開(Consent / Do not consent / Manage options、第一階層で拒否可能な構成)。

理由: 広告は副次収益(1本=24hチケット)で ATT による eCPM 上振れは小さく、起動体験にダイアログを増やすコストの方が大きい。EU 除外は de/it/fr/es の4言語ローカライズ投資と矛盾する。UMP のアプリ側実装は限定的(フォーム自体は Google ホスト・言語も向こう持ち)で、拒否時もフォールバック設計により UX が壊れない。

2026-07-20: レビュー促進は同意型ソフトアスク(初回=星ダイアログ / 2回目以降=write-review ページ)

背景: App Store レビューを促すポップアップの方式とタイミングを決める必要があった。三者議論4ラウンド(discussions/2026-07-20-review-prompt.md)で、Codex は直接 requestReview を推したが、ユーザーは同意を取ってから出す体験を選択。

決定: 自前ポップアップ(テキスト+ボタン2つ・★記号や星UIなし)で同意を取り、初回同意→StoreKit requestReview(アプリ内星ダイアログ)、2回目以降の同意→App Store write-review ページを直接開くハイブリッド。資格=獲得7日(detail_closed 契機は10日)、「また今度」の再訴求は45日+獲得10日→60日+獲得20日で通算3回まで、同意後は再提示なし。他モーダル(通知プライマー・Paywall・広告)と同一セッションでは出さず翌日以降へ持ち越し。マイに常設「App Storeで評価・レビューを書く」を併設。センチメントゲート(満足度での選別)はしない。実装後の追加判断でお気に入り追加は契機から除外(お気に入りの瞬間に別UIを被せない。契機は特集読了と作品詳細クローズの2つ)。

理由: Codex の懸念(同意後に OS がダイアログを出さない壊れた導線)は「2回目以降を表示保証のある write-review ページに切り替える」ことで個別に吸収できる。同意型は Apple の年3回表示枠を無反応ユーザーに浪費せず、「また今度」という標準APIでは取れないシグナルが計測できる。文言は「評価のお願い」であることを明示し(「気に入りましたか?」のような満足度質問を装わない)、「星1つ」と誤読される表現は9言語すべてで避ける。

2026-07-20: 通知許可は起動時プレパーミッション1回きり(許可機会温存型)

背景: 通知設定の入口がマイページのトグルのみで、許可を求める自然な導線が無かった。

決定: 一度も出していない端末の起動時に1回だけ、自前の許可促し画面 → OK なら iOS 本物のダイアログ → 許可なら時刻設定(既定8:00)/ 拒否ならマイ誘導、の3ステップを出す。「あとで」はシステムダイアログを出さずに閉じ(iOS の一度きりの許可機会を温存)、再訴求はしない。時刻設定ステップのみスワイプで閉じられない(許可まで済ませた人の未設定離脱を防ぐ)。

理由: iOS の通知許可ダイアログは一度しか出せないため、意思確認を挟む価値が大きい(レビューの星ダイアログとは前提が異なる)。マイのトグル経路は従来どおり残し、拒否済みユーザーの再有効化は設定アプリ誘導で対応する。

2026-07-20: AdMob は法人アカウント維持で再審査(即日再送信 + 公開後ストアリンクの二段構え)

背景: 2026-07-20 に AdMob 新規アカウント(pub-7837692984627105、RAMANU LLC 名義)の申し込みが「利用要件を満たしていない」の定型文で却下された。承認済みで稼働中の個人アカウント(別 pub ID)が既存のため、そちらへ切り替える選択肢もあった。

決定: 法人アカウントで続行し、ポリシー準拠を確認して即日再送信。App Store 公開後に AdMob でストア掲載にリンクし、未承認のままなら改めて再送信する。個人アカウントへの切替はしない。

理由: 受取人格が法人/個人で別のため重複アカウント違反ではないと実地確認済み(pay.google.com で両プロファイルの「アカウントの種類」を確認)。却下の本命はアプリ未公開によるコンテンツ確認不能と推定され、アカウントを替えても「公開 → ストアリンク → アプリ審査」までは配信不可の構造は同じ。収益は法人で受ける方針で、ID 差し替え(アプリ・app-ads.txt)の手戻りも避けられる。広告なし期間はフォールバック(無料開放)で UX・収益への実害が小さい。

2026-07-20: 月例特集の実装形を確定(4タブ目・記事内完結・ロックはぼかし帯+一文+CTA・記事単位access属性)

背景: 冒頭プレビュー方式(2026-07-19 決定)は確定済みだったが、アプリ内の置き場所・画面表現・配信形式が未決だった。

決定: ① 4タブ目「特集」を新設(今日/コレクション/特集/マイ)。② 記事は「導入+1作品目全文 → ぼかしサムネ帯(radius 1)+『この先、あと N 作品がつづきます』+ Pro CTA」のみで、ロック節の見出し・作品名・本文断片は出さない。③ 記事内から作品詳細画面への導線は張らない(記事内完結、画像ズームのみ)。記事冒頭のヒーロー画像も出さない(一覧カードのサムネ専用)。④ 記事データに access 属性(preview 既定 / open=全員全文開放)を持たせ、将来のプロモ特集も端末側の時間依存状態なしで出せる器にする。

理由: ① Pro の唯一のコンテンツ柱として発見性を最優先(月1本でもタブに値する)。② 当初実装した「ロック節のもくじ列挙(サムネ+作品名)」は未獲得作品6点の全開示となり、図鑑の「未獲得はシルエットも見せない」方針と矛盾し、後日の「今日の1枚」の出会いのネタバレにもなるため却下。完全非表示は訴求が弱く、弱いぼかしで「絵が待っている」気配だけ見せる折衷に実機比較(radius 9→5→3→2→1)で決着。③ 詳細画面は未獲得作品への裏口になるうえ、詳細画面の広告CTAが「特集は広告で開放しない」決定と同一導線内で矛盾する。④ 「最初の特集だけ例外」のような端末側フラグは決定済みの「時間依存の状態を持たない」原則に反するが、記事データ自体の属性なら原則と両立する。

2026-07-20: 特集記事は当面 ja のみ制作(配信の器は9言語対応・ja フォールバック)

背景: DECISIONS 2026-07-19 の未決事項「月例特集の9言語対応の範囲」を実装前に決める必要があった。

決定: 配信形式・同期・表示は9言語対応で実装する(content/featured/{lang}.json、記事のある言語だけ manifest に載り、無い言語は stories と同じ ja フォールバック表示)。記事制作は当面 ja のみ。

理由: 制作・品質チェック負荷を最小化してローンチを優先する。翻訳版は同じディレクトリに en.json 等を置いて export するだけで自動配信されるため、後からの言語拡張に実装変更が不要。海外ユーザーには ja 本文が出る妥協はあるが、UI 文言は9言語対応済みで導線は壊れない。

2026-07-20: プライバシーポリシーはコーポレートドメイン ramanu.co.jp 配下で公開、日英2言語(ja 正本)

背景: プライバシーポリシーURLがプレースホルダのままで、Paywall 表示と ASC 申請の両方をブロックするローンチブロッカーだった。公開先(新規プロダクトドメイン or 既存インフラ)と言語構成を決める必要があった。

決定: コーポレートサイト(Cloudflare Pages)配下の https://ramanu.co.jp/pocket-museum/privacy/ で公開する。言語は日本語(正本)+ 英語の2言語で、英語版に「相違がある場合は日本語版が優先」の注記を置く。ASC には en-US ローカリゼーションに英語版URLを設定し、ja ストア掲載情報の作成時に日本語版URLを設定する。

理由: 発行元(販売者 RAMANU LLC)とドメインが一致して審査・ユーザー双方に対する信頼性が高く、既存の Pages + wrangler 認証で追加費用・追加インフラゼロで即公開できた。新規プロダクトドメインは購入・管理の固定費に見合う益が現時点でない(将来買う場合も URL 差し替えはアプリ更新+ASC 編集で可能)。9言語展開は法務文書の翻訳品質管理コストに見合わないため見送り、アプリの主要市場(日本)+ グローバル既定(英語)の2言語とした。

2026-07-20: 本番コンテンツ配信は R2 バケット + カスタムドメイン content.ramanu.co.jp(S3 は不採用)

背景: Release ビルドの配信先が content.pocket-museum.invalid のプレースホルダのままで、R2 のアカウント有効化と配信ドメインの確定が必要だった。S3 との比較検討も行った。

決定: Cloudflare R2 のバケット pocket-museum-content(APAC)+ カスタムドメイン content.ramanu.co.jp で配信する。アップロードは新実装の pm upload(boto3・md5/ETag 差分同期)で行い、認証はバケット限定の Account API トークン(~/.config/r2/pocket-museum.env)。Cache-Control は manifest=60秒 / content JSON=5分 / 画像=7日。

理由: 画像配信アプリのコスト支配項はエグレスで、R2 は帯域完全無料(S3+CloudFront は無料枠1TB超で従量)。S3 単体は CDN でなく CloudFront 併設が必要で管理対象が増える。法人インフラ(DNS/Pages/メール/課金)は Cloudflare に集約済みで、pm export も R2 前提で実装済み。ストレージ単価も R2 が安く($0.015 vs 約$0.025/GB)、S3 互換 API のため将来の移行も容易。ドメインはプライバシーポリシーと同じ理由で ramanu.co.jp 配下とした。

2026-07-20: 期限切れ解説チケットの行は失効後7日間保持する(prune 猶予)

背景: Firebase Analytics のファネル計測で、レンタルモデルの効果判定に最重要の ticket_expired_gate_viewed(一度開いた解説への再訪でゲートに遭遇)を検出するには「かつてチケットがあった」事実が必要だが、従来の prune(DECISIONS 2026-07-19 のレンタルモデル実装)は起動時に期限切れ行を即削除しており、検出材料が消えていた。

決定: pruneExpiredTickets失効後7日を過ぎた行だけ削除する。ゲート判定は従来どおり expiresAt 比較のため再ロックは即時に効く(ユーザー可視の挙動は不変)。StoryGate.hasExpiredTicket で期限切れチケットの存在をゲート表示時の計測に流す。

理由: チケット台帳は端末限定・件数も小さく、7日保持のコストは無視できる。代替案(削除しない/別テーブルで履歴化)は肥大化・状態管理の複雑化に見合う益がない。7日は「再訪の大半を拾える最小限の窓」として設定。

2026-07-20: ASC アプリレコードの体裁 — プライマリ言語 en-US / 名前 "Pocket Museum: Daily Art" / SKU pocketmuseum

背景: ASC のアプリレコード作成(後から変更不可の項目を含む)にあたり、プライマリ言語・ストア名・SKU を確定する必要があった。アプリ名は 2026-07-11 決定(ja「ポケット美術館」、英語は "Pocket Museum" 単体が既存アプリと完全一致のため複合名)を踏襲。

決定: プライマリ言語は英語(アメリカ)、レコード名(= en-US のストア名)は "Pocket Museum: Daily Art"、SKU は pocketmuseum(Subnote の subnote と同じ流儀)。日本語ストア情報(名前「ポケット美術館」等)はローカリゼーションとして後から追加する。

理由: プライマリ言語はストア未対応言語の全市場でフォールバック表示されるため、グローバル配信(全175地域)では英語が既定であるべき。日本先行ローンチでも日本語は ja ローカリゼーションで完全にカバーでき、失うものがない。

2026-07-20: ストア価格は JPN ベース + Apple 均等化、全175地域配信でローンチ

背景: 未決だった「市場別価格ローカライズの具体テーブル」を ASC 商品作成時に確定する必要があった(2026-07-19 の価格決定の残課題)。

決定: pm_pro_monthly ¥300 / pm_pro_yearly ¥1,500 を JPN ベース価格とし、他174地域は Apple の価格均等化(購買力・為替調整済みの標準テーブル、例: US $1.99/$9.99、EUR €1.99/€9.99)をそのまま採用。市場別のカスタム価格テーブルはローンチ時点では作らない。配信は全175地域+新地域自動有効。

理由: 実測データがない段階で市場別に価格を弄る根拠がなく、Apple 均等化は購買力調整の実績ある既定値。価格は後からいつでも地域別に変更できる(既存購読者は preserve 可)ため、ローンチはシンプルに始めてデータで最適化する方が合理的。EU 配信の広告同意(UMP)問題はストア配信自体とは独立で、広告側の対応で解決する。

背景: Phase 2 スキャフォールド時(2026-07-16)に bundle ID が com.ichirokisanuki.pocketmuseum(GitHubアカウント名由来)と決め打ちされたまま議論されずに残っていた。リリースは Subnote と同じ info@ramanu.co.jp の Apple Developer 法人アカウント(チーム 9HZW92277N、これは当初から正しく設定済み)で行うため、RevenueCat / ASC の外部セットアップ開始前に User の指摘で発覚・修正。

決定: bundle ID は法人ドメイン ramanu.co.jp の逆DNSで jp.co.ramanu.pocketmuseum とする(bundleIdPrefix: jp.co.ramanu)。製品ドメイン由来(Subnote の me.subnote.app 流儀)は本アプリの実ドメインが未確定のため採らない。

理由: bundle ID はリリース後変更不可のため、外部サービス(RevenueCat / ASC / AdMobストアリンク)に登録が波及する前の今が修正の最終好機。法人ドメイン逆DNSは製品ドメインの取得有無に左右されず恒久的に揺るがない。

2026-07-20: 課金の識別子規約とPaywall法務リンク — entitlement pro / offering default、利用規約はApple標準EULA

背景: RevenueCat 接続にあたり、アプリ・App Store Connect・RevenueCat ダッシュボードで共有する識別子と、サブスク審査要件(利用規約・プライバシーポリシーのリンク表示)の充足方法を決める必要があった。

決定: エンタイトルメント pro / オファリング default(annual・monthly の標準パッケージ)/ 商品IDは pm_pro_monthlypm_pro_yearly を案とする(ASC 商品作成時に最終確定。作成後は変更不可)。アプリ側は offering のパッケージ参照のみで商品IDをコードに持たない。利用規約リンクは Apple 標準EULA(stdeula)を使用し、プライバシーポリシーは自前ページ(現状プレースホルダURL、実URL差し替えはローンチブロッカー)。

理由: 商品IDをコードから排除すると、市場別価格や商品差し替えを RevenueCat ダッシュボード側だけで完結でき、アプリ更新が不要になる。Apple 標準EULA は自前規約の作成・9言語化コストを回避でき、サブスク審査要件(Schedule 2 準拠の規約リンク)をそのまま満たせる。

2026-07-19: 価格体系を最終決定 — ローンチは月額¥300/年額¥1,500の2枚、買い切りは出さない

背景: 買い切り¥3,000(年額2年分)は「買い切り誘導が強すぎる」懸念で保留中だった。biz-expert / game-design-expert の壁打ちと三者議論(.devnotes/discussions/2026-07-19-pricing-final.md、全3ラウンド)で確定。

決定: ローンチ時のプランは月額¥300 / 年額¥1,500(既定選択)の2枚。7日無料トライアルは年額のみ。買い切りはローンチでは販売せず、Paywallでの「後日追加予定」予告もしない(購入延期を誘発するため)。D30/D90継続率・月額→年額移行率・広告ユーザーLTV・解約理由が実測できた時点で年額4年分程度を目安に再検討する。「買い切り=Pro完全同等」の原則(2026-07-11決定)は販売再開時も維持。トライアル消化済みユーザーには「試す」でなく即時課金の正確な表示に切り替え、表示価格はStoreKitの適格性・ローカライズ価格を正とする。

理由: ①類似構造(買い切り≒年額1.9年分)の実測で課金者の96.4%が買い切りに流れサブスク転換率0.12%となった前例があり、¥3,000のまま出すのはその再演 ②後日追加は摩擦ゼロだが安売りの回収は不可逆で、リテンション実測前は適正価格を決める根拠がない ③先行最大手DailyArt(月額¥800/年額¥5,000)は買い切りなしで成立しており、不在のレビューリスクは限定的 ④月額¥200は価値を安く見せ、¥300なら年額割引率58%で「年額が主商品」の定石構成になる。

2026-07-19: 解説全文アクセスをレンタルモデルに転換(最初の14作品は永久無料、以降は広告1本=その作品の24時間チケット)

背景: 2026-07-16決定の「広告1本でその日の分を永久開放」は、story_unlock台帳のCloudKit同期・Pro失効時のgrandfather判定という状態管理を伴い、「無料全文期間14日」も訪問駆動デッキと単位がずれていた(週2ユーザーは14日で4枚しか味見できない)。三者議論でUser発案の簡素化案を検証して確定。2026-07-16決定の「永久開放」部分をsupersedeする。

決定: 財産は作品(獲得・画像・題名・導入部=コレクション)のみとし、解説全文はアクセス商品にする。①最初の14作品(獲得順)は解説も永久無料。「無料期間」ではなく「ウェルカム特典」と定義し、free_story_count=14 は manifest 設定値として初回起動で端末にピン留め(オフライン初回はフォールバック14) ②15作品目以降、無課金者は当日分・過去分を問わず「リワード広告1本=その1作品の解説の24時間チケット」。起算は報酬確定時刻、期限内の再読自由、端末限定(iCloud同期なし)、正常完了広告に日次上限なし ③CTAは「広告1本で、この解説を24時間読む」と期限まで明示(AdMobの報酬明示ポリシー準拠) ④フォールバックは分離: 当日分のみ広告取得失敗で無条件24時間無料開放+「広告を読み込めなかったため、今日はそのまま全文を読めます。」の小さな1行表示。過去分は救済せず再試行案内のみ(機内モードでバックログ全読みできる穴を塞ぐ) ⑤Pro=契約中すべて広告なし。失効後は14作品以外また広告対象(開放台帳が存在しないため取り上げ処理も不要) ⑥ゲート初遭遇(15作品目)は「広告で読む」/「7日間Proを試す」を並列提示、トライアルは明示開始。予告は残り2枚から解説末尾に控えめに ⑦ストア文言の「永久収蔵」は作品に限定し、Paywallは「Proの利用中は、すべての解説を広告なしで読めます」とする。Review Notesに14枚・広告・Proの関係を記載。

理由: ①story_unlock集合・そのCloudKit同期・失効時grandfather判定がすべて消え、ゲート判定が「獲得順index≤14 or Pro or 有効チケット」の純関数になる ②旧モデルでは広告熱心な無課金者が全解説を財産化しProが広告除去商品に痩せていく——レンタルモデルはこれを構造的に消し、Pro=「いつでも全部・広告なし」が恒久的差別化として立つ ③ユーザー説明が1行で済む ④24時間チケットは「端末日付の終わりまで」方式の不公平(23:58に広告→2分で失効)を避けつつ期限後に削除できる最小の状態 ⑤「出会いを広告障害で壊さない」原則は当日分にだけ必要で、バックログの無制限救済は不要。

2026-07-19: 月例特集は恒久的な冒頭プレビュー方式(導入+1作品目無料、以降Pro限定、広告開放なし)

背景: 「特集当月分を無料の味見にするか」が未決だった。三者議論で確定。

決定: 当月・過去アーカイブ共通で、導入部+1作品目までを常に無料、2作品目以降はPro限定。リワード広告での特集開放はしない。1作品目は途中で切るティザーではなく単独で満足できる完全な一節とし、「1作品目まで=問いの提示、2作品目以降=答えと展開」を特集テンプレの編集規律とする。

理由: ①完全Pro限定は価値を一度も体験できず転換しない(類似前例で転換率0.12%) ②当月丸ごと無料は「待てば無料」でPro価値を弱め、翌月アーカイブ入り時の再ロック問題(grandfather状態管理の復活)を生む ③冒頭プレビューは全特集・全期間で同一ルール・時間依存の状態なしで、毎日の「導入無料・全文ゲート」と同じメンタルモデルに収まり、Paywall CTAを興味のピーク(続きが読みたい瞬間)に置ける ④特集を広告で開けないことでProの唯一のコンテンツ柱を守る。

2026-07-19: Firebase Analytics を導入しファネル計測を行う(購読状態の正本はRevenueCat)

背景: manifest設定値の変更をコホート比較として成立させるには行動計測が必要(User「計測基盤を入れるのは当たり前」)。AdMob導入済みでプライバシーラベルは既に広告SDK相当のため、追加の悪化は限定的。

決定: Firebase Analytics をATT不要の自社分析範囲で導入する。イベントは少数+パラメータ型: artwork_acquired / story_gate_viewed{context} / story_gate_action{action} / ad_result{context,result} / story_full_opened{access: free14|pro|ad_ticket|fallback} / ticket_reused / ticket_expired_gate_viewed / paywall_viewed{source} / featured_preview_completed / featured_cta_tapped。free_countや設定バージョンはユーザープロパティに載せる。購入・解約・トライアル転換の正本はRevenueCatとし、Firebaseは画面行動の分析専用(二重計上を避ける)。

理由: ファネルの分母(何を見せられ何を選ばなかったか)が取れないと、無料枚数変更やレンタルモデルの効果判定ができない。特に ticket_expired_gate_viewed 以降の行動を取らないと「レンタル化が広告収益を増やしたのか、再読を殺しただけか」を判定できない。

2026-07-19: オフラインDLは「獲得作品の自動保存」方式にする

背景: 旧仕様(引き継ぎ.md)ではオフラインDLは「ユーザー操作でDL保存」かつ Pro 特典の一つだったが、訪問駆動デッキ化で「図鑑1,000点を一括DL」の前提が消え、対象は獲得済み作品(年最大365点前後、約250MB/年)に縮んだ。

決定: 獲得済み作品の画像(thumb+full)を獲得時+起動/フォアグラウンド復帰時のバックフィルで自動ディスク保存する(ImageStore)。DL用のUIは追加せず、Pro 特典からも外す。デッキ更新で参照が消えたファイルは prune、iCloud バックアップは除外。

理由: 対象が小さいので全自動で容量問題がなく、追加UIゼロで全画面が無条件にオフライン対応になる。代替案(明示DLボタン/設定トグル/Pro特典)はUIと状態管理が増える割に益が薄く、Pro の価値は解説側(広告なし全文)に集約する方が訴求が明快。

2026-07-19: ホーム画面アプリ名は ja=ポケット美術館 / 他8言語=Pocket Museum の2種

背景: String Catalog 9言語対応で CFBundleDisplayName の言語別表記を決める必要があった。

決定: 日本語のみ「ポケット美術館」、他8言語はすべて「Pocket Museum」(InfoPlist.xcstrings)。App Store 上の正式名は別途「Pocket Museum: Daily Art」等の複合名にできる(商標チェック済みの既定方針)。

理由: 各言語ローカライズ(포켓 미술관 / 口袋美术馆 等)は管理コストが増えるうえブランドの一貫性を損なう。シンプルな2種構成が破綻しにくい。

2026-07-19: String Catalog はキー=日本語原文方式(基準言語 ja)

背景: UI文字列の9言語化にあたり、キー体系(意味キー vs 原文キー)を決める必要があった。

決定: developmentLanguage: ja とし、日本語原文をそのままキーにする。SwiftUI リテラルは自動キー化に任せ、String 型に落ちる箇所のみ String(localized:) を通す。翻訳は Localizable.xcstrings に手で追記する運用(Xcode の自動抽出には依存しない)。DEBUGメニューは対象外。

理由: コードの可読性が高く(日本語がそのまま読める)、キー命名の管理が不要。同一原文で訳し分けが必要な箇所(例: セクション見出しとボタンの「お気に入り」)は日本語側の文言を変えて対処する(「お気に入りに追加」に変更)。

2026-07-17: アプリアイコンは収録作品「真珠の耳飾りの少女」の無改変顔クロップに決定

背景: アプリアイコンが未設定(ホーム画面で真っ白)だった。AIアニメ改変の仮アイコン案は法的・審査的に問題ないが、美術ファン層(コアターゲット)への「AI改変名画」の印象がアプリの真正性ブランドと矛盾するため棄却し、実在の収録作品を無改変で使う方針で三者議論(全2ラウンド+3案実寸比較テスト)を実施した。

決定: いったんゴッホ自画像(AIC)に決定して実装したが、収集元拡大により真珠の耳飾りの少女が正規収録された時点で同作へ変更(User決定)。原画準拠・無加工の顔中心クロップ(Wikimedia Commons 由来、確定 crop box (328, 0, 4095, 3767))。金縁・背景加工・初日獲得特例などの演出はすべて不採用。

理由: 絵画の顔として世界最高クラスの認知度と「顔に目が行く」アイコン適性。見送りの唯一の実質的理由だった「看板と中身の不一致」(非収録作品を看板に使う問題)が収録実現で解消し、三者議論の決定ルール(収録され実際に閲覧可能なら採用可)に整合。無加工方針は「無改変の実在作品」というブランド一貫性の維持(加工はその転換理由を曖昧にするという ChatGPT の指摘を採用)。

2026-07-16: 収集元を4館追加し、追加式で図鑑を1,200点へ拡大

背景: 真珠の耳飾りの少女(マウリッツハイス所蔵)のような世界的名画が、3館(Met/AIC/Rijksmuseum)API収集の母集団に構造的に入らず埋もれていた。アイコン鼎談から「有名作の取りこぼし解消」が独立テーマとして分離された。

決定: 収集元にクリーブランド美術館 / ワシントンNGA / ゲティ / マウリッツハイスの4館を追加(計7館)。既存1,000点は凍結し、拡大母集団から200点だけ追加する追加式で枠を1,200点に拡大。マウリッツハイスは公式APIがないため Wikidata SPARQL + Wikimedia Commons API 経由で収集(公式サイトの高解像度DLは非商用限定のため使わない)。真珠の耳飾りの少女の「特別収録」手動レーン案は不採用とし、自動収集レーンに統一。

理由: 全面再選定は既存1,000点の9言語解説とFableチェック済み205点の投資を無駄にするため追加式が合理的(訴求「1,000点以上」とも矛盾しない)。手動レーンより自動収集レーンの方が編集方針(出自の一貫性)を保てる。モナリザ等ルーヴル所蔵作は商用可のオープンアクセスが存在せず対象外。

2026-07-16: リワード広告SDKは Google AdMob 単体を採用(ユニットID二段構え運用)

背景: マネタイズ「出会いは無料、解説全文は広告かPro」の確定により、スタブ境界(RewardedAdProvider)に差し込む広告SDKの選定が必要になった(未決事項として保留中だった)。

決定: Google Mobile Ads SDK(AdMob)単体を採用する。メディエーション(AppLovin MAX / Unity LevelPlay 等)は広告収益が月数万円規模を超えてから検討。リワードユニットIDは Debug=Google公式テストID / Release=本番ID に project.yml の設定変数で分離し、ユニットIDが空の場合は SDK 自体を起動せず unavailable → 当日フォールバックに流す安全弁を実装する。開発中の動作確認は今後もテストユニットのみで行う(本番広告の自己クリックはポリシー違反リスク)。

理由: ①日本市場のリワード広告で単体SDKとしてフィル率・eCPMが最も安定し、個人開発の初期ボリューム(DAU数百以下)ではメディエーションを組んでも収益差がほぼ出ない ②SPM対応で導入が最軽量、ドキュメント・審査実績も豊富 ③後から AdMob をメディエーション配下に移せるため移行コストが低い。安全弁は「本番ID未設定のままSDK初期化してクラッシュ」「テストIDのまま審査に出す」事故を構造的に防ぐため。

2026-07-16: 通知の許可リクエストは起動時ではなくマイのトグルON時に行う

背景: ローカル通知(毎朝の「今日の1枚」リマインダ)の実装にあたり、iOS の通知許可ダイアログをいつ出すか決める必要があった。一度拒否されるとアプリ内からは二度と出せず、設定アプリ経由でしか復活できない一発勝負。

決定: 起動時のコールドなプロンプトは出さず、マイ画面の「毎朝の通知」トグルを ON にした瞬間にだけ許可をリクエストする。デフォルト8:00・ユーザー変更可の repeating 通知1本。拒否時はトグルを戻して「設定を開く」導線を出す。文言は「今日の1枚が届いています / きょう開くと、新しい作品がコレクションに加わります。」

理由: ユーザーが自ら通知を求めた文脈でのリクエストが許可率最大で、取り返しのつかない一発勝負を無駄撃ちしない。文言を訪問駆動デッキの仕様(開いた日だけ獲得)そのままにすることで、通知がコアループの説明を兼ねる。

2026-07-16: ユーザー向け呼称を「朱印帳」から「コレクション」に変更

背景: 実装完了後の実機確認で、You から「朱印帳という言葉は一般的に使われず通じにくい」との指摘。さらに9言語ローカライズ(String Catalog 対応予定)で「朱印帳」には対応する自然な訳語が存在しない。

決定: タブ名・画面見出し・空状態文言・獲得バッジ(「朱印獲得」→「コレクションに追加」)などユーザー向け文言を「コレクション」に統一する。美術館らしさはサブタイトルの「収蔵 N 作品」表記で残す。設計文書・DECISIONS 内の概念名としての「朱印帳」(獲得済みのみ表示・訪問駆動のメタファー)はそのまま使い続ける。

理由: 候補(①コレクション ②収蔵 ③ギャラリー ④アルバム)のうち、誰にでも通じ、かつ Collection / Colección / 收藏 と全対象言語に自然に訳せる①を採用。②収蔵は美術館らしいが硬く、③④は「訪問して集めた記録」のニュアンスが薄れる。「マイ美術館」はコンセプト適合度が最も高いが既存の「マイ」タブと紛らわしいため見送り。

背景: 共通カレンダー(全員が同じ日に同じ作品)はローンチ日依存(--start 再生成待ち)、2年目の不変性・バージョン管理、後発ユーザーの大量ロック体験、タイムゾーン跨ぎなど仕様を複雑化させていた。You / Claude / ChatGPT の三者鼎談(.devnotes/discussions/2026-07-16-calendar-model.md、全8ラウンド)で全面再検討した。

決定: 事前生成の固定順序デッキを全ユーザーが持ち、その日初めてアプリを開いたときだけ現在月のサブデッキからカーソルが1つ進んで1作品を獲得する(開かなかった日は何も起きず、後から回収もできない)。デッキは月別12本(季節適合度で各作品をちょうど1つの月に割当・月の日数比例・スター散布・作家近接目標・地域比率60:25:15)、追加のみ可で既存順序の変更禁止。うるう日は2月デッキを1枚進めるだけ。複数端末の二重獲得はカジュアル許容(獲得集合の和集合+同一deckVersion内カーソル最大値で統合)。iCloud同期(CloudKit)を採用。pm calendar は廃止し pm deck に置き換える。

理由: ①朱印メタファー(訪れた日だけ朱印が押される)と完全に一致し、習慣形成=D7継続率(Android判断のKPI)に直接効く ②ローンチ日・2年目・後発ユーザー・アーカイブ空問題が構造的に消滅する ③端末側ランダム抽選ではなく固定デッキにすることで、決定的でテスト可能・pm calendar で培った編集品質を維持できる(ChatGPT指摘)④出会わなかった季節作品は翌年の同月に回ってくるため「桜は春にしか来ない」が構造的に保証される。

2026-07-16: マネタイズを「出会いは無料、解説全文は広告かPro」に刷新(全館アクセス廃止)

背景: 旧設計「遡りアーカイブ直近7日無料・8日以上前は朱印極ロック」はデッキ転換で意味を失った。中間案の Pro=自由鑑賞権(未獲得解説の全開放+機能束)は、権利の複雑化と「全館開放と出会いの初対面感は両立しない」矛盾(図鑑全点無料表示のネタバレ問題を You が指摘)で棄却。You 発案の「課金しても1,000点をいきなり読めない」を軸に再設計した。

決定: 誰も1日1枚のペースを買えない。 毎日無料=今日の1枚との出会い(画像・題名・作者・導入部)+朱印獲得。解説全文は初回起動から14日間無料(7/14/30日でA/B予定)→ 以降は無課金者はリワード広告1本でその日の分を永久開放(広告取得不可時はその日を無料開放するフォールバック必須)。Pro=広告なしで毎日の全文+特集(当月・過去アーカイブ)。獲得済み作品の解説は永久閲覧でPro失効で失うものはない。図鑑=朱印帳(獲得済みのみ表示・未獲得はシルエットも見せず「日本美術 12/180」式の進捗数字のみ)。記念日は今日の1枚を上書きせず月例特集(複数作品の編集記事・朱印獲得なし)として独立。朱印帳UIは欠席日の空白表示・連続日数の強調をしない。広告SDK導入に伴うプライバシーラベル悪化(「データ収集なし」の喪失)は許容する。

理由: ①ゲートが「解説全文が読める = story_unlock 集合に含まれる」の1本になり、説明・実装・失効処理が最小化される ②出会いの神聖性が全ユーザーで保たれ、広告は儀式ではなく読み物の前に置かれる(「今日の1枚そのものを広告で施錠」は広告SDK障害がコア機能を止めるため棄却)③無課金ユーザーからも広告収益が出る二重収益 ④朱印帳=財産の原則(一度得たものは失わない)を全面で維持。保留: 価格体系(買い切り¥3,000=年額2年分は買い切り誘導が強すぎる懸念)、特集当月分を無料の味見にするか、無料期間の日数。

2026-07-15: 「今日」の日付判定は端末時計を基本に、CDN応答時刻でサニティ補正(ラチェットなし)

背景: 端末の日付変更で「今日の1枚」の先読みや、将来実装する「8日以上前の遡りはPro」のすり抜けができてしまう。ただし配信は認証なしの静的CDNなので本気の回避は時計対策では防げず(JSONを直接取れる)、守る対象はカジュアルなすり抜けのみ。課金・トライアルは RevenueCat/StoreKit のサーバ判定なので時計操作では破れない。

決定: 「今日」は端末時計を基本とし、オンライン時は manifest 取得時の HTTP Date ヘッダと端末時計のズレを記録、ズレが大きい(目安1日超)場合のみサーバ時刻由来の日付を採用する。オフライン時は端末時計にフォールバック。時計の逆行を禁止するラチェットは実装しない(海外旅行のタイムゾーン移動による正当な日付逆行を誤爆するため)。連続鑑賞ストリークは閲覧記録から寛容に計算し、時計偽装対策はしない(報酬経済がなく自分をだますだけ)。

理由: バックエンド不要(R2/CDNの標準ヘッダのみ)で実装が小さく、正当なユーザーを誤爆しない。実装タイミングは遡り+Proゲート実装時にまとめて行う。

背景: 引き継ぎ.md の技術スタックで「SwiftData or GRDB ※選定理由をDECISIONSに記録」となっていた。Phase 2 着手にあたり確定が必要。

決定: GRDB.swift 7.x(SPM)を採用する。

理由: ①同期処理が「マニフェストのsha256差分 → 変わったファイルだけ全削除・全挿入」というSQL的な一括操作で、GRDBのトランザクション+バッチinsertが素直に書ける(SwiftDataは大量upsertが苦手で挙動もOSバージョン依存)。②将来のWidgetKit(App Group共有DB)や全文検索(FTS5)into拡張が実績豊富。③スキーマをマイグレータで明示管理でき、配信スキーマ(schema_version)との対応が追いやすい。SwiftDataの利点(SwiftUI @Query統合)は本アプリでは薄い——表示データは読み取り専用のカタログで、書き込みは同期エンジンだけだから。

2026-07-15: Xcodeプロジェクトは XcodeGen で生成(.xcodeproj はGit管理外)

背景: CLI主体の開発で .xcodeproj の手管理(GUIDの衝突・コンフリクト)を避けたい。

決定: app/project.yml を正として xcodegen generate で .xcodeproj を生成する。生成物はGit管理外。

理由: プロジェクト定義がテキスト1ファイルでレビュー・diff可能。ファイル追加は app/PocketMuseum/ に置いて再生成するだけ。hinata-mahjong 等での運用実績もある標準手法。

2026-07-15: 配信形式は「manifest + 言語別stories分割」の静的JSON(pm export で dist/ 生成)

背景: R2 は Cloudflare 認証待ちだが、アプリ開発を先行させたい。また9言語×1,000件の解説を1ファイルに束ねると約9MBになり、初回同期が重い。

決定: pm exportdata/dist/ に R2 と同一レイアウト(manifest.json + content/artworks.json + content/calendar.json + content/stories/{lang}.json + images/)を生成する。stories は言語別分割(各約1MB)で、アプリは端末言語+jaフォールバックのみ同期する。manifest.json に各ファイルの sha256 を持たせ、アプリは前回同期時のハッシュと比較して変わったファイルだけ再取得する。開発中は python3 -m http.server 8787(dist/ 配下)をアプリのDebugビルドが向く。

理由: R2到達前にアプリ開発を止めないため、「pm upload = dist/ をそのままR2に置く」だけになる形で配信レイアウトを先に確定させた。ハッシュ差分方式はETagやバージョン番号管理より実装が単純で、静的配信と相性がよい。言語別分割で初回同期は約1.6MB(artworks 564KB + calendar 25KB + stories 1言語約1MB)に収まる。

背景: Fable による9言語解説の最終チェック方式を、コストと精度の実測で決める必要があった。

決定: 1作品=1サブエージェント(クリーンコンテキスト・8並列・完了通知駆動)で回し、エージェントはデータ読み取り専用、結果はscratchpad経由でメインが単一プロセスマージする。

理由: 実測比較で、メインセッション集中型は$3/作品と高コスト、4作品バッチ型は$0.78/作品だが事実照合が甘く誤訳を見逃した(Woman Reading の再検証で判明)。集中型は$1.03/作品で、ja原文の視覚的事実誤り(205作品中10件)を美術館公式画像との照合まで自走して検出できた。読み取り専用+中央マージは並行生成プロセスとの書き込み競合を構造的に排除するため。

2026-07-14: story_quality 3段階と revisions.jsonl 追記型修正履歴

背景: Fable が修正したことを後から追跡でき、Fable 修正後の再修正(人間・別モデル)にも耐える履歴管理が必要だった。

決定: story_quality を ai_generated → ai_reviewed → human_reviewed の3段階とし、チェック済みレコードに review{score, reviewer, reviewed_at, notes}revision を付与。修正は data/stories/revisions.jsonl に1件1行(id/lang/editor/edited_at/score_before/reason/before/after全文)で追記する。

理由: レコード内に全履歴を埋めると肥大するため「現在値はレコード、履歴は追記型ログ」に分離。editor フィールドで修正主体を区別でき、将来の再修正も同じログに追記するだけで済む。80点以上は無修正、80点未満のみ最小修正という基準も併せて確定。

2026-07-14: チェックは毎日少しずつ実行(1回100作品目安)

背景: 集中型チェックは100作品で約$103相当(API単価換算)とMaxプラン消費が大きい。

決定: 残り795作品は一括せず、毎日100作品目安で消化する。

理由: 1日の使用量上限への影響を抑えつつ、1回約100分で完了する運用単位として100作品がちょうどよい。calendar 順に消化しているため、配信開始が早い作品から品質が担保される。

2026-07-13: 解説生成は Codex CLI(サブスク枠)を既定バックエンドに

背景: pm generate は Claude API の Message Batches(従量課金・要APIキー)前提で実装したが、パイプラインとしての再現性よりコストを抑えることを優先するとの判断(You)。Codex CLI(gpt-5.6-sol)はサブスク枠内で追加費用がかからない。

決定: codex exec(読み取り専用サンドボックス・--output-schema でJSON強制・--ephemeral)を並列実行する codex バックエンドを追加し、pm generate の既定にする。Claude API バッチ実装は --backend api で温存。

理由: 追加費用ゼロ。品質は同一プロンプトの3件サンプル(睡蓮・寝室・神奈川沖浪裏)で確認済み(事実誤りなし、ゴッホの手紙引用まで正確)。代償は実時間(1件60〜120秒 × 9,000件 ÷ 並列数 ≈ 30〜40時間/4並列)だが、失敗・中断分は記録されない設計なので再実行=続きからで夜間放置できる。言語追加時の再現性も「再実行するだけ」は維持される(コストがゼロになっただけ)。

2026-07-13: 解説の文字数は300〜450字目安(上限500字)に改定

背景: 当初仕様(引き継ぎ.md §5)は200〜300字。サンプル生成したところ「フック+技法描写」だけで埋まり、逸話・時代背景に踏み込む余白がなかった(ゴッホ「寝室」で療養の逸話に触れられない等)。

決定: 本文は300〜450字を目安、語るべき逸話が豊富な作品は500字まで可、水増し禁止。基本形は「フック → 逸話・時代背景 → 画面の見どころ → 締めのひと言」(機械的強制はしない)。

理由: 読了時間45〜90秒で「朝の1枚」の習慣に収まる。美術館の実物キャプション(100〜200字、短すぎて差別化にならない)と DailyArt(日本語換算500〜600字、長さへの不満レビューあり)の中間。新旧サンプル比較で、ゴッホの手紙の実引用・北斎のベロ藍など逸話が入るようになり品質向上を確認して確定。

2026-07-12: 画像品質は「目標2000px・許容下限1600px」の2段構え

背景: 仕様の解像度下限(長辺2000px以上)で実寸検証したところ、選定1,000点中77件が未達。その中にメトの至宝級(カンピン「メロードの祭壇画」、スーラ「グランド・ジャット島」習作、ラファエロ、ワトー「メズタン」等)が多数含まれており、機械的に差し替えるとコンテンツ品質を大きく損なうことが判明した。

決定: 2000pxは選定スコアリング上の目標値のまま維持し、実寸検証後の差し替え判定は許容下限1600px(ACCEPT_LONG_EDGE_PX)で行う。1600px未満と画像URL切れのみ次点と自動差し替え。

理由: スマホの全画面表示は実効1200px前後で、1600pxあればズーム鑑賞にも実用十分。名作の代替は存在しない(差し替えた瞬間に図鑑の格が下がる)が、ピクセル数の不足はユーザーがほぼ知覚できない。規格純度よりコンテンツ品質を優先。

2026-07-12: キュレーションはスコアリング+地域枠+自動差し替えループで機械選定

背景: 44,792件から図鑑1,000点を選ぶ方式を決める必要があった。

決定: ①スコア = Wikidataリンク+3 / 館ハイライト+4 / 有名画家ティア表(手動メンテ、pm/artists.py、+3〜+10)/ 画質 / AIC閲覧シグナル ②地域枠(西洋600・日本250・その他150)ごとにスコア順で貪欲選定、作者あたり上限15 ③作者+正規化タイトル(最初のカンマ以降を除去)で館間重複を排除 ④pm images の実寸検証結果を pm curate が読み込み、不適格作品を除外して次点を繰り上げる自動差し替えループ。

理由: 完全自動の知名度シグナル(Wikidata・ハイライト)だけでは館ごとの格差が大きく(AICはWikidataリンク無し)、名作の取り逃しが起きた(ゴッホ「寝室」落選事件)。手動ティア表は約150名分のメンテナンスコストで確実な品質底上げができ、重み・比率・上限はすべてパラメータ化してあるので後から再調整・再実行が容易。

2026-07-12: 収集の設計原則「疑わしきは再試行、確定した対象外のみスキップ台帳へ」

背景: Met がスロットリング時に返す一過性の異常応答(403・中身の欠けたJSON)を「public domain でない」と同列の恒久スキップとして台帳に記録していたため、ゴッホ・フェルメールを含む約1.1万件を取りこぼす重大バグが発生した。

決定: スキップ台帳に入れるのは「APIが明示的に対象外と答えたもの」(isPublicDomain: false、画像が存在しないことの確定)のみ。応答が None・必須フィールド欠け・リトライ上限到達は台帳に入れず、次回の再実行で自動再試行させる。403 はリトライ対象ステータスに含める。あわせて中断の安全装置は「累計50件エラー」ではなく「連続50件エラー」とする。

理由: 収集は追記式+台帳による冪等設計のため、「誤って捨てる」コストは「もう一度試す」コストより桁違いに大きい。一過性エラーの再試行は再実行1回で済むが、誤った恒久スキップは台帳を破棄しての全数再検査(約1時間)を要した。

2026-07-12: Rijksmuseum は新 Data Services(Linked Art)で実装

背景: 引き継ぎ.md が想定していた旧 Rijksmuseum API(APIキー式)は 410 Gone で廃止されていた(2025年に新サービスへ移行)。

決定: キー不要の新 Data Services を採用。検索(pageToken式)→ HumanMadeObject → VisualItem(権利表示の確認)→ DigitalObject(IIIF画像URL)と辿る。作品1件=3リクエスト。

理由: 選択肢がこれしかない(旧APIは死んでいる)。副次的メリットとして APIキー登録が不要になり、VisualItem の権利表示で作品ごとの Public Domain 判定を明示的に確認できる。Linked Art はリスト/dict/文字列が混在する揺れの大きい形式のため、抽出関数はすべて防御的に実装した(_dicts / _ref_id ヘルパー)。

2026-07-12: パイプラインCLIは argparse サブコマンド式の pm(uv 管理)

背景: 引き継ぎ.md に「CLI体裁は intelligence-bank の ib コマンドの流儀に合わせる」とあったが、intelligence-bank は静的HTMLサイトで ib コマンドの実体はどこにも存在しなかった(PATH・シェル設定・リポジトリ内・git履歴を確認)。

決定: 標準的な「単一エントリポイント + サブコマンド」式の argparse CLI として実装(uv run pm collect met|aic|rijks / pm status)。パッケージ管理は uv + pyproject.toml、依存は requests のみ。

理由: 参照先が実在しない以上、Python 標準の慣例に従うのが最も保守しやすい。将来のサブコマンド追加(curate / generate / images / upload / calendar)も自然に収まる。

2026-07-11: アプリ名は日本語「ポケット美術館」維持、英語名は複合名にする

背景: 引き継ぎ.md の未決事項だった名称チェックを実施(倍音ヒーリングと同様の手順: ストア検索 + 商標確認)。App Store 調査で2件の被りを発見: ①「ポケット美術館 ~間違い探しゲーム~」(Char Room、2022年6月リリース、同年7月から更新停止、評価35件)②「Pocket Museum」(Kazuki Shinagawa、2025年12月30日リリース、id6756817667)。特に②は英語名完全一致に加え、コンセプトがほぼ同一(メトロポリタン美術館のコレクションから毎日1枚配信)。ただし規模は最小(英語のみ・無料・課金なし・評価0件)。Google Play には完全一致なし。商標は chizai-watch(日本)・Justia(米国)のインデックスにヒットなし。

決定: 日本語名は「ポケット美術館」を維持。英語名は "Pocket Museum" 単体が使用不可(App Store はストア全体でアプリ名の完全一致を許さない)のため、"Pocket Museum: Daily Art" 等の複合名にする。

J-PlatPat 手動確認の結果(2026-07-11 追記): 「ポケット美術館」はヒットなし。「ポケットミュージアム」は商願2026-039383(ソーシャル知財株式会社、2026/04/07出願、係属-審査待ち)が存在するが、区分は第16類(紙製品・印刷物)のみで、アプリ(第9類)・コンテンツ配信(第41類)とは商品役務が非類似。出願人は第30類(食品)・第14類(宝飾)中心に出願する実業会社でトロールではない。称呼も「ポケットビジュツカン」と「ポケットミュージアム」で非類似のため、アプリ名としての使用に支障なしと判断。留意点: ①将来グッズ展開(ポストカード・画集=第16類)をする場合は正面被りになる ②防衛的な商標出願(「ポケット美術館」第9類+第41類)は今は見送り、アプリが軌道に乗ったら検討すると決定(2026-07-11)。

理由: 先行の同名アプリは英語のみ・機能最小(解説なし・多言語なし・課金なし)で、こちらは9言語・図鑑1,000点・解説付きのため正面競合しても優位。日本語名の部分被りは放置状態のカジュアルゲームで実害が小さい。完全な別名への変更はコンセプト適合度の高い現名称を捨てるコストに見合わない。

2026-07-11: 買い切り¥3,000はPro entitlementと完全同等(将来追加コンテンツも含む)

背景: 引き継ぎ.md の未決事項「コンテンツ追加が続いた場合、買い切りに新コレクションを含めるか」を確定させた。

決定: 買い切りは月額/年額と同一の entitlement pro に紐付け、将来追加されるコレクション・解説もすべて含む。コンテンツ追加コストが重くなった場合は、新規購入者向けの買い切り価格を引き上げて対応する(既購入者は据え置き)。

理由: ①年額¥1,500の2年分という価格設定で回収ラインとして妥当 ②entitlement 1本のまま管理がシンプル ③「買い切りなのに後から制限」はレビュー炎上の典型パターンで、完全同等が好感度最優先の選択。DailyArt 等の先行例も Lifetime = サブスク同等。

2026-07-11: 残りの未決事項を一括確定(言語セット・キュレーション比率・誤訳報告UI・Android時期)

背景: 引き継ぎ.md の未決事項をまとめて確定させた。

決定: ①言語セットはローンチ9言語(ja/en/es/fr/de/it/pt/ko/zh-Hans)で確定、zh-Hant はパイプライン再実行で v1.x 追加 ②キュレーション比率は西洋60% : 日本25% : その他15%を目安とし、スコアリングの重みパラメータとして実装して後から調整可能にする ③誤訳報告UIは解説末尾の控えめなテキストリンク→カテゴリ選択(誤訳/不自然/事実誤り)+任意コメントのシート→mailto送信(作品ID・言語コードを自動埋め込み)。報告が増えたら Workers エンドポイントに置き換え ④Android版は今は決めず、iOSリリース+2ヶ月時点でKPI(D7継続率・課金転換率)を見て判断する。

理由: ①ローンチ時の言語追加コストは翻訳(数百円〜千円規模)よりASO・スクショ・審査の言語別作業が支配的で、増やすほどリリースが遅れる ②Met/AIC は浮世絵のCC0画像が豊富(北斎・広重・写楽など)で日本25%は現実的に埋まる ③mailto はバックエンドを持たない方針と整合する最小実装 ④Android の判断材料(継続率・課金転換)はリリース前には得られない。

DEVLOG(作業ログ)

開発日誌

このプロジェクトでの作業を時系列で記録する。 最新のエントリが上に来る。


2026-08-18

21:07 - 特集公開と休眠復帰のお知らせ通知を実装(iOS)→ 1.0.3/build 10 を TestFlight へ

やったこと:

  • 通知の方式を相談で確定: 「特集を追加したとき通知したい/深夜は避けたい/地域で変えられるか」から出発。結論は 案A = ローカル通知の先出し予約で、FCM もバックグラウンド同期も入れない。特集は月次・低頻度で即時性がなく、審査中の申告(プッシュトークン)を触るコストに見合わないため。「休眠掘り起こしはプッシュしかない」は同期(新情報の取得)の話で、内容が前回起動時点で決まる声かけならローカルで完結する、と切り分けた
  • パイプライン: featured.py に任意の publish_at(YYYY-MM-DD)。形式チェック + 全言語で ja と一致の検証。未指定・過去日は通知しないので既存記事で誤爆しない
  • iOS 実装: PMNotifications.swift 新設。特集公開=publish_at の現地19:00に1本 / 休眠復帰=最終起動から 7/21/60 日後の現地19:00に3本(起動のたびに貼り直すデッドマンズスイッチ)。発火は UNCalendarNotificationTrigger(端末の暦の壁時計)で組み、経過秒トリガは使わない(最終起動が深夜だと深夜に鳴る・TZ 移動でズレる)
  • DB に featured.publishAt 列 + マイグレーション featured-publish-at-v1ContentQueriespendingFeaturedNotices、既存の言語マージを mergedFeatured に共通化
  • マイに「特集のお知らせ」トグル(既定ON)。毎朝リマインダとは独立で、システムの通知許可のみを条件にする(許可ダイアログはここから出さない)
  • 通知タップは特集公開だけ特集タブへ遷移(RootTabView に selection 追加 + NotificationRouter)。休眠は通常起動に任せる。notification_opened(kind=featured / dormant_7|21|60)を計測に追加
  • 文言5キー×9言語を xcstrings に追加 → Codex(gpt-5.6-sol / xhigh)でレビュー。指摘5件(すべて中・高ゼロ)を全反映: fr の名詞句並置、ko/zh の語彙と述語欠落、zh の「站到」が物理動作を足していた点
  • 1.0.3 / build 10 をアーカイブ → export → validate → upload。Delivery UUID 6f5ac1b7-9528-4f61-aabd-1166409625ae・16.6MB。internalBuildState=IN_BETA_TESTING で内部テスターがインストール可能な状態

詰まったこと / 気づき:

  • Swift 6 の並行性: UNUserNotificationCenterDelegate@MainActor クラスに素直に生やせない(UNNotificationResponse が非 Sendable)。nonisolated + 完了ハンドラ版にして、その場で identifier(String)だけ取り出してから MainActor へ渡す形が通る
  • 通知タイトルの折り返しは実測が要る: de 40字が …zur… と語中で切れた。37字は収まり境界は38前後。ただし検証機 iPhone 17 は 402pt 幅で、iOS 17 対応なら 375pt 幅も入るため32字を上限に全言語を詰めた。xcrun simctl push に任意の文字列を流し込めばアプリを触らずバナーの見え方だけ検証できる(コード変更もビルドも不要。長さ検証はこれが最速)
  • 通知センターの合成タップではアプリが起動しない(XcodeBuildMCP の tap も座標タップも空振り)。バナーが出ている数秒のあいだに実タッチを送るのが確実
  • build_sim はビルドするだけでインストールしない。挙動を見るときは build_run_sim。古いバイナリのまま検証して一度誤読した
  • 配布 export で errSecInternalComponent: 署名専用キーチェーン(~/.config/asc/pocket-museum-dist/pm-signing.keychain-db)に WWDR 中間証明書が入っておらずチェーンが自己完結していなかった。加えて検索リストに前セッションの scratchpad パス(実体なし)が残っていた。復旧手順 = 検索リストを「署名用 + login」に設定し直す → login から WWDR を書き出して署名用にも import → security set-key-partition-list → export。作業後は検索リストを login のみに戻す
  • 配布プロファイルはローカルに無かったが、ASC API(/v1/profiles)から profileContent を取って ~/Library/Developer/Xcode/UserData/Provisioning Profiles/<UUID>.mobileprovision に置けば export が通る
  • ASC の MCP 既定キーは別チーム。RAMANU 用は ~/.config/asc/AuthKey_8M2SWG78S6.p8(issuer は subnote の .mcp.json にある)。archive は自動署名+このキー、配布署名は exportOptions.plist の二段構えという既存の型がそのまま効いた
  • 配信データの分類は全12種すべて平面作品(絵画924・版画256・素描14ほか)で立体はゼロ。Codex の ko/zh 指摘が「絵画以外を含むか」を条件にしていたので、データで裏を取ってから採否を決めた

決めたこと:(DECISIONS 参照)

  • お知らせ通知はローカル通知で実装し、FCM とバックグラウンド同期は採らない
  • 通知トグルは2本構成にし「特集のお知らせ」を既定ONにする
  • 休眠復帰通知は特集にも特定の作品にも紐づけない
  • 通知タイトルは全言語32字以内に収める

次回やること:

  • TestFlight 実機で確認(トグルの表示と独立動作。通知の発火を見るなら端末の日付を進めるか、publish_at 入りコンテンツを本番 CDN へ)
  • Android の後追い実装(Play 審査の結果が出てから。文言は xcstrings 正本から生成スクリプトで展開)
  • ドイツ語の du / Sie 統一(既存の通知プライマー文言が Sie、別の既存文言が du で割れている。今回の追加分は中立なので影響なし)
  • Play 審査結果の確認 / AdMob 開通チェーン / PR TIMES 骨子(継続)

09:40 - iOS 1.0.2 の公開確認と YouTube 著作権通知の切り分け(旧動画由来・実害なし)

やったこと:

  • iOS 1.0.2 の公開を確認: iTunes Lookup で jp / us とも version 1.0.2・公開 2026-08-18 08:13 JST。What's New も ja「フェルメール特集を無料開放いたしました。」/ en「Our Vermeer editorial is now free for everyone to read.」で意図どおり。releaseType=AFTER_APPROVAL の自動公開が想定どおり機能した
  • YouTube の再ブロック通知(8/18 05:48 着)を切り分け: 件名・本文とも昨日の通知と同一だが、メール本文の「すべてのアクションを表示する」のリンク先が studio.youtube.com/video/Q62huvtjorg/edit初代デモ動画への申し立てと確定(Naxos / Clair de lune・上野真、更新日 8/17)。3本の playabilityStatus を実測して現行 oPT_g_lx5v0status OK・isUnlisted:false・72秒、UNPLAYABLE は旧2本(7BoL3VbVYIQ / Q62huvtjorg)のみと確認。Devpost 公開ページの埋め込みも oPT_g_lx5v0Submitted 維持 → 審査員が見る動画は無傷で実害ゼロ
  • 旧2本は削除せず限定公開のまま残すことに決定(DECISIONS 参照)。Play は審査中のまま変化なし

詰まったこと / 気づき:

  • 同一タイトルの動画が3本あると通知の宛先が件名・本文からは分からない → 判別はメール本文の Studio リンクに埋まった動画 ID が最速。今後同じ件名が来ても旧2本宛なら無視でよい
  • 動画の生存確認は curl で watch ページを取って "playabilityStatus" を見れば足りる(ログイン不要。全世界ブロックなら日本からも UNPLAYABLE)。"isUnlisted" で公開/限定公開も判別できる
  • ASC の MCP 既定キーは thomsons チームのもので、RAMANU の Pocket Museum(Apple ID 6792521728)は 404 になる。iOS のストア公開状態の確認は iTunes Lookup(itunes.apple.com/lookup?id=...&country=jp)で代替するのが早い

次回やること:

  • Play 審査結果の確認(通常7日以内)→ 承認後: 一時的なアプリ名 (unreviewed) の解消・ストアページ確認・実機での製品版動作確認
  • 両OS公開が揃ったら PR TIMES 骨子 → 9月中旬配信 / Devpost に Google Play URL 追記(〜9/30)
  • AdMob 開通チェーン(iOS・ストア掲載リンク)/ GA4 定点観測

2026-08-17

23:15 - Android 版を Play 審査に提出(利用規約新設 → versionCode 4 → 製品版リリース → 審査送信)

やったこと:

  • 利用規約ページを新設・公開: https://ramanu.co.jp/pocket-museum/terms/ (ja/en・プライバシーポリシーと同デザイン。サブスク条項=両ストアの課金/解約/返金、PD/CC0 画像と自社コンテンツの権利区分、禁止事項、免責+消費者契約法の留保、東京地裁管轄。company-operation 04733d8・wrangler pages deploy 済み)
  • Android Paywall に利用規約リンクを追加0ff0eb1): iOS と同じ3リンク並び(利用規約/プライバシーポリシー/購入を復元)。iOS は Apple 標準 EULA 維持・Android は自前 ToS ページ。ラベルは xcstrings 正本の既存キー「利用規約」をマッピング追加して9言語生成。エミュレータで表示・遷移(/terms/ 起動)を確認
  • versionCode 4 をビルドして内部テストに公開060bda7): UI磨き込み5件 + 無料公開中バッジ + ToS リンクの全部入り
  • Play 掲載文9言語に利用規約行を追記して API 再登録f651450): ja は /terms/、他8言語は /terms/en/。ラベルは ASC 旧 EULA 行の訳語を流用
  • 製品版リリースを作成: 配信国 176か国(全選択)→ ライブラリから versionCode 4 を追加 → リリースノート9言語(言語タグ形式の一括 textarea)→ 保存。警告はデバッグシンボル推奨のみ
  • 提出前クイックチェックのブロッカー1件を解消: 「広告 ID の申告が不完全」— AAB のマニフェストに AD_ID 権限が実在(Firebase Analytics のライブラリマニフェストが自動マージ。ローカルの merged_manifests 中間ファイル確認では検出できず「なし」と誤認していた)。申告を「使用する(分析、広告・マーケティング)」に修正して解消。DATA_SAFETY.md も訂正
  • 19件の変更を審査に送信(You の GO 確認後): 製品版 4 (1.0.0) 完全公開 + 掲載9言語 + 全申告。「審査中の変更」に遷移し、クイックチェック完了後に自動で審査へ。審査目安は通常7日以内・キルスイッチ 9/8 に対し約3週間の余裕

詰まったこと / 気づき:

  • 広告系申告の整合は Play 側の実測が正: ローカルの中間ファイルでの AD_ID 有無確認は信用できない(bundletool の最終マージと一致しない)。「広告あり申告 × 広告ID なし申告 × マニフェストに権限あり」の3すくみを提出前チェックが検出してくれた
  • 製品版の操作も確立済みの型で完走: 国/地域は mat-checkbox のヘッダー全選択 → 保存 → 確認ダイアログ、リリースノートは1つの textarea に <ja-JP>...</ja-JP> 形式で9言語一括、ライブラリからのバンドル追加はファイルダイアログ不要
  • 提出前判断の残り: 審査用プロモコードは用意せず送信(Play 審査は自動主体・ログイン不要アプリのため)。削除ページの保持期間明記は任意のまま持ち越し

次回やること:

  • クイックチェック完了後の送信確定を確認(タイマー仕込み済み)→ 以後は審査結果待ち(通常7日以内)
  • 承認後: ストア公開確認 → PR TIMES 骨子(両OS揃い)/ Devpost に Google Play URL 追記(〜9/30)
  • AdMob 開通チェーン(iOS)/ GA4 定点観測(持ち越し)

22:02 - フェルメール特集を恒久無料開放 → 8言語全文レビュー74件修正 → iOS 1.0.2 審査提出

やったこと:

  • フェルメール特集を恒久無料開放: 設計時から用意していた記事単位の access 属性(preview/open)を初適用。9言語 JSON を open 化し、iOS/Android の特集一覧カードに「無料公開中」バッジを実装(Pro には非表示・文言は xcstrings 正本に9言語追加 → Android は生成スクリプトで展開)。pm exportpm upload で既存アプリにもゲート解除が即反映(バッジ表示のみアプリ更新が必要)。iOS シミュレータで一覧バッジ + 非Pro状態の全文表示を実機確認(929db85
  • 特集8言語の全文レビュー: 検収が機械+一部目視のみだった8言語(es/fr/it/pt は本文未読だった)を、訳者(Codex/GPT)と別モデルの Claude エージェント言語別8並列で ja 正本と全文対読。時代錯誤ゼロ・作品タイトル訳語は8言語×7作品一致の一方、高2件(en 壁の描写の構文破綻 / it「ペンを止め」→「ペンを置き」の視覚的事実)+ 中24 + 低約48 を検出。高中30置換 → You 指示で低44置換も適用(据え置きは fr 1件のみ)。revision 2 で本番反映。結果正本は レビュー結果_特集記事8言語全文レビュー.md70e7b75
    • 発見: ja/en は本文で作品名を名指ししないが Codex 7言語はタイトル明記スタイル / 機能名「今日の1枚」の訳が6言語で UI 訳語と不一致(すべて UI に統一)
  • iOS 1.0.2(build 9)を審査提出: project.yml 1.0.2/9 → xcodegen → archive/export/validate/upload(build 8 と同一コマンド構成・Delivery UUID d4c5b6c6)→ ASC に 1.0.2 新設 + What's New 9言語 + build 紐付け → asc-submission-check.mjs → 提出。You 指示で What's New を「フェルメール特集を無料開放いたしました。」(9言語・タブ名/固有名詞はアプリ内訳語に一致)へ差し替え — 提出取り下げ(canceled PATCH → 約20秒で DEVELOPER_REJECTED)→ whatsNew PATCH → 再提出で WAITING_FOR_REVIEW(20:29)。さらに releaseType を MANUAL → AFTER_APPROVAL(承認後自動公開) に変更(d4f8074

決めたこと:(DECISIONS 参照)

  • フェルメール特集の恒久無料開放(access=open 初適用・バッジは Pro 非表示)
  • 特集翻訳の検収に「別モデル・言語別並列・全文対読」レビューを組み込む
  • iOS 1.0.2 から承認後自動公開(AFTER_APPROVAL)

気づき:

  • ASC は審査待ち(WAITING_FOR_REVIEW)中でも releaseType は PATCH で変更可。whatsNew 等ローカライズは取り下げが必要(auto-memory asc-direct-access に追記済み)
  • 翻訳レビューは「訳者と別モデル」が効く。機械検証(構造・タイトル一致)を通過済みでも、視覚的事実の誤り・非成立連語・機能名の UI 不一致は全文対読でしか出なかった
  • 特集の同期は manifest sha256 差分なので revision 更新なしでも配信されるが、版管理として記事 revision は上げて運用する

次回やること:

  • iOS 1.0.2 の審査結果確認(承認後は自動公開・操作不要)
  • Android 製品版 AAB の版判断: バッジ入り最新 main で versionCode 4 にするか、実購入E2E 検証済みの versionCode 3 のまま提出するか

18:53 - Shipaton デモ動画の Content ID ブロック対応(BGM差し替え → 再公開 → Devpost更新)

やったこと:

  • YouTube から「Pocket Museum: Daily Art — Demo (Shipaton 2026)」(7BoL3VbVYIQ) が全世界ブロックの通知。Naxos が「Suite Bergamasque: III. Clair de lune(上野真 演奏)」との一致を申し立て(ストライクではなく Content ID 申し立て・チャンネルペナルティなし)。BGM は Wikimedia Commons の PD 録音の認識だったが、誤検知か PD 誤表記かは未確定のまま追及せず(実益なし)
  • 対応はBGM 差し替え + 新規アップロードで決着(You 選択)。YT オーディオライブラリに旧クラシック PD 音源(Clair de Lune / Wahneta Meixsell)は現存せず → クラシック×穏やか44曲から「Night Snow」(Asher Fulero・YouTube ライセンス・帰属表示不要) を選定。Gymnopedie No 2 (Kevin MacLeod) は CC-BY で帰属表示が必要なため見送り
  • 音なし版 build-wall/demo-noaudio.mp4(72.2秒・映像は承認済みのまま)に同一パラメータ(-19LUFS/TP-1.5dB・フェードイン1.5秒/アウト3.2秒)+ AAC 48kHz で再合成 → ~/ichirokisanuki/pocket-museum-video/pocket-museum-daily-art-demo-shipaton2026-v2.mp4(旧 Shipaton 版の 96kHz 問題も解消)。6面チェックシートで映像の無変化を確認
  • 公開オペレーション: 旧 7BoL3VbVYIQ限定公開に降格(Q62huvtjorg と同運用)→ 新動画 oPT_g_lx5v0 を公開(タイトル同一・説明=Night Snow クレジット・子ども向けでない・著作権チェック「問題は検出されませんでした」で通過)→ Devpost の software[video_url] を form_input で差し替え → SUBMITTED / 5/5 steps 維持・公開ページの埋め込みも新IDを確認

詰まったこと / 気づき:

  • 実 Chrome(claude-in-chrome)のファイル選択: file_upload ツールは合計10MB上限(動画17.5MBで不可)→ cliclick 物理クリック経路へ。ネイティブダイアログは表示まで4秒前後かかる。早撃ちしたキーは Chrome 本体に流れ、⌘⇧G=「前を検索」で検索バーが開くだけの空振りに(2回)。クリック → 待ち → screencapture で表示確認 → キー送出、の順で成功
  • OSレベル入力の前に screencapture で frontmost 確認が必須。並行セッションで You がタイピング中だったため、AskUserQuestion で「数秒画面を借りる」合意を取ってから実行して事故なし
  • ファイル選択後の YouTube アップロードウィザード(タイトル/説明/子ども向け/公開)は拡張のページ内操作だけで完結する(You は作業続行可)
  • 手順と罠は auto-memory youtube-video-swap-ops に保存済み

決めたこと: DECISIONS 2件(差し替えBGM は YT オーディオライブラリ音源 / App Store プレビュー動画は現状維持)

次回やること: 本件はクローズ(Shipaton 参加状態=SUBMITTED を確認済み)。既存の Play 審査提出チェーンに変更なし

16:18 - Play 提出物を全登録(掲載9言語 API 一括 + プライバシーポリシー両OS化 + 全申告完了)

やったこと:

  • Play ストア掲載テキスト9言語を制作: ASC 1.0.1 の掲載文を API で取得(scripts/外の scratchpad 経由)→ Apple 課金定型文を Google Play 版に差し替え・Apple 標準 EULA 行を削除して store-assets/play-listing/LISTING.md を正本化。タイトル30/簡単80/詳しい4000字の全ロケール制限内。広告の記述は iOS と同文維持(You 決定)
  • スクショを 9:16 (1080x1920) で9ロケール×6枚生成: Console の現行要件が「16:9 または 9:16」で旧 2:1 前提を作り直し。方式=壁側だけ行ごとの端色延長(01/04=左294px・02=右294px・03/05=左右147px・06=下クロップ)。ミラー方式は端末ブリード側で鏡像複製が出て NG だった。store-assets/screenshots/android/*/phone/
  • feature graphic 1024x500(スクショ06の壁面から文字なし切り出し・全ロケール共通)+ アイコン512store-assets/play-listing/graphics/ に作成
  • プライバシーポリシーを両OS対応に改定・デプロイ(company-operation e0db059): iOS 限定記述の一般化 + Google Play 課金/解約 + **データ削除リクエスト章(#data-deletion アンカー)**を ja/en に追加 → wrangler pages deploy で本番反映
  • SA に「ストアでの表示の管理」(+自動付帯のポリシー申告)と「未公開のアプリの編集、削除」を追加(前者はチェック操作を Claude が実施・後者は You 承認のうえ You が操作)→ scripts/play-upload-listing.mjs9言語テキスト + スクショ162枚(電話/7"/10"×6枚×9ロケール)+ アイコン + FG を Publishing API で一括登録・commit 成功
  • アプリのコンテンツ 9/9 申告完了: 広告=はい(先行申告)/ 広告ID=いいえ(AAB に AD_ID 権限なしを実測確認)/ ログインの詳細=はい+英語手順(fail-open 説明。「全機能アクセス可」チェックが必須仕様)/ コンテンツレーティング=ESRB 13+ / PEGI 3 / USK 6+(暴力=現実的・遠目まれ・流血軽度、ヌード=尻+乳房まれ、アルコール=使用まれ、教育商品=はい)/ ターゲット=13-15/16-17/18+ / データセーフティ=送信(収集3種・共有なし・削除URL設定)/ 行政・金融・健康=なし
  • ストアの設定: カテゴリ=教育・連絡先 support@ramanu.co.jp・サイト https://ramanu.co.jp/ (即時公開・確認ダイアログ「承認して公開」あり)
  • 公開の概要で9言語すべて「必要なすべての情報を指定しました」を確認 → ② Play 提出物は完了

詰まったこと / 気づき(Play Console 自動化の型):

  • テキスト入力は read_page の ref → form_input が唯一モデルに載る(JS ネイティブセッター+input イベントはカウンタだけ動いて検証は空扱い)
  • 選択操作と保存クリックは別ティックに分ける(同一 JS 内で連続実行すると保存が空振り)。保存確認は「変更を保存しました」トーストの有無で行う
  • material-checkbox/radio は input.click() で モデルに載る。IARC の表現方法設問だけ radio でなく checkbox 群
  • 連絡先ダイアログは「保存して公開」→ 確認ダイアログ「承認して公開」の2段。JS クリックでは確認が出ず座標クリックで発見
  • Publishing API: edit は短時間で失効(commit 前に1時間超放置で FAILED_PRECONDITION)→ 再アップロードで解決。commit には「未公開のアプリの編集、削除」権限が必要(ストア表示管理だけだと書き込みは通るが commit で 403)
  • データセーフティの削除「はい」にはデータ削除用 URL(Web ページ)が必須 → プライバシーポリシー改定が芋づるで必要になった

次回やること:

  • 製品版リリースの作成(AAB を製品版トラックへ + 配信国選択)→「審査のために送信」
  • 提出前判断: ToS リンク要否 / 審査用 Play プロモコード要否 / 削除ページへの保持期間明記(任意)

06:03 - Android 内部テスター設定 → Play Store エミュレータで実購入E2E 完走

やったこと:

  • Play Console で内部テスターを設定(ブラウザペイン・info@ramanu.co.jp): メーリングリスト「内部テスター」を作成し ichirokisanuki@gmail.com を登録 → 内部テストトラックに適用・保存。保存後にトラックが「非アクティブ」→「有効」に遷移
  • 同リストをライセンステスト(アカウント全体設定)にも登録 → 購入が「Test card, always approves」のテスト決済扱いに。こちらは既存リストのチェックボックス選択式なので入力不要
  • Play Store 入りエミュレータ pm-playstore を新規作成(Pixel 6・API 35・google_apis_playstore・PlayStore.enabled=yes 手動追記)。既存 kowai16k は Google APIs のみで課金不可のため。Play Store ログインは You の手作業(購入認証は「パスワード」を選択)
  • opt-in: You の実 Chrome(ichirokisanuki@gmail.com ログイン済み)で opt-in リンクを開いて Accept invite → 「You're a tester」確認
  • 実購入E2E 3点すべて合格:
    • 購入: Paywall が実価格表示(Yearly ¥1,500+7 days free バッジ / Monthly ¥300)→ テスト購入成功 → アプリ即時解錠 → RC に entitlement pro 到達(テスト時間圧縮: トライアル7日→3分・1年→30分)
    • 復元: pm clear → 再起動だけで自動復元。RC Android SDK が Play の既存購入を検出し、新しい匿名ユーザーへ entitlement を自動移管(iOS と違い明示的な復元操作は不要)
    • トライアル表記: Paywall バッジ+注記、購入シートのトライアル行を確認。さらにトライアル→有料の自動更新を RC の expires_at 延長(+30分)で観測
  • これで WIP 残件①(内部テスター設定 → 実購入E2E)が完了。E2E は英語UIで実施したため「en ロケール表示」の未検証項目も実質カバー

詰まったこと / 気づき:

  • Play Console のテスター用メールチップ入力は合成キーイベントで確定できない(CDP 経由の Enter・JS dispatch とも不発)→ You の実キー入力で確定してもらった。ユーザー招待フォーム制約と同根で、Play Console のフォームは総じて合成入力に弱い
  • opt-in 後 Play Store に出るまで20〜30分「Item not found」が続いた(Play Store キャッシュクリアも併用。焦らず待てば出る)
  • 購入後の「Require authentication for purchases?」は安全側の Yes, always を選択(以後この端末の購入時はパスワード確認あり)
  • E2E 環境と落とし穴は auto-memory android-play-e2e-setup にも保存済み

次回やること:

  • Play 提出物: ストア掲載9言語 / スクショ(iOS 9言語の流用リサイズ)/ データセーフティ / コンテンツレーティング
  • 提出前判断: Android Paywall の ToS リンク要否 / ピンチ実指・ダブルタップ復帰の実機確認

02:39 - 1.0.1 審査承認 → API から手動公開

やったこと:

  • 1.0.1(build 8)の審査承認を確認: ASC API 照会で PENDING_DEVELOPER_RELEASE(releaseType=MANUAL のため公開待ち)
  • 配信国 175 か国の維持を先に確認: 1.0.0 承認直後の「配信国ゼロで App Store から消える」事故(2026-08-11 復旧)の再発がないことを公開前にチェック → 問題なし
  • POST /v1/appStoreVersionReleaseRequests で公開実行READY_FOR_DISTRIBUTION に遷移を確認。ストア反映は最大数時間
  • これで iOS 1.0.1 チェーン(コレクション地域別カード撤去 + ストアメディア9言語刷新 → 審査 → 公開)が完結

気づき:

  • 承認確認 → 配信国チェック → 公開 → 事後確認まで、自作 JWT(asc-direct-access メモどおり)で API 完結できた。接続済み app-store-connect MCP は別アカウント(Thomsons)を見るので今回も不使用

次回やること:

  • Android 内部テスター設定 → Play Store 入り端末で実購入E2E(持ち越し)
  • scripts/asc-submission-check.mjs に配信国チェック追加(軽作業・再発防止)

2026-08-16

08:03 - ストア掲載メディアを9言語で刷新し 1.0.1 を審査提出(Shipaton動画の壁背景化〜コレクションUI変更まで)

やったこと:

  • Shipaton デモ動画を美術館の壁背景に刷新: 旧・濃緑ベタ背景 → ストアスクショの make_wall() を 1080x1920 に移植した壁+端末フレーム+濃墨キャプションへ。承認コンプ4枚を Claude が制作 → 本番組み立ては Codex(~/ichirokisanuki/pocket-museum-video/)。尺72.2秒・構成/BGM/文言は不変
    • YouTube は同一URLのまま動画差し替え不可 → 新規公開 7BoL3VbVYIQ、旧 Q62huvtjorg は削除せず限定公開に降格 → Devpost の Video URL を Chrome 自動操作で更新(芋づる更新に注意)
  • App Store プレビュー動画: まず ja 壁背景29秒版を制作(日本語UI素材を 17 Pro Max ja-JP で再収録。Release 上書きインストールで DEBUG 欄回避 / touch_path 点列でスクロール速度制御 / 静止は tpad=stop_mode=clone 補完 / DB に獲得12件仕込み→撮影後バックアップ復元)→ のちに Codex 制作の統一デザイン版9言語(886x1920・24.5秒・AAC 48kHz)で置き換え
  • ASC にバージョン 1.0.1 を新設: 配信中バージョンにはプレビュー/スクショを後付けできない(POST /v1/appPreviewSets が 409 INVALID_STATE)ため。メタデータ掲載目的の build 7 → のち build 8 に差し替え。新機能テキストは9言語「細かな改善」系。releaseType=MANUAL
  • コピーの多言語レビュー: COPY_REVIEW.md(スクショ)は要修正2件(en 05 サブが 06 と趣旨重複 / de 04 だけ筆致フック欠落)→ Codex 反映・受蔵番号も AIC 正式 1954.326 に統一。VIDEO_COPY_REVIEW.md(動画)は要修正ゼロ
  • 多言語スクショ検品でレンダバグ2件を発見・修正(コミット ef0665f):
    • NewYork.ttf のハイフン系グリフは PIL でインクが描画されない(advance/bbox は正常)→ fr「chefs d'œuvre」pt「obra prima」の綴り欠落・en「Self Portrait」化。tracked_text_mask に「インクが出ない場合のみメトリクス準拠の矩形で描く」フォールバックを実装
    • SFNS.ttf は 15px ちょうどのとき「ART INSTITUTE」のスペースが潰れる(raqm shaping 起因。-kern では直らず、14px 以下は正常)→ 美術館・都市行を 14px 化
    • ほか en 05 見出しの主語・動詞間カンマ除去(joins 化で文法エラーになっていた)
  • ASC へ 9ロケール一括登録(自作 JWT + reserve→chunk PUT→md5 PATCH の API 完結フロー): スクショ6枚×9(ja/en は旧5枚を置換、並び順は relationships PATCH で 01→06 を明示)/ プレビュー動画9本(ja は壁背景版から差し替え)。すべて検証 COMPLETE
  • コレクション画面の地域別 acquired/total カードを両OSから撤去(You 指示。DECISIONS 参照): iOS ExploreView + Android CollectionScreen から削除、死にコード掃除(RegionProgress / regionProgress / regionLabel / artworkRegions DAO)。build 8 としてアップロード・1.0.1 紐付け(e40aa18)。スクショ05 は Codex が新UIで再生成 → ASC 差し替え
  • 1.0.1 を審査提出: reviewSubmission 作成 → アイテム追加 → submitted PATCH で WAITING_FOR_REVIEW(2026-08-16 08:00 頃)

決めたこと:

  • コレクションの地域別カード撤去(DECISIONS 参照)
  • store-assets/app-previews/ は中間物含め全部 git 管理(+1.2GB、.git は約2.6GBに。ファイル単体はすべて 50MB 未満で GitHub 制限内)

気づき:

  • 接続済みの app-store-connect MCP は別アカウント(Thomsons)を見る。RAMANU は自作 JWT(auto-memory の asc-direct-access どおり)
  • App プレビューは音声 44.1/48kHz 必須(Shipaton 版の 96kHz は不可)・尺15〜30秒・886x1920 も 6.9" 枠で受理される
  • ffmpeg のセグメント concat を -c copy でやると DTS 非単調警告 → ASC 投入前に再エンコードで詰め直す
  • スクショ/動画の多言語量産は「コピー原本 md でレビュー → Codex 反映 → Claude が原寸検品」の分業が機能した。検品はフォント描画レベルまで見る価値がある(今回の2バグはどちらも縮小表示では見逃しやすい)

次回やること:

  • 審査結果の確認 → 承認後に手動公開
  • Android: 内部テスターE2E / Play 提出物(ストアスクショは iOS 9言語が揃ったので流用リサイズが容易になった)

2026-08-15

18:08 - RC の Play サービスアカウント認証情報 + リアルタイム通知(課金の外部チェーンが全部つながった)

やったこと(コード変更なし・すべて外部設定。Cloud Console / Play Console / RC ダッシュボードをアプリ内ブラウザで操作、GCP は gcloud CLI 併用):

  • 購入検証用のサービスアカウントを新規作成: GCP プロジェクト pocket-museum-d060f(このアプリの Firebase プロジェクト)に revenuecat-play@pocket-museum-d060f.iam.gserviceaccount.com を作成(GCP ロールなし=権限は Play Console 側で与える設計)。同プロジェクトで Google Play Android Developer API を有効化
    • このデベロッパーアカウントには Subnote 用の revenuecat-play@subnote-ab213... がアカウント権限で既に居て、そのまま流用もできたがアプリごとに鍵を分離する方を選んだ(DECISIONS 参照)
  • Play Console で権限付与: ユーザーと権限からサービスアカウントを招待し、ポケット美術館に限定したアプリ権限で4つ(アプリ情報の閲覧 / アプリの品質情報の閲覧 / 売上データの表示 / 注文と定期購入の管理)。アカウント権限には広げずに済んだ
  • 鍵の発行と登録: gcloud iam service-accounts keys create~/.config/android/pocket-museum-play-sa.json(chmod 600・git 外、アップロード鍵と同じ場所)に発行 → RC ダッシュボードにアップロード → validate-app-credentials で3チェックすべて valid(購入検証 / in-app 商品カタログ / サブスクカタログ)
  • Google developer notifications(RTDN)を接続: Pub/Sub API 有効化 + SA に roles/pubsub.admin → トピック projects/pocket-museum-d060f/topics/pocket-museum-play-rtdn 作成 + google-play-developer-notifications@system.gserviceaccount.com に Publisher 付与 → RC で「Connect to Google」(プッシュサブスクリプション RevenueCat-Subscriber-appebb22cf191 が自動生成・宛先は RC の webhook)→ Play Console の収益化のセットアップにトピック名を登録して「リアルタイムの通知を有効にする」をオン・保存 → テスト通知を送信して RC 側に Last received が立つところまで実データで確認
    • 通知の内容は既定の「定期購入と取り消し済みの購入のみ」、RC の Track new purchases from server-to-server notifications はオフのまま

決めたこと:

  • Play の購入検証用サービスアカウントはアプリ専用に新規作成し、権限もアプリ単位に絞る(DECISIONS 参照)

詰まったこと / 気づき:

  • Play Console の権限は API に反映されるまで数分かかる。RC の検証が insufficient permissions で落ちても権限不足とは限らない。切り分けは サービスアカウント自身で Purchases API をダミートークンで叩き、400 Invalid Value なら権限は通っている / 401・403 なら本当に足りない(auto-memory に保存)
  • Play Console のユーザー招待フォームへの入力は権限判定でブロックされる(デベロッパーアカウントへのアクセス権付与にあたるため)。ここは You の手作業になる。回避せず、pbcopy で貼り付け用の値を用意して渡すのが最短
  • ブラウザペインのクリックは tabs_select で前面化してから撮り直したスクリーンショットの座標でクリックするのが一番通る。Cloud Console の Material メニュートリガーは ref クリックでも合成クリックでも開かない(プレーンなボタンは開く)。一覧テーブルが空描画になるのも前面化で直る(auto-memory に保存)
  • RC の React Select は form_input で value を入れても内部状態が更新されず送信ボタンが disabled のまま。開いて候補を実クリックする必要がある
  • RC のトピック選択は既存の Pub/Sub トピックを一覧するだけなので先に gcloud で作っておく(「Play-Store-Notifications(RevenueCat が生成)」という選択肢も出るが、Publisher 権限を自分で当てたトピックの方が把握しやすい)
  • Play Console の api-access / settings/api-access URL は現在アプリ一覧へリダイレクトされる。サービスアカウントの導線は Cloud Console 側 + ユーザーと権限からの招待に一本化されている

次回やること:

  1. 内部テスターの設定 → 実購入E2E: メーリングリスト作成 → opt-in リンク → Play Store 入りの端末でインストール(kowai16k は Google APIs イメージなので不可)→ 購入・復元・トライアル表記の確認
  2. Play 提出物: ストア掲載9言語 / スクショ / データセーフティ / コンテンツレーティング → 審査提出
  3. AdMob 開通チェーン(iOS)/ PR TIMES 骨子
  4. (後回し枠)Android の広告+UMP / 自前 ToS ページの要否判断

16:00 - Play Console 開通(アプリ作成・内部テスト公開・サブスク2種・RC 配線完了)

やったこと(コード変更なし・すべて外部作業。Play Console はアプリ内ブラウザの info@ramanu.co.jp / Ramanu 組織アカウントを Claude が操作):

  • アプリ「ポケット美術館」を作成: package jp.co.ramanu.pocketmuseum・デフォルト言語 ja-JP・アプリ・無料・申告2種(ポリシー/米国輸出法)同意。初回作成時の「パッケージ名はすでに使用されています」は一過性エラー(個人アカウント等も調査したが該当なし → 再試行で「使用できます」→ 作成成功)
  • 内部テストリリース 1 (1.0.0) を公開(審査不要・即時): 署名済み AAB をアップロード。Play App Signing が既定で有効 = 手元の鍵はアップロード鍵扱い(紛失時も再設定可)。警告2件(テスター未指定・ネイティブ デバッグシンボル無し)は実害なしで公開
    • AAB アップロードの技法: ブラウザペインの合成クリックではファイル選択が開かない → cliclick の物理クリックで本物のダイアログを開き、⌘⇧G+クリップボード貼り付けでパス指定(IME 日本語だと keystroke がかな変換される罠をクリップボードで回避)。auto-memory に保存済み
  • サブスク2種を作成・有効化(DECISIONS 参照: 2本立て構造):
    • pm_pro_monthly「Pro(月額)」: 特典3(広告なし/過去作品/特集)・基本プラン monthly(1か月ごと・自動更新・猶予7日)・JPY 300 基準で177地域一括換算・有効
    • pm_pro_yearly「Pro(年額)」: 特典3・基本プラン yearly(1年ごと・自動更新・猶予14日)・JPY 1,500 基準・有効・オファー free-trial無料試用7日・適格性=新規ユーザーの獲得=この定期購入を利用したことがない・有効)
    • フォームの罠: 特典(benefits)を先に保存しないと販売開始できない / 基本プランは価格未設定のまま保存すると失敗(Set prices → 全177地域選択 → 基準通貨で一括換算 → 保存)/ 有効化は保存後の別ステップ
  • RevenueCat 配線(MCP で完結): Play 商品 pm_pro_monthly:monthly(prodf4b4b90551)/ pm_pro_yearly:yearly(prod7cee310b80)を作成 → entitlement pro(entl5ef65a9d4c・iOS と共有)offering default の $rc_monthly / $rc_annual パッケージにアタッチ
  • 配線完了の検証: アプリの offerings エラーが「RC に Play 商品未登録(構成エラー)」→「BILLING_UNAVAILABLE(エミュレータに Play 課金基盤が無いだけ)」に変化 = RC ⇄ Play の構成は完成

決めたこと:

  • Play のサブスク構造は「2本立て」(DECISIONS 参照)

次回やること(実購入E2Eまでの残り2つ):

  1. RC の Play サービスアカウント認証情報(購入検証に必須): Cloud Console でサービスアカウント作成 → Play Console ユーザーと権限で招待(財務データ+アプリ権限)→ RC ダッシュボードに JSON アップロード
  2. 内部テスターの設定: メールリスト作成 → opt-in リンク → Play Store 入りの実機/エミュレータでインストール → 購入E2E(テスターはテスト決済扱い)
  3. Play 提出物(ストア掲載9言語・スクショ・データセーフティ・コンテンツレーティング)→ 審査提出

08:04 - Android の Analytics・オフライン画像・通知プライマー・共有テストベクタ(残実装完了)

やったこと(2c63244 / e68460b / 0a9db7c):

  • Firebase Analytics(2c63244: PMAnalytics を docs/analytics-events.md 正本準拠で移植(16イベント・状態イベントのセッション内 dedupe・30分/日付跨ぎのセッション区切り・ユーザープロパティ)。You が Firebase Console で Android アプリ登録 → google-services.json 配置(コミット済み・iOS plist と同運用)。RC への App Instance ID 連携、onResume のフォアグラウンド処理(セッション区切り+日付跨ぎ再同期)も追加。エミュレータ実ログで story_full_opened{access=fallback}/ticket_reused/特集ファネル3連/ユーザープロパティを検証済み = 両OSが同一イベントに合流する状態
  • オフライン画像保存(e68460b: ImageStore 移植(files/offline-images に永続化・新しい獲得順バックフィル・prune・並行DL集約・tmp→rename)。表示は保存済みファイル優先→CDN URL。Auto Backup/デバイス移行から除外。機内モードで今日の1枚・ズーム原寸・コレクショングリッドの表示を検証済み(15作品×2=30ファイル/11MB)
  • 通知プライマー(0a9db7c: iOS と同条件の3ステップ(2枚目獲得以降・1回きり・モーダル抑制・許可確定済みスキップ・1.2秒ディレイ)。全ステップE2E検証(許可→時刻設定→アラーム登録→再起動で再表示なし)
  • 抽選ロジックの共有テストベクタ(0a9db7c: 正本 docs/test-vectors/deck-draw-test-vectors.json(240ケース)+ 生成器 scripts/gen-deck-draw-vectors.swift。Android 単体テスト(test resources が docs/ を直接参照=コピードリフトなし)+ iOS テストターゲット新設(project.yml に PocketMuseumTests + テストスキーム、xcodebuild test で実行)。両OSとも全240ケース通過 = DECISIONS「正本データで担保」の仕組み③が完成

詰まったこと / 気づき:

  • Firebase プロジェクトは法人アカウント側で CLI(個人アカウント)から見えない → Android アプリ登録は Console 手作業(2分)で解消
  • M3 TimePicker はスクロール可能なシート内で文字盤がジェスチャを奪う → プライマーのシートは skipPartiallyExpanded で常に全展開に
  • M3 の TimePicker 選択枠の紫は ColorScheme の primaryContainer 未指定が原因(テーマに追加して金に)
  • テストターゲット新設時は GENERATE_INFOPLIST_FILE: YES が必要。xcodegen 再生成直後の初回 xcodebuild test は一過性で失敗することがある(再実行で通る)
  • Android の Analytics デバッグは setprop debug.firebase.analytics.app <pkg> + logcat -s FA FA-SVC(iOS の log stream 相当がこれ)

次回やること:

  • Play Console にアプリ作成(You 手作業) → AAB アップロード → サブスク作成 → RC 商品登録・offering アタッチ・サービス認証情報 → 実購入E2E
  • Play 提出物: ストア掲載9言語 / スクショ / データセーフティ / コンテンツレーティング
  • AdMob 開通チェーン(iOS)/ PR TIMES 骨子
  • (後回し枠)Android の広告+UMP / 自前 ToS ページの要否判断

07:20 - Android 通知・アダプティブアイコン・リリース署名AAB・今日の1枚本格化

やったこと(0eb5b8d):

  • 毎朝リマインダ通知: iOS DailyReminder と対の Android 版。AlarmManager で「次の1回」を予約し、発火・再起動(BOOT_COMPLETED)・時刻/タイムゾーン変更のたびに再予約する方式。正確アラーム権限(SCHEDULE_EXACT_ALARM)は使わない(Doze で数分ずれても朝のリマインダには十分・Play の権限審査摩擦を避ける)。マイ画面に通知セクション(トグル+Material3 TimePicker・POST_NOTIFICATIONS 実行時許可・拒否時は設定アプリ導線・システム側で取り消されたらトグルを実態に合わせる)。エミュレータで許可ダイアログ→dumpsys のアラーム登録→受信機直接発火で実配達まで検証
  • アダプティブアイコン: 原画(真珠の耳飾りの少女)を 88/108 で中央配置した前景 + 端と同色 #000312 の背景レイヤー。円形マスクでも顔・ターバン・真珠が欠けない配分を円クロップのプレビュー比較で選定。ドロワーで円形フルブリード表示を確認(旧 legacy PNG は白円に縮小されていた)
  • リリース署名 + AAB: アップロード鍵を git 外の ~/.config/android/pocket-museum-upload.keystore に生成(properties も同所・chmod 600・iOS の ~/.config/asc/ と同じ流儀)。build.gradle.kts は properties が無いマシンでは未署名で組めるフォールバック付き。署名済み AAB(6.4MB)をビルド済み = Play Console 作成後すぐアップロード可能。R8 適用のリリース APK をエミュレータで起動確認(新規インストール→同期→抽選→表示まで正常)・apksigner で CN=RAMANU LLC を確認
  • 今日の1枚画面を iOS TodayView 相当に本格化: ヘッダ(ポケット美術館+日付)・金額縁の額装(タップでズーム)・「コレクションに追加」収蔵表示・キャプションカード(題名セリフ体・作者/制作年/技法・GatedStory 組み込み・お気に入り/シェアの等幅ボタン)・エラー時リトライ。壁背景(WallSurface)と額装(FramedArtwork)を Components に共通化し作品詳細と共用
  • ロック状態のゲートとフェイルオープンを実表示で初検証: DB に過去日の獲得14件を挿入してウェルカム枠消化状態を作成 → 導入部+広告CTA+Pro CTA の表示 → 広告CTAタップ → fallback チケット付与 → 全文開放+注記まで E2E 動作。コレクションの複数作品グリッド(15点・ja 題名解決)も副産物で確認

詰まったこと / 気づき:

  • root で push した DB はファイル所有者が root になりアプリが SQLiteCantOpenDatabaseException で落ちるchown u0_aXXX:u0_aXXX + chmod 660 + restorecon が必須(auto-memory に保存)
  • keytool の -printcert -jarfile は APK Signature Scheme v2/v3 を読めず「署名付きJARではない」と出る → 署名確認は apksigner で
  • build.gradle.kts の android {} ブロック内では java.util が別解決されるため import java.util.Properties をファイル先頭に置く

次回やること:

  • Android 残実装: Analytics 送信(Firebase Android アプリ登録 + docs/analytics-events.md の16イベント)/ オフライン画像保存 / 通知プライマー / 共有テストベクタ
  • Play Console アプリ作成(You 手作業)→ AAB アップロード → サブスク作成 → RC 商品登録
  • エミュレータの DB は検証用の擬似獲得14件入り(意図的なテストデータ。素の状態が要る時は再インストール)

06:44 - Android 画面移植(4画面+ズームビューア)と RevenueCat 課金移植

やったこと:

  • 画面移植(c459b63: コレクション(地域別進捗・訪問の記録)/ 作品詳細(額装・解説ゲート・お気に入り・シェア・誤訳報告 mailto 簡易版・メタデータ・美術館ページリンク・CC0 クレジット)/ 特集(一覧+記事+ぼかしロック帯+Pro CTA)/ マイ(お気に入りグリッド。通知等のセクションは機能実装時に追加)を iOS 実装を正本に移植
  • 全画面ズームビューア: ピンチ(フィット〜8倍・中心点保持)・ダブルタップ拡大・シングルタップで✕切替・フィット中の縦スワイプで閉じる(背景の透け・縮小も再現)。Coil は Size.ORIGINAL で原寸ロード
  • 骨格: タブごと NavHost(iOS の NavigationStack と対)+ SaveableStateHolder でタブ切替後もスタック保持。ズームビューアはルート直上のオーバーレイ(fullScreenCover と対)
  • データ層拡張: ContentQueries に explore / regionProgress / archive / featured / favorite 系クエリ、FavoriteDao 新設。AppViewModel に contentRevision(お気に入り・チケット変化で表示中画面を再読込)
  • ゲートはフェイルオープンで実装: 広告SDK未導入のため iOS の unavailable 時と同じ挙動(当日獲得分のみ fallback チケット付与・過去分は再試行案内)
  • エミュレータ検証(ja): 4タブ遷移・詳細→ズーム(拡大・パン・スワイプ閉じ)・お気に入りのタブ横断反映・特集ロック帯・訪問の記録まで一巡確認
  • RevenueCat 課金移植(ba9367f: RC MCP で Play アプリ「Pocket Museum (Play Store)」(appebb22cf191)を作成 → 公開SDKキー goog_ を取得し build.gradle に配線。purchases-android 10.16.2 導入、PurchaseProvider 境界 + RevenueCatPurchaseProvider を移植(entitlement pro は iOS と共有)。AppViewModel.isPro を購読ストリーム連動の StateFlow 化(変化で表示中ゲート即再評価)。PaywallSheet 移植(プランカード2枚・年額に7日間無料バッジ・金グラデ購入ボタン・復元・プライバシーポリシーリンク)。ゲート「7日間Proを試す」と特集「Proで続きを読む」から表示
  • 課金の検証: RC バックエンドとの通信開通を実ログで確認(subscriber 304 / entitlement mapping 200)。offerings は「Play 商品未登録」の構成エラーのみ = 想定どおりで、Paywall は「プランを読み込めませんでした+再試行」のグレースフル表示

詰まったこと / 気づき:

  • adb の input tap 2連発はダブルタップ判定窓(300ms)を外れることがあり不安定。ピンチは adb では再現不可(auto-memory に保存済み。実指確認はエミュレータ手動で)
  • Android には iOS の checkTrialOrIntroDiscountEligibility 相当が無く、トライアル適格性は「無料トライアルオファーの有無」で近似(Play が適格外オファーを productDetails から除外する仕組みを利用)
  • Google Play の購入シートは Activity 起点でしか出せない(PurchaseProvider.purchase の iOS との差分)
  • Android Paywall の「利用規約」リンクは Apple 標準 EULA 相当が無いため当面省略(プライバシーポリシー+復元のみ)。自前の利用規約ページを作るなら Play 提出前に判断

次回やること:

  • Play Console にアプリ作成(手作業・API 不可) → AAB 内部テスト → サブスク pm_pro_monthly / pm_pro_yearly 作成(¥300/¥1,500・年額のみ7日無料)→ RC 商品登録・offering default アタッチ・サービスアカウント認証情報 → 実購入E2E
  • Android 残実装: 通知 / Analytics 送信 / オフライン画像保存 / アダプティブアイコン / 抽選ロジックの共有テストベクタ
  • ズームのピンチ実指確認・en ロケール確認・ダブルタップでフィット復帰(エミュレータ手動)
  • AdMob 開通チェーン(iOS 側)も並行して忘れない

05:54 - Android 版開発着手(技術選定・土台構築・今日の1枚まで動作・クロス整合の仕組み2本)

やったこと:

  • 技術選定を決定: Kotlin + Jetpack Compose 単体(KMP 不採用)。iOS 本体が36ファイル・約5,100行と小さく共有の利得が薄い、KMP は既存 iOS の載せ替え回帰リスク、9月上旬提出の工期リスク最小、が理由(DECISIONS 参照)
  • 環境整備: Gradle(brew)+ platform android-36 を導入。Android Studio / SDK / AVD kowai16k(Pixel 6・API 35)/ JBR(JDK 21)は既存を利用。Gradle wrapper は 8.14.3(brew の Gradle 9.7 と AGP 8.11 の互換回避のため空ディレクトリで生成してコピー)
  • android/ に Gradle プロジェクト新規作成(8ce74b1: AGP 8.11.1 / Kotlin 2.2.0 / Compose BOM 2025.06.01 / Room 2.7.2(KSP) / Coil 3 / kotlinx-serialization / OkHttp。compileSdk・targetSdk 36(Play の 2026-08-31 以降の新規アプリ要件で9月提出なら必須)・minSdk 26・applicationId は iOS bundle ID と同一 jp.co.ramanu.pocketmuseum
  • データ層を iOS から移植: SyncEngine(sha256 差分同期・free_story_count ピン留め・snake_case JSON)/ DeckEngine(splitmix64 seed 抽選・作家3日除外・24h チケット・prune)/ ContentQueries(StoryGate 純関数・todayItem)/ Room スキーマ(iOS の SQLite と同一構成。iOS 固有遺物の deckCursor は持たない)
  • UI 骨格: 4タブ + 今日の1枚画面 + PMTheme 配色(深緑の壁・和紙・金)。アイコンは iOS の 1024px から sips で各密度 mipmap 生成
  • エミュレータで縦のスライス実証: 本番CDN 同期 → seed 抽選 → 広重「小田原 酒匂川」表示 → ウェルカム特典で解説全文表示。en/ja 両ロケール確認
  • クロス整合①: xcstrings → strings.xml 変換(e4ff7fa: scripts/xcstrings_to_android.py + 対応表 android/l10n/xcstrings-map.json(128キー全対応)。iOS の9言語翻訳資産をそのまま Android に供給。プレースホルダ変換(%@→%1$s・%lld→%1$d)・plural variations→<plurals>・Android エスケープ対応。双方向の過不足でエラー停止するドリフト検知つき
  • クロス整合②: Analytics 共通リファレンス(b4446e8: docs/analytics-events.md に全16イベント・パラメータ実値・dedupe 規則・ユーザープロパティ・セッション規則・RevenueCat 境界を明文化。Analytics.swift に正本参照コメント追加

決めたこと:

  • 技術スタック = Kotlin + Compose 単体(DECISIONS 参照)
  • 両OSの整合は共有コードではなく「正本データ」で担保する方針(DECISIONS 参照)。① 文言=xcstrings が正本(実施済み)② Analytics=docs/analytics-events.md が正本(実施済み)③ 抽選ロジックの共有テストベクタ(Android テスト整備時に実施)④ デザイントークンは Theme.swift 正本+コメント運用 ⑤ 画面仕様は iOS 実装が正本で仕様書は起こさない

詰まったこと / 気づき:

  • xcstrings は sourceLanguage=ja のため ja の localization エントリを持たない(キー自体が原文)。変換スクリプトは ja をキーで補完する
  • エミュレータ起動コマンドに | head を繋ぐと SIGPIPE で落ちる。ログはファイルへリダイレクトする
  • エミュレータのロケール切替は adb root + setprop persist.sys.locale ja-JP + zygote 再起動(cmd package set-app-locales は API 35 エミュレータに無かった)。システムロケールは ja-JP のままにしてある
  • RevenueCat の Android 用公開キー(goog_)は未取得。RC プロジェクトに Play アプリを追加すれば entitlement pro を共有できる

次回やること:

  • 画面移植の続き(コレクション・作品詳細・ズーム・特集・マイ)
  • RevenueCat: RC に Play アプリ追加 → goog_ キー配線 → Paywall 移植
  • AdMob 開通チェーン(iOS 側タスク・再審査結果の確認から)も並行して忘れない

04:34 - リリース後戦略の整理と Shipaton 2026 応募完了(デモ動画制作・Devpost 提出)

やったこと:

  • リリース後の運用選択肢を整理: ① Shipaton 応募(最優先・締切 9/30)② iOS プロモ(AdMob 開通・PR TIMES)③ Android 開発(初速実測まで見送り)の優先順位で決定
  • Shipaton 2026 の資格精査: 提出期間 7/31〜9/30 に「初の公開版リリース」が条件 → App Store 記録上 8/7 リリースで適合(配信国事故での実露出 8/11 は資格面で無関係と判明)。RC SDK 必須(サブスクで充足)・日本から参加可
  • 応募素材を制作store-assets/shipaton/): 英文ドラフト devpost-draft-en.md / assets/icon-1024.png / フレームなしスクショ3枚(1179×2556・英語UI・17e 実画面を中央クロップ+リサイズ)
  • デモ動画 1:12 を制作assets/demo-video.mp4、構成承認後に8シーン)。制作メモ:
    • ゲート状態は 17e の DB に acquisition 12行 INSERT して作成(8/14 付がたまたま北斎「神奈川沖浪裏」でゲートデモの主役に)。録画後に元へ戻した
    • Debug ビルドの DEBUG 欄が映り込む問題 → Release を再ビルド+インストール(データ保持)で解消、該当シーンは録り直し
    • **simctl recordVideo は VFR(画面変化時のみフレーム書き込み)**で静止区間の切り出しが空になる → 全素材を CFR 30fps に変換してから編集
    • タイトル/エンドカードは PIL 生成、キャプションは ffmpeg drawtext、BGM はパブリックドメイン録音「月の光」(Wikimedia Commons・-19LUFS・フェード付き)
    • Paywall はシミュレータでも実価格表示($9.99/年・7日無料バッジ)で撮影できた
  • You フィードバック: プロモ素材に作品数・美術館数などの規模数字を入れない → エンドカード・Devpost 文面から除去(auto-memory にも保存)
  • YouTube 公開: RAMANU チャンネル(@ramanu-jp)に公開 https://www.youtube.com/watch?v=Q62huvtjorg
  • Devpost 提出完了(SUBMITTED): Chrome 自動操作でフォーム入力(名前/ピッチ/本文/タグ8/App Store リンク/動画URL/RC project ID proj8f670edd/HAMM・Design・Catvertising のカテゴリ説明/必須チェック3種=アイコン添付・フレームなしスクショ・期間内リリース)。file_upload ツール不調のため画像4点は You が D&D。CAPTCHA・Devpost ログイン・規約同意・最終 Submit は You が実施。締切 10/1 15:45 JST まで編集可
  • Devpost の必須チェック2つ(フレームなしスクショ・期間内リリース)を見落として一度バリデーションエラー → 事実どおりチェックして解消

決めたこと:

  • Android 開発は初速データ実測まで見送り(DECISIONS 参照)
  • プロモ素材にコンテンツ規模数字を入れない(DECISIONS 参照)
  • Shipaton のカテゴリ戦略: HAMM 本命 + Design + Catvertising(AdMob 利用明記)、#BuildInPublic/Influencer/その他スポンサー枠は見送り(DECISIONS 参照)

気づき:

  • Shipaton の Grand Prize / HAMM はトラクション(〜9/30 の伸び)が審査材料 → PR TIMES・AdMob 開通などのプロモ運用がそのまま Shipaton 対策を兼ねる
  • Devpost に RevenueCat Growth Fund(投資検討 opt-in)の設問あり。非拘束の意思表明のみで詳細条項は未公表

次回やること:

  • AdMob 開通チェーン(ストア掲載リンク → アプリ審査 → 配信開始確認)
  • PR TIMES 骨子(promo-expert 壁打ち)+ 横長メイン画像
  • (任意)Devpost サムネイル 3:2 の差し替え

2026-08-11

16:44 - 「App Storeから削除済み」事故の調査と復旧(原因は配信国ゼロ、全世界 availability を API 作成)

やったこと:

  • 事故の発見(8/9): 審査承認(8/7 04:44 UTC、「eligible for distribution」メール受信)にもかかわらず、ASC 上でアプリが「App Storeから削除済み」表示になっているのを You が発見。実際に App Store から日米とも消えていた(商品ページ 404・iTunes Lookup 0件)
  • 診断(Apple の取り下げではないことを確定): ①バージョン 1.0.0 は READY_FOR_SALE / READY_FOR_DISTRIBUTIONdownloadable: true ②appInfos も READY_FOR_DISTRIBUTION ③審査提出2件とも COMPLETE ④Apple からの削除・違反通知メールは一切なし(Apple の取り下げなら REMOVED_FROM_SALE への遷移+通知メールがあるはず)⑤GET /v1/apps/{id}/appAvailabilityV2404 = 配信国リソースが存在しない。対照実験として配信中の別チームアプリで同エンドポイントが 200 を返すことを確認し、「配信国ゼロ」が原因と確定。価格スケジュール(無料・基準国JPN)は正常に存在
  • 原因の見立て: API 経由の審査提出は、Web UI なら提出前に強制される「配信国の設定」ステップを未設定のまま素通りできる。承認された瞬間に「配信国ゼロ=App Storeから削除済み」表示に落ちた。7/29 のサブスク取りこぼし事故未遂と同根(ASC の Web UI 前提のバリデーションが API では効かない)
  • 復旧(8/11): GET /v1/territories で全175か国を取得 → POST /v2/appAvailabilities で全世界を配信対象にした availability を作成(201)。ペイロードは included に ${TERRITORY} 形式の一時IDで territoryAvailabilities(available: true)を175件並べ、availableInNewTerritories: true を指定。検証クエリで available=175 / unavailable=0 を確認
  • ストア反映の監視: iTunes Lookup (JP) を2分間隔でポーリングする監視を稼働(このセッションの Monitor。掲載検知で通知)。記録時点ではまだ反映待ち

気づき:

  • 影響は「公開が4日遅れた」だけ: 8/7 の承認時点から配信国ゼロだったため、アプリは一度も公開されていなかった。既存ユーザー消失などの実害はなし
  • ASC の「App Storeから削除済み」表示は Apple のペナルティとは限らない。バージョン状態が READY_FOR_SALE のままで appAvailabilityV2 が 404 なら配信国ゼロを疑う
  • 接続済み app-store-connect MCP は別アカウント参照のため使えない(既知)。ramanu チームは自作 ES256 JWT + ~/.config/asc/AuthKey_8M2SWG78S6.p8 で直接 API を叩いた

次回やること:

  • ストア掲載の確認(監視が検知したら実ページ確認 → 公開後タスクへ: AdMob 再審査・ストアリンク・プレスリリース)
  • scripts/asc-submission-check.mjs に配信国(availability)存在チェックを追加(再発防止)

2026-07-29

13:03 - 1.0.0 (build 6) を審査提出(計測修正・Crashlytics・画像最適化・通知プライマー変更、サブスク取りこぼし事故未遂の回収まで。7/28午後からの継続分含む)

やったこと:

  • 計測実装の Codex レビュー → 修正(build 4): 提出前確認で Firebase Analytics のみ同梱(Crashlytics なし)を確認後、Codex にレビュー依頼。指摘の重要2件を修正 — ①dedupe が「プロセス生存期間」になっていた問題(30分超離脱 or 日付跨ぎで計測セッションを区切り reportedKeys/sessionGrantedTickets をリセット)②RevenueCat に Firebase App Instance ID を連携(paywall_viewed→購入をユーザー単位で結合可能に)。story_gate_action/story_full_opened に context も追加。残り7件(表示検知の分母過大等)はリリース後改善
  • Crashlytics 導入(build 5): SPM に FirebaseCrashlytics 追加 + dSYM アップロードの postBuildScript(project.yml)。コード変更不要(既存 FirebaseApp.configure() で自動起動)。ASC プライバシー詳細に「クラッシュデータ」(関連付けなし・トラッキングなし・アプリの機能)を Chrome 操作で追加=9タイプ目。build 4 が Crashlytics 抜きで先行アップロードされていたため、Xcode の「バージョンとビルド番号を管理」が 5 へ自動繰り上げ(同番号は再アップ不可の仕様を Xcode が回避する挙動)
  • TestFlight 内部テスト開通: 内部グループ「内部テスト」作成(全ビルド自動配信・API では作成不可のため Web UI)+ info@ をテスター追加。内部テストは Beta App Review 不要で即配信
  • 画像表示が激遅の根本解決: 実測で cf-cache-status: MISS 常態=R2 カスタムドメインが Cache Rule なしでは一切エッジキャッシュされない事実を特定(TTFB 0.6〜1.0秒/枚)。Cloudflare に Cache Rule「content-cdn-cache」(ホスト一致→キャッシュ対象)を作成し HIT・1枚約50ms へ。アプリ側も枠内表示(今日の1枚・作品詳細・特集ヒーロー)を thumb 化(転送量約1/10、backfill は両サイズ保存なのでオフライン表示は無影響)+ 取得失敗時の自動リトライ(2秒→4秒×2回。失敗すると永久プレースホルダの弱点を解消)。small 追加の3階層化は効果小で v1.1 見送り
  • 「特集サムネが出ない」の正体: 実機テストが TestFlight ではなく Xcode インストール(Debug)で、配信先が LAN IP 直書き(しかも IP 変更済み+ローカルサーバ停止中)だった。Debug も本番CDN 参照に変更し、Wi-Fi 変更のたびに project.yml を直す運用を廃止(ローカル差し替え検証時のみ一時的に戻す)
  • 通知プライマーを「2枚目の獲得時」に変更(build 6): 初回起動直後の表示をやめ、レビュー促進と同じポジティブ契機型に(獲得処理で判定→1.2秒の一呼吸→シート。モーダル過多回避も継承)。シミュレータ E2E で初日出ない/2日目出る/「あとで」後は再表示なしを検証
  • build 6 を CLI で提出: アーカイブ(自動署名+ASCキー)→ export(手動配布署名)→ validate → upload すべてエラーなし。TestFlight へも自動配信
  • 審査提出のブロッカー3点を API で解消: 7/20 登録セッションの取りこぼしだった ①コンテンツ配信権(サードパーティコンテンツを含む=権利保有) ②価格(無料・基準国日本) ③カテゴリ(教育×ライフスタイル)。ついでに年齢制限の新質問 socialMediaAgeRestricted も回答(期限9/7の宿題を先取り)
  • サブスク取りこぼし事故未遂 → 回収: 初回提出がバージョンのみでサブスク2種が「提出準備中」のまま残っていることに You が気づく(このままだと公開後にペイウォールで購入不可)。審査開始前だったため提出を取り下げ → サブスクグループ+月額+年額+バージョンを1つの提出に合体 → 再提出(12:53、4アイテム全部 WAITING_FOR_REVIEW を API 確認)
  • 再発防止: scripts/asc-submission-check.mjs 新設(提出と課金アイテムの状態を突き合わせて取りこぼしを検出、終了コード1)。汎用版+罠の解説を ~/cdev/knowledge/asc-review-submission-iap-check.md にナレッジ化
  • 前日分の補足: en-US ストア名は Daily Art へ変更済み(DECISIONS 2026-07-28)。ASC ヘッダー表示でも反映確認

決めたこと:(DECISIONS 5件: 通知プライマーのタイミング / 画像配信の最適化方針 / 審査提出のチェック運用 / Crashlytics 導入 / カテゴリ確定)

詰まったこと / 気づき:

  • R2 カスタムドメインは Cache Rule を作らないとエッジキャッシュが一切効かない(Cache-Control を返していても無視される)。cf-cache-status ヘッダーを2連発で見れば10秒で診断できる
  • ASC の審査提出は「バージョン」と「課金」が別アイテムで、バージョン単独でも通ってしまう。初回サブスクは同一提出必須なのに UI は止めない(詳細はナレッジ参照)。審査待ち状態の提出には項目追加不可=取り下げて組み直す
  • WIP の「価格・プライバシー申告まで登録済み」のうち価格は誤記(実際は未設定だった)。外部状態の記録は API で実確認してから書くべき
  • サブスクの「審査用に追加」はドロップダウンで提出先を選ぶ UI。クリックしただけでは追加されないことがあり、下書きパネルのアイテム数で確認する
  • 通知プライマーの旧実装(初回起動直後)は価値体験前の許可要求だった。同意型ソフトアスクの設計原則(レビュー促進で確立済み)を通知にも適用した形

次回やること:

  • 審査結果待ち(承認後は自動公開)。リジェクト時は Resolution Center を確認
  • 公開後: AdMob 再審査結果の監視 → ストア掲載リンク設定 → 広告のアプリ審査 → 配信開始確認
  • TestFlight で build 6 の体感確認(Cache Rule + thumb 化の効果。任意)
  • プレスリリース骨子 + 横長メイン画像 → 配信は公開後

2026-07-28

12:38 - en-US ストア名を「Pocket Museum: Daily Art」へ変更(Masterpieces を撤回)

やったこと:

  • ASC API(自作 JWT、~/.config/asc/AuthKey_8M2SWG78S6.p8)で en-US の appInfoLocalization を PATCH し、ストア名を「Pocket Museum: Masterpieces」→「Pocket Museum: Daily Art」(24字)に変更。再取得で反映を確認
  • サブタイトル「One masterpiece, every day」と他8言語の名前は変更なし。1.0.0 は PREPARE_FOR_SUBMISSION のままなので提出前の変更として即反映(ビルド・スクショへの影響なし)

決めたこと:(DECISIONS.md に記録済み)

  • en-US ストア名を「Pocket Museum: Daily Art」に戻す(2026-07-27 の Masterpieces 確定を supersede。コンセプト伝達を優先)

次回やること:

  • 変わらず: ASC で build 3 の処理完了を確認 → 1.0.0 に build 3 を紐付けて審査へ提出(You の操作)

2026-07-27

20:23 - 月例特集1本目を9言語化(Codex 翻訳分業 → 本番R2配信)

やったこと:

  • リリース時に特集を9言語で読める状態にする方針転換(2026-07-20「当面 ja のみ制作」を supersede、DECISIONS 参照)を受け、残り7言語(de/es/fr/it/pt/ko/zh-Hans)を Codex に翻訳依頼
  • 依頼書は 実装依頼_特集記事7言語翻訳.md(過去の解説生成依頼と同形式)。構造厳守・作品タイトルは stories/{lang}.jsonl の既存訳語と一字一句一致・逐語訳でなく論の運び保持、を要件化。訳語一覧を先に出力させるスニペット同梱
  • 検収は機械+目視: 構造検証 7/7 OK・pm featured check 9言語認識/参照切れゼロ・訳語一致 7言語×7作品すべて一致・かな残存なし・de/ko/zh-Hans の冒頭を目視(トーン良好)。Codex の質疑欄は空=迷いなく完走
  • pm exportpm upload で本番反映(差分8ファイルのみ)。CDN で7言語すべて title+7節の配信を実確認
  • アプリ改修・再ビルドは不要(特集は R2 配信のみで反映。build 3 はそのまま提出可能)

次回やること: 来月以降の特集も「ja 執筆 → 同依頼書の形式で7+en 翻訳」が月次フローの型になる(en だけは手元翻訳の前例もあり)

17:19 - リリース準備の一気通貫(build 1〜3・deck 1,200点化+v2・seed抽選移行・ストア名確定・support@開設)

前半は前セッション「リリース準備」の作業。終盤に API 接続エラーでセッションが中断したため、build 3 の検証〜アップロードと本記録は後続セッションが引き継いで完遂した。

やったこと:

  • build 1 (1.0.0/1) を ASC へアップロード: Info.plist がバージョンをハードコードしていて MARKETING_VERSION が効かない問題を発見・修正(1.0 のままだと ASC の 1.0.0 レコードにビルドが紐づかない)。PrivacyInfo.xcprivacy を新規追加(UserDefaults を CA92.1 で申告・トラッキングなし)。チームに配布証明書が0枚だったため ASC API で直接発行(Apple Distribution: RAMANU LLC / 期限 2027-07-27)、プロファイル「Pocket Museum App Store」も API で作成。キーチェーンの errSecInternalComponent は署名専用キーチェーンの新設で回避(ログインパスワード不要)。altool validate/upload ともエラーなし
  • App Review 情報を登録: 連絡先(氏名・国際形式の電話番号・info@ramanu.co.jp)と Review Notes。提出必須3点(ビルド・スクショ・Review 情報)がすべて揃った
  • ストアスクショの ja 実画面化 + en-US 新規制作(コミット c6a3dac): 見開きの端末画面が実アプリに存在しないUI(装飾額)で描かれていた問題を実キャプチャ+透視変換で解消(ガイドライン 2.3.3 リスク対応、replace_phone_screen.py)。en-US 5枚は英語UIで raw を撮り直し Baskerville で英訳コピー。両ロケールを ASC 登録
  • 特集記事1本目の英訳: 「フェルメール、窓辺の光」の en.json(intro+7節+結び、タイトル "Vermeer, and the Light by the Window")。ja と構造完全一致を検証、pm featured check → export → シミュレータ英語表示で実物確認。英語UIの ja フォールバックが解消
  • デッキの実害を発見 → 1,200点化 → v2 全面組み直し: deck.json が 7/16 05:32 生成の1,000件のままで、同日夜に追加した200点(真珠の耳飾りの少女・デルフトの眺望・天秤を持つ女など看板作品を含む)が配信対象外=「今日の1枚」に永遠に出ない状態だった。pm deck 再生成は既存分を接頭辞固定して末尾積みにする(新規200点の1年目到達0点)ため、deck.json を消して v2 で全面組み直し(作家近接違反 80→34件・新規200点の位置中央値 92→44番目・1年目到達 62点)
  • 本番R2 を 1,200点版に差し替え: 414ファイル/152MB をアップロードし、artworks/deck v2/stories×9言語/featured ja・en が本番CDN(content.ramanu.co.jp)配信中。7/15 検証用1,000点版を置き換え。Release ビルドは本番URL固定なのでアプリ側の作り直し不要
  • 「今日の1枚」を個人別seed抽選に移行(build 2 に搭載): 固定順カーソルの「全員が同じ並びを同じ位相でたどる」構造が、知り合い同士・SNS で翌日以降の作品がネタバレになる問題を生むため。(seed, 日付, 残りプール) の splitmix64 決定的ハッシュで月プールから抽選、直近3日の獲得作家を除外(空なら制約解除)、seed は最初の獲得時に生成して appState.deckSeed へ永続化(マイグレーション seeded-draw-v1)。DEBUG は PM_DECK_SEED で再現可。検証=非連番抽選・作家除外違反0・月またぎ・2台で同日別作品・新規インストールE2E。build 2 (1.0.0/2) をアップロード
  • support@ramanu.co.jp を開設: wrangler email routing rules create で受信転送ルールを作成(Cloudflare Email Routing → Gmail)。送信名義は Gmail の send-as(SMTP 経由)を You が設定し、テスト受信まで確認済み
  • build 3 (1.0.0/3) を仕上げてアップロード: AppConfig.supportEmailsupport@ramanu.co.jp に差し替え + 特集タブの英語名を Features→Editorial に変更(英語圏で「機能一覧」と誤読されるため。xcstrings 3キーの en のみ)+ CURRENT_PROJECT_VERSION=3。後続セッションで英語UI実表示を検証(タブ・画面見出し・一覧カードとも Editorial 系表示、seed 抽選も正常)→ アーカイブ → validate/upload エラーなし(Delivery UUID 4dc47a4b)。提出時は build 3 を選ぶ(build 1=旧デッキロジック+旧宛先、build 2=宛先とタブ名が旧のまま)

決めたこと:(DECISIONS 3件)

  • 「今日の1枚」を個人別seed抽選に移行(2026-07-16 固定デッキ決定の一部を supersede)
  • en-US ストア名を「Pocket Museum: Masterpieces」に確定(2026-07-20 保留の決着)
  • Fable チェック完走をリリース条件から外し、リリース後に順次実施

詰まったこと / 気づき:

  • xcodebuild archive にコマンドラインで手動署名設定を渡すと SPM パッケージターゲットに波及して失敗する(Firebase 等が「does not support provisioning profiles」)。正解は、アーカイブは自動署名(ASC キー + -allowProvisioningUpdates。開発署名のクラウド署名は通る)で行い、配布署名は exportOptions.plist(manual / Apple Distribution)で export 時に当てる二段構え
  • -allowProvisioningUpdates での配布証明書の新規作成は「Cloud signing permission error」で不可(ASC API キーにクラウド署名権限がない)。証明書・プロファイルは ASC API を直接叩けば発行できる
  • 署名資材(dist.p12 / 秘密鍵 / 署名専用キーチェーン)は scratchpad(/tmp 配下)にあったため、~/.config/asc/pocket-museum-dist/ へ退避した。恒久運用するなら Xcode で p12 を login キーチェーンへ取り込むのが本筋
  • pm deck は既存 deck.json があると全件を接頭辞固定する(--version 2 を指定しても同じ)。全面組み直しは deck.json を消してから(.devnotes の従来記述の意味を実地で確認)
  • LAN IP がまた変わった(192.168.1.133 → 192.168.1.5)。project.yml 更新 + xcodegen 再生成
  • DECISIONS.md の 2026-07-20 ATT/UMP エントリの見出し行が欠落していたのを発見し修復
  • 前セッションは終盤に API 接続エラー(ENOTFOUND)で中断。未コミット変更が宙に浮いたが、セッション transcript の参照で後続セッションが文脈を完全復元して継続できた

次回やること:

  • ASC で build 3 の処理完了を確認 → 1.0.0 に build 3 を紐付けて審査へ提出(You の操作)
  • 公開後: AdMob 再審査の結果監視 → ストア掲載リンク設定 → アプリ審査
  • rewarded 経路の実機手動確認 / EEA フォームの実表示確認(任意・公開後でも可)
  • プレスリリース骨子 + 横長メイン画像(配信は App Store 公開後)
  • リリース後: Fable 残985 の順次チェック → 差し替え

2026-07-26

15:12 - PR TIMES 企業登録〜企業ページ整備(ローンチ告知の土台づくり)

やったこと:

  • 無料枠の前提を訂正: 公式ページを実確認し、スタートアップチャレンジの対象条件は ①日本国内の株式会社 ②設立24カ月以内 ③フォロワー3人 の3点だと判明。expert-brains の promo 知識ベースに「ラマヌは2026年6月設立なので対象になる可能性が高い」と書いてあったのは法人形態の要件を見落とした誤りで、合同会社ラマヌは原則対象外。従量課金 1配信3万円(税別=税込33,000円)が既定線として承認を取り直した
  • 企業登録申請を送信(日曜 11:21): アプリ内ブラウザでフォームを機械的に埋め、パスワード・規約同意チェック・送信の3つは You の手で実施。ramanu.co.jp の会社概要が審査条件「事業内容が確認できること」を満たしているか事前に実確認(商号・設立日・代表者・資本金・所在地・事業内容・法人番号・連絡先が完備 → 登記簿謄本の追加提出は不要と判断)
  • 審査承認(13:43、所要 約2時間20分): サポート&サクセスデスクが土日祝も10:00〜17:00稼働しているため日曜でも通った。本登録URLをクリックして登録完了・企業ID 187992
  • 担当者からの個別指摘に対応: 登録した代表電話番号が個人携帯で、企業情報としてWeb公開される旨の案内が来た → 設定>企業情報から削除し、公開ページで「電話番号 -」を実確認(固定電話がないため差し替え先はなく、記者の連絡先はメールで足りると判断)
  • 企業プロフィールを整備(スタートガイド②): 企業説明155/200字(会社の器の説明に限定し Pocket Museum には触れない)・ロゴ画像250×250・カバー画像1920×450 を登録。フォロワー機能=利用する、X/Facebook/YouTube=表示しない
  • ロゴ画像を作成: コーポレートサイトのインライン SVG(Σ=総和記号の線画、path M18 5H6l6 7-6 7h12、色 #2f3f9e)を 250×250 PNG にラスタライズ。ImageMagick は stroke を落として白紙を吐いたため、パスが直線4本であることを利用して PIL で直接描画(4倍スーパーサンプリング→Lanczos縮小、両端に丸キャップ)
  • カバー画像を作成: 方向性(Σの幾何パターン・文字なし・中央の情報量を落とす)を先に合意してから Codex CLI の ImageGen へ。1920×450 を寸法検証済み。中央を抜いた設計により公開ページで社名・ロゴと干渉しないことを実確認
  • ブランド資産を ~/cdev/company-operation/output/brand/ に集約(ramanu-logo-250.png / ramanu-logo-250.svg / ramanu-cover-1920x450.png
  • dev-timer #38(7/27 12:00「審査結果を確認」)は当日中に審査が通ったため cancel

決めたこと:

  • PR TIMES を Pocket Museum のローンチ告知に使う(subnote では 2026-07-16 に「使わない」で決着していた方針からの分岐。理由は「自信作だから」)。DECISIONS 参照
  • 無料枠が取れなくても従量課金3万円を払って出す
  • X @tazawa_works は企業ページに載せない
  • カバー画像は Σ の幾何パターン(文字なし・中央抜き)

詰まったこと / 気づき:

  • 資本金の入力欄の単位は「万円」1000000 と入れると資本金100億円の会社になる(社員数は「人」)
  • 代表電話番号は登録申請フォームでは必須だが、登録後の編集画面では必須バッジが付かず削除できる
  • スタートアップチャレンジは別途申し込み不要。企業情報に設立年月を登録しておけばログイン時に適用対象確認の質問が出て、配信前にダッシュボードで適用状態を確認できる → 合同会社の可否は問い合わせずに判明する。よって問い合わせは「対象外と出たときの代替プログラム確認」用途に後退させた
  • Claude からのファイルアップロードは許可フォルダ外だと弾かれる~/cdev 配下も対象外)→ 画像2枚のアップロードは You の手で実施
  • PR TIMES の管理画面は /my_c3/ 配下。/main/html/mypage/dashboard は当たらない
  • アプリ内ブラウザの新規タブには Chrome のログインセッションが乗らない。You が開いているタブを Claude のタブグループにドラッグして渡すと解決する(同グループ内なら以降のタブもセッションを共有する)
  • 支払いは銀行振込のみでクレジット決済不可。配信日の当月末締め → 翌月初3営業日以内に請求書メール → 翌月末までに振込(手数料自己負担)
  • メイン画像の推奨は横1920×縦1280以上 → 縦長のストア用スクショ(1320×2868)はプレスリリースに流用できない
  • 並行セッションの wrap-up が expert-brains で git add -A を打ったため、本セッションの promo 知識ベース編集が別件のコミット d028a18 に巻き込まれて記録された(内容は無事なので履歴は触っていない)

次回やること:

  • プレスリリースの骨子(ニュース価値の軸決め。promo-expert に壁打ち)
  • 横長メイン画像の制作
  • 配信は App Store 公開後(本文に実ストアURLを入れるため)

2026-07-22

09:28 - ストア用スクリーンショット(ja・6.9インチ)全5枚完成+拡大鑑賞のピンチ競合バグ修正

やったこと:

  • store-screenshots スキルでアプリ本体のストアスクショ制作。store-assets/screenshots/ を新設(raw / ios/ja/6.9inch / concepts / _archive / preview)
  • 1〜2枚目(見開き): 試行錯誤の末、確定デザインは You が Codex と直接対話して制作(concepts/pocket-museum-campaign-spread-v7〜v9.png → 最終 accent-arch 版)。2640×2868 のマスター見開きを中央分割して2枚化。「名画をひらく。世界がひろがる。」/「次の一枚が、あなたを待っている。」
  • 03 今日の一枚: デバッグ「翌日にする」で日送りして光琳「金地の白い芥子」に着地(デッキは月別カーソル仕様=月替わりで m8 リストに切替わることを把握。8月分は先頭から)。Pro トグルでゲート非表示の素の画面を撮影。「今日の一枚が、毎朝とどく。」
  • 04 拡大鑑賞: 9回イテレーション。最終形=実際にピンチズームした本物の画面(ダヴィッド「ジェラール将軍」)×勲章の金縁ルーペ×巨大デバイス断ち落とし。「筆づかいまで 拡大鑑賞。」(読点なし)
  • 05 コレクション: 日送りの副産物で収蔵37作品に増量し、色の揃ったグリッド段(セザンヌ/光琳/モネ等)を撮影。「出会った名画が、あなたのコレクションに。」+事実線「世界7美術館・1,200点」
  • 特集シートは作らず全5枚で確定(DECISIONS 参照)
  • 全5枚 1320×2868 を sips 実測で検証、preview/index.html ギャラリー再生成
  • ピンチズームのバグ修正ZoomableImageViewer.swift): 閉じるスワイプ用 dismissPan が2本指ピンチもパンとして拾い、同時認識でズームと閉じるが衝突していた。maximumNumberOfTouches = 1numberOfTouches == 1 ガード・ピンチ開始時の進行中ドラッグをキャンセル・cancelled 時は閉じる判定をしない、の4点で修正。シミュレータで実ズーム動作確認済み
  • LAN IP を 192.168.1.5 に更新(project.yml Debug)→ xcodegen 再生成・17e 再ビルド

詰まったこと / 気づき:

  • App Store 6.9インチの正規サイズは 1290×2796 または 1320×2868(1260×2736 ではない。Web で確認)
  • ピンチ/ダブルタップは XcodeBuildMCP から送れない → 実ズーム画面は「You が手動操作 → Claude がキャプチャ」の分業で解決
  • debugDayOffset はメモリのみ(アプリ再起動でリセット)。再起動すると今日の作品が変わりデッキカーソルだけ進む
  • Codex exec は画像生成でなく PIL 合成を選ぶため、実画面ピクセル保持のストア規約と相性が良い
  • シミュレータの status_bar override はアプリ再起動をまたいで持続する

次回やること:

  • スクショの他ロケール(en ほか)と iPad 13インチの展開要否を判断 → ASC への登録
  • Fable チェック再開(残985)

21:34 - 広告同意(UMP)の決定・実装と AdMob GDPR メッセージ公開・サブスク審査スクショ登録

やったこと:

  • ATT / EU 配信の方針を決定(DECISIONS 参照): ATT は要求しない・EU 配信は継続・広告同意は UMP で対応(2e9272e
  • UMP をアプリ実装: AdConsent 新規(起動時と広告要求前に同意状態更新・EEA では広告表示直前にフォーム提示・拒否/失敗は unavailable→当日無料開放フォールバック)、AdMobRewardedAdProvider の SDK 起動を canRequestAds ゲート後に移動、マイに EEA 限定「広告のプライバシー設定」導線(8言語)。DEBUG 用 PM_UMP_DEBUG_EEA=1 で EEA シミュレート可
  • AdMob コンソールで GDPR メッセージ「Pocket Museum GDPR」を作成・公開6a7a83b、Chrome の実セッション経由): en+7言語(ko は UMP 非対応)・Consent / Do not consent(全対象国オン)/ Manage options・EEA/UK/CH のみ表示・ポリシーURL=/privacy/en/。アカウント再審査中でも「プライバシーとメッセージ」は操作可能だった
  • 検証: 非EEA の広告経路は無傷(テスト広告→報酬獲得まで)。メッセージ公開後は同意情報更新がエラーなしで成功(伝播済み)
  • サブスク審査用スクリーンショットを登録し MISSING_METADATA を解消8d4459f): Paywall 実写 1170×2532 を ASC API(予約→アップロード→md5コミット)で両商品に登録 → pm_pro_monthly/pm_pro_yearly とも READY_TO_SUBMIT に遷移
  • en-US ストア名「Pocket Museum: Daily Art」の競合衝突を発見ae7632f): iTunes Search API で「daily art」検索の筆頭が競合 DailyArt(Moiseum)と確認。リリース前に接尾辞を再決断する未決事項として WIP に記録(第一候補「Art History」)。当面は現状維持

詰まったこと / 気づき:

  • UMP はフォーム未設定・取得失敗時にフェイルオープン(canRequestAds=true で広告が出る)。Google 公式サンプル準拠の挙動だが、「コンソールで GDPR メッセージを公開して初めて EEA ゲートが効く」ことを意味する — メッセージ公開をローンチ前チェックリストに入れるべき類のもの
  • シミュレータでは UMP のジオデバッグ(DebugSettings.geography=EEA)が無視され notRequired 判定になる。EEA フォームの実表示確認は実機+テストデバイスID登録か公開後の EEA 実配信で行う(AdConsent の DEBUG ログで status/formStatus を確認可能)
  • サブスク審査用スクショは ASC API で完全自動化できた(subscriptionAppStoreReviewScreenshots: 予約→uploadOperations に PUT→uploaded+sourceFileChecksum で PATCH)。登録後 READY_TO_SUBMIT への遷移には数秒〜数十秒のラグあり

次回やること: ストア用スクリーンショット制作(アプリ本体・ASO設計込み)/ Fable チェック再開(残985)/ rewarded 実機手動確認

19:53 - 通知プライマーとレビュー促進ソフトアスクの実装(設計議論込み)

やったこと:

  • ASC ストア掲載の実態確認: WIP に残っていた「ja ストア掲載情報作成」が別セッションで完了済みと判明(記憶メモ→ASC API で実在確認: 9言語の name/サブタイトル/説明/キーワード/プロモ文 + ja のポリシーURL)。WIP を実態に合わせて修正。説明文に特集への言及が無いことも発見(追記は任意タスク化)
  • 通知プレパーミッション(プライマー)を実装d2f2ba7): 起動時に一度だけ、①自前の許可促し画面 → ②iOS 本物の許可ダイアログ → ③許可なら時刻設定(既定8:00)/ 拒否ならマイ誘導。「あとで」はシステムダイアログを出さず許可機会を温存。NotificationPrimerSheet 新規 + DailyReminder 拡張 + xcstrings 9キー×8言語。シミュレータで3経路+英語表示+再起動非表示を検証
  • プライマー実装を discussion スキルで Codex(GPT-5.6 Sol)にレビュー依頼 → 指摘8件中4件を採用して修正: enable() の通知登録失敗ロールバック / リマインダ操作の直列化(完了順逆転で古い操作が勝つ競合の解消)/ 時刻設定中のみスワイプ dismiss 禁止 / シートの ScrollView 化+detent 2段。見送り4件は理由つきでログに記録(discussions/2026-07-20-notification-primer-review.md)
  • レビュー促進の設計を三者議論4ラウンドで決着4f51ff3、discussions/2026-07-20-review-prompt.md): 同意型ソフトアスク(下記 DECISIONS 参照)。文言・タイミング・再訴求・計測まで確定
  • レビュー促進を実装a286a94): ReviewAskEngine(状態機械)+ ReviewAskSheet + AppModel のモーダル追跡 + マイの常設リンク + Analytics 6イベント + xcstrings 9キー×8言語。E2E: 初回同意→iOS星ダイアログ表示 / followUp同意→App Store ハンドオフ / 同意後の再提示なし / 初回・followUp の文言出し分け を確認
  • 実装後に You の判断でお気に入り追加を契機から除外(detail_closed を再訴求でも使う形に調整、同コミットに同梱)
  • LAN IP を 192.168.1.3 に更新(project.yml Debug + xcodegen)

詰まったこと / 気づき:

  • simctl spawn defaults writeアプリのコンテナ外(data/Library/Preferences/)のデバイスレベル plist に書くため、アプリ自身が書いたキーには勝てず、コンテナ側にキーが無いときだけ読まれる二重状態を作る。シミュレータの UserDefaults を確実に操作するには「シミュレータをシャットダウン → コンテナ内 plist を plutil で直接編集(キーのドットは \. エスケープ)→ boot」が正解。デバイスレベル plist の消し忘れにも注意
  • requestReview のシステム星ダイアログはアプリ外プロセスのため snapshot_ui に写らない(screenshot でのみ確認可能)。通知許可ダイアログは写るので挙動が異なる
  • 17e の検証データはセッション冒頭にバックアップ → 検証後に復元する運用で今回も維持

次回やること: Fable チェック再開(残985)/ 審査用スクリーンショット / rewarded 手動確認(WIP 参照)

11:30 - AdMob アカウント却下の調査と再申請(法人アカウント確定・原因切り分け・再送信)

やったこと:

  • 朝に届いた AdMob 却下メール(「利用要件を満たしていない・理由非開示」の定型文)を精査。対象はサイト運営者 ID pub-7837692984627105 = info@ramanu.co.jp の法人アカウントで、app-ads.txt・Release ビルドの広告 ID(project.yml)と一致することを確認
  • ログイン済み Chrome 経由で両アカウントを実地確認(閲覧のみ):
    • pay.google.com: ramanu 側お支払いプロファイル = 組織 RAMANU LLC(2026-06-30 確認済みバッジ)、gmail 側 = 個人 → 受取人格が別で「1受取人1アカウント」の重複違反説は棄却
    • AdMob コンソール: ramanu 側はオンボーディング 2/4(お支払い完了✓ / 「アプリストアにリンクする」未完了 / アカウント未承認)。個人側は別 ID pub-7148493676889381 で承認済み・稼働中 → 今回の件と無関係(6月収益メールはこちら宛の定例レポート)
  • 却下の本命原因を「アプリが App Store 未公開 → ストア掲載にリンクできず、コンテンツ確認が不能」と推定
  • 影響整理: 新規アプリは「公開 → ストアリンク → アプリ審査承認」後にしか実広告が配信されない仕様のため、公開初日から広告が出ないのは今回の却下と無関係に不可避。未配信の間はフォールバック(広告取得不可 → 当日全文無料開放)が働き UX は担保、収益主軸のサブスクは影響なし
  • You がポリシー準拠を確認のうえ再送信(再審査依頼)を実施

決めたこと:(DECISIONS.md に1件転記済み)

  • AdMob は法人アカウント維持で再審査(即日再送信 + 公開後ストアリンクの二段構え。個人アカウントへの切替はしない)

詰まったこと / 気づき:

  • 受取人格(個人/組織)は pay.google.com の「設定」タブ →「アカウントの種類」で確認できる。?authuser=<メール> を付けると Google 各サービス(pay.google.com / apps.admob.com)をアカウント指定で開けて切り分けが速い

次回やること:

  • 再審査結果のメール(info@ramanu.co.jp 宛)を確認
  • App Store 公開後: AdMob「アプリ」でストア掲載にリンク → アプリ審査 → 実広告の配信開始を確認

11:07 - 月例特集を実装(4タブ目・配信の器・1本目「フェルメール、窓辺の光」・E2E完了)

やったこと:

  • パイプライン側の器: pipeline/pm/featured.py 新設(読込・検証の純関数)+ pm featured check サブコマンド。pm exportcontent/featured/{lang}.json を出力し manifest に featured/{lang} キーを追加(記事のある言語のみ)。作品参照切れは export 自体を停止(deck 警告より厳格)。pm upload は content rglob で自動対象(--dry-run で featured/ja が差分に載ることを確認)
    • 原稿は pipeline/data/featured/{記事id}/{lang}.json(ja 正本)。.gitignore を pipeline/data/* 化して featured/ だけ Git 管理下に(手作りの少量資産のため)
    • 記事単位の access 属性(preview=導入+1作品目無料が既定 / open=全員全文開放)で、将来のプロモ特集にも端末側状態なしで対応
  • アプリ側: マイグレーション featured-v1(featured / featuredItem テーブル、story と同じ (id, lang) 複合キー流儀)、SyncEngine の言語別差分同期(manifest にキーが無い言語は no-op → クエリ側 ja フォールバック。stories と同型)、ContentQueries に featuredList / featuredArticle(ja を土台に表示言語で上書き、節の作品題名は storyTitles でローカライズ)
  • UI: 4タブ目「特集」新設(sparkles.rectangle.stack、マイの前)。FeaturedListView(ヒーローサムネカード一覧・month 降順)→ FeaturedArticleView(導入 → 1節目全文 → ゲート)。PaywallSheet の特典行「(今後)」を除去。xcstrings に新規文言×8言語
  • ゲート表現を実機比較で反復: もくじ列挙(サムネ+作品名)→ 未獲得作品の全開示になり却下 → 見出しのみ → 一文+CTA → ぼかし帯(radius 9/5/3/2/1 を順に比較)→ ぼかしサムネ帯 radius 1 + 「この先、あと6作品がつづきます」+ Pro CTA(縦幅約44pt)で確定。広告ボタンなし・ブラー本文なし・作品詳細への導線なし(記事内完結)
  • 記事冒頭のヒーロー画像は1節目の画像と重複するため廃止(hero_artwork_id は一覧カードのサムネ専用に)
  • Analytics: featured_preview_completed{featured_id}(ロックブロック onAppear、logOnce で dedupe)/ featured_cta_tapped{featured_id} / paywall_viewed{source: gate_featured}。実ログで3イベント+dedupe(ロック2回表示でも1回)を実証
  • 1本目「フェルメール、窓辺の光」を執筆: intro 206字 + 7節(平均308字)+ 結び。1節目=問い(真珠の耳飾りの少女・単独完結)→ 2節目以降=答えと展開(牛乳を注ぐ女/水差し/青衣の女/手紙を書く女/天秤)→ デルフト眺望+結びで回収。既存 ja 単体解説を事実の下敷きにし矛盾記述を排除(特集文は転載ではなく書き下ろし)
  • E2E(iPhone 17e): pm export(1,200点版に更新)→ ローカル http.server → 同期 → 一覧・記事表示 / 無料状態のゲート / Pro ON で全節+結び・OFF で即再ロック(contentRevision 連動)/ CTA → Paywall(実価格表示)/ 英語UI起動で UI=英語・特集本文=ja フォールバック

決めたこと:(DECISIONS.md に2件転記済み)

  • 月例特集の実装形(4タブ目・記事内完結・ロックはぼかし帯+一文+CTA・access 属性)
  • 特集記事は当面 ja のみ制作(配信の器は9言語対応・ja フォールバック)

詰まったこと / 気づき:

  • Firebase Analytics のイベント送信ログ(Logging event)は debug レベルのため log show では照会できない。log stream --level debug --predicate 'subsystem == "com.google.firebase.analytics"' を先に流してから -FIRAnalyticsDebugEnabled 起動が正解(auto-memory にも保存済み)
  • ローカル dist/ は 1,200点版に再生成された(マウリッツハイス等の新200点が特集から参照可能に)。deck.json は温存(デッキは1,000点のまま・export は警告のみで問題なし)。R2 本番は 7/15 検証用のままで、実アップロードは Fable 完走後
  • LAN IP が変わっていたため project.yml Debug の配信先を 192.168.1.83 に更新
  • ポート 8787 は前セッション起動の http.server が存命でそのまま再利用できた(dist はディスク読みなので内容は最新)

次回やること:

  • Fable チェック再開(残985)→ pm deck → pm export → pm upload(特集もこの流れで本番配信に乗る)
  • 審査用スクリーンショット登録(特集画面もスクショ候補に)/ rewarded 経路の手動確認
  • ja ストア掲載情報 / ATT・EU/UMP の方針決め / supportEmail 差し替え
  • 特集の残運用課題: 翻訳制作の範囲確定・ローンチ前バッファ本数・月次制作フロー

04:19 - プライバシーポリシー公開(ローンチブロッカー解消)+ ASC残タスク消化 + R2本番配信開通(pm upload 実装)

やったこと:

  • プライバシーポリシー日英2ページを公開(ローンチブロッカー解消): コーポレートサイト(Cloudflare Pages プロジェクト ramanucompany-operation/website/)に追加し wrangler pages deploy でデプロイ
    • 日本語(正本): https://ramanu.co.jp/pocket-museum/privacy/ / 英語: 同 /en/(日本語版優先の注記付き、hreflang 相互リンク)
    • 内容は実装の事実に整合: アカウント登録なし / Firebase Analytics(IDFA 不取得・ATT 不要求を明記)/ AdMob リワード / Apple+RevenueCat / 配信サーバー通信 / 端末内データ / ローカル通知 / 事業者情報
    • アプリ側 AppConfig.privacyPolicyURL を実URLに差し替え(77b1ae9)、ASC の en-US appInfoLocalization に privacyPolicyUrl(英語版URL)を API で設定。ja のストア掲載情報は未作成のため、作成時に ja 版URLを設定する
  • サブスク表示名・説明の残り7言語を ASC に一括登録(全9言語完了): グループ「Pocket Museum Pro」+ 月額・年額 × es-ES/fr-FR/de-DE/it/pt-BR/ko/zh-Hans の21件(全て201)。訳語はアプリ xcstrings と統一(解説 = textos/textes/Texte/testi/해설/解说)。商品側の残件は審査用スクリーンショットのみ
  • app-ads.txt を公開 + ASC の URL 設定: https://ramanu.co.jp/app-ads.txtpub-7837692984627105 の1行(0f69f99)。ASC 1.0.0 の en-US に supportUrl / marketingUrl = https://ramanu.co.jp/ を設定し、AdMob クローラがストア掲載 → デベロッパーサイト → app-ads.txt を辿れる配線が完成
  • R2 を有効化し本番配信を開通:
    • R2 サブスクリプション追加($0/月、超過時のみ課金。You がログイン、操作は Browser ペインで実施)
    • バケット pocket-museum-content(APAC)作成 + Account API トークン「pocket-museum upload」(バケット限定・Object Read&Write・無期限)を発行、S3互換キーは ~/.config/r2/pocket-museum.env(600)に保存
    • pm upload を実装(pipeline/pm/upload.py + cli 配線、boto3): ローカル md5 と R2 ETag の比較による差分同期。Cache-Control は manifest=60秒 / content JSON=5分 / 画像=7日。画像は artworks.json 参照分のみ上げる(孤児除外)
    • 検証用 dist(1,000点・7/15生成)2,012ファイル / 712MB をアップロード完了、直後の再実行で差分0(冪等性確認)
    • カスタムドメイン content.ramanu.co.jp をバケットに接続(wrangler r2 bucket domain add、Zone ID はダッシュボードから取得)。curl 検証: JSON/画像とも 200・ヘッダ正常。JSON は既定でエッジ非キャッシュ(常に R2 直で鮮度優先・Class B 無料枠内)、webp はエッジキャッシュ対象という理想形
    • project.yml の Release PM_CONTENT_BASE_URLhttps://content.ramanu.co.jp に差し替え → xcodegen → Release ビルド成功・焼き込み値確認
    • E2E: 空いていた iPhone 17 シミュレータ(iOS 26.5)に Release を新規インストール → 本番URLから同期して「今日の1枚」(ロートレック「ニス嬢」)が画像・ja解説全文つきで表示。検証環境 17e は無傷、iPhone 17 は検証後停止

決めたこと:(DECISIONS.md に2件転記済み)

  • プライバシーポリシーはコーポレートドメイン ramanu.co.jp 配下で公開、日英2言語(ja 正本)
  • 本番コンテンツ配信は R2 バケット + カスタムドメイン content.ramanu.co.jp(S3+CloudFront は不採用)

詰まったこと / 気づき:

  • ASC の privacyPolicyUrl は appStoreVersionLocalizations ではなく appInfoLocalizations 側の属性
  • 公開中の Cloudflare Pages はメールアドレスを自動難読化する(mailto は動作に問題なし)
  • Cloudflare の既定エッジキャッシュ対象拡張子に .json は含まれない(.webp は含まれる)→ 追加設定なしで「JSON 鮮度優先・画像キャッシュ」になる
  • XcodeBuildMCP の build_sim / screenshot は configuration・simulatorId 指定よりセッション既定が勝つことがある。Release 検証は xcodebuild 直、スクショは simctl 直が確実
  • wrangler r2 bucket list の code 10042 は「アカウントで R2 未有効化」の意味(ダッシュボードでの有効化が必要だった)
  • 今上がっているのは検証用データ。本番は Fable 完走後に pm deck → pm export → pm upload で置き換え(差分同期なので変更分だけ再アップ)

次回やること:

  • Fable チェック再開(残985、看板作品200点優先の判断込み)→ 完走後に本番デッキで配信差し替え
  • 審査用スクリーンショット登録(MISSING_METADATA 解消)/ rewarded 経路の手動確認
  • ja ストア掲載情報の作成(アプリ名・説明等 + ja プライバシーURL設定)/ ATT・EU/UMP の方針決め / supportEmail 差し替え

02:54 - サンドボックス実購入E2E完了(実機)+ free_story_count 実バグ2件修正 + Firebase Analytics 導入

やったこと:

  • 月額 pm_pro_monthly の StoreKit 伝播を確認: Paywall に年額 $9.99(7日間無料バッジ)+ 月額 $1.99 の2プラン表示、「7日間無料、その後 $9.99/年」のイントロ表記も出た(前回の伝播待ち2件が解消)
  • シミュレータのサンドボックス購入は不可と判明: 17e で購入 → Apple Account サインイン → OK 直後に RevenueCat ログで「Purchase was cancelled」(2回再現)。サンドボックスの商品取得(価格表示)までは動くが実購入フローは完了しない既知の制限。実購入E2Eは実機で行うに切替
  • サンドボックステスター作成(You): applesandboxtester1@ramanu.co.jp(JPN、受信不可アドレスで問題なし・確認メールなし)。ASC UI で作成し API(/v2/sandboxTesters)で登録確認
  • 実機 iPhone 14 へ CLI デプロイ: LAN IP を 192.168.1.5 に更新 → xcodegen → ASC キー署名でビルド → devicectl で install/launch(uninstall→再install も CLI 完結)
  • 実バグ2件を発見・修正(39531e7: ゲートを出すため配信 manifest の free_story_count を一時 0 にしても実機初回起動で効かず、調査で判明:
    1. [SyncEngine] manifest 値のピン留めが AppState 行の存在前提で、まっさらな初回起動では空振り → 行がなければ作ってピン留めするよう修正
    2. [DeckEngine] bootstrap()(同期→獲得)と scenePhase .active 発火の handleForeground()(即獲得)がコールド起動で並走し、同期完了前にフォールバック14が確定 → フォールバックのピン留めを「実際に獲得が発生する時点」(デッキ同期後にしか起きない)へ遅延させ、レースを構造的に解消
    • シミュレータの過去E2Eで通っていたのは rental-v1 マイグレーション経路(AppState 行が既存)だったため。サーバからウェルカム枚数を調整する機能が新規ユーザーに一切効かないローンチ後に効く実バグだった
  • 実機サンドボックス購入E2E成功: ゲート表示 → Paywall ¥1,500/年(7日間無料)/ ¥300/月の円表示 → サンドボックス購入承認(「Sandbox」タイトル+[Environment: Sandbox] 表記のパスワードダイアログ)→ 購入成功・全文解錠。RevenueCat に entitlement pro active / status trialing / will_renew / environment sandbox / 国 JP / 売上 $0 を確認。RevenueCat→ASC→StoreKit→実機→RC サーバの全経路が実購入で開通。検証後 manifest は 14 に復元
  • Firebase Analytics 導入(アプリ側+外部+検証、b41b130:
    • PMAnalytics 境界を新設(GoogleService-Info.plist 未同梱時は全て no-op)。8イベント配線: artwork_acquired / story_gate_viewed{context} / story_gate_action{action} / ad_result{context,result} / story_full_opened{access} / ticket_reused / ticket_expired_gate_viewed / paywall_viewed{source}。featured_* 2種は特集実装時に追加。ユーザープロパティ free_count / deck_version
    • 状態イベントはセッション内 dedupe(story_full_opened は context 跨ぎの重複も排除)。ticket_reused は「このセッションで発行していないチケットでの開封」と定義(AppModel.sessionGrantedTickets
    • チケット prune を失効後7日保持に変更(ticket_expired_gate_viewed 検出用。DECISIONS 参照)
    • firebase-ios-sdk 12.16.0(SPM / FirebaseAnalytics)。AppDelegate didFinishLaunching で plist 存在時のみ configure
    • 外部セットアップ(Browser ペインで実施): Firebase プロジェクト Pocket Museumpocket-museum-d060f、GA=Default Account for Firebase、Gemini in Firebase オフ)→ iOS アプリ登録(bundle jp.co.ramanu.pocketmuseum / App Store ID 6792521728)→ plist を Resources に配置
    • 検証: -FIRAnalyticsDebugEnabled 起動で story_gate_action{action: pro} / paywall_viewed{source: gate_today} の送信+real-time マークをログで実証(DebugView 表示可能)

決めたこと:(DECISIONS.md に1件転記済み)

  • 期限切れ解説チケットの行は失効後7日間保持する(prune 猶予。再ロックは expiresAt 比較で即時のまま)

詰まったこと / 気づき:

  • シミュレータのサンドボックスは「商品取得まで○・実購入×」。以後の課金実購入検証は実機 iPhone 14 で行う
  • Apple アカウント名は大文字小文字非区別(自動大文字化で先頭が大文字になってもサインインに影響なし)
  • Firebase のイベント単位のデバッグログは log show では見えず、log stream --level debug で見る。XcodeBuildMCP の launchArgs では -FIRAnalyticsDebugEnabled が効かないことがあり、simctl launch に直接引数を渡すのが確実
  • 「IDFA will not be accessible」ログは想定どおり(ATT なし方針に合致)
  • 実機の検証インストールは freeStoryCount=0 でピン留めされた特殊状態のまま(Pro 有効なので実害なし。素の状態を試すときは入れ直し)

次回やること:

  • Fable チェック再開(残985)→ 完走後 pm deck 本実行
  • pm upload(R2)/ rewarded 経路の手動確認 / プライバシーポリシーページ(ローンチブロッカー)
  • (任意)サンドボックスのトライアル→課金転換の観測、月額プランの購入E2E

01:20 - RevenueCat/ASC 外部セットアップ完了(アプリレコード・サブスク商品・キー連携・実価格表示まで)

やったこと:

  • RevenueCat 側を MCP で構築完了: App Store アプリ「Pocket Museum (App Store)」(app5291deeaf4、bundle jp.co.ramanu.pocketmuseum)作成 / 商品 pm_pro_monthlypm_pro_yearly 作成 → entitlement pro と offering default$rc_monthly$rc_annual パッケージに紐付け / 公開SDKキー(appl_...)取得
  • project.yml の PM_REVENUECAT_API_KEY に公開SDKキーを配線 → xcodegen → 17e で実SDK(RevenueCatPurchaseProvider)起動を確認。ASC 商品未登録段階では Paywall が「プランを読み込めませんでした+再試行」で gracefully degrade することも確認
  • 重要判明: 接続済みの app-store-connect MCP は別アカウントjp.thomsons.* 系、キー 765NS3X2S3)を見ていた。前セッションの「ASC 未登録確認」は別チームに対するものだった。ramanu チーム(9HZW92277N)へは subnote の ASC キー 8M2SWG78S6(App Manager、issuer は subnote/.mcp.json 参照)で直接 API を叩く方式に切替(スクラッチパッドに簡易クライアント asc-ramanu.mjs を作成)
  • bundle ID jp.co.ramanu.pocketmuseum を Developer Portal に API 登録POST /v1/bundleIds9UPTQ5B2Z6、IAP capability 自動付与)
  • ASC アプリレコード作成(API 非対応のため Browser ペインのログイン済み ASC を UI 操作): Pocket Museum: Daily Art / Apple ID 6792521728 / プライマリ言語 en-US / SKU pocketmuseum(DECISIONS 参照)
  • サブスクグループ+商品2つを ASC API で一括構築: グループ「Pocket Museum Pro」(22248556、en-US/ja ローカリゼーション)/ pm_pro_monthly(月額 ID 6792522445)・pm_pro_yearly(年額 ID 6792522649、groupLevel 同一)/ 価格は JPN ベース(¥300・¥1,500)+ Apple 均等化で全175地域に設定 / 可用性は全地域+新地域自動 / 年額のみ7日無料イントロオファーを175地域に作成。両商品とも en-US/ja の表示名・説明付き(状態は審査用スクリーンショット未登録による MISSING_METADATA、サンドボックスの妨げにはならない)
  • In-App Purchase Key を RevenueCat に登録: 新規発行せず、既存の「RevenueCat」キー S5S7WUD6JY(2026-07-15 に Subnote 用に発行済み・アカウント共通)を再利用。/Downloads に残っていた .p8 を使用し、update-app MCP で登録 → subscription_key_configured: true。あわせて ASC API キー 8M2SWG78S6 も登録 → app_store_connect_api_key_configured: true(RevenueCat MCP のストア状態照会・商品提出系ツールが解禁され、ASC ライブデータ取得を実証済み)。.p8 は `/.config/asc/SubscriptionKey_S5S7WUD6JY.p8` へ移動(600)
  • E2E 実価格表示を確認: アプリ再起動 → Paywall に StoreKit 実価格「年額 $9.99/年」表示(シミュレータの US ストアフロント。日本では ¥1,500)。RevenueCat → ASC → StoreKit → Paywall の全経路が開通
  • Paid Apps 契約は有効と You が確認(銀行・税務含む外部前提はクリア済み)

決めたこと:(DECISIONS.md に2件転記済み)

  • ASC アプリレコードの体裁: プライマリ言語 en-US / 名前 "Pocket Museum: Daily Art" / SKU pocketmuseum
  • ストア価格は JPN ベース + Apple 均等化・全175地域配信(市場別カスタム価格テーブルはローンチ時点では作らない)

詰まったこと / 気づき:

  • 公式 ASC API にはアプリレコード作成エンドポイントが存在しない(bundle ID 登録は POST /v1/bundleIds で可能)。レコード作成だけが UI 必須
  • POST /v1/subscriptionPrices に territory relationship を含めると 409「An error occurred while processing the pricing information」になる。price point ID(base64 JSON で {s,t,p} を内包)だけ渡せば通る。ベース価格を入れても他地域への自動展開はされないため、GET .../equalizations で均等化ポイントを取得して1地域ずつ POST する(territory は ID をデコードして特定)
  • equalizationsfields[subscriptionPricePoints] を指定すると relationships が落ちて territory が取れなくなる(fields 指定なしか ID デコードで回避)
  • ASC API のレートリミット: 約350連続リクエストで 429。数分で回復する
  • ASC で作成した商品がサンドボックス StoreKit から見えるまでラグがある(年額は約30分で出現、月額は本セッション中は未伝播。イントロオファーの表示も同様に伝播待ち)

次回やること:

  • 月額の StoreKit 伝播を確認 → サンドボックス実購入E2E(シミュレータ購入にはサンドボックステスターアカウントが必要になる場合あり)
  • 審査用スクリーンショット登録(MISSING_METADATA 解消。Paywall UI 確定後でよい。最初の IAP はアプリ本体の新バージョンと同時提出の規則)
  • サブスクのストア表示名の残り7言語追加
  • Firebase Analytics 導入 / プライバシーポリシーページ(ローンチブロッカー)

00:13 - RevenueCat課金のアプリ側実装(PurchaseProvider境界・Paywall実価格化)

やったこと:

  • PurchaseProvider プロトコル新設(RewardedAdProvider と同型のスタブ境界): 本番 RevenueCatPurchaseProvider(エンタイトルメント pro の有効性=Pro状態、offerings の annual/monthly パッケージ参照で商品IDに非依存)+ APIキー未設定の Debug 用 DebugPurchaseProvider(確定価格固定表示・購入でメモリ内Pro化)
  • AppModel 配線: isPro を購読状態ストリーム(customerInfoStream→AsyncStream)に連動、変化時 contentRevision 加算で表示中ゲートを即再評価。paywallPlans / purchasePro / restorePurchases を追加
  • PaywallSheet 刷新: ¥ハードコード廃止 → StoreKit ローカライズ価格を正に(%@/年 等のフォーマットキー)。トライアル適格性で「7日間無料」バッジと「無料で試してみる」⇄「購入する」を切替(消化済みユーザーは即時課金表示 = DECISIONS 2026-07-19 の要件)。購入・復元・エラーアラート、自動更新注記、利用規約(Apple標準EULA)/プライバシーポリシーのリンク、プラン読込失敗時の再試行UIを追加
  • project.yml: RevenueCat SDK(SPM 5.x)追加。PM_REVENUECAT_API_KEY(現在空文字)→ Info.plist → AppConfig.revenueCatAPIKey の AdMob と同じ流儀。空キー時は SDK 不起動(Debug=スタブ / Release=購入不可・再試行表示)
  • xcstrings: 新キー12件×8言語追加・「いつでもキャンセルできます」を自動更新注記キーに置換(86→97キー)
  • シミュレータE2E検証: ロック解説 →「7日間Proを試す」→ Paywall(¥1,500/年+7日間無料バッジ・¥300/月・注記・リンク・復元)→ 購入(スタブ)→ シート閉 → 全文即開放 → DEBUG メニュー Pro: ON。Release 構成のビルドも成功
  • ASC 確認(MCP list_apps): 現アカウントに本アプリのレコードは未登録と判明(bundle ID com.ichirokisanuki.pocketmuseum なし)。外部セットアップ手順を WIP に整理

決めたこと:(DECISIONS.md に1件転記済み)

  • 課金の識別子規約: entitlement pro / offering default / 商品ID案 pm_pro_monthlypm_pro_yearly(ASC作成時に最終確定)。利用規約は Apple 標準EULA、プライバシーポリシーは自前ページ(実URL差し替えはローンチブロッカー)

詰まったこと / 気づき:

  • iOS 26 のフローティングタブバーが画面下部ボタンに重なり、snapshot_ui 座標のタップがタブ切替に誤爆する → 事前に少しスクロールしてボタンを画面中央に寄せてからタップで回避
  • 並行セッションが同一シミュレータ(iPhone 17 Pro)で Subnote を操作しており前面を取り合いに → テストDB・オフライン画像・Preferences ごと iPhone 17e に複製して検証環境を分離。今後の課金検証は 17e を使う

次回やること:

  • RevenueCat / ASC の外部セットアップ(You)→ サンドボックス実購入E2E
  • Firebase Analytics 導入
  • プライバシーポリシーページの作成(ローンチブロッカー)

2026-07-19

23:42 - 価格体系を最終決定(三者議論3R)+ レンタルモデルのゲート実装・Paywall刷新

やったこと:

  • 価格体系の壁打ち: biz-expert / game-design-expert に並行で意見出し(①買い切りと③特集で対立、②14基準・④月額¥300・⑤フォールバック表示はほぼ一致)。詳細は expert-brains の sessions 参照
  • 三者議論(discussion スキル、全3ラウンド): .devnotes/discussions/2026-07-19-pricing-final.md。Round 2 でほぼ収束後、You 発案で「広告=永久開放」を捨てるレンタルモデルへの転換を Round 3 で検証・確定(ChatGPT が24時間チケット・CTA期限明示・フォールバック分離・14枚永久無料維持を条件に賛成)
  • レンタルモデルのゲート実装: story_unlock(永久開放台帳)を廃止 → storyTicket(24時間チケット、端末限定・同期外・期限切れprune)。ゲート判定は ContentQueries.storyGate の純関数「獲得順の最初のN作品(ウェルカム特典) or Pro or 有効チケット」。ウェルカム集合は獲得履歴から導出し専用状態なし。free_story_count は manifest 配信値(export.py に追加、現在14)を初回起動でピン留め(オフライン初回はフォールバック14)。マイグレーション rental-v1 で既存DBから移行
  • フォールバック分離: 当日獲得作品のみ広告取得失敗で無条件24時間開放+「広告を読み込めなかったため、今日はそのまま全文を読めます。」の注記。過去分は救済せず再試行案内アラート(機内モードでのバックログ全読み穴を封鎖)
  • ゲートUI刷新: CTA「広告1本で、この解説を24時間読む」+「7日間Proを試す」の並列提示。ウェルカム枠残り2枚から「解説全文の無料はあと◯作品です」予告(欧州6言語は複数形対応)
  • Paywall刷新: 買い切りカード削除・月額¥300・特典文言を決定どおりに変更
  • xcstrings: 不要キー8件削除・新キー9件×8言語追加(85→86キー)
  • シミュレータE2E検証: マイグレーション+ピン留め(freeStoryCount=14)/ ウェルカム枠内全文無料+残1予告 / 15枚目でゲート初遭遇 / 当日フォールバック開放+注記+チケット(source=fallback) / 日送りで24h失効→prune→再ロック / 過去分の広告失敗=再試行案内のみ / Pro ONで全文 / Paywall 2プラン表示、すべて確認

決めたこと:(DECISIONS.md に4件転記済み)

  • 価格体系: 月額¥300 / 年額¥1,500(7日トライアルは年額のみ)。買い切りはローンチ非搭載・予告もなし(再検討条件つき)
  • 解説全文アクセスをレンタルモデルに転換(2026-07-16「永久開放」を supersede)。財産は作品、解説はアクセス商品。最初の14作品=ウェルカム特典で永久無料
  • 月例特集は恒久的な冒頭プレビュー方式(導入+1作品目無料、広告開放なし)
  • Firebase Analytics 導入(ファネル型イベント、購読の正本は RevenueCat)

詰まったこと / 気づき:

  • rewarded 経路の E2E は実テスト広告の表示と「報酬を獲得しました」まで確認したが、AdMob 広告の閉じるボタンが自動操作で押せず(XcodeBuildMCP は elementRef 必須・広告UIは要素非公開)、最後のチケット付与まで通せていない。付与コードはフォールバックと同一の grantTicket(source 違いのみ)。次回シミュレータで手動1回確認
  • レンタルモデルでは Pro 状態がゲート判定に直結するため、デバッグの Pro トグルに contentRevision 加算を追加(表示中ゲートの即時再評価)
  • xcstrings を Python で再整形したため diff が大きいが、実質変更は上記キーの増減のみ

次回やること:

  • Fable チェック再開(残985)→ 完走後 pm deck 本実行
  • StoreKit(RevenueCat)実装 + Firebase Analytics 導入(価格決着済みで着手可能に)
  • rewarded 経路の手動確認(広告を閉じてチケット付与を確認)

20:38 - String Catalog 9言語 + オフライン画像保存を実装(Phase 2 のアプリ実装が完了)

やったこと:

  • String Catalog 9言語対応: app/PocketMuseum/Resources/Localizable.xcstrings を新規作成(85キー × 8言語 en/es/fr/de/it/pt/ko/zh-Hans、キー=日本語原文・基準言語 ja)。project.ymldevelopmentLanguage: ja を追加。「収蔵 %lld 作品」は欧州6言語で複数形バリエーション対応
  • InfoPlist.xcstrings: ホーム画面のアプリ名を ja=ポケット美術館 / 他8言語=Pocket Museum に(DECISIONS 参照)
  • コード移行: String 型に落ちる箇所(通知文・アラート本文・メタデータラベル・地域ラベル・館名・Paywallプラン名等)を String(localized:) 化。日付表示は ja_JP 固定 DateFormatter をやめ formatted(.dateTime.month().day().weekday()) の locale 追従に。セリフ体は ja/zh-Hans=Hiragino Mincho / 他=システム New York に分岐(PMTheme.serif)。DEBUGメニューは対象外(日本語のまま)
  • 副産物の修正2件: ① AppConfig.museumName が旧3館のままだった → 新4館(CMA/NGA/ゲティ/マウリッツハイス)を追加して7館×9言語化 ② お気に入りボタンの文言を「お気に入り」→「お気に入りに追加」(マイのセクション見出し「お気に入り」と英訳が衝突するため。済み状態は「お気に入り済み」のまま)
  • オフライン画像保存(獲得作品の自動保存方式、DECISIONS 参照): ImageStore(actor)を新規実装。獲得済み作品の thumb+full を Application Support/OfflineImages へ保存、起動/フォアグラウンド復帰時にバックフィル(新しい獲得順)、デッキ更新で参照が消えたファイルは prune、iCloudバックアップ除外、in-flight 重複DL排除、NSCache でデコード済みキャッシュ
  • 表示置換: AsyncImage 互換の StoredAsyncImage(ディスク優先 → 無ければCDN取得・保存)で全5箇所を置換。ZoomableImageViewer は URL 渡し → パス渡し + ImageStore 経由に変更
  • シミュレータ検証: ja/en/zh-Hans の3言語で実表示確認(UI・日付書式・複数形「13 works in your collection」・地域ラベル・解説の言語切替・書体切替すべて正常)。.app に9言語分の lproj 生成を確認。配信サーバ停止状態で再起動 → 今日の1枚・コレクショングリッド・詳細・拡大ビューアすべて表示OK(26ファイル/7MB 保存済みを確認)

決めたこと:(DECISIONS.md にも転記)

  • オフラインDLは「獲得作品の自動保存」方式(明示DLボタン・Pro特典としない)
  • ホーム画面アプリ名は ja=ポケット美術館 / 他8言語=Pocket Museum の2種
  • String Catalog はキー=日本語原文方式(UI文字列追加時は xcstrings に8言語を手で追記する運用)

気づき:

  • Swift 6 strict concurrency では @MainActor クラスの static メンバも MainActor 隔離になる。AppModel.resolveContentLanguage / supportedLanguagesnonisolated 化して PMTheme(非隔離)から参照できるようにした
  • Mac の LAN IP が 192.168.1.3 → 192.168.0.146 に変わっていたため project.yml を更新(既知の運用事項)

次回やること:

  • Fable チェック再開(残985)→ 完走後 pm deck 本実行
  • 価格体系の決着 → StoreKit(Phase 3)。Paywall の価格表記は現在 ¥ハードコードなので StoreKit 接続時に実価格表示へ

2026-07-17

02:36 - アプリアイコン確定(真珠の耳飾りの少女)+ 収集元4館追加で1,200点化の受け入れ

やったこと:

  • アプリアイコンの検討から実装まで完走: AIアニメ改変の仮アイコン案を評価(法的・審査的にOKだが、美術ファン層への「AIスロップ」印象リスクでブランド毀損と判定)→ 実在の収録作品を無改変で使う方針に転換 → 収録1,000点から顔アップ候補を洗い出し
  • 三者議論(discussion skill)全2ラウンド + 実寸比較テスト: ゴッホ自画像(AIC) / 少女(Met) / 真珠の耳飾りの少女(非収録) の3案を、原画準拠クロップの同一条件(1024/180/60px・明暗壁紙・App Store検索行モック)で比較。いったんゴッホに決定し、Codex への依頼書(実装依頼_アプリアイコン.md)で実装 → 受け入れ基準4項目クリア(Assets.xcassets 新設、iOS 18 ダーク/ティンテッド外観、project.yml は ASSETCATALOG_COMPILER_APPICON_NAME の1行のみ、シミュレータ実表示)。全記録: .devnotes/discussions/2026-07-16-app-icon-artwork.md
  • 並行セッション + Codex による「収集元拡大」の成果を受け入れ検証: 収集元4館追加(クリーブランド美術館 / ワシントンNGA / ゲティ / マウリッツハイス、pipeline/pm/sources/ に新コレクタ4本)+ 図鑑1,200点化 + 追加200点の9言語解説生成。検証結果: 9言語すべて1,200件・追加200点のID完全一致・重複ゼロ・既存1,000点無変更・story_quality: ai_generated・識別子の本文漏れなし・トーン一致(平均324字 vs 既存327字)・NGA [obverse] 注記の和題処理も自然。真珠の耳飾りの少女(334字)の解説はトローニーの説明・真珠の光の点描表現まで正確で看板に足る出来
  • アイコンを真珠の耳飾りの少女へ変更(User決定): 収録実現により Round 1〜2 で見送った唯一の理由「看板と中身の不一致」が解消。マスターは Wikimedia Commons Meisje met de parel.jpg(4095×4794)の顔中心クロップで、アプリ内画像(pm/sources/mauritshuis.py = Commons API 経由)と同一出自。左の空きを詰めるためクロップ窓を原画右端へシフト(確定 crop box (328, 0, 4095, 3767))し、シミュレータのホーム画面で User 承認
  • ダーク=マスター同一 / ティンテッド=generate_tinted_icon.py でグレースケール再生成。証跡: app/design/app-icon/verify/

決めたこと:(DECISIONS.md にも転記)

  • アプリアイコンは収録作品「真珠の耳飾りの少女」の無改変顔クロップに決定
  • 収集元4館追加・追加式1,200点化(既存1,000点凍結)、マウリッツハイスは Wikidata+Commons 経由の自動収集レーンで収録

気づき:

  • 既存分の ai_reviewed が205→215に増加(並行セッションが Fable チェックを10点進行中)。Fable チェックの分母は1,200点になった(残985)
  • モナリザはルーヴル所蔵で、ルーヴルは商用再利用可のオープンアクセスを提供していないため構造的に自動収録不可(入れるなら Commons PD 画像の手動収録のみ。現時点では不要と判断)
  • 1,200点中のレオナルドは3点: ジネーヴラ・デ・ベンチ(NGA、表裏)+ クリーブランド「聖母子」(帰属は Fable チェックで要精査)
  • マウリッツハイス公式サイトの高解像度DLは非商用限定 → Commons 経由に限り商用可が収集元拡大調査の結論(詳細: .devnotes/discussions/2026-07-16-collection-source-expansion.md

次回やること:

  • 新200点を含む Fable チェックの再開(残985。看板の真珠の耳飾りの少女を含む新200点の優先チェックを検討)
  • Fable 完走後: deck.json を消してから pm deck 本実行

やったこと:

  • 広告SDKを AdMob 単体に決定して即日実導入: Google Mobile Ads SDK 13.6.0(SPM)を project.yml に追加し、AdMobRewardedAdProvider を新規実装して既存のスタブ境界(RewardedAdProvider)に差し込み。在庫先読み・50分失効対応・報酬/キャンセル/取得不能のマッピング。Release専用スタブ UnavailableRewardedAdProvider は削除、解錠ボタン表記を「広告を見て読む」に統一
  • Info.plist キーを project.yml の設定変数で二段構え運用に: アプリIDは Debug/Release 共通で本番、リワードユニットIDは Debug=Google公式テストID / Release=本番ID。SKAdNetwork 推奨50件も追加。ユニットIDが空だとSDK自体を起動せず unavailable → 当日フォールバックの安全弁つき
  • 本番アプリID・リワードユニットIDを AdMob コンソールで発行(You)→ 反映: Debug/Release 両ビルドの成果物 Info.plist を直接確認
  • 広告E2E検証(シミュレータ): ロック作品 → 広告視聴 → Googleテスト動画広告 → 「報酬を獲得しました」→ 全文解錠、DB に source=ad 記録。広告クリックで別アプリへ飛ばされても復帰後に dismiss → 解錠が正常動作
  • SaaS台帳(saas-manager)に admob をカタログ追加して pocket-museum と紐付け(commit & push 済み)
  • ローカル通知を実装: DailyReminder(毎朝8:00デフォルト、固定IDの repeating カレンダートリガー1本、時刻変更は同ID上書き)。マイ画面に「通知」セクション(トグル+時刻ピッカー、拒否時は「設定を開く」導線、設定アプリでの取り消しにも同期)。TodayView デバッグメニューに「通知テスト(10秒後)」+ 登録/配達/設定の読み戻しログ
  • 通知E2E検証: 許可ダイアログ → 登録(翌朝8:00 JST を読み戻しで確認、再起動後も維持)→ 配達記録 → バナー実写確認

決めたこと:(DECISIONS.md に2件記録)

  • リワード広告SDKは AdMob 単体(メディエーションは規模が出てから)+ ユニットID二段構え運用
  • 通知の許可リクエストは起動時ではなくマイのトグルON時(コンテキスト内リクエスト)

詰まったこと / 気づき:

  • 通知が「配達されていないように見える」罠が2つ: ① テスト通知を固定IDで再スケジュールすると、iOS の仕様で配達済みの同ID通知が置き換え消去される(読み戻し直前に自分で消していた)→ テストIDは一意化 ② バナーの5〜6秒表示窓は MCP ツールのレイテンシでは毎回逃す → simctl pushxcrun simctl io <udid> screenshot同一シェルコマンド内で叩けば確実に撮れる
  • 広告検証のためシミュレータDBを書き換えた(firstLaunchDay→2026-06-01、当日 unlock 行削除)。シミュレータは14日無料窓が切れた状態なので今後も広告ゲートを即試せる(実機は無変更)
  • 実機・Debug の広告確認は今後もテストユニットで行う(本番広告の自己クリックはポリシー違反リスク)。AdMob 登録直後は実広告の配信開始まで数時間〜数日かかることがあり、その間 Release は unavailable → フォールバックで動くので実害なし
  • ホーム画面スクショでアプリアイコン未設定(真っ白)が改めて目立った

次回やること:

  • ローンチ前の広告残タスク: app-ads.txt 設定 / ATT ダイアログの方針 / EU 配信するなら UMP 同意フロー
  • Fable チェック再開(残り795)/ 価格体系の決着 → StoreKit(Pro) 実装 / String Catalog 9言語 / アプリアイコン

08:10 - Codex実装(訪問駆動デッキ移行)の受け入れ検証完了・実機デプロイ・呼称を「コレクション」に変更

やったこと:

  • Codex の実装をレビュー: 依頼書に忠実で質疑ゼロ。新設4ファイル(DeckEngine / ProgressSyncProvider / RewardedAdProvider / GatedStoryView)+ pm deck 新設・pm calendar 廃止。DB は visit-driven.sqlite に分離して破壊的作り直し、iCloud マージ形(獲得=和集合・カーソル=同版内最大値)も準備済み
  • 受け入れ基準6項目をすべて検証しクリア:
    1. pm deck 決定性: deck.json を消して2回フル生成 → バイト一致(Codex 生成分とも一致)。--check 通過(1,000件がちょうど1回、作家近接違反45件は編集目標内)。既存 deck.json を接頭辞固定する再実行も同一出力
    2. pm export: dist/content/deck.json 生成・manifest 掲載・calendar.json 消滅 3〜5. ios-debugger エージェントでシミュレータ検証(freeFullStoryDays を一時2日に短縮): 初回起動で1枚獲得 / 同日再起動で増えない / 日付送りで翌日獲得 / 無料期間外ロック→スタブ広告で永久unlock / 広告 unavailable→当日作品フォールバック無料開放 / Pro ON で獲得時自動unlock / コレクションは獲得済みのみ表示+region別進捗数字正確 / 訪問の記録は新しい順・ロックUIなし
    3. 旧概念(遡り・極・7日無料・calendar)の残骸 grep ゼロ
  • 実機(iPhone 14)デプロイ: Wi-Fi 変更で LAN IP が 192.168.0.146→192.168.1.3 に変わっていたため project.yml 更新(Codex が 127.0.0.1 にしていた Debug URL を LAN IP 運用に戻した)。dist/ を 0.0.0.0:8787 で配信し、インストール・起動・同期を確認
  • ユーザー向け呼称を「朱印帳」→「コレクション」に変更: タブ名・画面見出し・空状態文言・獲得バッジ(「朱印獲得」→「コレクションに追加」)。「収蔵 N 作品」表記は残す。実機にも反映済み

決めたこと:(DECISIONS.md に1件記録)

  • ユーザー向け呼称「朱印帳」→「コレクション」(ローカライズ容易性を優先。設計文書内の概念名はそのまま)

詰まったこと / 気づき:

  • CLI からの実機署名で2段階詰まった: ① xcodebuild が「No Accounts」(Xcode アカウントに CLI からアクセス不可)② プロファイルに iPhone 12 mini 未登録。解決策 = subnote の .mcp.json にあった ramanu アカウント(チーム 9HZW92277N)の ASC API キー 8M2SWG78S6(App Manager ロール、~/.config/asc/)を xcodebuild -allowProvisioningUpdates -authenticationKeyPath/-authenticationKeyID/-authenticationKeyIssuerID に渡すとプロファイル自動再生成まで CLI で完結。ASC キーはチーム単位(JFBRCYHN24 用の Downloads のキーでは 9HZW92277N を操作できない)。ローカルプロファイルの登録デバイスは security cms -D -i *.mobileprovision で確認できる
  • フォールバック開放(当日作品×広告unavailable)は無言で全文が開く実装(アラートは非当日作品のみ)。仕様どおりだが、一言出すかは今後の検討余地
  • Debug 日付送りはメモリ上のオフセットなので、アプリ再起動で実日付に戻り当日分をもう1枚獲得する(Debug 限定の現象。実運用では発生しない)
  • 検証用 deck.json / dist は生成済み(Git 管理外)。Fable チェック完走後の本実行時は既存 deck.json を消してから pm deck する(残すと接頭辞として固定される)

次回やること:

  • Fable チェック再開(残り795作品)→ 完走後に deck.json を作り直して本実行
  • 価格体系の再評価(買い切り¥3,000 の位置づけ、保留中)
  • Phase 2 残り: ローカル通知 / String Catalog 9言語 / アプリアイコン
  • 実機で広告ゲートの見た目を確認したければ短縮ビルド再インストール(または「翌日にする」14回)

04:50 - カレンダーモデル鼎談(全8ラウンド)→ 訪問駆動デッキ + 「出会い無料・全文は広告かPro」に確定、Codex向け実装依頼書を作成

やったこと:

  • discussion スキルで三者鼎談(You / Claude / ChatGPT GPT-5.6 Sol)を全8ラウンド実施。全記録: .devnotes/discussions/2026-07-16-calendar-model.md
  • Round 1〜4(配信モデル): 共通カレンダー維持 vs インストール日起点の個人化を検討 → You の「開いた日だけ届く」案を軸に訪問駆動デッキ(固定順序・月別サブデッキ12本・開いた日だけカーソルが1つ進む)で一次クローズ。ローンチ日依存・2年目バージョン管理・後発ユーザーの大量ロック・うるう日・タイムゾーンの問題が構造的に消えることを確認
  • Round 5〜8(Pro設計): Pro=自由鑑賞権(機能束)→ 権利複雑化で You がゼロベース要求 → 「権利1つ・ゲート1本」→ 図鑑全点無料表示の矛盾を You が指摘(出会いのネタバレ)→ 最終的に You 発案の「課金しても1,000点は読めない」を軸に**「出会いは無料、解説全文は広告かPro」**で最終クローズ
  • Codex向け実装依頼書を作成: 実装依頼_訪問駆動デッキ移行.md(リポジトリ直下)。pm deck 新設 / アプリデータ層・UI改修 / 受け入れ基準6項目。広告SDKと CloudKit はアカウント・entitlement が必要なためスタブ境界を切ってスコープ外に(RewardedAdProvider プロトコル+Debugスタブ、マージ可能な永続化構造の設計まで)

決めたこと:(DECISIONS.md に2件記録)

  • 「今日の1枚」を共通カレンダーから訪問駆動デッキ(月別サブデッキ)に転換
  • マネタイズを「出会いは無料、解説全文は広告かPro」に刷新(全館アクセス廃止・遡りロック廃止・図鑑=朱印帳化・広告SDK導入許容)

詰まったこと / 気づき:

  • ChatGPT の効果的な反論が設計を3回変えた: ①端末側ランダム抽選→固定デッキ(テスト可能性・編集品質維持)②記念日オーバーライド→独立した月例特集(例外処理の復活を回避)③「今日の1枚を広告で施錠」→「解説全文に広告」(広告SDK障害がコア機能を止める構造の回避)
  • 「見逃し180日分がPro転換に効く」という当初の想定は、後発ユーザーには「見逃した思い出ではなく無関係なコンテンツ」という指摘で崩れた
  • 図鑑の全点無料表示は共通カレンダー時代の名残で、コレクションループ(朱印帳)とは根本的に相性が悪かった。モノクロサムネイル案も「失効時に一斉に灰色へ戻る喪失感」で棄却され、「未獲得はシルエットも見せない+進捗数字のみ」に

次回やること:

  • Codex に実装依頼書を渡して実装 → 完了後にレビュー・検証(codex-qa-loop 候補)
  • 価格体系の再評価(買い切り¥3,000 = 年額2年分の構造問題、保留中)
  • Fable チェック再開(残り795作品)→ 完走後に pm deck 実行

02:25 - Phase 2 着手: pm export + iOSアプリ雛形〜お気に入り・アーカイブ・ペイウォール骨組みまで(実機動作)

やったこと:

  • pm export 実装・実行: R2 と同一レイアウトの配信ディレクトリ data/dist/ を生成(manifest.json に sha256 / content/artworks.json 1,000件564KB / calendar.json 365日 / stories/{lang}.json 9言語×1,000件・各約1MB / images はsymlink)。R2 認証待ちでもアプリ開発を止めない布石で、将来の pm upload は「dist/ をそのまま R2 へ」になる
  • iOSアプリ雛形を app/ に新規作成(SwiftUI / iOS 17+ / XcodeGen / GRDB 7 / Swift 6): manifest の sha256 差分同期 → SQLite 取り込み(SyncEngine)、端末言語+jaフォールバックの言語別 stories 同期
  • 画面一式: 今日の1枚(深緑壁・金額縁・キャプションプレート、モックのトーン再現)/ 図鑑1,000点グリッド / 作品詳細(メタデータ・所蔵館リンク・CC0表記)/ 誤訳報告(カテゴリ+コメント→mailto、作品ID・言語・リビジョン自動埋め込み、メール不可時は宛先コピーにフォールバック)/ 全画面ズームビューア(ピンチ8倍・ダブルタップ・ビューア中のみ横向き許可・シングルタップで✕トグル・縦スワイプで閉じる)/ お気に入り(favoriteテーブル、今日+詳細から保存→マイに一覧)/ 遡りアーカイブ(直近7日無料、8日以上前は朱印「極」ロック)/ ペイウォール骨組み(確定価格 年額¥1,500・月額¥200・買い切り¥3,000、決済はPhase 3)
  • CDN時刻補正: manifest 応答の HTTP Date ヘッダと端末時計のズレを保存し、20時間超ズレ時のみサーバ時刻で「今日」を判定(端末日付変更によるカジュアルなすり抜け対策)
  • 実機(iPhone 14)で動作確認: 自動署名(チーム 9HZW92277N、subnote と同じ)+ devicectl でインストール。配信は Mac の LAN IP(http.server を 0.0.0.0 バインド)
  • 仕様議論: ①初回インストール時の今日の1枚=全員共通カレンダーで日付のみ依存と確認 ②「インストール日起点の順番モデル」を比較検討(季節・記念日連動と共有感を失うため保留)③通知見逃しは直近7日無料遡りでカバーされる設計と確認
  • pm dashboard に Fableチェック状況(review/revision)の表示を追加(You 実装分)

決めたこと:(DECISIONS.md に記録済み)

  • SQLiteキャッシュは SwiftData ではなく GRDB
  • Xcodeプロジェクトは XcodeGen 生成(.xcodeproj は Git 管理外)
  • 配信形式は manifest + 言語別 stories 分割の静的JSON(pm export)
  • 「今日」判定は端末時計 + CDN応答時刻でサニティ補正(ラチェットなし)

詰まったこと / 気づき:

  • Swift 6 strict concurrency: @Sendable クロージャに JSONDecoder(非Sendable)を捕捉させるとエラー → クロージャ内で都度生成
  • シミュレータの自動操作は FBSimulatorHIDEvent が touch move 非対応で drag 不可・ピンチ不可(swipe は可)。スワイプ閉じは自動検証できたが、ピンチズームは実機確認頼み
  • 実機は 127.0.0.1 に届かない → Debug の配信URLを Mac の LAN IP に固定(ネットワーク変更時は project.yml 更新 + xcodegen 再生成が必要)。iOS 14+ のローカルネットワーク許可ダイアログ対応で NSLocalNetworkUsageDescription が必要
  • 端末ロック中は devicectl の launch が失敗する(インストールは成功する)
  • 全画面ビューアの回転は AppDelegate の supportedInterfaceOrientationsFor を動的に切り替える方式。閉じるとき requestGeometryUpdate で縦に強制復帰

次回やること:

  • Phase 2 残り: ローカル通知 / String Catalog 9言語 / オフラインDL
  • 今日の1枚のカレンダーモデルの結論(共通カレンダー維持 or 個人化。遡りアーカイブは共通前提で実装済みなので、変えるなら早めに)
  • Fable チェック再開(205/1,000、毎日100作品目安)
  • R2 認証 → pm upload 実装(dist/ を上げるだけ)

2026-07-14

02:08 - Fable最終チェック体制を確立、205作品×5言語の品質チェック完了

やったこと:

  • Fable最終チェックの仕組みを設計・実装: 各言語レコードに review: {score, reviewer, reviewed_at, notes}revision(0/1) を付与し、story_qualityai_reviewed に昇格。修正は data/stories/revisions.jsonl に追記型で全履歴を記録(1修正1行、editor/score_before/reason/before/after 全文つき。将来の人間・別モデルによる再修正も同じログに追記可能)
  • 方式検証: ①メインセッション1作品集中($3/作品・コンテキスト肥大)②サブエージェント4作品バッチ($0.78/作品・事実照合が甘い)③1作品=1サブエージェント集中型($1.03/作品・精度最高)を実測比較。Woman Reading の再検証でバッチ型が見逃した誤訳(en「its floral pattern」= ドレスに花柄と断定する事実ドリフト等)を集中型が検出し、③を本番方式に採用
  • チェック実行: calendar 順に第1バッチ100作品 + 第2バッチ100作品 + 先行5作品 = 205作品×5言語(ja/en/es/fr/de)=1,025件チェック完了。スコア平均90.2・全件80点以上で着地。修正35作品・71言語分(revisions.jsonl 72行)
  • 実行基盤: 完了通知駆動で常時8並列を維持する1作品1エージェント方式。エージェントは pipeline/data 読み取り専用、結果JSONを scratchpad に出力 → メインが単一プロセスで一括マージ(エージェント間・生成プロセスとの書き込み競合ゼロ)。マージ前に targets との突合で投入漏れを検出(第1バッチで2件検出→補完、第2バッチは漏れゼロ)
  • 9言語生成の完走を確認: 別セッションの pm generate が全8翻訳言語を完走。9言語×1,000件、全言語 ja と ID 完全一致

決めたこと:(DECISIONS.md に記録済み)

  • story_quality 3段階運用と revisions.jsonl 追記型修正履歴
  • 最終チェックは「1作品=1サブエージェント集中型」を本番方式に
  • チェックは5言語先行、残4言語は生成完了後に追いチェック(→生成完走したので次回から可能)
  • コスト実測($1.03/作品)を踏まえ、残りは毎日少しずつ実行

詰まったこと / 気づき:

  • 最重要の発見: 品質リスクの主因は翻訳ではなく ja 原文の事実誤り。205作品中10作品で原文由来の視覚的事実誤りを検出(例: 源氏物語「宿木」の場面を題名から「蔦の絵」と誤解、モネの積みわら「3つ」→実画像2基、「白いレースの帽子」→実際はレースの襟、手の左右逆転、地球儀→天球儀)。全言語に伝播するためエージェントが美術館公式画像と照合して全5言語修正した。残り795作品にも同比率(約5%)で存在する見込み
  • 修正の言語分布は fr/de/es が多く en は少ない。「anticipant l'impressionnisme」型の時代錯誤と、原文の曖昧な帰属を訳で断定する「具体化ドリフト」が翻訳系修正の2大パターン
  • 生成中の言語ファイルにチェックの書き戻しをすると競合リスク(今回2回発生、実害ゼロを検証済み)。エージェント読み取り専用+中央マージ方式で恒久解決
  • サブエージェントのトークンは ~/.claude/projects/<proj>/<session>/subagents/agent-*.jsonl の usage を requestId 重複排除で集計できる。1作品集中型は約35k tok/件・674リクエスト/100作品・$103/100作品(API単価換算)で再現性が高い

次回やること:

  • 残り795作品のチェック(毎日100作品目安。今後は9言語揃ったので、9言語一括チェックに切り替えるか5言語+追いチェックの2段構えを維持するか要判断)
  • チェック済み205作品への it/ko/pt/zh-Hans 追いチェック

2026-07-13

18:45 - pm calendar / pm generate(Codex既定)実装、ja解説1,000件生成完了

やったこと:

  • pm calendar 実装・実行完了: 記念日13日を2パスで先取り確保 → 残りを月テーマ+知名度で割当。ばらけ制御(作家14日クールダウン・地域連続ペナルティ・スター/地域比率の年間ペース配分)。検証済み(365日連続・ID一意・地域60:26:15・記念日全13件一致・再実行で同一ハッシュ)。出力 data/curated/calendar.json(開始日は仮の2026-10-01、ローンチ日確定後に再生成)
  • pm generate 実装: バックエンド2系統。codex(既定) = Codex CLI(gpt-5.6-sol)を read-only サンドボックス + --output-schema(JSON強制)+ --ephemeral で並列実行、冪等再開つき。api = Claude API Message Batches(50%オフ、--resume-batch 回収)。{title, story} を構造化出力で強制、story_quality: ai_generated 付与
  • 解説の文字数を200〜300字 → 300〜450字目安(上限500字) に改定(Codexで新旧サンプル3件を比較し、逸話が入るようになるのを確認して確定)
  • ja マスター解説1,000件の生成完了: 平均327字・中央値325字・256〜425字に全件収まり逸脱ゼロ。タイムアウト失敗2件も再実行で回収(冪等設計が機能)。実所要約1.5時間(4並列・実効730件/時)
  • 途中でコード分をコミット(0bffc39)

決めたこと:(DECISIONS.md に記録済み)

  • 解説文字数の改定(300〜450字目安・上限500字)
  • 解説生成は Codex CLI(サブスク枠)を既定バックエンドに(コスト優先、Claude APIバッチは --backend api で温存)

詰まったこと / 気づき:

  • 記念日割当の教訓: 類義キーワード(child/children等)を加算すると重複ヒットが知名度差を逆転させる → 最良1語のみ採用が正解。タグは連想的で誤ヒットしやすい(「パリスの審判」にタグ venus/cupid、ムーラン・ルージュにタグ night)ためタイトル一致をタグ一致の2倍重くした。月テーマと重なる記念日(9月 moon と十五夜)は先取りしないと在庫切れになる → 2パス化
  • Codex CLI は codex exec --output-schema で構造化出力を強制でき、バッチ生成基盤として実用的。1件実効20秒(想定90秒の4倍速)。1件15分のタイムアウト保険は実際に2回発動
  • Codex への依頼は「これは執筆タスク。ファイル操作・コマンド実行・Web検索不要。最終メッセージはJSONのみ」と明示するのがコツ(自律エージェントなので放っておくと探索し始める)
  • ANTHROPIC_API_KEY 無しでの SDK 失敗は TypeErrorAnthropicError ではない)。事前に models.list で軽くプローブして分かりやすく即失敗させる実装にした

次回やること:

  • en を --limit 5 で翻訳品質確認 → 良ければ8言語×1,000件を夜間実行(4並列で約11時間見込み)
  • 人力監修フロー(カレンダー365件×日英を human_reviewed へ昇格)。You 実装中の pm dashboard がレビューUIになりそう
  • pm upload(R2 + マニフェスト)← wrangler / Cloudflare 認証が必要

2026-07-12

02:32 - pm curate(1,000点選定)と pm images(WebP 2解像度)完了

やったこと:

  • pm curate 実装: スコアリング(Wikidataリンク+3 / 館ハイライト+4 / 有名画家ティア表 pm/artists.py +3〜10 / 画質 / AIC閲覧シグナル)→ 地域枠(西洋600・日本250・その他150)×スコア順の貪欲選定、作者あたり上限15、作者+正規化タイトルで館間の同一作品を重複排除
  • pm images 実装: 選定作品の画像DL(ソース別戦略: AICはReferer+幅指定 / Rijksは IIIF !2400,2400 / Metは原寸)→ 実寸検証 → WebP 2解像度生成(thumb 800px / full 2400px)
  • 1,000点すべての画像生成完了(計709MB)。curate→images の自動差し替えループ(実寸不足・URL切れを次点と交代)が4周で収束

選定バグを検証で3件潰した:

  • 「神奈川沖浪裏」が Met/AIC の副題書式違いで重複 → タイトルの最初のカンマ以降を落として照合
  • ゴッホ「寝室」落選 → AIC の place_of_origin が都市名(Saint-Rémy)で地域誤分類 + AICにWikidataが無いシグナル格差 → artist_bio の国籍も判定材料に、AIC boosted を+3底上げ
  • 画家名の表記揺れ(ハイフン有無)でティア表照合ミス → 正規化照合

気づき:

  • Met の画像実寸は至宝級でも1700〜1900px台が多い(メロードの祭壇画、スーラの習作、ラファエロ等)。規格2000pxで機械的に切ると名作を失うため、許容下限1600pxの2段構えに(DECISIONS参照)
  • AIC の IIIF はまれに特定幅の派生キャッシュが壊れている(truncated)。幅+100で別キャッシュを引くと直る
  • Met の primaryImage はまれにURL切れ(404、4件)。恒久失敗として記録し自動差し替え

次回やること:

  • 解説生成バッチ(Claude API・9言語・story_quality 管理)← ANTHROPIC_API_KEY が必要
  • R2アップロード+マニフェスト / 365日カレンダー生成(カレンダーは外部依存なしで先行可能)

01:11 - Phase 1 収集スクリプト実装と3館フルラン完了(44,792件)

やったこと:

  • pipeline/ に uv ベースの Python CLI pm を新規実装(uv run pm collect met|aic|rijks / pm status
    • 追記式 JSONL + source_id 重複排除 + スキップ台帳で、冪等・中断再開可能な設計
    • 正規化スキーマは3館共通(pm/sources/__init__.py の docstring 参照)、raw に生レスポンス保持
  • 3館フルラン完了: Met 13,554 / AIC 26,359 / Rijksmuseum 4,879 = 合計 44,792件
  • 分布分析: 西洋60% / 日本28% / その他11%(目標比率 60:25:15 とほぼ一致)、Wikidataリンク25%、AIC は全件画像寸法付きで97%が長辺2000px以上。北斎776・広重2,192・レンブラント244・フェルメール9件など有名画家の在庫も確認

詰まったこと / 気づき(APIの癖、詳細は pipeline/README.md):

  • Met search はパラメータ順に敏感(q を先頭に置くとフィルタが壊れ 14,289→112件に激減)
  • Met search インデックスは不正確(「PD+画像あり」で返る候補の過半が実データでは非PD)。object エンドポイントが正
  • Met はスロットリング時に 403 や接続拒否を返す。keep-alive 維持が正解で、接続クローズ化はローカルDNS障害を招いた(誤診→修正→巻き戻しの経緯は DECISIONS 参照)
  • 重大バグを踏んだ: 一過性の異常応答を恒久スキップとして台帳登録し、ゴッホ・フェルメール含む約1.1万件を取りこぼし。判定厳格化(明示的な非PDのみ台帳入り)+ 台帳破棄・再検査で全回収
  • AIC の search は1,000件打ち切り → list エンドポイント全走査で回避。画像取得は Referer: https://www.artic.edu/ 必須、サイズ max 指定は403(明示幅ならOK)
  • Rijksmuseum 旧APIは廃止済み(410) → キー不要の新 Data Services(Linked Art)で実装。作品1件=3リクエスト
  • Met の持続的403で約250件(0.6%)が未回収だが、台帳に入れない設計なので再実行すれば自動再試行される

次回やること:

  • pm curate 実装: 知名度(Wikidataリンク・館ハイライト)・地域バランス(重みパラメータ 60:25:15)・画質(長辺2000px+)のスコアリングで1,000点選定

2026-07-11

17:54 - 未決事項の一括確定(名称・商標チェック含む)

やったこと:

  • 引き継ぎ.md の未決事項6件をすべて確定し、引き継ぎ.md・DECISIONS.md・ROADMAP.md に反映
  • 名称チェック実施(ストア検索+商標確認):
    • App Store 日本語部分被り1件(「ポケット美術館 ~間違い探しゲーム~」2022年から放置、実害小)
    • App Store 英語完全一致1件(Kazuki Shinagawa「Pocket Museum」2025-12リリース、同コンセプトだが英語のみ・解説なし・課金なし・評価0件)→ 英語名は複合名必須
    • Google Play は完全一致なし。商標インデックス(chizai-watch / Justia / patent-i)はヒットなし
  • J-PlatPat 手動確認(You実施)で「ポケットミュージアム」商願2026-039383(ソーシャル知財株式会社、2026/04/07出願、審査待ち)を検出 → 第16類(紙製品)のみでアプリ(第9類)・配信(第41類)と非被り、称呼も非類似のため、アプリ名使用に支障なしと判断

決めたこと:(詳細は DECISIONS.md の 2026-07-11 の3エントリ)

  • アプリ名: 日本語「ポケット美術館」維持、英語は "Pocket Museum: Daily Art" 等の複合名
  • 言語は9言語でローンチ確定(zh-Hant は v1.x)/ キュレーション比率は西洋60:日本25:その他15 / 買い切り¥3,000は Pro と完全同等(将来コンテンツ込み)/ 誤訳報告は mailto 方式 / Android は iOSリリース+2ヶ月の KPI で判断
  • 防衛的な商標出願(第9類+第41類)は見送り、軌道に乗ったら再検討(ROADMAP「いつか」に記載)

次回やること:

  • Phase 1 着手: pipeline/ に収集スクリプト(Met Open Access / Art Institute of Chicago / Rijksmuseum の3館API)から

最近のコミット

README

pocket-museum

概要

(記入予定)

セットアップ

(記入予定)

使い方

(記入予定)