📝

ルールファイルはプロジェクトの暗黙知を減らすから今すぐ書け

に公開

目的

チーム開発においてルールファイルを書くことが効果的であることを実感したため、その実現手順を実例を交えて紹介をすること。

なぜルールファイルが暗黙知を減らすのか

暗黙知を減らすとは、それすなわち知識が明文化されることです。ルールファイルを書くことでプロジェクトのルール(知識)が明文化されるため、暗黙知を減らすことに直結します。

なぜ暗黙知を減らしたいのか

様々なメリットがあります

  • AIや新しいメンバーのキャッチアップを早めるため
  • 既存のメンバーの認識の齟齬をなくすため
  • 属人化を防ぐため

ルールの明文化

周知の事実ですが、AIコーディングエージェントにルールファイルを提供すると出力の品質が上がります。したがってプロジェクトをAIファーストにするためにはルールファイルの整備は欠かせません。
残念ながらzoomやslackの会話を見聞きして勝手にルールを覚えてくれるようなインテグレーションはまだない(技術的には可能)ので、人間がルールファイルを整備する必要があります。

具体的な方法

普通のコードと同じように誰かがルールファイルを書き、誰かがそれをレビューします。
スムーズにいけばそれでルールファイルの作成は終わりです。

しかし、ここでほぼ100%、え、そんなルールあった?そのルール間違ってるよこの2つのルール矛盾してない?このルール書き忘れてるよ などの話が出てきます。
例えば1ファイルにつき1つの関数しか書いてはいけないというルールを口頭で決めていても1年後には忘れます。そしてルールファイルを作ろうとすると、1つしかだめだよ勢と複数書いてもいいでしょ勢の議論が起こるんですね。
議論それ自体は問題ないです。むしろ暗黙知を防ぐための第一歩です。

あとは簡単で、議論の結論をルールファイルに記載してください。これにより今後ルールがブレることもなく、AIも新しい人間のメンバーもそれを知ることができます。

まとめると以下です。普通のコードレビューと変わらず特に難しいことはないですね。

具体例

抽象的な話は上記で終わりですが、具体的にどういうファイルを作るべきかも具体例を見せて話していきましょう。
我々はモノレポで開発をしているのでその前提で話します。

現状

以下がルールを整備した現状です。

<repository-root>/
├── rules/
│   ├── all.md
│   └── rule.md
├── apps/
│   ├── admin/
│   │   └── rules/
│   │       └── admin.md
│   ├── api/
│   │   └── rules/
│   │       ├── api.md
│   │       └── infrastructure.md
│   └── web/
│       └── rules/
│           ├── app.md
│           ├── config.md
│           ├── data-access.md
│           ├── feature.md
│           ├── i18n.md
│           ├── lib.md
│           ├── navi.md
│           ├── persistence.md
│           ├── util.md
│           └── web.md
└── packages/
    ├── core/
    │   └── rules/
    │       ├── core.md
    │       ├── entity.md
    │       ├── repository.md
    │       └── usecase.md
    ├── database/
    │   └── rules/
    │       └── database.md
    └── ui/
        └── rules/
            └── ui.md

トップレベルとapps/*packages/*にrulesディレクトリがあります。
トップレベル: 全体に関わるルールやどのパッケージにも分類できないルール
apps/*, packages/*: それぞれに関するルール

パス 説明
rules/ 全体に関わるルールやどのパッケージにも分類できないルール
apps/**/rules/, packages/**/rules/ それぞれに関するルール

rule.mdは少し特別で、ルールファイル更新時のルールを書いてます。CLAUDE.mdも更新しろ、などですね。

拡張子

各ルールファイルは純粋なmarkdownファイルでcursorの.mdcなどではありません。いつcursorが衰退するかも分かりませんし、ルールファイルの仕様変更でファイル移動やリネームさせたりするのは面倒なので。

ルールファイルの中身を紹介

all.md
# 命名規約

- [ファイル名] すべてsmall-kebab-caseを使用する
- [フォルダ名] すべてsmall-kebab-caseを使用する。さらに、単数系表記とする。
apps/web.md
# web

## ディレクトリ構造

- `app/`: 詳しくは @/apps/web/rules/app.md を参照すること。
- `feature/`: 詳しくは @/apps/web/rules/feature.md を参照すること。

## 命名規約

- **関数型コンポーネント**: PascalCase
- **定数**: UPPER_SNAKE_CASE
- **その他のモジュール**: camelCase

ルールファイル内部で別のルールファイルを言及しています。@をリポジトリルートのエイリアスとして参照しています。ログを見ている限り、特に@の定義を書かなくても勝手に参照先のファイルも確認してくれているので問題ありません。

docsディレクトリ

上記には書いてませんが、docsディレクトリも存在します。複数ルールファイルから参照されるような概念についての説明をまとめています。
今のところdocs/architecture.mdのみで全体のアーキテクチャの説明を書いています。

cursor rules

我々のメンバーにはcursorユーザーがいるためcursor rulesがあると嬉しいです。やり方は簡単で以下のように書くだけです。

apps/.cursor/rules/web.mdc
---
description: apps/webディレクトリ全体のルール
globs: *
alwaysApply: false
---

@/apps/web/rules/web.md を参照すること。

CLAUDE.md

これも単純で、ディレクトリを指定しているだけです。

CLAUDE.md
# web

@/apps/web/rules を参照

やってみてどうだったか

お恥ずかしながら私がプロジェクトのアーキテクチャを勘違いしていたことが分かりました。他のメンバーも分かってなかったようで、思った以上にそれぞれのメンバーの理解には違いがありました。
ルールファイルの整備は、結果もさることながらそのプロセスも非常に重要だと感じました。

まとめ

ルールファイルの利点を説明し、具体的な我々のルールファイルの整備方法を紹介しました。

フィシルコム

Discussion