[{"data":1,"prerenderedAt":614},["ShallowReactive",2],{"content-/2026-05-27-diary":3,"all-pages-for-dir":612,"og-image-/2026-05-27-diary":613},{"id":4,"title":5,"body":6,"category":593,"description":594,"extension":595,"meta":596,"navigation":534,"ogImage":597,"path":598,"project_name":599,"published":600,"publishedAt":601,"seo":602,"stem":603,"tags":604,"todo":597,"unpublished":600,"updatedAt":597,"__hash__":611},"pages/2026-05/2026-05-27/diary-2026-05-27.md","2026年5月27日の開発日記 - 残骸9222リスナーを片付け、過去問と参考書をDBに流し込んだ一日",{"type":7,"value":8,"toc":576},"minimark",[9,14,18,22,29,32,37,53,59,91,102,105,109,112,116,127,135,137,141,144,148,167,175,177,181,184,188,203,211,213,217,224,228,239,247,249,252,474,476,479,517,519,523,549,551,554],[10,11,13],"h1",{"id":12},"_2026年5月27日の開発日記","2026年5月27日の開発日記",[15,16,17],"p",{},"朝から、起動するたびに固まるツールに足を止められた。「still connecting」の文字が点滅したまま、ブラウザを操る道具が一切生えてこない。数日前から続いていたこの詰まりの真因を、思い込みを一枚ずつ剥がして掘り当てたのが今日の入口だった。そこから先は、散らばっていたデータをひたすらDBへ流し込む一日になった——別アプリの過去問、自炊した参考書655ページ、そして「状態を上書きするな」という設計論を操作できる教材に仕立てる作業まで。",[19,20,21],"h2",{"id":21},"今日のタイムライン",[15,23,24],{},[25,26],"img",{"alt":27,"src":28},"タイムライン","/2026-05/2026-05-27/timeline-2026-05-27.png",[19,30,31],{"id":31},"今日やったこと",[33,34,36],"h3",{"id":35},"_1-chrome-devtools-mcp-が固まる真因を掘り当てたclaude-code-tools","1. Chrome DevTools MCP が固まる真因を掘り当てた（claude-code-tools）",[15,38,39,40,44,45,48,49,52],{},"数日前から、Claude Code 起動時に ",[41,42,43],"code",{},"chrome-devtools"," MCP が \"still connecting\" で固着し、",[41,46,47],{},"mcp__chrome-devtools__*"," が一切ロードされない事象が出ていた。最初は Chrome 136+ のデフォルトプロファイル制約だと思い込んでいたが、調べさせたら別物だった。ポート9222は LISTENING しているのに ",[41,50,51],{},"/json/version"," が HTTP 404 を返す——「ポートは開いているがDevToolsとして機能していないゾンビ」が真因だった。",[15,54,55],{},[56,57,58],"strong",{},"主な成果:",[60,61,62,70,80],"ul",{},[63,64,65,66,69],"li",{},"真因＝",[56,67,68],{},"前のデバッグChromeを閉じ損ねて残った「壊れた残骸の9222リスナー」の居座り","と特定。設定やChromeバージョンの問題ではなかった",[63,71,72,73,79],{},"全体再起動は不要で、",[56,74,75,78],{},[41,76,77],{},"/mcp"," の reconnect だけで復活","すると実証（当初「再起動必須」と書いたのは過剰断定だった）",[63,81,82,83,86,87,90],{},"issueメモを自己完結したクイックスタートに整備し、",[41,84,85],{},"apps/web/CLAUDE.md","・",[41,88,89],{},"windows.md"," にも追記。codex（gpt-5.5）でレビューして断定しすぎを修正、issueはクローズ",[15,92,93,96,97],{},[56,94,95],{},"詳細:"," ",[98,99,101],"a",{"href":100},"/chrome-devtools-mcp-zombie-port-recovery","Chrome DevTools MCP が \"still connecting\" で固まる真因は『残骸9222リスナーの居座り』だった",[103,104],"hr",{},[33,106,108],{"id":107},"_2-ある国家資格試験の過去問を-turso-db-に丸ごと移行misc-dev","2. ある国家資格試験の過去問を Turso DB に丸ごと移行（misc-dev）",[15,110,111],{},"別アプリに散らばっていた、ある国家資格試験の過去問JSONを Turso DB に全件コピーした。問題499・選択肢1992、解説や法令参照のネスト構造もJSON列でそのまま保持した。将来はCloudflare上のDBとして使っていく前提のメモも残した。",[15,113,114],{},[56,115,58],{},[60,117,118,121,124],{},[63,119,120],{},"スカラー値は列、ネストした解説・法令参照はJSON列、という方針で全データを保持",[63,122,123],{},"過去問10回分を全件格納し、HTTP接続でクラウド到達まで検証",[63,125,126],{},"バッチファイルのトップレベルが dict / 配列で混在していた問題に、両対応の分岐で対処",[15,128,129,96,131],{},[56,130,95],{},[98,132,134],{"href":133},"/exam-past-questions-turso-migration","ある国家資格試験の過去問データを Turso DB に丸ごと移して全文検索できるようにした",[103,136],{},[33,138,140],{"id":139},"_3-自炊した4分冊の参考書をocrして蔵書dbに取り込み章節単位に再構造化book-knowledge-base","3. 自炊した4分冊の参考書をOCRして蔵書DBに取り込み、章・節単位に再構造化（book-knowledge-base）",[15,142,143],{},"蔵書DBにこの分野の参考書が1冊も無かったので、自炊した市販の参考書（4分冊・合計655ページ）をyomitokuでOCRして取り込んだ。当初60分と見積もったが、GPU逐次処理が約1秒/ページで走り15〜20分で終わった。ページ単位640チャンクを、目次に沿って章・節単位74チャンクへ整理し直した。",[15,145,146],{},[56,147,58],{},[60,149,150,153,160],{},[63,151,152],{},"4分冊をそれぞれ独立した書籍として格納（図1181枚もリネーム）、横断FTS検索が章/節ラベルでヒット",[63,154,155,156,159],{},"サブエージェント経由で Embedded Replica の ",[41,157,158],{},"sync()"," がハングしたため、全ステップHTTP直接接続に切り替えて回避",[63,161,162,163,166],{},"クラウドだけ更新してローカルレプリカが陳腐化・破損（",[41,164,165],{},".db-info"," 欠落）したので、退避して約80MBを再DLし自動再構築",[15,168,169,96,171],{},[56,170,95],{},[98,172,174],{"href":173},"/textbook-ocr-to-knowledge-base","自炊した4分冊の参考書をOCRして蔵書DBに取り込み、章・節単位に整理し直すまで",[103,176],{},[33,178,180],{"id":179},"_4-状態-vs-イベントを操作して見比べる教材を実装mdx-playground","4. 「状態 vs イベント」を操作して見比べる教材を実装（mdx-playground）",[15,182,183],{},"farstepさんの「テーブルに状態を持たせてはいけない」を題材に、読むだけでなく操作して学べる教材を作らせた。会員データに「入会→利用停止→復帰→退会」を流し込むと、状態カラム上書き／イベント記録／状態テーブル分割の3設計が同時に更新され、履歴がどう残る／消えるかを見比べられる。",[15,185,186],{},[56,187,58],{},[60,189,190,193,200],{},[63,191,192],{},"監査の問い（いつ入会したか・何回停止されたか）に各設計が自分のデータだけで答えられるかを○×表で対比",[63,194,195,196,199],{},"ロジックは純粋関数（",[41,197,198],{},"app/utils/membershipState.ts","）に隔離し、Vueページは副作用シェルに徹する構成。ユニットテスト19件pass",[63,201,202],{},"技術内容のレビューも実施。「イベントソーシングの一言で済む」への反論（安価な設計の規律と重いアーキテクチャの混同を避ける）も差し込んだ",[15,204,205,96,207],{},[56,206,95],{},[98,208,210],{"href":209},"/state-vs-events-interactive-lesson","「テーブルに状態を持たせてはいけない」を、会員データを操作して3設計を見比べる教材に仕立てた",[103,212],{},[33,214,216],{"id":215},"_5-セキュリティレビュープラグインの有効化スコープを整理eurekapu-nuxt4","5. セキュリティレビュー・プラグインの有効化スコープを整理（eurekapu-nuxt4）",[15,218,219,220,223],{},"Claude が書いたコードを自動レビューするプラグインを導入しようとして、いったん手を止めて有効化スコープを整理した。結論は「ローカル一人運用なら ",[41,221,222],{},"/plugin install","（ユーザーレベル）だけで全プロジェクトに効くので、プロジェクトの settings.json は冗長」。settings.json が要るのは web版を使うか他人とリポジトリを共有する場合だけ、と切り分けた。",[15,225,226],{},[56,227,58],{},[60,229,230,233],{},[63,231,232],{},"有効化はユーザーレベルのみ・settings.json は作らず、ガイダンス2ファイルだけ作成",[63,234,235,238],{},[41,236,237],{},"server/api/"," の決済・認証ガードをレビュー観点に反映",[15,240,241,96,243],{},[56,242,95],{},[98,244,246],{"href":245},"/claude-code-security-review-setup","Claude Code のセキュリティレビュー・プラグインは、ローカル一人運用ならユーザーレベルだけで十分だった",[103,248],{},[19,250,251],{"id":251},"今日の試行錯誤",[253,254,255,277],"table",{},[256,257,258],"thead",{},[259,260,261,265,268,271,274],"tr",{},[262,263,264],"th",{},"#",[262,266,267],{},"テーマ",[262,269,270],{},"試したこと",[262,272,273],{},"結果",[262,275,276],{},"気づき",[278,279,280,298,317,335,352,368,385,400,421,440,455],"tbody",{},[259,281,282,286,289,292,295],{},[283,284,285],"td",{},"1",[283,287,288],{},"MCP固着",[283,290,291],{},"Chrome 136+ のプロファイル制約を疑う",[283,293,294],{},"外れ",[283,296,297],{},"9222は404を返すゾンビ。バージョン制約ではなかった",[259,299,300,303,305,308,311],{},[283,301,302],{},"2",[283,304,288],{},[283,306,307],{},"9222を解放しtemp profileでクリーン起動",[283,309,310],{},"成功",[283,312,313,316],{},[41,314,315],{},"webSocketDebuggerUrl"," 入りJSONが返る正常状態に復旧",[259,318,319,322,324,327,330],{},[283,320,321],{},"3",[283,323,288],{},[283,325,326],{},"全体再起動が必須と断定",[283,328,329],{},"訂正",[283,331,332,334],{},[41,333,77],{}," reconnect だけで復活すると実証。断定が過剰だった",[259,336,337,340,343,346,349],{},[283,338,339],{},"4",[283,341,342],{},"パースエラー",[283,344,345],{},"大量パス調査で履歴が肥大",[283,347,348],{},"頻発",[283,350,351],{},"「tool call could not be parsed」連発。履歴肥大が真因",[259,353,354,357,359,362,365],{},[283,355,356],{},"5",[283,358,342],{},[283,360,361],{},"1回ずつ小さく刻んで進める",[283,363,364],{},"回避",[283,366,367],{},"出力崩れが止まった。長い調査は刻むのが効く",[259,369,370,373,376,379,382],{},[283,371,372],{},"6",[283,374,375],{},"過去問移行",[283,377,378],{},"移行スクリプト初回実行",[283,380,381],{},"exit 1",[283,383,384],{},"トップレベルが配列の14ファイルで失敗",[259,386,387,390,392,395,397],{},[283,388,389],{},"7",[283,391,375],{},[283,393,394],{},"dict/配列どちらも処理する分岐",[283,396,310],{},[283,398,399],{},"外部由来データはトップ構造のばらつきを先に診断すべき",[259,401,402,405,408,411,414],{},[283,403,404],{},"8",[283,406,407],{},"OCR進捗",[283,409,410],{},"非TTYで進捗が見えない",[283,412,413],{},"不安",[283,415,416,417,420],{},"Pythonのブロックバッファリング。",[41,418,419],{},"-u"," で可視化",[259,422,423,426,429,434,437],{},[283,424,425],{},"9",[283,427,428],{},"蔵書再構造化",[283,430,431,432],{},"サブエージェントで ",[41,433,158],{},[283,435,436],{},"ハング",[283,438,439],{},"Embedded Replicaはバッチ/サブエージェントで固まる既知問題",[259,441,442,445,447,450,452],{},[283,443,444],{},"10",[283,446,428],{},[283,448,449],{},"全ステップHTTP直接接続に変更",[283,451,310],{},[283,453,454],{},"残り3冊はハング無しで完了",[259,456,457,460,463,466,469],{},[283,458,459],{},"11",[283,461,462],{},"レプリカ破損",[283,464,465],{},"クラウドだけ更新→ローカル陳腐化",[283,467,468],{},"破損",[283,470,471,473],{},[41,472,165],{}," 欠落。退避して再DLで自動再構築",[103,475],{},[19,477,478],{"id":478},"今日の学び",[60,480,481,490,499,505,511],{},[63,482,483,486,487,489],{},[56,484,485],{},"思い込んだ制約と実際の真因は違うことがある","。MCP固着は「Chromeのバージョン制約」だと決めつけていたが、真因は「壊れた残骸9222リスナーの居座り」。",[41,488,51],{}," が404という観測事実を見るまで、仮説を真因と取り違えていた",[63,491,492,495,496,498],{},[56,493,494],{},"断定しすぎず、実証して書き直す","。「全体再起動が必須」と書いたが、",[41,497,77],{}," reconnect だけで直ると実際に確かめられた。codexにも「因果を断定しすぎ」と突かれた。ドキュメントは実測で上書きするのが正しい",[63,500,501,504],{},[56,502,503],{},"会話履歴を肥大させない","。大量のファイルパスを履歴に流し込むと、ツール呼び出しの出力が崩れて「could not be parsed」が頻発する。長い調査は小さく刻むと回避できる",[63,506,507,510],{},[56,508,509],{},"Embedded Replica はバッチ/サブエージェントでハングする","。書き込みやFTSリビルドはHTTP直接接続が安全。そしてクラウドだけ更新するとローカルレプリカが陳腐化するので、退避→再構築の手順を覚えておく",[63,512,513,516],{},[56,514,515],{},"読む教材より、操作して見比べる教材の方が腹落ちする","。同じ操作を3設計に同時に流すと、履歴が残る／消えるの差が一目で出る。ロジックを純粋関数に出しておくとテストも楽だった（19件pass）",[103,518],{},[19,520,522],{"id":521},"明日やること任意","明日やること（任意）",[60,524,527,537,543],{"className":525},[526],"contains-task-list",[63,528,531,536],{"className":529},[530],"task-list-item",[532,533],"input",{"disabled":534,"type":535},true,"checkbox"," 過去問DBをCloudflare上のDBとして使う構成の検討（D1 連携 or Turso のまま）",[63,538,540,542],{"className":539},[530],[532,541],{"disabled":534,"type":535}," 蔵書DBに取り込んだ参考書を使った横断検索の使い勝手を試す",[63,544,546,548],{"className":545},[530],[532,547],{"disabled":534,"type":535}," 状態 vs イベント教材の最終ブラウザ動作チェック（パースエラーで途中までだった分）",[103,550],{},[19,552,553],{"id":553},"関連記事",[60,555,556,560,564,568,572],{},[63,557,558],{},[98,559,101],{"href":100},[63,561,562],{},[98,563,134],{"href":133},[63,565,566],{},[98,567,174],{"href":173},[63,569,570],{},[98,571,210],{"href":209},[63,573,574],{},[98,575,246],{"href":245},{"title":577,"searchDepth":578,"depth":578,"links":579},"",2,[580,581,589,590,591,592],{"id":21,"depth":578,"text":21},{"id":31,"depth":578,"text":31,"children":582},[583,585,586,587,588],{"id":35,"depth":584,"text":36},3,{"id":107,"depth":584,"text":108},{"id":139,"depth":584,"text":140},{"id":179,"depth":584,"text":180},{"id":215,"depth":584,"text":216},{"id":251,"depth":578,"text":251},{"id":478,"depth":578,"text":478},{"id":521,"depth":578,"text":522},{"id":553,"depth":578,"text":553},"diary","Chrome DevTools MCP が固まる真因（残骸9222リスナー）を掘り当てて reconnect だけで直すと実証し、ある国家資格試験の過去問と自炊した参考書を Turso DB に流し込み、状態 vs イベントの設計教材を仕上げた一日。","md",{},null,"/2026-05-27-diary","daily-log",false,"2026-05-27T00:00:00.000Z",{"title":5,"description":594},"2026-05/2026-05-27/diary-2026-05-27",[605,606,607,608,609,610],"日記","Claude Code","Turso","OCR","Vue","データベース設計","FO30ZClFt_BOwAJw6tZwE_LurjZTtImkAfSzKgUXUO8",[],"https://log.eurekapu.com/og/blog/2026-05-27-diary.png?v=2026-05-27T00%3A00%3A00.000Z&title=2026%E5%B9%B45%E6%9C%8827%E6%97%A5%E3%81%AE%E9%96%8B%E7%99%BA%E6%97%A5%E8%A8%98%20-%20%E6%AE%8B%E9%AA%B89222%E3%83%AA%E3%82%B9%E3%83%8A%E3%83%BC%E3%82%92%E7%89%87%E4%BB%98%E3%81%91%E3%80%81%E9%81%8E%E5%8E%BB%E5%95%8F%E3%81%A8%E5%8F%82%E8%80%83%E6%9B%B8%E3%82%92DB%E3%81%AB%E6%B5%81%E3%81%97%E8%BE%BC%E3%82%93%E3%81%A0%E4%B8%80%E6%97%A5&author=Kei%20Komatsu&sig=fa67a8f8d7773ffc",1782528842946]