test(architecture): 規約違反を機械で検出し, 機械化した分を Skill から削る - #7116
Closed
ttokoro20240902 wants to merge 2 commits into
Closed
ttokoro20240902 wants to merge 2 commits into
ttokoro20240902 wants to merge 2 commits into
Conversation
AI 向けレイヤ規約(.claude/skills)は、description による自動発火に依存するため 必ず読まれるとは限らない。実測では、実際の Issue に対応させたときレイヤ規約への 到達は 6 割程度で、残りは規約を読まないまま実装が進む。 読まれなくても守られる分を機械検査で確保する。人が書いた場合にも同じく効く。 追加する検査は 3 本。いずれも違反を仕込んで検出力を確認済み。 1. AdminRoutePrefixTest — 管理コントローラのルートが %eccube_admin_route% 配下に あるか。管理画面の認可は admin ファイアウォールが担うため、配下から外すと 未認証で到達できる。画面は動いてしまうので気づく契機が無い。 現状 0/187 違反(回帰防止のゲートとして入れる)。 2. CsrfProtectionTest — GET 以外だけを受けるアクションが CSRF から保護されて いるか。isTokenValid / handleRequest / isXmlHttpRequest / 同クラス内への委譲の いずれかを必須とする。現状 0/74 違反。 外部エージェント向け API(AgentCommerce・Mcp)はブラウザセッションを使わない ため対象外とした。単純な検査では偽陽性が 14 件出たので、除外条件を組み込んで 0 件にしている。 3. SkillFrontmatterTest — Skill の description が YAML として壊れていないか。 クォートされないプレーンスカラーのため「: 」や「 #」で以降が捨てられ、 一覧に載る説明が欠けてトリガ語が失われる。本文は Markdown として読めるため 気づく契機が無い。実際に eccube-migration が壊れていたので併せて修正した。 DB もカーネルも使わない静的な検査のため、PHP/DB のマトリクス(16 セル)から --exclude-group architecture で外し、専用ジョブで 1 セルだけ実行する。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
CI を足す目的は Skill を守ることではなく、実コードを守り、その分 Skill を軽く することにある。機械が落とせるものを Skill に残すと二重管理になり、1 Skill 10 項の枠を食って本当に必要な項を書けなくする。 本 PR の CsrfProtectionTest が「GET 以外だけを受けるアクションの CSRF 保護」を 機械で検査するようになったため、同じ内容を指示していた 2 項を削る。 eccube-controller 削除/Ajax 等の状態変更でトークン未検証 eccube-security フォームを介さない POST/DELETE/Ajax で CSRF 未検証 次の 1 項は機械化されていないため残した。 eccube-controller 戻り値を捨てた isTokenValid(); を「CSRF 未検証」と誤読 isTokenValid() は失敗時に AccessDeniedHttpException を投げるため、戻り値を 捨てた bare 呼び出しでも検証は成立する(AbstractController の実装で確認)。 呼び出しの有無ではなく読み手の誤解を正す項なので、検査では代替できない。 あわせて AGENTS.md の歯止め(1 項 120 字)を超えていた 6 項を、内容を落とさず 短縮した。 eccube-purchase-flow 132 字 → 119 字 eccube-phpunit 130 字 → 102 字 eccube-csv 127 字 → 102 字 eccube-mail 127 字 → 101 字 eccube-entity 124 字 → 104 字 eccube-purchase-flow 124 字 → 98 字 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ttokoro20240902
force-pushed
the
test/architecture-gates
branch
from
September 8, 2026 06:52
8c761e3 to
27a00b7
Compare
ttokoro20240902
added a commit
that referenced
this pull request
Sep 9, 2026
# Conflicts: # .claude/skills/eccube-controller/SKILL.md # .claude/skills/eccube-csv/SKILL.md # .claude/skills/eccube-entity/SKILL.md # .claude/skills/eccube-mail/SKILL.md # .claude/skills/eccube-migration/SKILL.md # .claude/skills/eccube-phpunit/SKILL.md # .claude/skills/eccube-purchase-flow/SKILL.md # .claude/skills/eccube-security/SKILL.md
6 tasks done
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要(Overview・Refs Issue)
AI 向けレイヤ規約(
.claude/skills)はdescriptionによる自動発火に依存するため、必ず読まれるとは限りません。実測では、実際の Issue に対応させたときレイヤ規約への到達は 6 割程度で、残りは規約を読まないまま実装が進みます。読まれなくても守られる分を機械検査で確保します。 人が書いた場合にも同じく効きます。
方針(Policy)
規約 152 項を機械検出の可否で分類すると、具体的な API 名・パスで書かれた 78 項(51%)が検出可能でした。そのうち実害が大きく、偽陽性をゼロにできるものから着手します。
追加する検査
AdminRoutePrefixTest%eccube_admin_route%配下にあるかCsrfProtectionTestSkillFrontmatterTestdescriptionが YAML として壊れていないか1・2 は現状 0 違反なので、既存コードを直す必要がなく、回帰防止のゲートとして機能します。
なぜこの 3 つか
いずれも画面上は正常に動いてしまい、気づく契機が無い種類の問題です。
pattern: ^/%eccube_admin_route%/)が担うため、配下から外すと未認証で到達できます。画面は動くのでレビューでも見落としやすい。descriptionはクォートされないプレーンスカラーなので、:(コロン+空白)や#(空白+シャープ)で以降が捨てられます。一覧に載る説明が欠け、失われたトリガ語では自動発火しなくなります。 本文は Markdown として普通に読めるため気づけません。実際にeccube-migrationが壊れていたので併せて修正しました。2 つ目のコミット: CI が機械化した分を Skill から削る
CI を足す目的は Skill を守ることではなく、実コードを守り、その分 Skill を軽くすることです。 機械が落とせるものを Skill に残すと二重管理になり、1 Skill 10 項の枠を食って本当に必要な項を書けなくします。
本 PR の
CsrfProtectionTestが機械で検査するようになったため、同じ内容を指示していた 2 項を削除しました。eccube-controllereccube-security次の 1 項は機械化されていないため残しました。
isTokenValid()は失敗時にAccessDeniedHttpExceptionを投げるため、戻り値を捨てた bare 呼び出しでも検証は成立します(AbstractControllerの実装で確認)。呼び出しの有無ではなく読み手の誤解を正す項なので、検査では代替できません。あわせて AGENTS.md の歯止め(1 項 120 字)を超えていた 6 項を、内容を落とさず短縮しました(最大 132 字 → 119 字)。
偽陽性の除去
CsrfProtectionTestは単純に書くと偽陽性が 14 件出ました。次を正当な例外として除外しています。AgentCommerce/Mcp/isXmlHttpRequest()LayoutController::preview→edit())偽陽性が 1 件でもあると検査ごと無効化されてしまうため、0 件にしてから提出しています。
CI での実行
DB もカーネルも使わない静的な検査なので、PHP × DB のマトリクス(16 セル)で走らせる意味がありません。
--exclude-group architectureを追加composer install --no-scripts)既存の
cache-clear/mcp/plugin-service/rectorなど 10 個のグループと同じ分離方式です。実装に関する補足(Appendix)
OrderController::bulkDeleteからisTokenValid()を外す、AdminControllerのルートから%eccube_admin_route%を外す、といった違反を仕込んで落ちることを確かめ、復元して緑に戻しています。eccube-migrationの 1 行修正は docs(skills): レイヤ規約 description の対象範囲にプラグインを含める #7106 にも含まれます。マージ順によってはこの 1 行がコンフリクトします。fgetcsv/fputcsvの直書き、Twig の|raw、Skill の項数・字数上限)は別 PR で順次追加する想定です。テスト(Test)
--exclude-group architecture --list-testsで確認(該当 0 件)相談(Discussion)
tests/Eccube/Tests/Architecture/とtests/Eccube/Tests/Skill/に新設しました。既存はsrc/Eccube/の構造に対応した命名(Controller/Doctrine/Repository…)なので、機能別ディレクトリに寄せるべきかご意見を伺いたいです。test(entity): if(!class_exists()) ガードの再発防止ゲートを追加 (refs #6891) #7113 はDoctrine/ORM/Mapping/に置いています。SkillFrontmatterTestは.claude/skills/を検査するもので、src/Eccube/のアーキテクチャとは性質が違います。PHPUnit でやるべきか(専用スクリプト + CI ステップにする案もあります)も論点です。マイナーバージョン互換性保持のための制限事項チェックリスト