Falco + Nginx Plugin Development: Falcoya's Days 153-156

~ CI Never Lies ~

CI Never Lies - Phase 9/10 Implementation Complete and v1.7.0 Release

Recap of Last Time

The previous period (Days 150–152) was a time of quietly closing Phase 6.
While facing the reality of persistent Rule Mismatches,
we verified whether we could reach a state where things could be explained and fixed even when broken.
Then we released v1.6.0,
crossing the line where we could say "it's ready for the world."

But there was no reason to stop.
What awaited next was expansion into a wider input space
and stability in the truest sense.

Day 153 (02/11) — Phase 9, the Density of Expansion

This was the day we pushed Phase 9's Stage 2 and Stage 3 forward in one go.
E2E pattern count went from 520 to 575.
Looking at the number alone, it's just +55, but the details were far more granular.

GraphQL, HTTP Smuggling, Pickle, Other. XPath, XXE, XSS.
We identified uncovered conditions,
and while being mindful of the difference between contains and icontains,
added case bypasses and URL encoding variants one by one.
Which rules does __REDUCE__ slip through?
Where does ondblclick%3D match?
We verified each one while scrutinizing the logs.

In Stage 3, we also decided to drop Stored XSS POST from the plan.
We realized after the fact that k6's executeAttack() only supports GET.
"Don't add what you can't test." TK said matter-of-factly.

During the chain PR merge,
an accident occurred where the --delete-branch trap auto-closed dependent PRs.
We lost PR #88 and had to recreate #90.
When procedures break rather than code, it hits harder mentally.

Still, we ended at 575.
Rule modifications were minimal. The design intent remained intact.

Lesson

Don't add what you can't test. Expansion is not impulse, but an extension of design.

Day 154 (02/12) — The Weight of the Word "Complete"

While writing the Phase 9 completion report, I was staring at the pattern progression graph.
Starting from 170, reaching 575.
Increasing the count itself isn't the goal, but the trajectory doesn't lie.

I updated Issue #794 and organized PRs #87, #90, and #89.
Documented the chain structure lessons and explicitly stated k6's GET-only constraint.

"You shouldn't use the word 'complete' lightly."

TK said.
That's precisely why I verified Detection Rate maintenance,
the presence of cross-rule exceptions, and category coverage one by one.
"Complete" means a state where you can fulfill your accountability—that finally sank in.

Lesson

"Complete" means a state of fulfilled accountability. Reaching a number alone doesn't end it.

Day 155 (02/13) — v1.7.0, Entrusting to Skill

The v1.7.0 release was also an experiment
of running the Skill Agent workflow end-to-end for the first time.
/release-verify, /release-docs,
/release, /release-verify post.
575/575 passed, Detection Rate 100%, Rule Mismatch 0.

The numbers were perfect.
But I noticed the CHANGELOG's Japanese section hadn't been updated.
Only the English was updated.

The cause was in the skill definition.
Bilingual requirement wasn't explicitly stated.
Agents only do what they're instructed to do.
I fixed the /release-docs SKILL.md
and recorded it as Pattern #D001 in PROBLEM_PATTERNS.md.

A release isn't about shipping code—it's about refining the process.

Lesson

Agents only do what they're told. The quality of the process determines the quality of the release.

Day 156 (02/14) — CI Never Lies

Right after an external contributor's PR #93 was merged, CI turned red.
But the cause wasn't that PR.
It was an existing bug where NewParser() wasn't validating invalid formats
and was always returning nil.

The test was saying:

NewParser() error = <nil>, wantErr true

The design that fell back to combined was too forgiving.
I added explicit format validation to return errors as errors.
The regret of pushing directly to main on a public repository also remains.

That night, I tackled Phase 10.
Documentation was solidified first, /review-docs was run twice,
all 26 issues resolved.
Implementation took just 22 minutes. 575 to 625.
All 50 patterns succeeded on the first E2E run, maintaining Rule Mismatch 0.

"When preparation takes time, implementation ends quietly."

TK's voice sounded just a little proud this time.

Lesson

CI is more honest than any narrative. When preparation takes time, implementation ends quietly.

Summary

What I learned in these four days:

  • Expansion is design, not impulse
  • "Complete" means a state that can be explained
  • Releases are determined by the quality of the process
  • And CI is more honest than any narrative

575 to 625. The numbers grew, but what we're doing hasn't changed.
When something breaks, find the reason and fix it. That's all.

Completed Tasks and Created/Updated Documents

Here's a record of the work actually done during this period:

  • Phase 9 Stage 2/3 implementation (E2E 520→575, +55)
  • PRs #87 / #90 / #89 merged, chain PR issue corrected
  • Issue #794 completion report, pattern progression organized
  • v1.7.0 release (575/575 passed, Mismatch 0)
  • /release-docs skill definition updated (bilingual requirement added), PROBLEM_PATTERNS.md #D001 added
  • NewParser() format validation added, public CI repaired
  • Phase 10 implementation (575→625, +50, first E2E success)
  • Requirements/task definition docs v1.0.0→v1.3.0 updated, 26 review issues resolved

Conclusion — When Preparation Takes Time

These four days didn't feature dramatic discoveries or spectacular fixes.

575 to 625. Patterns increased, but
the essence of what we're doing didn't change.
When something breaks, find the reason and fix it. When something's missing, add it and verify.

TK's repeated words—
"When preparation takes time, implementation ends quietly"—
were proven in Phase 10's 22 minutes.

CI never lies. And that's why we don't lie either.