朝のダイジェストが 20 日のうち 8 日欠けていた — 503 の再試行と 13:00 の作り直し
AI ニュースの毎朝のダイジェストが直近 20 日で 8 日欠けていた。Gemini の 503 を 3 秒で諦めていたのを間隔を空けた再試行に変え、失敗した日を 13:00 に作り直し、応答が止まる場合の 2 分の上限とタグキャッシュも足した。
BLOG
個人開発した Web アプリの設計・技術選定・更新内容を、実際のリポジトリと計測値をもとに書き残すブログ。
全 38 件
AI ニュースの毎朝のダイジェストが直近 20 日で 8 日欠けていた。Gemini の 503 を 3 秒で諦めていたのを間隔を空けた再試行に変え、失敗した日を 13:00 に作り直し、応答が止まる場合の 2 分の上限とタグキャッシュも足した。
chronoscroll の月次更新が、特集が 1,927 件から 1,922 件に減って失敗した。原因は本文のハッシュを含むイベント id と、7 日で消える Actions cache。消えた id を同じ日の最も近い行に結び付け、対応を記録して直した。
2026-10-15〜11-02 に全リポジトリへ入った変更のまとめ。Next 16.4 の障害、古い RSC を読みに行く問題、全リポジトリのセキュリティレビュー、静的サイトの空の 404、chronoscroll の id の継続、sumai-log の CSP 本適用。
Vercel が書き換えていた Cache-Control が Workers ではそのままブラウザに届き、デプロイ後に古い RSC が消えたチャンクを読みに行って画面が崩れた。Worker のラッパーで書き換え、Next.js の 8 本に同じ修正を入れた。
Workers の静的アセットは /index.html を 307 で / に転送する。これをそのまま precache すると転送済みの応答が保存され、ナビゲーションには使えない。PWA 4 本のシェルのキーを / に揃え、sw.js に初めてテストを付けた。
script-src の無かった sumai-log に、毎リクエストの nonce と Report-Only で CSP を入れ、5 日間違反 0 件を確かめて本適用した。zod の eval の試し、Google マップの nonce、ワイルドカードを入れなかった理由をまとめる。
2026-10-26 の全リポジトリのレビューで共通して多かった指摘は、外部呼び出しにタイムアウトが無いことだった。SDK ごとの渡し方の違い、上限の値の決め方、再試行に乗せる形、CI の audit-gate が失敗を合格にしていた件を整理する。
chronoscroll の初期に作った特集 32 本を、日付だけでなく文言も主題の Wikipedia 記事と照らして見直した。968 件を確認し、128 件を直して 26 件を外した。どんな誤りがあり、どう確かめたか。
chronoscroll の要約に残っていた日付の断片や {{Cite の切れ端を検出器で数え、469 件を年ページの元の行と突き合わせて直した。種類ごとの件数に上限を置いて戻りを防ぎ、イベントでない行は新しい suppress.yaml で取り除いた。
CSS Atelier に、プレビューの指定した点でいちばん手前の要素を調べる当たり判定の採点を足し、z-index や pointer-events のレッスンを作った。WebGL が使えない端末で 3D のあるレッスンが進めなかった問題の直し方も。
更新
2026-10-11〜14 に全リポジトリへ入った変更のまとめ。Next.js 7 本の nonce CSP とページのキャッシュ、chronoscroll の特集 64 本と監査と表示の高速化、CSS Atelier の当たり判定、Service Anatomy の期限つきの記述、学習アプリと技の追加。
Next.js 7 本の CSP を、Worker が HTML ごとに nonce を付ける方式に揃えて Observatory を A+ 125 にした。'strict-dynamic' を付けない理由と、nonce の信頼境界、塞いだ SVG の script href の穴。
OpenNext で載せた Next.js 6 本が incrementalCache を設定しておらず、事前生成したページをリクエストごとに描画し直していた。ai-primer ではプリフェッチの一斉リクエストで CPU 上限(1102)に当たった。直し方と、キャッシュで出た 404 の言語の罠。
キャンペーンの終了日や月ごとの料率のように、いつか正しくなくなる記述を記事の frontmatter に expires として登録し、期限を過ぎたものをテストと freshness の一覧に出すようにした。最初に見つかった 2 件の書き直しまで。
トリッキングの技を 3D で見る tricking-3d を 27 技から 59 技にした。股関節の可動域・着地足の滑り・手をつく順番を数値のテストにし、移動する技はカメラが腰の軌跡を平滑化して追う。スマホでは注釈を番号の丸印にまとめた。
ACRO/FINDER の施設データを見直した。公式のページに書かれた事実だけを入れて薄い施設を 54 件から 5 件にし、200 を返しても中身が違うリンクを直し、閉鎖は公式の告知で判断した。座標と距離はテストで守る。
AI Primer は各レッスンに最終確認日を持たせ、90 日を過ぎた項目は月次のワークフローが知らせる。2026 年 10 月の見直しで変わっていた事実、一次情報で確かめられない出典の扱い、内部リンクと日付のテストで見つけた穴。
chronoscroll の特集を 7 本から 17 本にした。新しく書かずに既存のイベントを参照するだけで組み、Wikipedia の記事と日付や表現が食い違うイベントは外した。10 月のデータを巻き戻さない JSON の作り方、OGP、R2 への同期も。
Dependabot の更新 PR では通らなかった 2 つの理由(tsconfig の $app/tsconfig と古い cookie の override)、移行ツールの差分を全部読んだ理由、R2 に置く 27,453 ページのファイル名が変わらないことの確かめ方。
静的 HTML はビルド時の sha256 を _headers に、ルール上限に収まらないページは meta タグに、Worker を通る HTML は HTMLRewriter で毎回の nonce を。3 本の Observatory を A+ 125 にした方法の選び方と、CSP が 2 本重なった失敗。
CSS Atelier を 37 レッスンから 80 レッスンに増やしたときの採点の作り方。計算値と描画位置の使い分け、実ブラウザで記録した値を Node で再生するテスト、column-reverse で作るスクロール済みの状態、判定を見送ったもの。
2026-10-06 に source-map-js の勧告が全 lockfile に同時に当たった日の対応と、GitHub Actions のコミット SHA 固定、Dependabot の Actions 更新 PR 49 本の処理とグループ化、自動マージを minor/patch に限っている理由。
GLSL Atelier を 31 レッスンから 60 レッスンに増やした。描いた画素を 24×24 の点で採点し、シェーダーを JS に移して解答が通ることを Node で確かめ、ブラウザでは 4 通りの画面で全レッスンを回した。そこで見つかった初回実行のバグも書く。
acro-finder・chronoscroll・service-anatomy のモバイル Performance を 2026-10-06 に 90 以上にした記録。和文フォントと HTML の削減、フェードインで遅れた LCP、/ のリダイレクト、そして版とばらつきの扱い。
タイピングゲーム Snippet Sprint の問題を 118 問から 375 問に増やした。問題の文字列をそのまま処理系に通し、配布物はチェックサムで照合し、画面に収まるかも測った。確かめられなかったものも書き残す。
Next.js を OpenNext で載せたこのポートフォリオと acro-finder が、Workers 無料プランの CPU 上限で 503 を返した。原因の調べ方と、ページを静的アセットにして Worker を起動させない直し方、staticAssetsIncrementalCache の役目。
Lumen Bloom のモバイル Performance 45 → 99 までにやったこと。適応フレームレート、影パスの動的停止、段階的な初期化と compileAsync、タブ非表示で全停止。Skydial・Snippet Sprint の遅延読込とあわせて。
静的アセットの上限 20,000 ファイルに収まらない 27,231 ファイルを、イベント個別ページだけ R2 に置くことで無料枠のまま配信した設計。差分同期・プレビュービルドのガード・大量削除の安全弁について。
更新
2026-09-22〜10-06 に全リポジトリへ入った変更のまとめ。依存更新と ESLint 10、undici の脆弱性対応、axe 違反ゼロ化、UI 層のテスト、SHIG 2 巡目、Effect 4、chronoscroll の Workers 移行、Service Anatomy の新記事 8 本。
2026-09-30 GA の Effect 4.0 を、chronoscroll のビルドパイプライン・Somewhere Now の Cron・AI ニュースダイジェストの日次ジョブに同じ日に導入した記録。型付きの失敗、TestClock でのリトライ検証、Workers の CPU 上限との付き合い方。
このポートフォリオ自体の設計。npm registry・OSV・GitHub API から各アプリの状態を集め、ビルド時に静的化して Workers の CPU 上限を避けるまでの経緯と、セキュリティ列とバッジの意味の違い。
複数のアプリで繰り返し効いた手順。Three.js の動的 import、インライン polyfill の無効化、Next のフォント方針、CSP から unsafe-inline を外すこと、ビーコンに SRI を付けない理由、中央値判定の CI ガード。
CSS Atelier は constructable stylesheet、GLSL Atelier は readPixels と不透明オリジンの sandbox iframe、AI Primer はビルド時の Markdown 変換。「解説→記述→自動採点」を unsafe-inline なしで成立させた方法。
解剖スコア・確度3段階の技術構成・出典を frontmatter に持たせ、記事の整合性を CI で検証する仕組み。nonce CSP を捨てて全ルートを SSG 化し、Cloudflare Workers へ移すまでの判断も含めて。
確認ダイアログを取り消し通知に置き換える(57・54)、戻るで閉じる(59・60・82)、色だけに頼らない(96)、7mm のタップ領域(78)、寛容な入力(50)。コミットに番号を添えて 2026 年 9〜10 月に全リポジトリを 2 巡した記録。
ライブ配信は終わり videoId は変わる。カメラ定義と生存状態を分け、Cron が YouTube Data API で追いかける設計と、サブリクエスト上限・同時発火・waitUntil で失敗を飲み込む罠。
engine/lib を純関数に寄せて 100% の閾値を CI で強制し、2026-09-28〜10-01 に全リポジトリで UI 層にも jsdom + Testing Library の振る舞いテストと「実測値の 2 ポイント下」のゲートを足した経緯。書いて見つかったバグも。
2026-08-11 の Vercel 停止から始まった移行の定型手順と、_headers のカンマ連結・html_handling の 307・OpenNext の Cron ラッパー・nonce CSP・esbuild 未宣言・SITE_URL の localhost 化といった罠。