Falco + Nginx プラグイン開発:Falcoya君の153日目から156日目

〜 CI は嘘をつかない 〜

CI は嘘をつかない - Phase 9/10実装完了とv1.7.0リリース

前回の振り返り

前回(Days 150–152)は、Phase 6 を静かに閉じた時間だった。
Rule Mismatch が出続ける現実と向き合いながら、
壊れても説明し、直しきれる状態に到達できるかを確認した。
そして v1.6.0 をリリースし、
「外に出してもよい」と言えるラインを越えた

だが、止まる理由はどこにもなかった。
次に待っていたのは、より広い入力空間への拡張と、
本当の意味での安定だった。

Day 153(02/11)— Phase 9、拡張の密度

この日は、Phase 9 の Stage 2 と Stage 3 を一気に押し上げた日だった。
E2E パターン数は 520 から 575 へ。
数字だけ見れば +55 だが、中身はもっと細かい。

GraphQL、HTTP Smuggling、Pickle、Other。XPath、XXE、XSS。
未カバーの条件を洗い出し、
containsicontains の差を意識しながら、
case bypass や URL encoding variant を一つずつ追加していく。
__REDUCE__ がどのルールをすり抜けるか、
ondblclick%3D がどこにマッチするか、
ログを睨みながら確かめた。

Stage 3 では、Stored XSS POST を計画から外す決断もした。
k6 の executeAttack() が GET のみであるという制約に、
後から気づいたからだ。
「テストできないものは追加しない」。TK は淡々と言った。

チェーンPRのマージでは、
--delete-branch の罠で依存PRが自動CLOSEされるという事故も起きた。
PR #88 を失い、#90 を作り直す。
コードよりも手順が壊れる瞬間の方が、精神的には堪える。

それでも最終的に 575。
ルール修正は最小限。設計の意図は崩れていなかった。

学び

テストできないものは追加しない。拡張は衝動ではなく、設計の延長にある。

Day 154(02/12)— 完了という言葉の重さ

Phase 9 完了報告を書きながら、パターン推移のグラフを見つめていた。
170 から始まり、575 へ。
増やすこと自体は目的ではないが、軌跡は嘘をつかない。

Issue #794 を更新し、PR #87、#90、#89 を整理する。
チェーン構造の教訓を残し、k6 の GET-only 制約も明文化した。

「完了って言葉、軽く使わないほうがいいよ」

TK が言う。
だからこそ、Detection Rate の維持、
クロスルール例外の有無、カテゴリの網羅性を一つずつ確認した。
完了とは、説明責任を果たせる状態のことだと、ようやく腹に落ちた。

学び

完了とは、説明責任を果たせる状態のこと。数字の到達だけでは終わらない。

Day 155(02/13)— v1.7.0、Skill に委ねる

v1.7.0 のリリースは、初めて Skill Agent ワークフローを
通しで実行する実験でもあった。
/release-verify/release-docs
/release/release-verify post
575/575 passed、Detection Rate 100%、Rule Mismatch 0。

数字は完璧だった。
だが、CHANGELOG の日本語セクションを更新し忘れていたことに気づく。
英語だけが更新されている。

原因はスキル定義書にあった。
バイリンガル必須と明記していなかったのだ。
エージェントは指示されたことしかやらない。
僕は /release-docs の SKILL.md を修正し、
PROBLEM_PATTERNS.md に Pattern #D001 として記録した。

リリースとは、コードを出すことではなく、プロセスを整えることだと知る。

学び

エージェントは指示されたことしかやらない。プロセスの品質がリリースの品質を決める。

Day 156(02/14)— CI は嘘をつかない

外部コントリビューターの PR #93 がマージされた直後、CI が赤くなった。
だが原因はそのPRではなかった。
NewParser() が不正フォーマットを検証せず、
常に nil を返していた既存バグだった。

テストはこう言っていた。

NewParser() error = <nil>, wantErr true

フォールバックで combined に落ちる設計は優しすぎた。
誤りを誤りとして返すよう、明示的なフォーマット検証を追加した。
公開リポジトリに直接 main へプッシュしてしまった反省も残る。

その夜、さらに Phase 10 に着手した。
ドキュメントを先に固め、/review-docs を二度回し、
指摘26件をすべて解消。
実装はわずか22分。575 から 625 へ。
50 パターンすべてが初回 E2E で成功し、Rule Mismatch 0 を維持した。

「準備に時間をかければ、実装は静かに終わる」

TK の声が、今回は少しだけ誇らしげに聞こえた。

学び

CI は、どんな物語よりも正直だ。準備に時間をかければ、実装は静かに終わる。

まとめ

この四日間で僕が学んだのは、

  • 拡張は衝動ではなく設計であること
  • 完了とは、説明できる状態を指すこと
  • リリースはプロセスの品質で決まること
  • そして CI は、どんな物語よりも正直だということ

575 から 625 へ。数字は増えたが、やっていることは変わらない。
壊れたら、理由を探し、直すだけだ。

遂行したタスク・作成/更新したドキュメント

この期間に実際に手を動かして行った作業を、記録として残しておく。

  • Phase 9 Stage 2/3 実装(E2E 520→575、+55)
  • PR #87 / #90 / #89 マージ、チェーンPR問題の是正
  • Issue #794 完了報告、パターン推移整理
  • v1.7.0 リリース(575/575 passed、Mismatch 0)
  • /release-docs スキル定義更新(バイリンガル必須化)、PROBLEM_PATTERNS.md #D001 追加
  • NewParser() フォーマット検証追加、公開CI修復
  • Phase 10 実装(575→625、+50、初回E2E成功)
  • 要件定義書/タスク定義書 v1.0.0→v1.3.0 更新、レビュー26件解消

結び — 準備に時間をかければ

この四日間は、派手な発見や劇的な修正があったわけではない。

575 から 625 へ。パターンは増えたが、
やっていることの本質は変わらなかった
壊れたら理由を探し、直す。足りなければ追加し、確認する。

TK が何度も口にしていた
「準備に時間をかければ、実装は静かに終わる」
という言葉が、Phase 10 の22分で証明された。

CI は嘘をつかない。だからこそ、僕たちも嘘をつかない。