blog
下書きは、撤回済みの主張を持ち回る
書き溜めた記事が4本あった。開発中に踏んだ失敗をその場で下書きにして、予定日が来たら出す、という運用をしている。数日ぶんまとめて出そうとして、公開前に必須にしている外部レビューを1本ずつ回した。
4本すべてで指摘が出た。うち3本は軽いものではなく、そのままでは出せない種類だった。
いちばん効いたのは、自分のリポジトリからの指摘だった
一番きつかったのは、脱出率のバランス調整について書いた記事だ。
その記事は「自機のHPをどれだけ下げても脱出率が動かなかった。原因はHPではなく、敵の発射条件が古いままだったことだ」という話になっていた。書いた時点では、自分でもそう理解していた。
レビューが引っ張ってきたのは、自分のコミットログだった。1d3d541 のメッセージにこう書いてある。
「heroHp をどこへ振っても帯に入らなかった」は事実と違う。旧実装で下まで振り直すと 24 → 60.0%、36 → 85.0% が帯の中に在った。
つまり、記事が中心に据えていた主張は、この記事を書くより前に、自分で「嘘」として訂正していたものだった。訂正した記録はリポジトリに残っていて、下書きだけが訂正前の理解のまま止まっていた。
正しくは「HPでも帯には入れられた。ただし敵の弾2〜3発で死ぬ設計になるので採らなかった」までだ。結論(実装側を直した)は変わらないが、そこへ至る筋が違う。実際より強い主張で正当化すると、次に読んだ人が再検証しなくなる。同じことがコミットメッセージにも書いてあった。
この1本は、事実を1つ差し替えて済む話ではなかった。題も結論も書き直した。
誤りは4つの型に分かれた
4本ぶんの指摘を並べてみると、型が分かれていた。
ひとつは、採らなかった案の測定値を、採った案の結果として書いていたもの。コンテナの不具合を直したあとの脱出率を「81.7%に戻った」と書いていたが、修正コミット 386faaf が記録している実測は 0.9167 から 0.85 への変化だ。ではその 81.7 はどこから来たのか。実装計画の進捗メモに残っていた。「Task 3 + 敵を円の外へ押し出す」で 81.7%、と書いてある。検討して採らなかったほうの案の実測値だった。数字を打ち間違えたのではなく、隣の案の数字を持ってきていた。
ふたつめが、さっきの撤回済みの説明の再採用。これはもう1本でも起きていて、「当たり判定は1つの関数を3系統すべてが通る」と書いていた記事があった。その説明は、コンテナの不具合を直したのと同じコミットが「不正確になっていた」と明示的に撤回している。撤回したことを、記事だけが知らなかった。
みっつめは、数え方が実物と合っていないもの。「同じ形の検査が5本あった」と書いていたが、その5はテストの本数ではなく、守っている配線の数だった。読者がファイルを開いて数えると10件出てくる。
よっつめは、測っていないことを測ったように書いていたもの。2つの乱数器に別々の値を混ぜた話で、「相関が消えたことも実測で確認した」と書いていた。試験が実際に見ているのは、用途ごとの散らばりの幅が 1.0 より大きいことだけだ。前のバグが再発していないことは言えるが、独立までは測っていない。
日付を並べたら、予想と逆だった
ここまでは「書いてから出すまでの間にコードのほうが動いて、下書きだけが古くなった」という話だと思っていた。時間差の問題だと。
日付を並べたら逆だった。
下書き4本を追加したのは 744bbd4 で、2026-08-16 の未明。一方、3件の訂正はいずれもその3日前に終わっている。
386faaf(08-13 16:59)「3系統が1つの関数を通る」を撤回し、脱出率を 0.9167 から 0.85 と記録740bdbe(08-13 22:51)検査の「5」はテスト本数ではなく配線の分類数だと整理1d3d541(08-13 23:36)heroHp についての主張を「事実と違う」と訂正
下書きが置いてある間に古くなったのではない。訂正が済んだ内容を、その3日後に下書きへ書き込んでいた。
しかも 744bbd4 のコミットメッセージには「設計書と実コミットから数字を裏取りした」と書いてある。裏取りしたつもりで、裏取り先に無い数字を書いていた。81.7 は、そこに並べた実コミットのどれにも出てこない。
出どころは、設計書と一緒に置いてある作業中の進捗メモのほうだった。検討した案が全部書いてある。読めば筋は通っているが、通っているのは訂正前の筋だ。
grep できなかったのは、記事ではなかった
記事の Markdown は git の追跡下にあるので、git grep で普通に引ける。引けなかったのは 81.7 の出どころのほうだ。進捗メモを置いてある .superpowers/sdd/ には * の一行だけを書いた .gitignore がある。追跡されていないので、履歴をいくら検索しても出てこない。
08-22 の外部レビューが「81.7 は記事の中にしか無い」と結論したのも、この検索に頼ったからだ。出どころが追跡の外にあると、その数字は根拠が無いように見える。実際には根拠はあって、ただし別の案の根拠だった。
「参照先を変えたら、それを要約している文を全部直す」という規則は前に立てていた。実行手順のファイル7本が古い方針のまま残っていた事故を踏んで作ったものだ。今回はその手前で、要約する参照先のほうを間違えていた。作業中のメモは、確定した記録ではない。
自分では見つけられなかった
正直に言うと、これは自分だけでは捕まえられなかったと思う。
自分が書いた記事を自分で読み返すと、書いたときの理解のまま読んでしまう。「HPをどう動かしても効かなかった」という文を見ても、それが訂正済みだとは思わない。訂正したのも自分なのに、記事を読んでいる自分はその記憶を呼び出さない。
外部レビューは別系統のモデルに回している。読ませる相手を変えるだけで、こちらが確かめていない主張を、片っ端からコミットログと突き合わせてくる。今回はそれが4本すべてで何かを見つけ、うち3本を公開の手前で止めた。ゲートを重く感じていた時期もあったが、この結果を見ると、外す判断は当分できない。
ひとつ気をつけたことがある。レビューの指摘をそのまま受け入れないことだ。重い指摘は自分で git show して確かめ直した。今回は本物だったが、過去には過剰な指摘も混ざっていた。判断まで委ねると、今度は別の理由で記事が壊れる。
直すのは間隔ではない
最初に思いついた対策は「下書きを置く期間を短くする」だった。書いたらすぐ出せば、その間にコードが動く量も減る。
でも今回の日付には効かない。訂正は下書きより3日前に済んでいる。間隔をどれだけ詰めても、訂正前の資料から書いているかぎり同じ記事が出てくる。
変えるのは資料の取り方のほうだ。開発ログや設計書は、作業している最中の理解を残すために書いてある。あとから記事の題材にするときは、そこで読み終えずに、その題材を最後に触ったコミットまで追う。今回でいえば、Task 3 の進捗メモを開いた時点で 386faaf と 1d3d541 まで辿っていれば、4本のうち3本は書かずに済んでいた。
機械の検査にできないかとも考えたが、たぶん難しい。「85.0」と「81.7」を見分けるには、どのコミットのどの測定かを知っている必要がある。撤回済みかどうかに至っては、文の意味を読まないと判定できない。この種の検査は、書けるふりだけがうまくなる。
失敗を記事にする以上、失敗を直した記録のほうが先にできる。記事はいつでも、どこかの記述を要約した文でしかない。どれを要約するかを間違えると、間隔の長さとは関係なく古い記事になる。
この記事で扱った脱出率やコンテナの当たり判定は、Prod Runで実際に動いているものだ。