PRODUCT NOTE / PRD
Claude 認定資格の対策アプリ。
この文書は「何ができるか」ではなく、なぜ・誰のために・どんな判断で作っているかを記録した開発ノートです。
| ステータス | 2026-08-27 に App Store で公開(日本のみ)。Android は APK を直接配布。2026-10-31 まで全機能を無料で開放 |
|---|---|
| 現行バージョン | v1.9.0(ビルド 33。Android は配布中。iOS は審査提出待ち。Web は v1.7.0 のまま) |
| プラットフォーム | iOS / Android / Web(AI ワークスペースのタブ) |
| 対象ユーザー | Claude 認定資格(CCAR-F / CCAR-P ほか)の受験者。第一の想定ユーザーは著者本人 |
| マネタイズ | 資格ごとの買い切り(サブスクを採らない。理由は意思決定ログを参照) |
| 最終更新 | 2026-10-14 |
| 関連リンク | プロダクトページ ・ App Store ・ Android APK ・ 開発ノート一覧 |
Certly は、Claude 認定資格の問題を間隔反復(FSRS-5)と適応出題で解き続けるアプリです。特徴は解説の粒度で、正解の理由だけでなく選ばなかった選択肢がなぜ誤りかを全部出し、出典 URL を付けます。
さらに「なぜ今この問題が出たか」を重みの内訳ごと画面に表示します。
通信は教科書の読み上げ音声を取りに行くときだけで、学習データは端末内(drift)だけに置いています。このデータから対策本を出す計画は、いったん取り下げました(意思決定ログ book)。
資格対策アプリの失敗はだいたい 2 つに集約される。
Certly はこの 2 つに、誤答選択肢の解説と推定に基づく出題順で答えている。
afinfo と一致した(69.312 秒)。iPhone のシミュレータでは、問題 6 秒・考える 3 秒・答え 4 秒・間 1 秒が 1 問ごとに途切れず続いた。代わりに、答えの前の合図(ビープ)は外した。MP3 にするエンコーダがこの機械に無く、WAV は 1 本に混ぜられない。Watch の実機での確認はまだで、速度の変更は Watch の標準の「再生中」に無いため、iPhone でしかできない。code と太字)は、点線の下線をやめて、基調色の太字と淡い地で示す。節の頭のカードの中では、code の灰色の札も敷かない。_ と同じ高さに引かれて、tool_use が「tool use」に見える。文字が本文より小さい。前に「幅を取りすぎ」と言われて小さくしたことが、読みにくさの一因だった。ColorScheme.fromSeed に任せず、色を直接決める。明るいテーマの主色は種のコーラルより少し深い #BF4E2A、暗いテーマは種の #D97757 のまま、その上の文字は白ではなく濃いインクにする。面と補助色は温かい灰色にして、コーラルは強調にだけ使う。fromSeed にコーラルを渡すと、主色が茶色(#8F4C36)、暗い面が赤茶色(#1A110F)、tonal ボタンの容器が #5D4037 になり、設定の見本の丸だけが正しいコーラルだった。1 度目は主色だけを直して「直した」と報告し、面と容器が茶色のまま残った。RenderTable の flex は、同じ値を渡しても左右が半々にならず(左 170pt・右 710pt)、2 列では flex を使わずに幅を直接返すことにした。/ui-check)にした。security 章に足さず独立した章にし、security の直後に置いた。問題 20 問は基礎の新ドメイン quality へ。出典は到達できる公開資料だけに限り、iso.org は 1 件も引いていない。ISO 9001 も ISMS も SOC 2 も出てこない。security 章はあるが、あちらは脅威モデル・秘密の持ち方・認証と認可という技術的な守り方で、「組織としてどう回し、第三者にどう証明するか」が丸ごと無かった。読む理由が違うものを同じ章に混ぜると、守り方を読みに来た人が審査の話に当たる。出典については、iso.org が Cloudflare で存在しないパスにも 403 を返し 200 を確かめる運用に乗らないことが分かったので、JISC・ISMS-AC・JIPDEC・IPA・PPC・AICPA・NIST から取った。有料の規格を読んだふりはしない——公開資料が明記している構造・原則・数値だけを書き、条項番号も引用を載せている資料の範囲に限った。allowed-tools は事前承認であって制限ではない)のに、文章だと伝わりにくい。本物に繋ぐ案は 2 つの理由で採らなかった。API キーを端末に置かないのはこのリポジトリの決めごとで、サーバにプロキシを立てても「言うことが毎回変わる」教材になる。台本なら通信も鍵も要らず(無料版・Web 版・機内モードでも同じ)、出典を付けて検証でき、間違いの道も通して見せられる。代償は手触りなので、本物ではないと画面の頭で断る。古くなる問題は、仕様を模写しないことと asOf の札(90 日を過ぎた台本はビルドが毎回 id を出す)で受ける。fable と effort: xhigh)が見出しの行で 13px はみ出していたのを捕まえた。outOfExam か unconfirmed にし、問題 12 問も認定試験のバンクではなく基礎の練習セット(claude-tools)へ。日本語と英語の本文を最初から両方作り、読み上げ音声も日英で作った。curl で 200 を確認した。確認できなかったことは書かなかった(Cowork 自体の対象プラン、Artifacts のテンプレート別の共有既定、Claude Design の利用量の具体値など)。既存の章と重なる話(Claude Code 側の Artifact、Code タブの実行場所、キャッシュの効かせ方)は定義し直さず「〜の節で」と指すだけにしている。asOf(確認した日)と scope(exam / outOfExam / unconfirmed)を持たせ、画面に札を出す。範囲外・未確認の根拠は 1 文で必須にする。公式の試験ガイドは機密なので使わず、「試験に出る」の根拠は公開されているブループリントの記述に限る。載っていないものを「出ない」と言い切らず、判断できなければ「未確認」にする。範囲外・未確認の問題は認定試験のバンクに入れず、基礎の練習セット(claude-tools)に置く。/output-style は削除されていなかった、-p の既定は止まるのではなく拒否して続行、など)、日付を付けるなら先に確かめ直す必要があった。確かめきれなかった主張は削った。ListView(画面の外の子を作らない)で、押した時点で飛び先の見出しがまだ存在しなかったため。最初のテストは「見出しが並ぶ」だけを見ていて、動くことを検査していなかった。SingleChildScrollView)にして、「札を押すと見出しが画面に見える」テストを足した(修正前は見出しが存在せず落ちることを確認してから直した)。シミュレータで実際に押して移動を確認。指摘に応えたつもりで見出しだけ直し、動作を確かめなかったのが 2 回続いた——「並ぶ」と「動く」は別のテストにする。ProseColumnWidth の minIntrinsicWidth が maxIntrinsicWidth と
同じ値を返すようにし、列を縮める前提そのものをやめた。入りきらない表は
TableScrollView で横スクロールに回し、表の文字は本文より一回り小さくした。
RenderTable まで遡ると、列を左から順に縮めていく処理順そのものに非対称がある
と分かった。より左の列ほど「まだ削られていない不足分」を基準に多く削られ、右の列は左が削られた
あとの小さくなった不足分を基準に削られるため、同じ flex 比でも左の列だけ潰れる。下限という
間接的な手段でこの非対称を打ち消すのは表ごとの綱引きにしかならないと判断した。
ヘッダーの試験の切り替えに「エンジニアリング基礎」を 3 つ目として並べ、選ぶと教科書・単語帳・問題集・分析までまとめて基礎に切り替わるようにした。あわせて nzw.jp と App Store の紹介文を「Claude 認定資格の対策アプリ」一本から「資格の対策と、その土台になるエンジニアリングの基礎」の二本柱へ書き換えた。
やめたのは、基礎をホームのカードからだけ入れる形。カードにあった「基礎を解く」「基礎の問題一覧」のボタンも外し、行き先を「この範囲に切り替える」1 つに寄せた。
きっかけは実機での指摘——「クロードコード以外の教科書や問題が多くなっているのに、切り替えにも紹介文にも出ていない」。出荷物を数えると、そのとおりだった。
Claude Code は 40 章のうち 3 章・24 節、1,146 問のうち 82 問(章の 7.5%・問題の 7.2%)しかない。いちばん大きいのは Claude に依存しない一般ソフトウェア工学で、19 章 112 節・457 問(節の 44%・問題の 40%)。SQL・Git・Docker・UML・テスト・FastAPI・認証・PdM といった内容だ。それでもサイト 11 ページと App Store の説明文はすべて資格一本の打ち出しで、基礎は収録範囲の表に「※試験範囲外」と 1 行あるだけだった。
掲載していた数値も古くなっていた(問題 1,066 → 実際 1,146、教科書 35 章 239 節 → 40 章 256 節、用語 314 → 430、選択肢の解説 4,297 → 4,617)。読み上げも「英語は 211 節」と書いてあったが、9 月 22 日に英訳を終えて日英とも全 256 節+章概要 40 になっていた。
切り替えを足す作業で、出荷物そのものが足りていないことが分かった。assets/textbook/foundations.json と glossary/foundations.json が存在せず、しかも読み込みに失敗すると例外を握り潰して空を返す実装だったので、そのまま出せば教科書タブが「準備中」・単語帳が空になるところだった。章の並びの定義に 1 行足して生成し、この壊れ方をそのまま捕まえる回帰テストを置いた。
基礎には合格ラインも本番の形式もないので、選んでいる間は推定スコアと模擬試験を出さない。ただしカードごと消さずに理由を書く——黙って消すと不具合と区別が付かない。
最初の実装では、切り替えても 33 章中 26 章(節で 7 割)が共通なので「変わった気がしない」という指摘が続いた。そこでホームに「いま学んでいる範囲」を出し、教科書の基礎の見出しに「どの試験に切り替えても同じ 26 章です」と断りを入れた。切り替えが何を変えないのかを書くほうが、何を変えるかを書くより効いた。
問題の解説と「覚えること」(1,125 問)、選択肢の理由(1,982 件)、CCAR-P の教科書 7 章、単語帳の見出し 69 語の英語を一度に埋める。
訳は原稿を書き出し直さない差し込みのスクリプトで入れ、数えられるもの(日本語の混入・表と行とコードの数・項目数・日本語の欄が変わっていないこと)で機械に検査させてから採る。
訳す途中で見つけた原文の誤りは直させずに根拠つきで報告させ、公式ドキュメントで確かめてから直す。
英語表示でも解説はほぼ全問が日本語で、「Japanese only」の注記つきだった。CCAR-P の教科書の英語版は図と表を省いた要約で、検査にかけると 23 節で構造が日本語版と合わなかった。
約 66 万字を並行で訳すと、書式の崩れや訳の抜けを人が読んで見つけるのは現実的でない。訳の途中で原文を書き換えると、日本語と英語のどちらが正なのか分からなくなる。
3 試験 1,146 問・4,617 選択肢・教科書 256 節・用語 366 語のすべてに英語がそろった(122 ファイルとも検査の指摘 0、1,146 問を 320pt の幅に描いてはみ出し 0)。
訳の途中で原文の誤りが 20 件あまり見つかり、公式で確かめて直した(MCP の MRTR の正式名、キャッシュの前方一致の順番、プレフィルと temperature は現行世代で 400、フックの終了コード 0 の扱いなど)。
一方で、1 回の出力の上限(16,000 トークン)・通信の切断・利用上限で訳が 3 度止まり、差し込む前の分は失われた。
5 問ずつ差し込む形に直してからは失わなくなった。
日本語だけだった 7 章 43 節を章ごとに並行で英訳し、仕上がりは人の目の前に機械の検査を通す——英語欄に日本語が無いこと、見出し・コード・図・表の数が日本語版と一致すること、日本語の本文を触っていないこと。
検査は既存の英語版にも掛けた。
章ごとに別々に訳すと、表を 1 つ落とす・図を段落に言い換える、といった欠けが節ごとに起き、読み比べないと気づけない。数えられる構造だけでも揃っていれば、欠けは「数が違う」で必ず見つかる。
英訳は原文を 1 文ずつ読み直す作業なので、原文の誤りも拾えると見込んだ。
既存の英語版に 3 か所の欠け(JSON-RPC の図、LangGraph のコード、ツールループの図)が見つかり補った。
原文の誤り 9 件(デイリースクラムの目的、PMBOK の版、重複を消す順番、PKCE の理由、UML の終了状態の記号など)を問題・用語集までそろえて直した。
図の分岐の文字はテスト用フォントでは 12 か所はみ出して見えたが、実機に近いフォントで描き直すと本当にはみ出すのは 1 か所だけだった。
CCAR-P の 7 章の英語版は要約版で、図と表が欠けていることも同じ検査で分かったので、次に直す。
PdM・PMM の章の骨子で、直近の 3 章(SQL で数える・FastAPI・プロジェクト管理)に合わせて「日本語だけ」を提案したところ、「日本語だけはだめ」と明言された。
直近の章が日本語だけだったこと自体が欠けで、それを前例として次の章に引き継ぎかけていた。英語の本文が無い節は英語の音声も作れないので、英語を後回しにすると音声まで後回しになる。
解説まで英訳してみて、英語表示の解説シートが訳の有無にかかわらず「日本語のみ」と注記していたことにも気づいた。
新しい章は 7 節・問題 21・用語 17・音声 16 本(日本語 24 分・英語 21 分)をすべて両言語で出した。「日本語のみ」の注記は訳の無い問題でだけ出すように直した。
既存の 43 節の英訳は v1.3.2 の後に章ごとに進める。
最初の下書きは「GraphQL はエラーでも HTTP 200 を返す」「ブラウザは WebSocket の接続を CORS で止めない」と書いていた。
どちらも広く言われているが、前者は graphql.org では一部が取れた応答のときだけで、実行前の検証で弾かれたものはふつう 400。
根拠にするつもりだった GraphQL over HTTP の草案からは、該当の節が 2026-07 に削除されていた。
後者は OWASP にも書かれていなかった。出典の URL が生きていても、主張を支えているとは限らない。
25 件のうち、主張の書き換えが 4 件(GraphQL の 200・CORS の言い方・nginx の proxy_http_version 1.1 は 1.29.7 より前でだけ要る・Redis の Pub/Sub は届けっぱなし)、URL の差し替えが 4 件。
CORS の件は、他サイトのページから接続を張れること(PortSwigger)と、断るのはサーバーの仕事(RFC 6455)の 2 つに言い換えた。
入口は「章の画面の下端」に集約したはずだったが、目次から特定の節を聴くには本文を開いて下端を押す 2 手が必要だった。行にはヘッドホンの絵と長さが出ていたので「音声がある」ことは分かるのに、そこからは始められない。
状態の表示を押せるものに変えれば 1 手で済む、と実機で指摘された。押せることを示すためにヘッドホンを再生の三角へ変えている(絵が状態の表示に見えると、誰も押さない)。
目次から 1 手で鳴らせるようになった。本文へ連れ出さないので、耳で聴きながら目次で現在地を見る、という使い方が崩れない。
回帰テストは「節の行の札を押すと、その節から鳴る」「鳴っている節の札は一時停止になる」「音声の無い節には札を出さない」の 3 本。
既存の「データベースの基礎」に足さず、「SQL で数える(分析とデータ品質)」を別の章(7 節)として新設した。出題ドメインも分けて章末テストを別勘定にした。
粒度と JOIN のファンアウト・重複の検出・ウィンドウ関数・LAG での期間比較・データ品質の 4 点に加えて、再実行できる取り込み(at-least-once の Webhook が題材)と、個人情報を含む検証環境の作り方までを 1 つの章に入れている。
実務で詰まるのは SQL の文法ではなく「1 行が何を表すか」の取り違えで、JOIN で分母が壊れる・二重取り込みで件数が倍になる・LAG が 1 か月前ではなく 1 つ前の行を指す、という形で出る。
どれもエラーにならず、数字だけが静かに間違う。ところが既存の章は「どう作り、どう速く引くか」に寄っていて、この話がどこにも無かった。
同じ章に足すと、設計を読みに来た人が分析の話に当たり、分析を読みに来た人が実行計画の話に当たる。読む理由が違うものは章を分ける、という基礎トラックの方針をそのまま当てた。
重なる話(JOIN の種類・NULL の比較)は既存章に置いたまま、新章からは指すだけにしている。
教科書 7 節・問題 26 問・用語 15 語。比重 5pt は既存 4 ドメインから 1〜2pt ずつ削って捻出した(合計 100 を維持)。
実機で確かめる過程で、3 列の表が iPhone 幅で崩れること、シーケンス図の矢印の文言が 2 行を超えると切れること(INSERT ... ON CONFLICT DO NOTHING の NOTHING が消えていた)が分かり、原稿側を直した。
読み上げは日本語 10 節ぶんを作って配信済み。
本文(問題文・選択肢・教科書・用語)の言語を、アプリの表示言語とは別の設定として持つのをやめ、1 つにまとめる。ヘッダーの JA / EN は、設定画面の「アプリの表示言語」と同じ設定を書き換え、ボタンや見出しも本文と一緒に切り替える。
設定画面の「本文の言語」は外す。本文だけ英語にしていた人の選択は、起動時に 1 度だけアプリの言語として引き継ぐ(表示言語と同じなら何もしない)。
同じ回に、読み上げの入口を節の本文の頭から画面の下端へ移し、目次から章をはじめから聴くと章の概要 → 第 1 節の順に鳴らすようにした(概要の音声は 37 章 × 日英で新しく作った)。
2026-09-19、英語にした目次のスクリーンショットを添えて「英語表記にしているのに日本語表記が大量にある」と言われた。
本文の言語を分けたのは v1.1.0 の頃で、本試験が英語のみなので「メニューは日本語のまま本文だけ英語」がいちばん多い読み方になる、という仮説だった。
ところが、ヘッダーの 1 タップで英語にした人が期待するのは画面ごと英語になることで、「本文だけ」は説明しないと伝わらなかった。
選択肢として「本文と並ぶ札だけ合わせる」も出したが、選ばれたのは画面ごとの切り替え。旧設定を黙って捨てると、英語で読んでいた人が更新した瞬間に日本語へ戻るので、引き継ぐことにした。
入口も「聴き始めるのは一度きりだから本文の頭で足りる」と判断していたが、同じ時期に「押すたびに画面の上まで指を伸ばすのが面倒」「第 1 節から聴くのに 3 手かかる」と指摘された。
シミュレータで、「アプリは日本語・本文だけ英語」の状態から新しい版を入れると、ホームから英語で立ち上がった。
英語の目次は「About this chapter」「Resume reading」「Section 1」「Chapter test」まで英語で出た。
目次の入口を押すと章の概要(日本語 0:43、英語 0:36)が鳴り、終わると目次のまま第 1 節へ続いた。テストは全 624 本が通過。
「メニューは日本語、本文は英語」の読み方はできなくなった。それを望む人が出てきたら、設定に戻すかどうかをもう一度考える。
iOS の実機と Android ではまだ確かめていない。
再生を押したときに「頭に戻さず続きから鳴らす」かどうかを、節の鍵ではなく同じ音声か(節・言語・指紋)で決める。違えば、いま見えている本文の言語で並びを組み直して鳴らし直す。
節の頭の「聴く」と画面下のバーの再生の両方が同じ判定を通す。鳴らし直す位置は節の頭ではなく、読んでいた段落に当たる段落の頭(引き当ては再生中の訳の欄と同じ関数。対応が取れない節だけ、同じ割合の位置を含む段落の頭)。
鳴っている最中に本文の言語を切り替えても、音はその場では変えない。あわせて、再生バーのボタンを 44pt 以上にし、予定を鳴らし終えたら最後の節の 0:00 に戻して止める。
2026-09-17、「日本語で再生して停止し、JA から EN に変えて再生しても日本語のまま」と言われた。同じ節の日本語と英語は鍵が同じで、v1.1.0 から「同じ節なら続きから」の近道が鍵しか見ていなかった。
v1.1.3 で取りながら鳴らす作りをやめたときも、この近道は残っていた。直すだけなら頭から鳴らし直せば済むが、5 分の節の途中で言語を変えた人は、聞いていた段落を探し直すことになる。
その場で音を切り替える案は採らなかった。演習の画面でも同じ本文の言語を使うので、問題文を英語に変えただけで聞き流している音が途切れる。
同じ日に「バーのボタンが小さい」「聴き終えてもバーが右端のまま」とも言われた。聴き終えたあとの戻し先は並びの先頭ではなく最後の節にした。
先頭へ戻すと、節のタブまで最初の節へ連れ戻すため。
Android エミュレータで、英語を 0:53 で止めて JA に切り替え、バーの再生を押すと、通知の題名が日本語の節名に変わり、同じ見出し(段階的開示)から日本語で鳴った。
シークバーを右端まで送ると 0:00 と再生の顔に戻り、押すと頭から鳴った。テストは 18 本足して全 597 本が通過。
iOS の実機とシミュレータではまだ確かめていない。段落の引き当ては英訳のある 211 節のうち 197 節で効き、残りの 14 節(訳で見出しから組み直した節)は割合で近い段落に落ちる。
再生ボタンを押した節は、設定画面のダウンロードと同じ取り手で端末の一時保存へ落とし切ってから、そのファイルを再生器に渡す。
取っている間は「音声を取得中 N%」を出す。鳴り始めたら次の 1 節だけを先に取って並びに足し、2 節先は取らない。
次の節が取れなくても鳴っているものは止めず、末尾で止まって再生を押すと取り直す。just_audio の LockCachingAudioSource に URL を渡す作りは、Web と置き場所を開けない端末の逃げ道にだけ残した。
2026-09-17、「ダウンロードに時間がかかっているだけなのに、通信エラーの帯が出る」と言われた。
追うと、just_audio の中継(端末内の HTTP サーバ)が配信元から最初のデータが届くまで再生器に応答を返さず、Android の ExoPlayer は 8 秒で読み込み失敗にしていた。
その例外を「鳴らせなかった」として「通信を確かめて」の帯にしていたが、Dart 側の取得は誰も止めないので裏で最後まで落ち、押し直すと鳴る。
つまり帯の文言が事実と違っていた。ExoPlayer のタイムアウトを延ばす口は just_audio に無く、中継の作りも変えられない。
再生器に通信を待たせなければこの壁は消える。章まるごとを先に落とす案は、聴くのをやめた人の回線で数十 MB を落とすので採らず、1 節先までにした。
回線を絞ったエミュレータで、押して 2 秒後に「Fetching audio 46%」、8 秒後に再生開始、「次の節へ」を 2 回押してどちらも即座に切り替わり、帯も ExoPlayer のエラーも出なかった。
ただし「最初の 1 バイトが 8 秒以上遅い」状況そのものはエミュレータの回線制限が効かず再現できていない。
その場合の保証はテスト側で、再生器に渡るのが file:// だけであることを見ている(narration_player_test.dart、just_audio のプラットフォームを偽物に差し替えて 12 本)。
教科書を OpenAI の TTS(gpt-4o-mini-tts、声は alloy)で手元で MP3 にして nzw.jp から配る。
アプリは URL を鳴らすだけで、鍵は開発機の .env にしか無い。端末から API を叩く案も、サーバにプロキシを立てる案も採らなかった。
本文は Markdown のかたまり(見出し・段落・表・図)1 つを 1 回の読み上げにして、MP3 のフレームのまま繋いで節 1 本にし、繋ぐ前に各かたまりの秒数を数えて「何秒から何番目のかたまりか」を索引に焼く。
再生中はこれを引いて、読んでいる段落を光らせる。日本語と英語を別々に作り、再生バーには読んでいる段落のもう片方の言語の訳を出す。
鍵を Flutter に埋めないのはこのリポジトリの決めごと(LangBridge で鍵を漏らした事故がある)。プロキシなら鍵は守れるが、教科書の本文は変わらないのに再生のたびに合成して課金される。
1 度作れば、鍵は手元だけ・何度聴いても無料・一度聴いた節は通信なしで鳴る、の 3 つが同時に成り立つ。位置を実測にしたのは、節ごと 1 回で読ませて文字数で按分すると「図。」のような短いかたまりで必ずズレるから。
光る場所が耳と食い違うくらいなら、光らせないほうがまし。訳を並べるのは、本試験が英語のみで「UI は日本語・本文は英語」がいちばん多い読み方なので、英語の音を聞きながら日本語の意味を目で確かめる使い方に合わせた。
日本語 239 節(約 9.8 時間・540MB)と英語 211 節(約 6.9 時間・378MB)。台本と声とモデルから内容ハッシュを取り、変わった節だけ作り直す(バンクの取り込みと同じ判断)。
かたまりの秒数と実ファイルの長さのズレは最大 0.05 秒。見積もりは外した——最初は 60〜80MB と書いていたが、API の MP3 は 128kbps 固定で実際は 540MB だった。
踏んだ罠が 3 つある。1 つ目は配信元が Range に 206 で応えないと、音は鳴るのに再生位置が 0:00 に貼り付く(手元の Python の簡易サーバで踏んだ。配信スクリプトが毎回 206 を確かめる)。
残り 2 つはリリース作業中に APK をエミュレータで鳴らして初めて見つかった。
端末に残しながら鳴らすキャッシュは端末内の 127.0.0.1 に HTTP の中継を立てるので、Android 9 以降の平文 HTTP 禁止に当たって 1 秒も鳴らない。
さらにリリースビルドのリソース削除が通知の再生ボタンのアイコンを捨て、メディアセッションが立たずに画面を離れると OS に音を止められる。
どちらも単体テストと iOS シミュレータを素通りする壊れ方で、実機相当で鳴らすまで分からなかった。無料キャンペーンで配る 4 本目のビルドなので、kFreeCampaignBuildBelow は 4 → 5。
Claude Code の章にリファレンスの節を 15 本足した(16 節 21,879 字 → 31 節 54,305 字)。
CLI のフラグ、settings.json のキー、環境変数、権限ルールの書式、フックの入出力、MCP の設定、モデルの一覧、Agent SDK、CI、サンドボックス、チームとワークフロー。
公式ドキュメントが docs.claude.com/en/docs/claude-code/* から code.claude.com/docs/* へ移設されていたので、新しい節の出典は新ドメインを指す。
ただし既存 250 か所の旧 URL は置換しない。
実機で使うときに知りたいのは「そのフラグの名前」「そのキーの綴り」なのに、章にはひとつも載っていなかった。読めば分かるが、引けない——公式ドキュメントを開き直すなら、章がある意味が薄い。
Claude Code は CCAR-F の出題比重で 20% ある最大級のドメインなので、ここが概念の説明だけで終わっているのは配分としても合っていない。
旧 URL を一括置換しない理由は別で、改名・統廃合されたページがある(/iam は新ドメインに無く、カスタムコマンドは skills に統合された)。
ドメインだけ機械的に差し替えると、301 で救われていたリンクが 404 になる。壊れていないものを壊す変更は、まとめてやる価値がない。
1 章だけで +32,426 字(英文を含めると +80,000 字超)。作業中に副産物が 2 つ出た。
ひとつは強調チェックの誤検知——描いたあとの HTML に残る ** をそのまま数えていたので、Read(src/**) のような glob をインラインコードで書いた節が全部「強調が壊れている」に化けていた(47 件のうち 42 件)。
<code> の中を除いて数えるようにしてラチェットを 47 → 5 に下げた。もうひとつは「よくある誤解です」の向き——見出しで事実を言い切ってから「よくある誤解です」と続けると、その事実のほうが誤解だと読める。
日英 7 か所を「誤解の中身を先に言い切る」形に直した。無料キャンペーンで配る 3 本目のビルドなので、kFreeCampaignBuildBelow は 3 → 4。
2026-08-27 に App Store(日本のみ)で公開した。公開後、英語ローカライズのアプリ名が Certra - AI Exam Prep になっているのを見つけた——Certly のタイポ。
日本語名(Certly - AI認定資格の対策)・バンドル ID(jp.nzw.certly)・ホーム画面の表示名はどれも正しいので、直すのは英語ローカライズの 1 フィールドだけ。
ただし公開済みバージョンの名前欄はロックされるため、次の機能リリースを待たず v1.0.1 としてビルドごと出し直す。Android は Play ストアを待たず、APK の直接配布から始める。
審査に 13 日かかった(8/14 提出 → 8/27 公開)。承認メールの Submitted が 8/14 のまま動いていないので、これはリジェクトと再提出の往復ではなく、ひとつの提出が審査側で止まっていたことを意味する。
他社ブランド(Claude / Anthropic)の資格対策という題材が知的財産の確認に回されたと見ている。
この「いつ明けるか読めない」という性質が、無料キャンペーンを日付ではなくビルド番号で切っておいた判断を裏づけた——「9/30 まで無料」を日付で実装していたら、審査の明ける日が読めない以上、告知と実装が必ずズレていた。
名前のほうはストアの一覧に出る誤字で、機能の追加を待つ理由が無い。
ビルド番号を +2 に上げるのに合わせて、kFreeCampaignBuildBelow も 2 → 3 に上げた。ここを上げ忘れると +2 で入れた人が 10 月から有料側に落ちる。
この 2 つは別ファイルにあって連動が人任せなのが弱点なので、pubspec.yaml 側にも「増やしたら揃えること」と書き足した。
もう 1 つ分かったこと——国コードを含まない apps.apple.com/app/… の URL は米国ストアを引くので、日本のみ配信だと承認メールに載ったリンク自体が 404 になる。
配るリンクは /jp/ と id を必ず含める。
Android の APK は更新に気づく手段がストア側に無いので、DayGrid / Engly と共有の nzw_app_updater を載せ、JSON マニフェスト(update.json)で更新を配るところまで同時にやった。
書名『Claude 認定アーキテクト Foundations 完全対策』と、目次・問題数・出題比重の掲載をすべて取り下げた。
シリーズ Vol.3 は資格対策ではなく AI エージェント関連のテーマで考え直し、書名も内容も未定のまま「2026年9月 刊行予定」だけを出す。
アプリのデータから書籍を生成するパイプラインは停止し、Certly 側のページからも書籍への導線を外した。
「完全対策」を名乗る根拠は著者が受験して確かめたことにあるが、Claude 認定試験は Partner Network 所属組織の企業メールが要り、受験導線がまだ通っていない(下の未解決のこと)。
受験の見通しが立たないものを本の看板にすると、通らなかったときに中身ごと書き換えることになる。すでに手を動かして運用している領域= AI エージェントのほうが、シリーズの原則(実運用で下した判断だけを書く)を満たせる。
書籍ページは中立な URL /book/vol3/ へ移し(旧 /book/ccar-f/ は転送のみ)、「決まっていること/これから決めること」の 2 枚構成に置き換え、表紙も「?」の仮画像にした。
シリーズの 3 つ目のスタンス(試験で固める側)も取り下げ、トップ・ハブ・Certly の各ページを同じ表記へ揃えた。刊行予定は 8 月から 9 月へ 1 か月後ろ倒し。
同じ Flutter のコードから Web 版を作り、AI ワークスペースに単語帳・DayGrid と並べた。この版には課金を積まない——全機能が最初から開き、購入の導線ごと画面に出ない。
「課金を積まない配布形態」を kFreeEdition という 1 つのフラグで表し、Web と --dart-define=FREE_EDITION=true のビルドが同じ扱いになる。
ブラウザに App Store も Play も無いので、購入ボタンを置いても押せない行が並ぶだけになる。
動作確認用の解放(TestFlight 向けの PREVIEW_BUILD)とは別のフラグにしたのは、出荷したビルドを見たときに「確認用の解放が残っているのか、無料版として出したのか」を区別できなくなるため。
判定の差し替えは entitlementsProvider 1 か所だけにしてある。ゲートは 30 か所近くあり、画面ごとにフラグを見に行かせると必ずどこかが閉じたまま残る。
ブラウザでも端末内 SQLite(drift の WASM 版)で動く。
取り込みの作りに 2 つ穴が見つかって直した——毎起動で 3 試験ぶん 5 MB の問題バンクを読んで捨てていた(内容ハッシュだけを載せた索引を先に読むようにした)のと、1 行ずつ書いていた(Web ではステートメント 1 本ごとにワーカーとの往復が入るので、まとめて 1 回にした)。
どちらもネイティブでは見えていなかった無駄で、Web に出したことで表に出た。
月額課金は「使い続けさせる」ことが収益になる。これは zerohalf の方針——答えを渡さず、ユーザー自身の力を育てる——と正面から衝突する。
資格対策アプリのゴールは「受かって、二度と開かなくていい状態」にすることなので、受かったら払わなくていい形しか整合しない。
Certly+サブタイトルで運用する。アプリ内・ストア説明・書籍の 3 箇所に「Anthropic 非公式」を明示する。assets/*.json を作る。書籍側はこの JSON から原稿を生成する。依存の向きはアプリ → 書籍の一方通行に固定した。本とアプリの内容が構造的に一致する。「本は地図、アプリは反復」という売り方が、実態を伴った主張になった。
※ 2026-08-21:書籍側を白紙に戻したため、このパイプラインは現在停止中。アプリ単体の運用には影響しない。
lib/domain/srs/ は drift も Flutter も import しない。永続化先は drift のみに一本化する。問題数は v1.3.4 時点。
| CCAR-F(Foundations) | 356 問/5 ドメイン。公式ブループリントの比重に合わせて配分 |
|---|---|
| CCAR-P(Professional) | 214 問/7 ドメイン |
| エンジニアリング基礎 | 576 問/27 ドメイン。試験範囲外なので別 exam として分離した |
| 追加予定 | CCDV-F / CCAO-F を同スキーマで追加 |
問題が 3,208 問に(易しい問題・比重の補正)/正解が最長の偏りと断定語・理由節の是正/音声ドリルの考える時間 30 秒・問題数 3〜300・要点の読み上げ(ビルド 33)
音声ドリルに選択肢・カウントダウン・「すぐ答えを見る」/始めている間は画面を移れない/範囲を選ぶシート(一括操作・選択数)/ホームの「前回の続き」(ビルド 31)
音声ドリル(問題と答えの読み上げ・考える間・二言語・問題番号)/下タブを「ホーム・教科書・演習・分析・設定」にまとめ直し/ホームの「続きを聴く」とお知らせ/「演習」の上に範囲の切り替え(ビルド 28)
節の補助(場面・分かること・ポイント・ひとこと・つまずき)の読み上げ・項目スキップ・アコーディオン/鳴っている場所の動く波形と再生バーのボタン拡大/英語の字幕欄の見出しを欄の言語で出す
節の学習補助(場面・分かること・ポイント・ひとこと・つまずき・覚える語・確認クイズ)/考えてみよう・用語タップ・用語カードの復習/単語帳 1,265 語と全章の書き直し・読み上げの作り直し
途中で切れていた音声を作り直し、同じ壊れ方を捕まえる検査を追加/新章「SQLite を本番で使う」(日英・音声つき)/Claude Code カラーの配色を作り直し、2 列の表を 1 画面に収め、章の見出しを番号つきの全幅の行に(ビルド 24)
さわって覚える体験モード(選択肢で進む疑似 Claude。台本 8 本・全員無料)/「Claude 本体の機能」4 節と「品質と情報セキュリティのマネジメント(ISO・ISMS)」6 節を日英と音声つきで追加/関連の練習問題 32 問を基礎の練習セットへ
Claude Code のアプリ・Skills の新章 2 つ、教材に「試験に出るか・いつの時点か」の札、既存 3 章の照合と修正/教科書の目次(上段・見出し・語での絞り込み)とホームの新着カード/聴き終えたら声で知らせる
選択肢の位置を出題のたびに変え、解説の記号参照は画面の並びへ読み替え/問題文と解説の選択メニューに単語登録・Google 検索・マーカーを追加/問題文の版名・用語に説明を足し、MCP の版を日付として読める表記へ
教科書の表を縮めず横スクロールに回す設計へ変更/読み上げの追尾が画面外で黙って再開しないように/聴き始めるボタンを上段へ戻し、初回取得も自動で取り直す/無料キャンペーンを 10/31 へ延期
読み上げの再生バーを畳めるようにし、送り・追尾の入切・終了を残す/図とコードのかたまりで 3 秒止め、字幕の欄に現物と残り秒数を出す/試験の切り替えが何を変えるのかをホームに書き切り、章の一括操作に確認を足す
ヘッダーの切り替えに「エンジニアリング基礎」を足し、選ぶと教科書・単語帳・問題集までまとめて切り替わるように(基礎向けの出荷物も新設)/基礎では合格ラインが無いので推定スコアと模擬試験を出さない/nzw.jp と App Store の紹介文を二本柱に直し、古くなっていた数値を全面更新
全問の解説・覚えること・選択肢の理由を英訳(1,146 問)/CCAR-P の教科書 7 章を全訳し英語の音声を作り直す/単語帳の見出しを英語でも出し、訳で見つかった原文の誤りを直す
日本語だけだった 7 章 43 節を英訳し英語の読み上げも付ける(教科書の全節が両言語に)/英訳で見つかった原文の誤り 9 件を問題・用語集までそろえて直す/既存の英語版の図とコードの欠け 3 か所を補う
「プロダクトとマーケティングの分析(PdM・PMM の視点)」の章を新設(7 節・問題 21・用語 17、すべて日本語と英語、読み上げも両言語)/解説シートの「日本語のみ」の注記を訳の無い問題だけに/出典 27 件の根拠を確かめ主張 13 件を直す
「REST 以外の選び方(GraphQL・gRPC)」「WebSocket を本番で動かす」の 2 節を追加(問題 6・用語 5・読み上げ)/用語集の並びが語を足すたびに崩れていたのを直す/出典 25 件の根拠を 1 件ずつ確かめる
「SQL で数える」「FastAPI で API を書く」の 2 章を新設(各 7 節)/基礎の問題を 53 問追加/目次の節の行からその場で読み上げを始められるように
目次の章の概要を日本語・英語で読み上げる(37 章 × 2 言語)/聴き始める入口を画面の下端へ、再生中の文章から読んでいる場所へ移れる/JA / EN を画面ごとの切り替えに
一時停止して本文の言語を切り替えたら、その言語で読んでいた段落から鳴らし直す/再生バーのボタンを 44pt 以上に/聴き終えたらバーを 0:00 に戻す
読み上げの音声を鳴らす前に 1 節だけ取り終えてから渡す(回線が遅いだけで「通信を確かめて」の帯が出ていた)/取得中は進み具合を出す/鳴らしながら次の 1 節を先読み
教科書の誤り約 60 件を問題・用語集・音声ごと直す/Claude Code の章を 3 章に分ける(31 節 → 24 節)/章の目次タブと、入りきらない表の横スクロール
読み上げ音声を設定画面から言語ごとにダウンロードして通信なしで聴けるようにする/背面に回ったら止め、戻ったら続きから/ダウンロード分はバックアップから外す
教科書の読み上げ(日本語 239 節・英語 211 節、alloy で事前生成して nzw.jp から配信)/読んでいる段落を光らせ、再生バーに訳を出す/聴く範囲(節・章・教科書)と背面再生
Claude Code の章を 16 → 31 節に増補(CLI・設定・フック・MCP・モデル・CI)/出典を移設後の code.claude.com へ/強調チェックの誤検知を直しラチェットを 47 → 5
英語ローカライズのアプリ名の誤り(Certra → Certly)を直して再提出/無料キャンペーンのカットオフを +3 へ連動/Android APK の直接配布を開始
App Store で公開(日本のみ・審査に 13 日)。2026-09-30 まで全機能を無料で開放
Web 版を公開し AI ワークスペースに載せる(課金なしの全機能版)/バンク取り込みを索引+一括書き込みに/起動時の無駄読み 5 MB を削除/App Store へ提出
最上位資格 CCAR-P を追加/模擬試験モードと学習計画を実装
Flutter+drift+FSRS-5+適応出題/演習・解説・分析/完全オフライン
企画。「まず自分が合格する。合格した後に有料アプリとして出す」を前提に据える