公開記事 /spacex-s1-summary のメイキング側のログ。145万字のHTMLを章単位で読み解いて1本の記事に落とすまでに、どこで詰まってどう抜けたかを、自分が手を動かした順に並べる。AI に何をやらせて、自分はどこで判断したのかを切り分けながら残す。
きっかけ
2026-05-20、SpaceX が SEC EDGAR に Form S-1 を提出した。4月に出ていた機密ドラフトが公開版に切り替わったタイミング。アクセッション番号は 0001628280-26-036936。
自分のなかで「書類を全章読解するスキル」を SpaceX のような実物のIPO書類で一度通してみたかった。Form S-1 はリスクから財務諸表まで全部入っている。途中で「ここは飛ばす」をやらずに、最初から最後まで章単位で読み切る、というのが今回のゴール。
EDGAR からの取得で詰まった
最初に WebFetch でアクセスしようとしたら、403 が返ってきた。SEC は User-Agent でアクセス元を見ているので、汎用クローラはブロックする。
CLAUDE.md のルール通り、まず agent-browser にフォールバックした。
agent-browser open "https://www.sec.gov/Archives/edgar/data/1181412/000162828026036936/"
これも EDGAR の「automated tools detected」ページに飛ばされた。agent-browser は自分のログイン済み Chrome に繋がっているはずなのに、SEC は別の検出ロジックを使っているらしい。
SEC公式のアクセスガイドを見直して、「個人を特定できる連絡先入り User-Agent をセットしろ」という指示に従って curl を直接叩いた。
curl -A "keikomatsu keikomatsu@eurekapu.com" -o spacex-s1.htm \
"https://www.sec.gov/Archives/edgar/data/1181412/000162828026036936/spaceexplorationtechnologi.htm"
これで一発で取れた。本体は PDF ではなく HTML 形式。spaceexplorationtechnologi.htm、サイズ 11.8MB、28,107行。インライン XBRL タグ込み。
PDF 前提でツールを組んでいたら詰まっていた。S-1 のような大型書類は HTML 提出が標準なので、ここで方針を切り替えた。
テキスト化
XBRL タグが地の文に混ざっていて、grep が効かない。pandoc でも変換できるが、BeautifulSoup で XBRL タグを剥がして純テキストに落とす方が事故が少ない。
from bs4 import BeautifulSoup
html = open("spacex-s1.htm", encoding="utf-8").read()
soup = BeautifulSoup(html, "lxml")
text = soup.get_text("\n")
落とした結果は 145万字、28,107行。これを章単位に切り出していく。
章境界マップを行番号で作った
145万字を頭から流し読みすると確実に集中力が切れる。先に目次を抜いて、「章 → 開始行番号 → 終了行番号」のマップを作った。
| 章 | 行範囲 |
|---|---|
| Prospectus Summary | 865 – 2553 |
| Risk Factors | 〜 |
| MD&A | 〜 |
| Business | 〜 |
| Management / Compensation | 〜 |
| Underwriting | 〜 |
| Financial Statements | 〜 |
| Notes(Related Party / Subsequent Events 含む) | 〜 |
このマップを作ったあとは、章ごとに範囲を指定して Claude Code に読解させた。「spacex-s1.txt の 865〜2553 行を読んで、Prospectus Summary のポイントを構造化して」と頼む形。145万字を一度に流し込まず、章単位に分割して読ませるのが安全だった。
章別読解で次々に出てきた開示
Prospectus Summary を読み始めて30分くらいで、「これは普通のIPOではない」と分かった。順に出てきた衝撃ポイントを並べる。
- **Cursor (Anysphere) を
60B インプライドエクイティで買収オプション**、解約時10B termination - Anthropic 向け月
1.25B × 36か月 = 約45B のクラウドコンピュート契約 - Class A / Class B デュアル議決権で Musk が議決権 85.1% を掌握
- Nasdaq + Nasdaq Texas デュアル上場、ティッカー "SPCX"
- xAI(2026-02-02取得)と X(旧Twitter、xAI経由)を遡及取込、上場対象は3社統合体
Risk Factors 22項目、MD&A、Business、Management/Compensation/Stockholders、Underwriting、Financial Statements、Note 18 Related Party、Note 21 Subsequent Events まで章単位で全部カバーした。途中で「もういいか」と止めたくなる箇所が何度かあったが、章マップを目で追って残量を確認しながら進めた。
中間報告でゴール条件 hook が発動した
途中、ある章を読み終えた段階で「ここまでで一旦まとめますか?」と中間報告を出した。そこへユーザーから「はい、全ての章をまとめてください」と返ってきた。Stop hook 経由のゴール指示として届いたので、自分のなかで「途中で止めない」を確定させて、残りの章を全部読み切るモードに切り替えた。
中間報告の段階で止まらなかったのは、この指示が来たから。逆に言うと、指示が無ければ「Underwriting あたりで力尽きていた」可能性があった。
公開記事化
読み終わった内容を apps/web/content/2026-05/2026-05-22/spacex-s1-summary.md に落とした。公開判定で進めた。タイトルは「SpaceX S-1 全章まとめ — SpaceX + xAI + X(旧Twitter) の3社統合体としてNasdaq上場(ティッカー SPCX)」。
ここで終わったつもりだったが、表示確認をしたら別の問題が出た。
KaTeX の $ 衝突問題
公開した記事をブラウザで開いたら、本文の 「$18.7B」「(2.6)B」「Connectivity」「(Starlink)」「PwC LLP」 がセリフ系の数式フォントで描画されていた。明らかに普通の本文と違う見た目。
原因はすぐに分かった。Nuxt Content の MDC が $...$ をペアで拾って KaTeX のインライン数式として解釈している。本文中に $18.7B と $25B のようなドル記号が大量にあったので、勝手にペアを組まれて「18.7B ... 25B の間」を全部数式扱いにされていた。
awk の \$ 置換でやろうとしたら、エスケープが効かずに本文が壊れた。Python で確実に置換した。
text = open(path, encoding="utf-8").read()
text = text.replace("$", "$")
open(path, "w", encoding="utf-8").write(text)
$ を HTMLエンティティ $ に一括変換。KaTeX のスキャナは $ を直接見ているので、エンティティに変えればペアと認識されない。ブラウザ表示上は普通の $ に戻る。
ログの末尾だけ見て「直った」と早合点したくなったが、スクショで初めてフォントが正しいセリフ系に戻ったのが確認できた。表示確認をサボらない、というのを今回いちばん体に刻んだ。
dev server watcher 問題
Python で本文を書き換えた直後、dev server が記事を 404 で返す場面があった。frontmatter は健全。SQLite インデックスも壊れていない。dev server の watcher が「ファイルが更新されたこと」を見失っているだけ、というのが見た目から分かった。
復旧は touch でタイムスタンプを叩き直すだけ。
touch apps/web/content/2026-05/2026-05-22/spacex-s1-summary.md
これで re-index がトリガーされて記事が復活する。この watcher 落ち、1日のあいだに何度も再発した。Python で直接書き換えると watcher が拾い損ねる、という現象として記憶しておく。
テーブル日本式並び替え
公開記事には4つの数値テーブルを入れた。連結業績、BS 資産、BS 負債、CF。最初は S-1 原本の順序に従って「右が古い」米国式で並べていた。ユーザーから「日本式に並び替えて」と指示が入った。
日本式は 左が古い → 右が新しい。FY2023 → FY2024 → FY2025 → Q1 2026 と時系列が左から右へ流れる形に4テーブル全部を並び替えた。
並び替えのあと、また watcher が記事を見失った。touch で復活させて、ブラウザでスクショを撮り直した。左から FY2023 → FY2024 → FY2025 → Q1 2026 の順に並んでいるのを自分の目で確認して終わり。
学び
- WebFetch → agent-browser → curl with User-Agent の3段フォールバックは EDGAR で機能する。403 で諦めない
- 145万字は章マップを先に作ってから読む。一括では集中が切れる
- KaTeX の
$衝突はスクショ確認でしか気付けない。ログ末尾だけ見て終わらせない - Python で本文を直接書き換えたら touch をセット。watcher が記事を見失う
- テーブルの時系列方向は最後に目視で確認する。並び替え指示が来てから「左から右へ流れている」をスクショで確定させる
実行は AI、画面の違和感を拾うのは自分、という分担は今回もそのまま機能した。フォントが違う、テーブルの順が逆、watcher が止まっている、これらは全部自分が画面を見たから気付いた。AI に章を読ませる速度は速いが、表示が壊れていることは AI からは見えない。