メインコンテンツへスキップ
ルールは、Droidが毎回従う成文化された標準です。(決定と文脈を捉える)メモリーとは異なり、ルールはコードがどのように書かれるべきかを定義します。このガイドでは、個人やチームにおいて効果的にルールを整理する方法を説明します。
Works with Factory App: These conventions work identically in both CLI and Factory App—Droid reads the same .factory/rules/ files regardless of interface.

ルールと他の設定の比較

タイプ目的
ルールコードがどのように書かれるべきか”ネストした条件文の代わりに早期リターンを使用する”
Memory何が決定され、なぜそうしたか”Reduxが冗長すぎたため、Zustandを選んだ”
AGENTS.mdビルド/テスト/実行の方法”作業完了前に npm test を実行する”
Skills特定のタスクの実行方法”新しいAPIエンドポイントを実装するステップ”
ルールは規範的です—DroidにすべきことをL告します。一貫して適用されるべき標準に使用してください。

ルールディレクトリの設定

基本構造

プロジェクトに .factory/rules/ ディレクトリを作成します:
.factory/
└── rules/
    ├── typescript.md      # TypeScript conventions
    ├── react.md           # React patterns
    ├── testing.md         # Testing requirements
    ├── api.md             # API design rules
    └── security.md        # Security requirements
すべてのプロジェクトに適用される個人ルールの場合:
~/.factory/
└── rules/
    ├── style.md           # Your personal style
    └── tools.md           # Tool preferences

AGENTS.mdでルールを参照する

AGENTS.md にセクションを追加します:
## Coding Standards

Follow the conventions documented in `.factory/rules/`:
- **TypeScript**: `.factory/rules/typescript.md`
- **React**: `.factory/rules/react.md`
- **Testing**: `.factory/rules/testing.md`
- **API Design**: `.factory/rules/api.md`
- **Security**: `.factory/rules/security.md`

When working on a file, check the relevant rules first.

効果的なルールの記述

ルール構造

各ルールは以下であるべきです:
  • 具体的: 解釈の余地なく従えるほど明確
  • 実行可能: 避けるべきことではなく、すべきことを指示
  • スコープ化: いつ適用されるかを明記
  • 正当化 (任意): 複雑なルールに対する理由の説明

テンプレート

# [Category] Rules

## [Rule Name]
**Applies to**: [file types, contexts]
**Rule**: [specific instruction]
**Example**: [code showing correct usage]
**Rationale**: [why this matters - optional]

ルールファイルの例

TypeScriptルール

.factory/rules/typescript.md を作成します:
# TypeScript Rules

## Type Definitions

### Use `interface` for object shapes
**Applies to**: All type definitions for objects
**Rule**: Use `interface` for object types, `type` for unions, intersections, and primitives.

```typescript
// ✅ 正しい
interface User {
  id: string;
  name: string;
}

type Status = 'active' | 'inactive';
type UserWithStatus = User & { status: Status };

// ❌ 避ける
type User = {
  id: string;
  name: string;
};

Avoid any

Applies to: All TypeScript files Rule: Never use any. Use unknown with type guards, or define proper types.
// ✅ 正しい
function processData(data: unknown): string {
  if (typeof data === 'string') {
    return data.toUpperCase();
  }
  throw new Error('Expected string');
}

// ❌ 避ける
function processData(data: any): string {
  return data.toUpperCase();
}

Function Patterns

Use early returns

Applies to: All functions with conditionals Rule: Return early for edge cases instead of nesting.
// ✅ 正しい
function processUser(user: User | null): string {
  if (!user) return 'No user';
  if (!user.active) return 'User inactive';
  return `Processing ${user.name}`;
}

// ❌ 避ける
function processUser(user: User | null): string {
  if (user) {
    if (user.active) {
      return `Processing ${user.name}`;
    } else {
      return 'User inactive';
    }
  } else {
    return 'No user';
  }
}

Named exports over default

Applies to: All module exports Rule: Use named exports for better refactoring and import clarity.
// ✅ 正しい
export function createUser() {}
export const USER_ROLES = ['admin', 'user'] as const;

// ❌ 避ける
export default function createUser() {}

### Reactルール

`.factory/rules/react.md` を作成します:

```markdown
# React Rules

## Component Structure

### Functional components only
**Applies to**: All React components
**Rule**: Use functional components with hooks. Never use class components.

### Props interface naming
**Applies to**: All components with props
**Rule**: Name props interface as `{ComponentName}Props`.

```tsx
// ✅ 正しい
interface UserCardProps {
  user: User;
  onSelect: (user: User) => void;
}

export function UserCard({ user, onSelect }: UserCardProps) {
  return <div onClick={() => onSelect(user)}>{user.name}</div>;
}

Component file structure

Applies to: All component files Rule: Order sections as: imports, types, component, exports.
// 1. インポート(React、外部、内部、型)
import { useState } from 'react';
import { Button } from '@/components/ui';
import type { User } from '@/types';

// 2. 型
interface UserListProps {
  users: User[];
}

// 3. コンポーネント
export function UserList({ users }: UserListProps) {
  const [selected, setSelected] = useState<string | null>(null);
  
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

State Management

Zustand for client state

Applies to: Client-side state that isn’t server data Rule: Use Zustand stores in src/stores/. One store per domain.
// src/stores/useUserStore.ts
import { create } from 'zustand';

interface UserState {
  currentUser: User | null;
  setUser: (user: User) => void;
  logout: () => void;
}

export const useUserStore = create<UserState>((set) => ({
  currentUser: null,
  setUser: (user) => set({ currentUser: user }),
  logout: () => set({ currentUser: null }),
}));

React Query for server state

Applies to: All data fetched from APIs Rule: Use React Query. Queries go in src/queries/.
// src/queries/useUsers.ts
import { useQuery } from '@tanstack/react-query';

export function useUsers() {
  return useQuery({
    queryKey: ['users'],
    queryFn: () => fetch('/api/users').then(r => r.json()),
  });
}

### Testing Rules

Create `.factory/rules/testing.md`:

```markdown
# Testing Rules

## File Organization

### Colocate test files
**Applies to**: All tests except E2E
**Rule**: Place test files next to source files.

src/ └── components/ └── UserCard/ ├── UserCard.tsx ├── UserCard.test.tsx # ✅ Colocated └── index.ts

### E2E tests in dedicated directory
**Applies to**: End-to-end tests
**Rule**: Place E2E tests in `e2e/` at project root.

## Test Structure

### Descriptive test names
**Applies to**: All test cases
**Rule**: Format as "should [action] when [condition]".

```typescript
// ✅ Correct
it('should display error message when login fails', () => {});
it('should redirect to dashboard when login succeeds', () => {});

// ❌ Avoid
it('login error', () => {});
it('works', () => {});

One assertion per test

Applies to: Unit tests Rule: Test one behavior per test case. Multiple assertions OK if testing same behavior.
// ✅ Correct - testing one behavior
it('should format user name correctly', () => {
  const result = formatUserName({ first: 'John', last: 'Doe' });
  expect(result).toBe('John Doe');
});

// ✅ Also correct - same behavior, multiple aspects
it('should return complete user object', () => {
  const user = createUser('John');
  expect(user.id).toBeDefined();
  expect(user.name).toBe('John');
  expect(user.createdAt).toBeInstanceOf(Date);
});

// ❌ Avoid - testing multiple behaviors
it('should handle user operations', () => {
  expect(createUser('John').name).toBe('John');
  expect(deleteUser('123')).toBe(true);
  expect(listUsers()).toHaveLength(0);
});

Mocking

Mock at boundaries

Applies to: All mocked dependencies Rule: Mock external APIs and services, not internal functions.
// ✅ Correct - mock external API
vi.mock('@/lib/api', () => ({
  fetchUser: vi.fn().mockResolvedValue({ id: '1', name: 'John' }),
}));

// ❌ Avoid - mock internal implementation
vi.mock('@/utils/formatName', () => ({
  formatName: vi.fn().mockReturnValue('John'),
}));

Use MSW for API mocking in integration tests

Applies to: Integration tests that need API responses Rule: Use Mock Service Worker instead of mocking fetch directly.
// ✅ Correct
import { http, HttpResponse } from 'msw';

const handlers = [
  http.get('/api/users', () => {
    return HttpResponse.json([{ id: '1', name: 'John' }]);
  }),
];

### Security Rules

Create `.factory/rules/security.md`:

```markdown
# Security Rules

## Secrets Management

### Never hardcode secrets
**Applies to**: All code
**Rule**: Use environment variables for all secrets. Never commit secrets.

```typescript
// ✅ Correct
const apiKey = process.env.API_KEY;

// ❌ Never do this
const apiKey = 'sk-1234567890abcdef';

Validate environment variables

Applies to: Application startup Rule: Validate required env vars exist at startup.
// ✅ Correct
const config = {
  apiKey: requireEnv('API_KEY'),
  dbUrl: requireEnv('DATABASE_URL'),
};

function requireEnv(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Missing required env var: ${name}`);
  return value;
}

Input Validation

Validate all external input

Applies to: API routes, form handlers Rule: Use Zod to validate all input from users or external sources.
// ✅ Correct
import { z } from 'zod';

const CreateUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1).max(100),
});

export async function createUser(input: unknown) {
  const data = CreateUserSchema.parse(input);
  // data is now typed and validated
}

Error Handling

Never expose internal errors

Applies to: API error responses Rule: Log detailed errors server-side; return generic messages to clients.
// ✅ Correct
try {
  await processPayment(data);
} catch (error) {
  console.error('Payment failed:', error); // Detailed log
  throw new ApiError('Payment processing failed', 500); // Generic message
}

Authentication

Check authentication on every protected route

Applies to: All API routes requiring auth Rule: Use middleware or guards. Never assume auth from client.
// ✅ Correct
export async function GET(request: Request) {
  const session = await getSession(request);
  if (!session) {
    return new Response('Unauthorized', { status: 401 });
  }
  // ... handle authenticated request
}

---

## Organizing Team Rules

### Layered Rules

For teams, organize rules in layers:

.factory/rules/ ├── _base/ # Foundation rules (everyone follows) │ ├── typescript.md │ └── security.md ├── frontend/ # Frontend-specific │ ├── react.md │ └── styling.md ├── backend/ # Backend-specific │ ├── api.md │ └── database.md └── testing/ # Testing standards ├── unit.md └── integration.md

Reference in AGENTS.md:

```markdown
## Rules
- Base rules: `.factory/rules/_base/` - Apply to all code
- Frontend rules: `.factory/rules/frontend/` - React components
- Backend rules: `.factory/rules/backend/` - API and services
- Testing rules: `.factory/rules/testing/` - All tests

Rule Ownership

Add ownership to track who maintains each rule set:
# TypeScript Rules

**Owner**: Platform Team
**Last Updated**: 2024-02-15
**Review Cycle**: Quarterly

[rules content...]

Current Limitation: No Glob Pattern Support

Currently, Droid doesn’t support conditional rule application based on file patterns (e.g., “apply these rules only to *.tsx files”). This is on the roadmap.
回避策:
  1. ファイルタイプごとに整理: 別々のルールファイルを作成し、コンテキストに応じて参照する
# In AGENTS.md
When working on React components (*.tsx), follow `.factory/rules/react.md`
When working on API routes, follow `.factory/rules/api.md`
  1. ルールで明確なスコープを使用: 適用可能性を明確に述べる
## This rule applies to: React component files (*.tsx)
  1. 複雑なワークフローにはskillsを使用: Skillsはファイルタイプ固有の指示をエンコードできる

ルールの保守

新しいルールの追加

Droidを繰り返し修正している場合:
  1. パターンを特定する
  2. 例を含む明確なルールを記述する
  3. 適切なルールファイルに追加する
  4. 必要に応じてAGENTS.mdを更新する
  5. 類似の作業をDroidに依頼してテストする

ルールのレビュー

四半期レビューチェックリスト:
  • リンティングで強制されるようになったルールを削除
  • 変更されたルールを更新
  • 新しいパターンのルールを追加
  • 例がまだ正確かチェック
  • AGENTS.mdの参照が最新かを確認

ルールの廃止

ルールが時代遅れになった場合:
## ~~Use PropTypes for type checking~~ (DEPRECATED)
**Status**: Deprecated as of 2024-02
**Reason**: We now use TypeScript for all type checking
**Replacement**: See TypeScript rules for prop typing

ルールの自動実行

Droidは .factory/rules/ ファイルのルールに従いますが、hooks で自動実行を追加できます。

編集後にリンターを実行

ファイル編集後にリンターを自動実行するPostToolUseフックを追加します:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Create",
        "hooks": [
          {
            "type": "command",
            "command": "cd \"$FACTORY_PROJECT_DIR\" && npm run lint -- --fix 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

コードスタイルの検証

Prettierやフォーマッターを自動実行します:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Create",
        "hooks": [
          {
            "type": "command",
            "command": "cd \"$FACTORY_PROJECT_DIR\" && npx prettier --write \"$(jq -r '.tool_input.file_path')\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
See Auto-formatting hooks and Code Validation hooks for more examples.

クイックリファレンス

ファイルの場所

スコープ場所用途
個人~/.factory/rules/あなたのスタイル設定
プロジェクト.factory/rules/チーム標準

ルール形式

## [Rule Name]
**Applies to**: [scope]
**Rule**: [what to do]
**Example**: [code]
**Rationale**: [why - optional]

良いルールの条件

  • ✅ 具体的で曖昧さがない
  • ✅ コード例を含む
  • ✅ いつ適用されるかを明記
  • ✅ 実行可能(「Xを検討する」ではなく「Xを行う」)
  • ❌ 曖昧ではない(「クリーンなコードを書く」)
  • ❌ リンタールールと重複していない
  • ❌ 他のルールと矛盾していない

次のステップ