動くと、正しく作られている、は違いました
朝、メールを開いたら「ドラフトは拒否されました」と出ていました。
数日前、Chrome ウェブストアに申請した petapeta という拡張機能。
3 日かけて審査されて、却下されました。
理由は 2 つで、ひとつは「外部のコードを呼び出す URL が含まれている」、もうひとつは「使っていない権限がある」というものでした。
権限の方は、最初に作ったときに「念のため」で残していたもの。
使っていないなら消す、それだけです。
問題はもう一方の方でした。

「使っていない URL」が違反になる
Firebase という Google の認証ライブラリの中に、reCAPTCHA という別の機能を呼び出す URL が書かれていました。
petapeta はその機能を使っていません。
けれど「ファイルの中に URL が書かれている」というだけで、ストアの審査では違反扱いになるんです。
実行時には何も起きないのに。
動作テストでは引っかからないのに。
ファイルの中身そのものが、ものさしになる世界でした。
これは、自分で動かして確認するだけだと気づけない種類の問題だと思いました。

「動く」ものさしと「正しく作る」ものさし
普段、私が自分のアプリを作るとき、見ているのは「動くかどうか」です。
ボタンを押したら反応するか。
データが保存されるか。
エラーが出ないか。
それを順番に確認して、OK なら次の機能に進む。
シンプルな流れです。
でも今回、ストア側のものさしは違っていました。
「ファイルの中に外部 URL が書かれていないか」「使われていない権限が宣言されていないか」「コードが理解しやすい構造になっているか」。
動かしてみないと分からないことではなく、ファイルを開いて読めば分かること。
机に並べた書類を 1 枚 1 枚チェックされているような感覚でした。
動く、と、正しく作られている、は別の話なんですね。

「ちゃんとやる」を選んだ夜
直し方を相談しているとき、「応急処置で違反箇所だけ消す」案もありました。
表面だけ直して、また同じ仕組みを使い続けるパターン。
でも、今回は根本から直すことにしました。
理由は単純で、petapeta はまだ誰にも公開していないからです。
Phase 1 で限定公開、招待制の状態。
友達にも渡していません。
公開してから「やっぱり直します」と言うより、誰も使っていない今のうちにちゃんとした作りに変える方が、後がラクなんです。
Firebase の認証ライブラリを、Chrome 拡張機能専用のサブパスに切り替えました。
これは Google 自身が「Chrome 拡張で外部スクリプトをロードしない」契約として用意していたもの。
同じライブラリでも、入口を変えるだけで該当の URL 文字列が全部消えました。

ついでに 4 つ、追加で直しました
却下された 2 つを直したあと、再申請する前にもう一度全体を見直しました。
「念のため」で。
そうしたら、追加で 4 つ出てきたんです。
ひとつは、もう使っていない古いコードが残っていたこと。
昔の同期方式の名残りで、本番では走らない条件分岐の中に入っていたんですが、ファイルとしては残っている状態でした。
ひとつは、Google ロゴの画像を Google のサーバーから直接読み込んでいたこと。
これも「ファイルに URL がある」状態で、画像なので即違反ではないものの、他社の拡張機能で似たような形で弾かれた前例があると知りました。
ひとつは、招待制なのに「クラウド同期中」と緑色で表示してしまっていたこと。
実際は弾かれていてデータが空なのに、見た目だけ通っている風になっていて、誤解を生む UI でした。
ひとつは、ポップアップの幅が 320px で狭かったこと。
同じ系統の拡張機能(Pocket とか Raindrop とか)は 400px くらいあって、見比べると確かに窮屈でした。
ストアの審査と直接関係ないものも混ざっていましたが、どうせ全部開けて見直すなら、ついでに整えよう、と思って手を入れました。

普段なら気にしない場所
普段、自分のために作っているアプリだと、こういう細かいところまで見ません。
ファイルの中の URL を全部リストアップしてチェックするとか、エラーログのレベルを下げて拡張機能管理画面のエラー欄を綺麗にするとか、popup の幅が窮屈に感じないか他社と比べるとか。
審査という「外のものさし」が入って、初めて目が向いた場所でした。
これは、自分の使うものを作っているだけでは育たない視点なのかもしれません。
誰かに渡す、誰かに見られる、という前提があるから出てくる、別のレイヤー。

夜、もう一度送りました
直すべきものを全部直して、ultrathink モードで最終チェックをしました。
bundle の中の URL を全部リストアップ、残っているのは OAuth のエンドポイントと画像 service と自社サイトとライブラリ内のコメント URL だけ。
スクリプトを動的にロードする URL はゼロ。
夜、Developer Dashboard で新しい zip をアップロードして、「審査用に送信」を押しました。
結果は前回と同じく 1 日から 4 日くらいで返ってくる見込みです。
今度は通るか、また何か言われるか、まだ分かりません。

公開前の静かな時間
「まだ誰にも公開していない」というのは、不安にもなります。
本当にこれ、誰かの役に立つのかな、と。
でも今回、その状態が守ってくれました。
公開した後に「実は違反していました、直します、また審査待ちです」とユーザーさんに伝えるのは、しんどいです。
今のうちに、誰も触っていない状態で、全部直せた。
Phase 1 の限定公開期間って、こういう時間のためにあるのかもしれない、と思いました。
外に出る前に、外のものさしで、もう一度自分の作ったものを見直す時間。
審査が通っても通らなくても、今日見えた場所は残ります。

