PRODUCT NOTE / PRD

Certly

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 ・ 開発ノート一覧
TL;DR

ひとことで

Certly は、Claude 認定資格の問題を間隔反復(FSRS-5)と適応出題で解き続けるアプリです。特徴は解説の粒度で、正解の理由だけでなく選ばなかった選択肢がなぜ誤りかを全部出し、出典 URL を付けます。

さらに「なぜ今この問題が出たか」を重みの内訳ごと画面に表示します。

通信は教科書の読み上げ音声を取りに行くときだけで、学習データは端末内(drift)だけに置いています。このデータから対策本を出す計画は、いったん取り下げました(意思決定ログ book)。

Problem

解こうとしている問題

資格対策アプリの失敗はだいたい 2 つに集約される。

Certly はこの 2 つに、誤答選択肢の解説と推定に基づく出題順で答えている。

Decision Log

主要な意思決定ログ

v1.9.0 正解が最長になる偏りは、日本語だけでなく英語でも測って、誤答を書き直して下げる
DECISION
単一選択で「正解がいちばん長い選択肢」になる割合を日本語・英語の両方で測り、偶然(約 25%)に近づくまで、誤答を具体化する・正解の冗長を削る、で直した。誤答だけに付いた断定語(必ず・常に)と文末の「…から。」も、正解と同じ水準まで外した。機械的な置換は取り下げ、1 つずつ文意を読んで書き直した。
WHY / 仮説
査読で、正解がいちばん長い問題が CCAR-F で 54%、基礎で 62%、CCAR-P で 70%(偶然なら約 25%)と分かった。長さだけで当てられると、「なぜその誤答がもっともらしいか」を読む動機が消える。日本語だけ直すと英語側が 36〜40% のまま残り、誤答を水増しすると「必ず」や文末の理由節が新しい手がかりになった。
RESULT
正解が最長の割合は日本語で 31 / 27 / 28%、英語で 28 / 28 / 29%(CCAR-F / 基礎 / CCAR-P)。断定語と文末の「から」は、誤答と正解で同じ水準になった。正解の文を変えた問題は音声ドリルの索引から外して作り直した。
v1.8.0 音声ドリルを始めている間は、ほかの画面へ移れなくする
DECISION
再生中・一時停止中・音声を取っている間は、下タブ・ヘッダー・演習の上段のタブ・戻るを押せなくする。抜けるのは画面の「終了」だけにして、終了すれば音も止める。画面が外れたときも音を止める。
WHY / 仮説
音声ドリルの再生画面は「演習」タブの 1 枚で、別のタブへ移っても再生器は鳴り続ける。ところが移った先の画面は再生に追随しないので、音が鳴っているのに操作する画面が無く、止める手が分からなくなる、と指摘された。追随させる案(どの画面にも再生バーを出す)より、移れなくするほうが、止める場所が 1 つで済む。
RESULT
下タブの無効化と画面の離脱時の停止をテストで確かめた。代わりに、以前できた「聴きながら別の画面を見る」ができなくなる(画面ロックやほかのアプリへの切り替えでは、音は鳴り続ける)。聴きながら教科書を読みたい人には不便なので、教科書の読み上げのように再生バーを共有する案は残した。
v1.8.0 音声ドリルは、1 問を端末で 1 本の MP3 に組んで再生リストの 1 項目にする
DECISION
問題・考える間・答えを別の項目として並べず、1 問ぶんを端末で 1 本の MP3 に繋ぐ。間は同じ形式の無音フレームとして音声の中に置く。エンコーダは使わず、TTS が返した MP3 のフレームを並べるだけにした。
WHY / 仮説
最初は 1 問を「問題・無音 6 つ・合図・答え・無音 2 つ」の 11 項目に分けて並べた。画面のタイマーで間を取ると、画面をロックした時点でアプリが止められて音まで止まるためだ。ところが Apple Watch の「再生中」から飛ばしたいと頼まれて確かめると、「次へ」が次の問題ではなく次の無音の項目に着地する。ロック画面と AirPods も同じだった。1 問を 1 項目にすれば、次へ・前へ・10 秒送りがそのまま問題単位で効く。
RESULT
実音声で組んだ長さが macOS の afinfo と一致した(69.312 秒)。iPhone のシミュレータでは、問題 6 秒・考える 3 秒・答え 4 秒・間 1 秒が 1 問ごとに途切れず続いた。代わりに、答えの前の合図(ビープ)は外した。MP3 にするエンコーダがこの機械に無く、WAV は 1 本に混ぜられない。Watch の実機での確認はまだで、速度の変更は Watch の標準の「再生中」に無いため、iPhone でしかできない。
v1.8.0 聞いた問題は後ろへ回すが、覚えたことにはしない
DECISION
音声ドリルは採点も復習の記録も書かない。覚えた問題を飛ばす判定は、既存の FSRS で「いま 90% 以上覚えている」かどうかだけで決め、聞いた回数では数えない。同じ問題が毎回出ないように、聞いた問題は別の記録に残し、1 巡するまで後ろへ回す。
WHY / 仮説
聞き流しただけで FSRS を動かすと、答えを思い出していないのに覚えたことになり、演習の成績と混ざる。かといって何も残さないと、採点の記録が変わらないので、開き直すたびに同じ 30 問が並ぶ。「覚えた」と「もう聞いた」は別の話なので、記録を分けた。
RESULT
聞いた記録は直近 1,500 件で、全部聞き終えたら新しい巡りとして捨てる。コードレビューで、全部聞いたあとに選抜が落ちる欠陥と、記録が一度もリセットされない欠陥が見つかり、どちらも直した。
v1.8.0 単語帳と問題集を「演習」にまとめ、設定を右端の下タブへ移す
DECISION
下タブを ホーム・教科書・演習・分析・設定 にする。「演習」は演習問題・音声ドリル・問題集・単語帳を上段のタブで切り替える。演習問題のタブは、設定画面をそのまま置く。設定は各画面の ⋮ から外した。
WHY / 仮説
音声ドリルを足すと下タブが 6 つになる。どれも問題や語を使って練習する手で、別々のタブにしておく理由が薄かった。設定は「どの画面の ⋮ にも入れる」としていたが、右端に常に出ているほうが探さずに済む。学習計画も同じ理由で、⋮ の中から、今日のノルマのカードへ出した。
RESULT
ホームの演習ボタンは残した。毎日使うので 1 タップで押せるほうを取り、同じ行き先が 2 か所に見える代わりに、部品を 1 つにして食い違わないようにした。基礎の問題が出ないと指摘されたので、「演習」の上に範囲の切り替えを出した(基礎は別の試験なので、範囲を切り替えないと出ない)。ヘッダーの言語切替(JA | EN)は、並びが読み物の画面と逆だと指摘されて、検索と ⋮ のあいだにそろえた。
v1.8.0 問題の音声は問題と答えだけ作り、要点は後回しにする
DECISION
日本語・英語とも、問題と答えの音声だけを作る。要点(keyPoints)の音声は、作る仕組みだけ入れて、今回は作らない。声は nova に決めた。
WHY / 仮説
要点の音声は全体の約 4 割を占める。日本語で約 15 時間・英語で約 13 時間ぶんの見積もりが、問題と答えだけなら日本語 約 9.7 時間・英語 約 7.5 時間で済む。走りながら聞く用途なら、まず問題と答えがあれば足りる。声は教科書の落ち着いた alloy ではなく、運動中に聞くため元気な声を候補 8 つから選んだ。
RESULT
1,227 問 × 2 言語 = 4,908 本と、問題番号の読み上げ 400 本を作った(日本語 約 531MB・英語 約 413MB)。生成器のファイル名だけ、教科書の口調の指示で指紋を計算していた(音声の中身は正しかった)。4,908 本を改名して直し、作り直しの課金は出していない。送信スクリプトを引数なしで流すと、サーバーに無い古い教科書の音声まで約 2,800 本送る状態だったので、音声ドリルのフォルダだけを送る口を足した。
v1.7.1 補助の音声は項目ごとの別ファイルにして、本文に挟む
DECISION
節の頭と末尾の補助(場面・分かること・ポイント・ひとこと・つまずき)を、本文とは別の台本・項目ごとの別の音声で作り、MP3 のフレームのまま本文に挟んで節 1 本にする。本文の音声は作り直さない。項目の頭の位置は実測の秒数で索引に持ち、再生バーの項目スキップとアコーディオンの開閉が同じ手がかりを見る。
WHY / 仮説
きっかけは「この節で分かること、ポイントが読まれていない」という指摘だった。v1.7.0 は補助を画面にだけ出して音声に入れておらず、耳で聴く人には無いのと同じだった。最初は補助と本文を 1 本にまとめて作ったので、どこかを直すと全部を作り直す形になり、クレジットを使い切った状態で間違った音声を全節ぶん作ってしまった。別々に作り、あとから挟めば、補助だけを直しても本文に課金しない。
RESULT
日本語 281 節中 276 節、英語 281 節中 279 節に補助を入れた(補助の字数は日本語 約 19.6 万・英語 約 41.8 万)。末尾の短い 1 文を TTS が落とすことがあり、文字起こしで検査して取り直したが、日本語 5 節・英語 2 節は 1 文ずつ読ませても通らず、本文だけのままにしている。検査側の誤検知の可能性もあり、未解決。繋ぎ直しで、本文の最初のかたまりの手がかりが補助より前に残る不具合も見つけて直した(索引だけの修正で、音声ファイルは変わらない)。
v1.7.0 学習補助は本文の外に置き、読んだあとに思い出させる
DECISION
節の頭(場面・分かること・覚えるポイント)と末尾(ひとこと・つまずき・覚える語・確認クイズ)は、本文ではなく節の専用の項目に書く。画面は本文の外に枠つきで出す。本文に入れるのは「考えてみよう」の質問と、強調の印だけにした。
WHY / 仮説
きっかけは「読んでも頭に残らない、単語が覚えにくい、説明が難しい」という申告だった。調べると、節にゴールもまとめも無く、確認問題は章末のテストだけで、用語は定義のないまま先に出ていた。音声があるので聞けば流れは追えるが、思い出す機会がどこにも無い。補助を本文に混ぜると台本が変わって音声を作り直すことになるので、本文と補助を分けておけば、補助だけを直しても音声に響かない。
RESULT
CCAR-F の 76 節に補助を書いた。確認クイズは節を問う既存の問題がある節だけに付け、問題の無い節(background-and-parallel など)には付けていない。結局は全章を書き直したので音声も全部作り直しになったが、それは別の判断で、補助の置き場所を分けた効果は、あとで補助だけを直せることにある。
v1.7.0 新しい語は 1 日 10 語まで。数えて止める
DECISION
用語カードの復習は問題とは別の表で持ち、新しい語は 1 日 10 語までにする。その日に出した語は端末の設定に日付ごとに数える。
WHY / 仮説
最初は「山を作るとき新しい語を 10 まで取る」だけにしていた。コードレビューで、10 枚を終えて、もう一度「今日の山」を始めると次の 10 語が出ると指摘された。単語帳は 1,265 語あり、繰り返せば 1 日に何百語も入って数日後に復習が押し寄せる。復習の記録には「初めて見た日」が無く、山を作る側からは今日の分が見えなかった。
RESULT
初めて採点した語を日付つきで数え、残り枠が 0 なら新しい語を山に入れない。単語帳の先頭に出す枚数も、山の上限(30 枚)と残り枠で切った値にそろえた。復元した端末では当日だけ足止めが効かなくなるが、学習の記録は失わない。
v1.7.0 押せる語に下線を引かない
DECISION
本文の押せる語(用語集にある code と太字)は、点線の下線をやめて、基調色の太字と淡い地で示す。節の頭のカードの中では、code の灰色の札も敷かない。
WHY / 仮説
スクリーンショットを添えて「読みにくい」と指摘された。描いて測ると原因は 3 つあった。色のついた地に灰色の札が濁った斑点に見える。点線の下線が _ と同じ高さに引かれて、tool_use が「tool use」に見える。文字が本文より小さい。前に「幅を取りすぎ」と言われて小さくしたことが、読みにくさの一因だった。
RESULT
地を色のない面にし、文字を 13.5pt・行間 1.55 にした。そのぶん頭のカードは少し縦に伸びる。見た目は暗いテーマと 2 つの基調色の 4 通りで描いて確かめた。
v1.6.1 Claude Code カラーは、種から作らず色を直接置く
DECISION
主色・面・補助色・容器を ColorScheme.fromSeed に任せず、色を直接決める。明るいテーマの主色は種のコーラルより少し深い #BF4E2A、暗いテーマは種の #D97757 のまま、その上の文字は白ではなく濃いインクにする。面と補助色は温かい灰色にして、コーラルは強調にだけ使う。
WHY / 仮説
実機で「Claude Code カラーが誤っている」と 2 度指摘された。fromSeed にコーラルを渡すと、主色が茶色(#8F4C36)、暗い面が赤茶色(#1A110F)、tonal ボタンの容器が #5D4037 になり、設定の見本の丸だけが正しいコーラルだった。1 度目は主色だけを直して「直した」と報告し、面と容器が茶色のまま残った。
RESULT
青緑と Claude Code の 2 色 × 明るい・暗いの 4 通りで、主色の字と、主色の上の字が 4.5:1 以上あることをテストで見る。コーラルの上の白文字は 3.12:1、濃いインクは 5.33:1 だった。面と補助色が茶色に戻らないことも、彩度の上限で検査している。
v1.6.1 2 列の表は、文字の総量に比例して幅を割り、横に流さない
DECISION
2 列の表だけは列を縮めて 1 画面に収める。幅は両方の列の文字の総量に比例して割り、自然な幅が表の幅の 4 割以下の列(名前の列)は縮めない。縮める下限は 72pt。3 列以上は今までどおり、入りきらなければ横に流す。
WHY / 仮説
「名前 | 説明」の表を横スクロールにすると、左と右を見比べるたびにスクロールが要る。1 度目は「長いほうの列が残りを全部取る」にしたが、左右がどちらも長い表で、左を 5 行に縮めたのに右が 2 行のまま幅を占領した。RenderTable の flex は、同じ値を渡しても左右が半々にならず(左 170pt・右 710pt)、2 列では flex を使わずに幅を直接返すことにした。
RESULT
出荷している 2 列の表 550 件を、実機に近いフォントで描いて測る検査を足した。純関数の単体テストは通っていたのに、全件を測ると、右の列の切れない語に押されて左が 43pt・7 行まで潰れる表など 3 件が見つかった。見た目を変えるときは、実データを全件描いて測る手順(/ui-check)にした。
v1.6.1 音声が途中で切れたことは、索引との突き合わせでは捕まらない
DECISION
「本文の量に対する秒数」で異常を見つける検査を回帰テストに足した。言語ごとに「秒数 ÷ 地の文の字数」の中央値を取り、その 55% を切る節を落とす。あわせて、節を最後まで聴いたら読み進みに数えるようにした(割合は本文のスクロールと同じ 0.95)。
WHY / 仮説
ISO・ISMS の章の概要(日本語)が 276 字に対して 16.7 秒しか無く、聴いていて「途中でカットされて次へ移動する」と気づいた。配信時の突き合わせは索引と実物のバイト数が一致するかしか見ないので、TTS が途中までしか返さなかった場合は素通りする。実物が索引どおりである以上、別の軸——本文の量に見合った長さか——で見るしかない。読み進みの件は、耳で最後まで追ったのに記録が 0 のままだと、同じ読み方をしている人に別の答えを返すことになるため。
RESULT
索引全体(268 節)を走査したところ、壊れていたのはこの 1 件だけだった(中央値の 34%)。作り直して 56.5 秒。指紋は台本から作るので、台本が変わっていない作り直しはファイル名が同じまま中身だけ差し替わる——アプリは取得したバイト数を索引と突き合わせて失敗にするので、索引を更新した版(v1.6.1)を出さないと直らなかった。うまくいかなかった点: この性質に気づいたのが差し替えた後で、v1.6.0 を入れた人は一時的にその節だけエラーになった。
v1.6.0 ISO・ISMS は「守り方」の章に足さず、別の章として基礎トラックに置く
DECISION
品質と情報セキュリティのマネジメント(ISO 9001・ISO/IEC 27001 と ISMS・ISO/IEC 25010・ISO 31000・プライバシー・監査の実務)を、既存の security 章に足さず独立した章にし、security の直後に置いた。問題 20 問は基礎の新ドメイン quality へ。出典は到達できる公開資料だけに限り、iso.org は 1 件も引いていない。
WHY / 仮説
調べたらリポジトリ全体でヒット 0 だった——ISO 9001 も ISMS も SOC 2 も出てこない。security 章はあるが、あちらは脅威モデル・秘密の持ち方・認証と認可という技術的な守り方で、「組織としてどう回し、第三者にどう証明するか」が丸ごと無かった。読む理由が違うものを同じ章に混ぜると、守り方を読みに来た人が審査の話に当たる。出典については、iso.org が Cloudflare で存在しないパスにも 403 を返し 200 を確かめる運用に乗らないことが分かったので、JISC・ISMS-AC・JIPDEC・IPA・PPC・AICPA・NIST から取った。有料の規格を読んだふりはしない——公開資料が明記している構造・原則・数値だけを書き、条項番号も引用を載せている資料の範囲に限った。
RESULT
6 節・日本語 11,912 字と英訳、用語 20 語、問題 20 問、読み上げ音声は日英 7 本ずつ。狙う混同は実務で間違えるところに絞った(修正と是正処置、認証と認定、ISO/IEC 27001 と 27002、附属書 A と適用宣言書、規格と保証報告書、リスク低減とリスク受容)。根拠が取れないものは書かなかった——附属書 A のテーマ別の内訳、SOC 2 Type 2 の最低観察期間、ISO/IEC 27701 の移行期間、ISO/IEC 25010:2023 の 9 特性の名前。25010 の 8 特性は 2011 年版の形なので、現行版が 2023 年であることと「この 8 つを最新の分類として覚えないこと」を本文に明記した。副作用として、この repo が「教科書だけ先に入れる」ことを構造的に許していないことも分かった(基礎の章は必ず章末テストを持ち、その出題ドメインには 10 問以上要る)。
v1.6.0 Claude をさわって覚える場所は、本物に繋ぐのではなく「選択肢で進む台本」にする
DECISION
疑似 Claude の体験モードを足すが、本物の Claude には繋がない。選択肢で進む台本を教材として書き(原稿は YAML、出荷物は生成物、検証はビルドで落とす)、スキルの発火・ツールの実行・成果物を専用のカードで描く。画面は本物の見た目を模写しない。全員無料にし、入口はホームのカードと章の目次の 2 か所だけにして下タブは 5 つのまま据え置く。
WHY / 仮説
「スキルの使い方をマスターできるようにしてほしい」と頼まれたのがきっかけ。スキルは動きを見れば一発で分かる(description が発火条件、allowed-tools は事前承認であって制限ではない)のに、文章だと伝わりにくい。本物に繋ぐ案は 2 つの理由で採らなかった。API キーを端末に置かないのはこのリポジトリの決めごとで、サーバにプロキシを立てても「言うことが毎回変わる」教材になる。台本なら通信も鍵も要らず(無料版・Web 版・機内モードでも同じ)、出典を付けて検証でき、間違いの道も通して見せられる。代償は手触りなので、本物ではないと画面の頭で断る。古くなる問題は、仕様を模写しないことと asOf の札(90 日を過ぎた台本はビルドが毎回 id を出す)で受ける。
RESULT
台本 8 本・70 手(スキル 4 本に、許可リスト・設定ファイル・プロンプトの書き方を足した)。選択肢は全件に理由を書いた(選ばなかった誤答の理由も出す)。選ぶ手では「次へ」を出さない——押して流せるなら、理由を 1 つも読まずに終われる。進み具合は prefs(台本 id → どこまで開いたか)で、drift のスキーマは触らない(高々 10 本で増え続けないため)。320pt の端末で全台本を日英の両方で描く回帰テストを書いたら、モデルの札(fable と effort: xhigh)が見出しの行で 13px はみ出していたのを捕まえた。
v1.6.0 モデル・Artifacts・Claude Design・Cowork は 1 章にまとめ、試験範囲外として分けて置く
DECISION
「Claude 本体の機能」の章(4 節)を新設し、現行モデルの選び分けと effort・Artifacts・Claude Design・Chat / Cowork / Code をここに置く。節はすべて outOfExam か unconfirmed にし、問題 12 問も認定試験のバンクではなく基礎の練習セット(claude-tools)へ。日本語と英語の本文を最初から両方作り、読み上げ音声も日英で作った。
WHY / 仮説
調べたら教材に穴があった。Claude Design はリポジトリ全体でヒット 0、Artifacts は Claude Code の共有機能としてしか書いていなく(用語 0・問題 0)、モデルの比較表も無かった。一方これらは公開ブループリントに名前が無いので、認定試験の推定スコアや出題比重に混ぜると合格までの距離が読めなくなる。章を分けて「試験範囲外・未確認の教材」の見出しの下に置けば、合否に直結するものと「知っておくと役に立つもの」を混ぜずに出せる。
RESULT
本文 9,817 字(日本語)・用語 21 語・問題 12 問。出典は 14 本すべて curl で 200 を確認した。確認できなかったことは書かなかった(Cowork 自体の対象プラン、Artifacts のテンプレート別の共有既定、Claude Design の利用量の具体値など)。既存の章と重なる話(Claude Code 側の Artifact、Code タブの実行場所、キャッシュの効かせ方)は定義し直さず「〜の節で」と指すだけにしている。
v1.5.0 教材に「いつ確認したか」と「試験に出るか」を持たせ、試験外の問題は別の勘定に置く
DECISION
節と問題に asOf(確認した日)と scope(exam / outOfExam / unconfirmed)を持たせ、画面に札を出す。範囲外・未確認の根拠は 1 文で必須にする。公式の試験ガイドは機密なので使わず、「試験に出る」の根拠は公開されているブループリントの記述に限る。載っていないものを「出ない」と言い切らず、判断できなければ「未確認」にする。範囲外・未確認の問題は認定試験のバンクに入れず、基礎の練習セット(claude-tools)に置く。
WHY / 仮説
Claude Code のように仕様が頻繁に変わる教材は、古くなっても読み手に分からない。さらに IDE・デスクトップ・ウェブ版のような「アプリの使い方」を足すと、試験に出ない話が認定試験の推定スコアや比重に混ざる。照合してみると既存の 3 章にも食い違いが約 30 件あり(/output-style は削除されていなかった、-p の既定は止まるのではなく拒否して続行、など)、日付を付けるなら先に確かめ直す必要があった。確かめきれなかった主張は削った。
RESULT
新章 2 つと、24 節の照合・修正。点検(読者目線と各問題の正解の検証)で事実の誤りを 2 件見つけて直した(VS Code でモデルに見える IDE ツールは 2 つ、ほか)。うまくいかなかった点: 既存の問題 2 問(出力スタイル)は「未確認」の札のまま認定試験に残る(問題 id が解答履歴の紐付けなので、移すと履歴が切れる)。また、音声を作り直して索引だけ先にマージし、全員が再生で 404 を踏んだ(MP3 を送る前に索引が出た)。
v1.5.0 目次は「見出しを足す」ではなく、押して飛べるものにする
DECISION
教科書の一覧の上段に、見出しごとの章数と新着数を並べた目次を置き、押すとその見出しへ画面が移動する。試験範囲外の章は「試験の出題範囲」と別の見出しに分け、基礎(26 章)は初めたたむ。語で絞り込むと、その語が入っている章と節を目次の順のまま出す。
WHY / 仮説
新しい章が 35 章の一覧の下に埋もれて「全然どこにあるか分からない」と言われた。最初は「目次」という見出しを 1 行足しただけで、押して飛べる目次になっておらず、範囲外の章が「試験の出題範囲」の見出しの下に混ざって矛盾して見えた。直したあとも、札を押して画面が動かなかった。一覧が ListView(画面の外の子を作らない)で、押した時点で飛び先の見出しがまだ存在しなかったため。最初のテストは「見出しが並ぶ」だけを見ていて、動くことを検査していなかった。
RESULT
一覧を先に全部作る形(SingleChildScrollView)にして、「札を押すと見出しが画面に見える」テストを足した(修正前は見出しが存在せず落ちることを確認してから直した)。シミュレータで実際に押して移動を確認。指摘に応えたつもりで見出しだけ直し、動作を確かめなかったのが 2 回続いた——「並ぶ」と「動く」は別のテストにする。
v1.4.3 選択肢は出題のたびに並べ替え、解説の「(C)」は読み込み時に画面の記号へ読み替える
DECISION
選択肢の並びを、問題 id 由来の固定シードから、出題(読み込み)のたびの乱数に変えた。解説・理由の中で「選択肢 C」「(B)」「choice D」のように記号で他の選択肢を指している文は、原稿を直さず、読み込み時に原稿の記号から画面の記号へ機械的に読み替える。
WHY / 仮説
固定シードだと同じ問題の正解位置がいつも同じで、覚えてしまえば内容を読まずに当たる。変えると決めた時点で、解説の記号参照が壊れる問題が見えた。数えると ccar-f の 56 問に約 270 件あり、しかも原稿の記号で書かれているため、固定シードの頃から画面の並びとはずれていた。270 件を原稿で言い換えるより、並べ替えの瞬間に対応表を持てる読み込み側で直すほうが、将来の並べ替えの変更にも耐える。
RESULT
全問で解説中の記号が画面の選択肢に収まることをテストで検算した。「選択肢 A と B」「options A, B and C」のような並記も読み替え対象にした。うまくいかなかった点として、解説中の記号を含む文をマーカーで引くと、並びが変わった次の機会には文字列が一致せず表示されない場合がある(保存された行は残る)。
v1.4.2 教科書の表は「縮めて収める」のをやめ、入りきらなければ横スクロールに回す
DECISION
ProseColumnWidth の minIntrinsicWidth が maxIntrinsicWidth と 同じ値を返すようにし、列を縮める前提そのものをやめた。入りきらない表は TableScrollView で横スクロールに回し、表の文字は本文より一回り小さくした。
WHY / 仮説
実機で 3 回「まだ列幅が潰れている」と指摘された。もとは列幅の下限を「自然な幅の何割」で 指定して縮みすぎを止める方式で、3 割→5 割→3 割と調整し直したが、表ごとに安全な下限が 違いすぎて 1 つの定数では両立しなかった(Docker の章の表を直そうと下限を上げると、 UML の関係一覧表がぎりぎり収まっていたのが横スクロールへ落ちる)。原因を Flutter の RenderTable まで遡ると、列を左から順に縮めていく処理順そのものに非対称がある と分かった。より左の列ほど「まだ削られていない不足分」を基準に多く削られ、右の列は左が削られた あとの小さくなった不足分を基準に削られるため、同じ flex 比でも左の列だけ潰れる。下限という 間接的な手段でこの非対称を打ち消すのは表ごとの綱引きにしかならないと判断した。
RESULT
Docker の章・UML の章の表は、内容の列挙も「代表例+残り○種」に短縮した。あわせて読み上げの 追尾が画面外へ連れ去ったまま黙って再開する挙動も直し、聴き始めるボタンは画面の下段から 上段へ戻した。無料キャンペーンの終了は、このビルドから有料化する計画だったが公開前に 判断を変え、2026-09-30 から 2026-10-31 へ延期した。
v1.4.1 読み上げは「鳴らす機能」ではなく「聴きながら使う画面」だと認め、止まる間・畳む・追尾の入切を足す
DECISION
読み上げの UI を作り直した。再生バーを畳めるようにし(畳んでも送りと追尾は残す)、 図とコードのかたまりでは 3 秒止めて字幕の欄に現物を出し、本文の追尾を入切できるようにした。 終了と最小化はバーの右上へ移し、字幕の言語の札には「字幕」と書いた。 聴き終えたときに戻る先も、最後の節の頭から聴いた範囲の先頭へ変えた。
WHY / 仮説
実機で続けて 7 件指摘された。フッターの境界線と再生ボタンが薄くてそこに操作があることに気づけない、 字幕の JA|EN が音声の切り替えだと読まれる、終了ボタンが速さの札の隣にあって設定の一部に見える、 畳めないので流しっぱなしのときに場所を取るだけになる、追尾を切る口が無いので読み返しても十数秒で引き戻される、 図とコードは「図。」「コード例。」としか読まれないので見る間もなく通り過ぎる(実測で 1.3 秒)。 どれも「鳴らす機能」としては動いているが、聴きながら本文を読む人の画面としては成立していなかった。
RESULT
3 秒の間は「読み切る時間」ではなく「続きを見たい人が一時停止を押す時間」と定義したので、 図とコードで長さを変えていない。止める位置は 2 度直した——かたまりに入った瞬間だと 「3 秒の沈黙 →『コード例。』」の順になり、出たあとだと次の文の 1 文字目が鳴ってから止まって 「フリーズしたよう」に聞こえた。いまは終わりの 100ms 手前で止め、位置を見る間隔も 40ms に詰めてある。 追尾を足したことで「目次にいる間は動かさない」という例外も要らなくなり、判断が 1 つ減った。
v1.4.0 収録の 4 割を占める基礎を、資格と並ぶ学習範囲として選べる場所に出す。アピールも二本柱に直す
DECISION

ヘッダーの試験の切り替えに「エンジニアリング基礎」を 3 つ目として並べ、選ぶと教科書・単語帳・問題集・分析までまとめて基礎に切り替わるようにした。あわせて nzw.jp と App Store の紹介文を「Claude 認定資格の対策アプリ」一本から「資格の対策と、その土台になるエンジニアリングの基礎」の二本柱へ書き換えた。

やめたのは、基礎をホームのカードからだけ入れる形。カードにあった「基礎を解く」「基礎の問題一覧」のボタンも外し、行き先を「この範囲に切り替える」1 つに寄せた。

WHY / 仮説

きっかけは実機での指摘——「クロードコード以外の教科書や問題が多くなっているのに、切り替えにも紹介文にも出ていない」。出荷物を数えると、そのとおりだった。

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 になっていた。

RESULT

切り替えを足す作業で、出荷物そのものが足りていないことが分かった。assets/textbook/foundations.json と glossary/foundations.json が存在せず、しかも読み込みに失敗すると例外を握り潰して空を返す実装だったので、そのまま出せば教科書タブが「準備中」・単語帳が空になるところだった。章の並びの定義に 1 行足して生成し、この壊れ方をそのまま捕まえる回帰テストを置いた。

基礎には合格ラインも本番の形式もないので、選んでいる間は推定スコアと模擬試験を出さない。ただしカードごと消さずに理由を書く——黙って消すと不具合と区別が付かない。

最初の実装では、切り替えても 33 章中 26 章(節で 7 割)が共通なので「変わった気がしない」という指摘が続いた。そこでホームに「いま学んでいる範囲」を出し、教科書の基礎の見出しに「どの試験に切り替えても同じ 26 章です」と断りを入れた。切り替えが何を変えないのかを書くほうが、何を変えるかを書くより効いた。

v1.3.4 残っていた英語の欠けをまとめて埋める。訳は差し込みのスクリプトと構造の検査で採り、原文の誤りは訳す側に直させない
DECISION

問題の解説と「覚えること」(1,125 問)、選択肢の理由(1,982 件)、CCAR-P の教科書 7 章、単語帳の見出し 69 語の英語を一度に埋める。

訳は原稿を書き出し直さない差し込みのスクリプトで入れ、数えられるもの(日本語の混入・表と行とコードの数・項目数・日本語の欄が変わっていないこと)で機械に検査させてから採る。

訳す途中で見つけた原文の誤りは直させずに根拠つきで報告させ、公式ドキュメントで確かめてから直す。

WHY / 仮説

英語表示でも解説はほぼ全問が日本語で、「Japanese only」の注記つきだった。CCAR-P の教科書の英語版は図と表を省いた要約で、検査にかけると 23 節で構造が日本語版と合わなかった。

約 66 万字を並行で訳すと、書式の崩れや訳の抜けを人が読んで見つけるのは現実的でない。訳の途中で原文を書き換えると、日本語と英語のどちらが正なのか分からなくなる。

RESULT

3 試験 1,146 問・4,617 選択肢・教科書 256 節・用語 366 語のすべてに英語がそろった(122 ファイルとも検査の指摘 0、1,146 問を 320pt の幅に描いてはみ出し 0)。

訳の途中で原文の誤りが 20 件あまり見つかり、公式で確かめて直した(MCP の MRTR の正式名、キャッシュの前方一致の順番、プレフィルと temperature は現行世代で 400、フックの終了コード 0 の扱いなど)。

一方で、1 回の出力の上限(16,000 トークン)・通信の切断・利用上限で訳が 3 度止まり、差し込む前の分は失われた。

5 問ずつ差し込む形に直してからは失わなくなった。

v1.3.3 英訳は、日本語版と構造(見出し・コード・図・表の数)が一致するかを機械で突き合わせてから採る
DECISION

日本語だけだった 7 章 43 節を章ごとに並行で英訳し、仕上がりは人の目の前に機械の検査を通す——英語欄に日本語が無いこと、見出し・コード・図・表の数が日本語版と一致すること、日本語の本文を触っていないこと。

検査は既存の英語版にも掛けた。

WHY / 仮説

章ごとに別々に訳すと、表を 1 つ落とす・図を段落に言い換える、といった欠けが節ごとに起き、読み比べないと気づけない。数えられる構造だけでも揃っていれば、欠けは「数が違う」で必ず見つかる。

英訳は原文を 1 文ずつ読み直す作業なので、原文の誤りも拾えると見込んだ。

RESULT

既存の英語版に 3 か所の欠け(JSON-RPC の図、LangGraph のコード、ツールループの図)が見つかり補った。

原文の誤り 9 件(デイリースクラムの目的、PMBOK の版、重複を消す順番、PKCE の理由、UML の終了状態の記号など)を問題・用語集までそろえて直した。

図の分岐の文字はテスト用フォントでは 12 か所はみ出して見えたが、実機に近いフォントで描き直すと本当にはみ出すのは 1 か所だけだった。

CCAR-P の 7 章の英語版は要約版で、図と表が欠けていることも同じ検査で分かったので、次に直す。

v1.3.2 教材は、最初から日本語と英語の両方で作る。日本語だけの章は前例ではなく欠けとして扱う
DECISION
新しい章は、本文・概要・用語・問題(問題文から解説・覚えることまで)・読み上げの音声を、最初から日本語と英語の両方で作る。先に足した本文が日本語だけの 7 章 43 節も、順に英訳する。
WHY / 仮説

PdM・PMM の章の骨子で、直近の 3 章(SQL で数える・FastAPI・プロジェクト管理)に合わせて「日本語だけ」を提案したところ、「日本語だけはだめ」と明言された。

直近の章が日本語だけだったこと自体が欠けで、それを前例として次の章に引き継ぎかけていた。英語の本文が無い節は英語の音声も作れないので、英語を後回しにすると音声まで後回しになる。

解説まで英訳してみて、英語表示の解説シートが訳の有無にかかわらず「日本語のみ」と注記していたことにも気づいた。

RESULT

新しい章は 7 節・問題 21・用語 17・音声 16 本(日本語 24 分・英語 21 分)をすべて両言語で出した。「日本語のみ」の注記は訳の無い問題でだけ出すように直した。

既存の 43 節の英訳は v1.3.2 の後に章ごとに進める。

v1.3.1 教材の主張は、出典のページで根拠の一文を見つけてから出す
DECISION
節を書いたあと、出典 25 件を 1 件ずつ開き、主張ごとに根拠の記述を探す工程を挟んだ。見つからない主張は、出典を替えるか言い方を弱める。URL が 200 で開けるだけでは通さない。
WHY / 仮説

最初の下書きは「GraphQL はエラーでも HTTP 200 を返す」「ブラウザは WebSocket の接続を CORS で止めない」と書いていた。

どちらも広く言われているが、前者は graphql.org では一部が取れた応答のときだけで、実行前の検証で弾かれたものはふつう 400。

根拠にするつもりだった GraphQL over HTTP の草案からは、該当の節が 2026-07 に削除されていた。

後者は OWASP にも書かれていなかった。出典の URL が生きていても、主張を支えているとは限らない。

RESULT

25 件のうち、主張の書き換えが 4 件(GraphQL の 200・CORS の言い方・nginx の proxy_http_version 1.1 は 1.29.7 より前でだけ要る・Redis の Pub/Sub は届けっぱなし)、URL の差し替えが 4 件。

CORS の件は、他サイトのページから接続を張れること(PortSwigger)と、断るのはサーバーの仕事(RFC 6455)の 2 つに言い換えた。

v1.3.0 聴き始める入口は、読む場所のすぐ隣にも置く
DECISION
章の目次の節の行に、その節を鳴らす再生ボタンを置いた。押しても本文へは移らず、目次を開いたまま鳴り始める。鳴っている節では一時停止に変わる。音声を持たない節には札ごと出さない。
WHY / 仮説

入口は「章の画面の下端」に集約したはずだったが、目次から特定の節を聴くには本文を開いて下端を押す 2 手が必要だった。行にはヘッドホンの絵と長さが出ていたので「音声がある」ことは分かるのに、そこからは始められない。

状態の表示を押せるものに変えれば 1 手で済む、と実機で指摘された。押せることを示すためにヘッドホンを再生の三角へ変えている(絵が状態の表示に見えると、誰も押さない)。

RESULT

目次から 1 手で鳴らせるようになった。本文へ連れ出さないので、耳で聴きながら目次で現在地を見る、という使い方が崩れない。

回帰テストは「節の行の札を押すと、その節から鳴る」「鳴っている節の札は一時停止になる」「音声の無い節には札を出さない」の 3 本。

v1.3.0 SQL は「どう作るか」と「数えた数字が合っているか」で章を分ける
DECISION

既存の「データベースの基礎」に足さず、「SQL で数える(分析とデータ品質)」を別の章(7 節)として新設した。出題ドメインも分けて章末テストを別勘定にした。

粒度と JOIN のファンアウト・重複の検出・ウィンドウ関数・LAG での期間比較・データ品質の 4 点に加えて、再実行できる取り込み(at-least-once の Webhook が題材)と、個人情報を含む検証環境の作り方までを 1 つの章に入れている。

WHY / 仮説

実務で詰まるのは SQL の文法ではなく「1 行が何を表すか」の取り違えで、JOIN で分母が壊れる・二重取り込みで件数が倍になる・LAG が 1 か月前ではなく 1 つ前の行を指す、という形で出る。

どれもエラーにならず、数字だけが静かに間違う。ところが既存の章は「どう作り、どう速く引くか」に寄っていて、この話がどこにも無かった。

同じ章に足すと、設計を読みに来た人が分析の話に当たり、分析を読みに来た人が実行計画の話に当たる。読む理由が違うものは章を分ける、という基礎トラックの方針をそのまま当てた。

重なる話(JOIN の種類・NULL の比較)は既存章に置いたまま、新章からは指すだけにしている。

RESULT

教科書 7 節・問題 26 問・用語 15 語。比重 5pt は既存 4 ドメインから 1〜2pt ずつ削って捻出した(合計 100 を維持)。

実機で確かめる過程で、3 列の表が iPhone 幅で崩れること、シーケンス図の矢印の文言が 2 行を超えると切れること(INSERT ... ON CONFLICT DO NOTHING の NOTHING が消えていた)が分かり、原稿側を直した。

読み上げは日本語 10 節ぶんを作って配信済み。

v1.2.0 本文の言語を表示言語と別に持つのをやめ、ヘッダーの JA / EN は画面ごと切り替える
DECISION

本文(問題文・選択肢・教科書・用語)の言語を、アプリの表示言語とは別の設定として持つのをやめ、1 つにまとめる。ヘッダーの JA / EN は、設定画面の「アプリの表示言語」と同じ設定を書き換え、ボタンや見出しも本文と一緒に切り替える。

設定画面の「本文の言語」は外す。本文だけ英語にしていた人の選択は、起動時に 1 度だけアプリの言語として引き継ぐ(表示言語と同じなら何もしない)。

同じ回に、読み上げの入口を節の本文の頭から画面の下端へ移し、目次から章をはじめから聴くと章の概要 → 第 1 節の順に鳴らすようにした(概要の音声は 37 章 × 日英で新しく作った)。

WHY / 仮説

2026-09-19、英語にした目次のスクリーンショットを添えて「英語表記にしているのに日本語表記が大量にある」と言われた。

本文の言語を分けたのは v1.1.0 の頃で、本試験が英語のみなので「メニューは日本語のまま本文だけ英語」がいちばん多い読み方になる、という仮説だった。

ところが、ヘッダーの 1 タップで英語にした人が期待するのは画面ごと英語になることで、「本文だけ」は説明しないと伝わらなかった。

選択肢として「本文と並ぶ札だけ合わせる」も出したが、選ばれたのは画面ごとの切り替え。旧設定を黙って捨てると、英語で読んでいた人が更新した瞬間に日本語へ戻るので、引き継ぐことにした。

入口も「聴き始めるのは一度きりだから本文の頭で足りる」と判断していたが、同じ時期に「押すたびに画面の上まで指を伸ばすのが面倒」「第 1 節から聴くのに 3 手かかる」と指摘された。

RESULT

シミュレータで、「アプリは日本語・本文だけ英語」の状態から新しい版を入れると、ホームから英語で立ち上がった。

英語の目次は「About this chapter」「Resume reading」「Section 1」「Chapter test」まで英語で出た。

目次の入口を押すと章の概要(日本語 0:43、英語 0:36)が鳴り、終わると目次のまま第 1 節へ続いた。テストは全 624 本が通過。

「メニューは日本語、本文は英語」の読み方はできなくなった。それを望む人が出てきたら、設定に戻すかどうかをもう一度考える。

iOS の実機と Android ではまだ確かめていない。

v1.1.4 「続きから鳴らす」は節ではなく音声で見分け、言語を切り替えたら読んでいた段落の頭から鳴らし直す
DECISION

再生を押したときに「頭に戻さず続きから鳴らす」かどうかを、節の鍵ではなく同じ音声か(節・言語・指紋)で決める。違えば、いま見えている本文の言語で並びを組み直して鳴らし直す。

節の頭の「聴く」と画面下のバーの再生の両方が同じ判定を通す。鳴らし直す位置は節の頭ではなく、読んでいた段落に当たる段落の頭(引き当ては再生中の訳の欄と同じ関数。対応が取れない節だけ、同じ割合の位置を含む段落の頭)。

鳴っている最中に本文の言語を切り替えても、音はその場では変えない。あわせて、再生バーのボタンを 44pt 以上にし、予定を鳴らし終えたら最後の節の 0:00 に戻して止める。

WHY / 仮説

2026-09-17、「日本語で再生して停止し、JA から EN に変えて再生しても日本語のまま」と言われた。同じ節の日本語と英語は鍵が同じで、v1.1.0 から「同じ節なら続きから」の近道が鍵しか見ていなかった。

v1.1.3 で取りながら鳴らす作りをやめたときも、この近道は残っていた。直すだけなら頭から鳴らし直せば済むが、5 分の節の途中で言語を変えた人は、聞いていた段落を探し直すことになる。

その場で音を切り替える案は採らなかった。演習の画面でも同じ本文の言語を使うので、問題文を英語に変えただけで聞き流している音が途切れる。

同じ日に「バーのボタンが小さい」「聴き終えてもバーが右端のまま」とも言われた。聴き終えたあとの戻し先は並びの先頭ではなく最後の節にした。

先頭へ戻すと、節のタブまで最初の節へ連れ戻すため。

RESULT

Android エミュレータで、英語を 0:53 で止めて JA に切り替え、バーの再生を押すと、通知の題名が日本語の節名に変わり、同じ見出し(段階的開示)から日本語で鳴った。

シークバーを右端まで送ると 0:00 と再生の顔に戻り、押すと頭から鳴った。テストは 18 本足して全 597 本が通過。

iOS の実機とシミュレータではまだ確かめていない。段落の引き当ては英訳のある 211 節のうち 197 節で効き、残りの 14 節(訳で見出しから組み直した節)は割合で近い段落に落ちる。

v1.1.3 読み上げの音声は「取りながら鳴らす」をやめ、鳴らす前に 1 節だけ取り終えてから渡す
DECISION

再生ボタンを押した節は、設定画面のダウンロードと同じ取り手で端末の一時保存へ落とし切ってから、そのファイルを再生器に渡す。

取っている間は「音声を取得中 N%」を出す。鳴り始めたら次の 1 節だけを先に取って並びに足し、2 節先は取らない。

次の節が取れなくても鳴っているものは止めず、末尾で止まって再生を押すと取り直す。just_audio の LockCachingAudioSource に URL を渡す作りは、Web と置き場所を開けない端末の逃げ道にだけ残した。

WHY / 仮説

2026-09-17、「ダウンロードに時間がかかっているだけなのに、通信エラーの帯が出る」と言われた。

追うと、just_audio の中継(端末内の HTTP サーバ)が配信元から最初のデータが届くまで再生器に応答を返さず、Android の ExoPlayer は 8 秒で読み込み失敗にしていた。

その例外を「鳴らせなかった」として「通信を確かめて」の帯にしていたが、Dart 側の取得は誰も止めないので裏で最後まで落ち、押し直すと鳴る。

つまり帯の文言が事実と違っていた。ExoPlayer のタイムアウトを延ばす口は just_audio に無く、中継の作りも変えられない。

再生器に通信を待たせなければこの壁は消える。章まるごとを先に落とす案は、聴くのをやめた人の回線で数十 MB を落とすので採らず、1 節先までにした。

RESULT

回線を絞ったエミュレータで、押して 2 秒後に「Fetching audio 46%」、8 秒後に再生開始、「次の節へ」を 2 回押してどちらも即座に切り替わり、帯も ExoPlayer のエラーも出なかった。

ただし「最初の 1 バイトが 8 秒以上遅い」状況そのものはエミュレータの回線制限が効かず再現できていない。

その場合の保証はテスト側で、再生器に渡るのが file:// だけであることを見ている(narration_player_test.dart、just_audio のプラットフォームを偽物に差し替えて 12 本)。

v1.1.0 教科書の読み上げは端末で合成せず、手元で 1 度だけ作って配る。位置は推し量らず、かたまりごとに実測する
DECISION

教科書を OpenAI の TTS(gpt-4o-mini-tts、声は alloy)で手元で MP3 にして nzw.jp から配る。

アプリは URL を鳴らすだけで、鍵は開発機の .env にしか無い。端末から API を叩く案も、サーバにプロキシを立てる案も採らなかった。

本文は Markdown のかたまり(見出し・段落・表・図)1 つを 1 回の読み上げにして、MP3 のフレームのまま繋いで節 1 本にし、繋ぐ前に各かたまりの秒数を数えて「何秒から何番目のかたまりか」を索引に焼く。

再生中はこれを引いて、読んでいる段落を光らせる。日本語と英語を別々に作り、再生バーには読んでいる段落のもう片方の言語の訳を出す。

WHY / 仮説

鍵を Flutter に埋めないのはこのリポジトリの決めごと(LangBridge で鍵を漏らした事故がある)。プロキシなら鍵は守れるが、教科書の本文は変わらないのに再生のたびに合成して課金される。

1 度作れば、鍵は手元だけ・何度聴いても無料・一度聴いた節は通信なしで鳴る、の 3 つが同時に成り立つ。位置を実測にしたのは、節ごと 1 回で読ませて文字数で按分すると「図。」のような短いかたまりで必ずズレるから。

光る場所が耳と食い違うくらいなら、光らせないほうがまし。訳を並べるのは、本試験が英語のみで「UI は日本語・本文は英語」がいちばん多い読み方なので、英語の音を聞きながら日本語の意味を目で確かめる使い方に合わせた。

RESULT

日本語 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。

v1.0.2 教科書の章を「読む章」から「引く章」へ。ただし出典の URL は一括置換しない
DECISION

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 は置換しない。

WHY / 仮説

実機で使うときに知りたいのは「そのフラグの名前」「そのキーの綴り」なのに、章にはひとつも載っていなかった。読めば分かるが、引けない——公式ドキュメントを開き直すなら、章がある意味が薄い。

Claude Code は CCAR-F の出題比重で 20% ある最大級のドメインなので、ここが概念の説明だけで終わっているのは配分としても合っていない。

旧 URL を一括置換しない理由は別で、改名・統廃合されたページがある(/iam は新ドメインに無く、カスタムコマンドは skills に統合された)。

ドメインだけ機械的に差し替えると、301 で救われていたリンクが 404 になる。壊れていないものを壊す変更は、まとめてやる価値がない。

RESULT

1 章だけで +32,426 字(英文を含めると +80,000 字超)。作業中に副産物が 2 つ出た。

ひとつは強調チェックの誤検知——描いたあとの HTML に残る ** をそのまま数えていたので、Read(src/**) のような glob をインラインコードで書いた節が全部「強調が壊れている」に化けていた(47 件のうち 42 件)。

<code> の中を除いて数えるようにしてラチェットを 47 → 5 に下げた。もうひとつは「よくある誤解です」の向き——見出しで事実を言い切ってから「よくある誤解です」と続けると、その事実のほうが誤解だと読める。

日英 7 か所を「誤解の中身を先に言い切る」形に直した。無料キャンペーンで配る 3 本目のビルドなので、kFreeCampaignBuildBelow は 3 → 4。

v1.0.1 App Store 公開。アプリ名の誤りは日本語名ではなく英語ローカライズ側を、機能リリースを待たずに直す
DECISION

2026-08-27 に App Store(日本のみ)で公開した。公開後、英語ローカライズのアプリ名が Certra - AI Exam Prep になっているのを見つけた——Certly のタイポ。

日本語名(Certly - AI認定資格の対策)・バンドル ID(jp.nzw.certly)・ホーム画面の表示名はどれも正しいので、直すのは英語ローカライズの 1 フィールドだけ。

ただし公開済みバージョンの名前欄はロックされるため、次の機能リリースを待たず v1.0.1 としてビルドごと出し直す。Android は Play ストアを待たず、APK の直接配布から始める。

WHY / 仮説

審査に 13 日かかった(8/14 提出 → 8/27 公開)。承認メールの Submitted が 8/14 のまま動いていないので、これはリジェクトと再提出の往復ではなく、ひとつの提出が審査側で止まっていたことを意味する。

他社ブランド(Claude / Anthropic)の資格対策という題材が知的財産の確認に回されたと見ている。

この「いつ明けるか読めない」という性質が、無料キャンペーンを日付ではなくビルド番号で切っておいた判断を裏づけた——「9/30 まで無料」を日付で実装していたら、審査の明ける日が読めない以上、告知と実装が必ずズレていた。

名前のほうはストアの一覧に出る誤字で、機能の追加を待つ理由が無い。

RESULT

ビルド番号を +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)で更新を配るところまで同時にやった。

book このアプリから対策本を出す計画を取り下げ、Vol.3 は別テーマ(AI エージェント関連)で組み直す
DECISION

書名『Claude 認定アーキテクト Foundations 完全対策』と、目次・問題数・出題比重の掲載をすべて取り下げた。

シリーズ Vol.3 は資格対策ではなく AI エージェント関連のテーマで考え直し、書名も内容も未定のまま「2026年9月 刊行予定」だけを出す。

アプリのデータから書籍を生成するパイプラインは停止し、Certly 側のページからも書籍への導線を外した。

WHY / 仮説

「完全対策」を名乗る根拠は著者が受験して確かめたことにあるが、Claude 認定試験は Partner Network 所属組織の企業メールが要り、受験導線がまだ通っていない(下の未解決のこと)。

受験の見通しが立たないものを本の看板にすると、通らなかったときに中身ごと書き換えることになる。すでに手を動かして運用している領域= AI エージェントのほうが、シリーズの原則(実運用で下した判断だけを書く)を満たせる。

RESULT

書籍ページは中立な URL /book/vol3/ へ移し(旧 /book/ccar-f/ は転送のみ)、「決まっていること/これから決めること」の 2 枚構成に置き換え、表紙も「?」の仮画像にした。

シリーズの 3 つ目のスタンス(試験で固める側)も取り下げ、トップ・ハブ・Certly の各ページを同じ表記へ揃えた。刊行予定は 8 月から 9 月へ 1 か月後ろ倒し。

web Web 版は課金を積まず、AI ワークスペースのタブとして出す
DECISION

同じ Flutter のコードから Web 版を作り、AI ワークスペースに単語帳・DayGrid と並べた。この版には課金を積まない——全機能が最初から開き、購入の導線ごと画面に出ない。

「課金を積まない配布形態」を kFreeEdition という 1 つのフラグで表し、Web と --dart-define=FREE_EDITION=true のビルドが同じ扱いになる。

WHY / 仮説

ブラウザに App Store も Play も無いので、購入ボタンを置いても押せない行が並ぶだけになる。

動作確認用の解放(TestFlight 向けの PREVIEW_BUILD)とは別のフラグにしたのは、出荷したビルドを見たときに「確認用の解放が残っているのか、無料版として出したのか」を区別できなくなるため。

判定の差し替えは entitlementsProvider 1 か所だけにしてある。ゲートは 30 か所近くあり、画面ごとにフラグを見に行かせると必ずどこかが閉じたまま残る。

RESULT

ブラウザでも端末内 SQLite(drift の WASM 版)で動く。

取り込みの作りに 2 つ穴が見つかって直した——毎起動で 3 試験ぶん 5 MB の問題バンクを読んで捨てていた(内容ハッシュだけを載せた索引を先に読むようにした)のと、1 行ずつ書いていた(Web ではステートメント 1 本ごとにワーカーとの往復が入るので、まとめて 1 回にした)。

どちらもネイティブでは見えていなかった無駄で、Web に出したことで表に出た。

pricing 月額サブスクを採らず、資格ごとの買い切りにする
DECISION
無料で試せる枠+資格ごとの買い切りという構成にした。月額課金は採らない。価格と無料枠の範囲は未定で、ストア公開時に確定する。
WHY / 仮説

月額課金は「使い続けさせる」ことが収益になる。これは zerohalf の方針——答えを渡さず、ユーザー自身の力を育てる——と正面から衝突する。

資格対策アプリのゴールは「受かって、二度と開かなくていい状態」にすることなので、受かったら払わなくていい形しか整合しない。

RESULT
売上は読みにくくなるが、訴求としてはむしろ強い。原価が発生する AI 機能(類題生成・追質問)だけは消耗型クレジットに分離し、失敗時は返還する。
naming アプリ名に「Claude」を冠さない
DECISION
中立名 Certly+サブタイトルで運用する。アプリ内・ストア説明・書籍の 3 箇所に「Anthropic 非公式」を明示する。
WHY / 仮説
「Claude」を冠した名前は商標上のリスクがあり、App Store の審査でも引っかかりやすい。対策教材としての記述的な使用は通常問題ないが、公式だと誤認させないことが前提になる。
RESULT
アプリのホーム画面下部に免責を常時表示している。「問題はすべて公開されている試験ガイドと公式ドキュメントをもとに作成したオリジナルであり、実際の試験問題ではありません」まで書く。
transparency 「なぜ今この問題が出たか」を毎回見せる
DECISION
出題選択の重み(切迫度・苦手さ・放置期間・優先度など)の内訳を、そのまま画面に表示する。
WHY / 仮説
適応出題はブラックボックスになりやすく、「なんか同じ問題ばかり出る」と感じた瞬間に信用を失う。理由が見えれば、出題順に納得して従える。
RESULT
副次的に、自分の弱点がどこかを説明なしで理解できるようになった。分析画面を開かなくても弱点が伝わる。
pipeline アプリを正とし、書籍はそこから生成する(一方通行)
DECISION
問題・教科書・用語集の原本は YAML で持ち、検証して assets/*.json を作る。書籍側はこの JSON から原稿を生成する。依存の向きはアプリ → 書籍の一方通行に固定した。
WHY / 仮説
同じ内容を 2 箇所で手管理すると必ずズレる。どちらかを正にするしかない。日々直すのはアプリ側なので、アプリを正にした。
RESULT

本とアプリの内容が構造的に一致する。「本は地図、アプリは反復」という売り方が、実態を伴った主張になった。

※ 2026-08-21:書籍側を白紙に戻したため、このパイプラインは現在停止中。アプリ単体の運用には影響しない。

architecture SRS のコアは純 Dart に隔離する
DECISION
lib/domain/srs/ は drift も Flutter も import しない。永続化先は drift のみに一本化する。
WHY / 仮説
間隔反復と能力推定は間違えても気づきにくい部分なので、UI や DB なしでテストできる形に隔離しておきたかった。
RESULT
テスト 23 ファイル・271 件。出題選択とスコア推定を単体で回せている。
Contents

収録範囲

問題数は v1.3.4 時点。

CCAR-F(Foundations)356 問/5 ドメイン。公式ブループリントの比重に合わせて配分
CCAR-P(Professional)214 問/7 ドメイン
エンジニアリング基礎576 問/27 ドメイン。試験範囲外なので別 exam として分離した
追加予定CCDV-F / CCAO-F を同スキーマで追加
Milestones

これまでの歩み

v1.9.02026-10-14

問題が 3,208 問に(易しい問題・比重の補正)/正解が最長の偏りと断定語・理由節の是正/音声ドリルの考える時間 30 秒・問題数 3〜300・要点の読み上げ(ビルド 33)

v1.8.02026-10-11

音声ドリルに選択肢・カウントダウン・「すぐ答えを見る」/始めている間は画面を移れない/範囲を選ぶシート(一括操作・選択数)/ホームの「前回の続き」(ビルド 31)

v1.8.02026-10-11

音声ドリル(問題と答えの読み上げ・考える間・二言語・問題番号)/下タブを「ホーム・教科書・演習・分析・設定」にまとめ直し/ホームの「続きを聴く」とお知らせ/「演習」の上に範囲の切り替え(ビルド 28)

v1.7.12026-10-10

節の補助(場面・分かること・ポイント・ひとこと・つまずき)の読み上げ・項目スキップ・アコーディオン/鳴っている場所の動く波形と再生バーのボタン拡大/英語の字幕欄の見出しを欄の言語で出す

v1.7.02026-10-10

節の学習補助(場面・分かること・ポイント・ひとこと・つまずき・覚える語・確認クイズ)/考えてみよう・用語タップ・用語カードの復習/単語帳 1,265 語と全章の書き直し・読み上げの作り直し

v1.6.12026-10-03

途中で切れていた音声を作り直し、同じ壊れ方を捕まえる検査を追加/新章「SQLite を本番で使う」(日英・音声つき)/Claude Code カラーの配色を作り直し、2 列の表を 1 画面に収め、章の見出しを番号つきの全幅の行に(ビルド 24)

v1.6.02026-10-03

さわって覚える体験モード(選択肢で進む疑似 Claude。台本 8 本・全員無料)/「Claude 本体の機能」4 節と「品質と情報セキュリティのマネジメント(ISO・ISMS)」6 節を日英と音声つきで追加/関連の練習問題 32 問を基礎の練習セットへ

v1.5.02026-10-02

Claude Code のアプリ・Skills の新章 2 つ、教材に「試験に出るか・いつの時点か」の札、既存 3 章の照合と修正/教科書の目次(上段・見出し・語での絞り込み)とホームの新着カード/聴き終えたら声で知らせる

v1.4.32026-10-02

選択肢の位置を出題のたびに変え、解説の記号参照は画面の並びへ読み替え/問題文と解説の選択メニューに単語登録・Google 検索・マーカーを追加/問題文の版名・用語に説明を足し、MCP の版を日付として読める表記へ

v1.4.22026-09-28

教科書の表を縮めず横スクロールに回す設計へ変更/読み上げの追尾が画面外で黙って再開しないように/聴き始めるボタンを上段へ戻し、初回取得も自動で取り直す/無料キャンペーンを 10/31 へ延期

v1.4.12026-09-24

読み上げの再生バーを畳めるようにし、送り・追尾の入切・終了を残す/図とコードのかたまりで 3 秒止め、字幕の欄に現物と残り秒数を出す/試験の切り替えが何を変えるのかをホームに書き切り、章の一括操作に確認を足す

v1.4.02026-09-23

ヘッダーの切り替えに「エンジニアリング基礎」を足し、選ぶと教科書・単語帳・問題集までまとめて切り替わるように(基礎向けの出荷物も新設)/基礎では合格ラインが無いので推定スコアと模擬試験を出さない/nzw.jp と App Store の紹介文を二本柱に直し、古くなっていた数値を全面更新

v1.3.42026-09-22

全問の解説・覚えること・選択肢の理由を英訳(1,146 問)/CCAR-P の教科書 7 章を全訳し英語の音声を作り直す/単語帳の見出しを英語でも出し、訳で見つかった原文の誤りを直す

v1.3.32026-09-22

日本語だけだった 7 章 43 節を英訳し英語の読み上げも付ける(教科書の全節が両言語に)/英訳で見つかった原文の誤り 9 件を問題・用語集までそろえて直す/既存の英語版の図とコードの欠け 3 か所を補う

v1.3.22026-09-22

「プロダクトとマーケティングの分析(PdM・PMM の視点)」の章を新設(7 節・問題 21・用語 17、すべて日本語と英語、読み上げも両言語)/解説シートの「日本語のみ」の注記を訳の無い問題だけに/出典 27 件の根拠を確かめ主張 13 件を直す

v1.3.12026-09-21

「REST 以外の選び方(GraphQL・gRPC)」「WebSocket を本番で動かす」の 2 節を追加(問題 6・用語 5・読み上げ)/用語集の並びが語を足すたびに崩れていたのを直す/出典 25 件の根拠を 1 件ずつ確かめる

v1.3.02026-09-20

「SQL で数える」「FastAPI で API を書く」の 2 章を新設(各 7 節)/基礎の問題を 53 問追加/目次の節の行からその場で読み上げを始められるように

v1.2.02026-09-20

目次の章の概要を日本語・英語で読み上げる(37 章 × 2 言語)/聴き始める入口を画面の下端へ、再生中の文章から読んでいる場所へ移れる/JA / EN を画面ごとの切り替えに

v1.1.42026-09-18

一時停止して本文の言語を切り替えたら、その言語で読んでいた段落から鳴らし直す/再生バーのボタンを 44pt 以上に/聴き終えたらバーを 0:00 に戻す

v1.1.32026-09-17

読み上げの音声を鳴らす前に 1 節だけ取り終えてから渡す(回線が遅いだけで「通信を確かめて」の帯が出ていた)/取得中は進み具合を出す/鳴らしながら次の 1 節を先読み

v1.1.22026-09-16

教科書の誤り約 60 件を問題・用語集・音声ごと直す/Claude Code の章を 3 章に分ける(31 節 → 24 節)/章の目次タブと、入りきらない表の横スクロール

v1.1.12026-09-13

読み上げ音声を設定画面から言語ごとにダウンロードして通信なしで聴けるようにする/背面に回ったら止め、戻ったら続きから/ダウンロード分はバックアップから外す

v1.1.02026-09-13

教科書の読み上げ(日本語 239 節・英語 211 節、alloy で事前生成して nzw.jp から配信)/読んでいる段落を光らせ、再生バーに訳を出す/聴く範囲(節・章・教科書)と背面再生

v1.0.22026-09-02

Claude Code の章を 16 → 31 節に増補(CLI・設定・フック・MCP・モデル・CI)/出典を移設後の code.claude.com へ/強調チェックの誤検知を直しラチェットを 47 → 5

v1.0.12026-08-30

英語ローカライズのアプリ名の誤り(Certra → Certly)を直して再提出/無料キャンペーンのカットオフを +3 へ連動/Android APK の直接配布を開始

v1.0.02026-08-27

App Store で公開(日本のみ・審査に 13 日)。2026-09-30 まで全機能を無料で開放

v1.0.02026-08-11

Web 版を公開し AI ワークスペースに載せる(課金なしの全機能版)/バンク取り込みを索引+一括書き込みに/起動時の無駄読み 5 MB を削除/App Store へ提出

v0.10.12026-08

最上位資格 CCAR-P を追加/模擬試験モードと学習計画を実装

MVP2026-08

Flutter+drift+FSRS-5+適応出題/演習・解説・分析/完全オフライン

plan2026-07

企画。「まず自分が合格する。合格した後に有料アプリとして出す」を前提に据える

Roadmap / Open Questions

未解決のこと