← ドキュメント一覧/アーキテクチャ

Log-Driven Development (LDD)

Log-Driven Development (LDD)

概要: Log-Driven Development(LDD)は、思考プロセスと作業結果を完全に構造化ログとして記録する運用手法です。codex_prompt_chain、tool_invocations、memory_bankの3要素により、Agent間コンテキスト共有と監査可能性を実現します。

対象読者: 実装者 / Agent開発者 所要時間: 12分 前提知識: Agent階層システム


LDDの目的

3つの主要目標

  1. 思考プロセスの可視化: AIがどのように考え、判断したかを記録
  2. 作業履歴の完全追跡: すべてのコマンド実行を監査可能に
  3. Agent間コンテキスト共有: メモリバンクによる知識継承

従来のログとの違い

従来のログLDD
エラー時のみ記録すべての作業を記録
実行結果のみ思考プロセス + 実行結果
ファイル単位構造化YAML/JSON
Agent単体Agent間共有

LDD構成要素

1. codex_prompt_chain

役割: 思考プロセスの構造化記録

codex_prompt_chain:
  intent: "タスクの目的を1文で記載"

  plan:
    - "主要ステップ1(5-7語)"
    - "主要ステップ2(5-7語)"
    - "主要ステップ3(5-7語)"

  implementation:
    - "編集/追加したファイル: src/auth/login.ts"
    - "編集/追加したファイル: tests/auth/login.test.ts"

  verification:
    - "実行したテスト: npm run test:unit"
    - "検証結果: ESLint 0 errors, TypeScript 0 errors"

実例: Issue #270の記録

codex_prompt_chain:
  intent: "Firebase Auth invalid-credential エラーを修正し、E2Eテストを追加する"

  plan:
    - "Firebase認証エラー原因特定"
    - "invalid-credentialエラー修正"
    - "E2Eテスト追加(Playwright)"
    - "ドキュメント更新"

  implementation:
    - "src/services/authService.ts: 認証ロジック修正"
    - "src/services/authService.ts: エラーハンドリング追加"
    - "tests/e2e/auth.spec.ts: E2Eテスト追加"
    - "docs/AUTH.md: 認証フロー図更新"

  verification:
    - "ESLint: 0 errors"
    - "TypeScript: 0 errors"
    - "Test coverage: 85% (target: 80%)"
    - "E2E test: 100% pass"
    - "Quality score: 95/100"

2. tool_invocations

役割: 実行コマンド履歴の完全記録

tool_invocations:
  - command: "npm run lint"
    workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
    timestamp: "2025-10-10T12:34:56Z"
    status: "passed"
    notes: "ESLintエラー0件"

  - command: "npm run build"
    workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
    timestamp: "2025-10-10T12:35:20Z"
    status: "passed"
    notes: "TypeScriptコンパイル成功"

  - command: "npm run test:unit"
    workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
    timestamp: "2025-10-10T12:36:10Z"
    status: "passed"
    notes: "全テスト成功、カバレッジ85%"

  - command: "git commit -m 'fix: Firebase Auth修正'"
    workdir: "/Users/shunsuke/Dev/Autonomous-Operations"
    timestamp: "2025-10-10T12:37:00Z"
    status: "passed"
    notes: "コミット成功 (SHA: abc123)"

JSON形式(機械可読):

{
  "tool_invocations": [
    {
      "command": "npm run lint",
      "workdir": "/Users/shunsuke/Dev/Autonomous-Operations",
      "timestamp": "2025-10-10T12:34:56Z",
      "status": "passed",
      "duration_ms": 3500,
      "exit_code": 0,
      "notes": "ESLintエラー0件"
    }
  ]
}

3. memory_bank_updates

役割: Agent間コンテキスト共有

memory_bank_updates:
  - section: "active_tasks"
    summary: "Issue #270の実装完了、PR #309作成済み"
    timestamp: "2025-10-10T12:40:00Z"
    details:
      - task_id: "task-270"
      - status: "completed"
      - next_action: "PR #309のレビュー待ち"
      - blocking: []

  - section: "known_issues"
    summary: "Firebase Auth修正により、既知の認証エラーが解消"
    timestamp: "2025-10-10T12:40:30Z"
    details:
      - issue_id: 270
      - resolution: "authService.tsのエラーハンドリング改善"
      - impact: "全ユーザーの認証成功率向上"

ログファイル構造

ディレクトリ構成

.ai/
├── logs/                           # LDDログ
│   ├── 2025-10-10.md              # 日次ログ(人間可読)
│   ├── 2025-10-10-1234-issue-270.yaml  # タスクログ(YAML)
│   └── 2025-10-10-1234-issue-270.json  # タスクログ(JSON)
├── parallel-reports/               # 並行実行レポート
│   └── agents-parallel-20251010-1234.json
└── issues/                         # Issue同期
    └── issue-270.md

ログファイル命名規則

.ai/logs/YYYYMMDD-HHMM-{task}.{format}

例:
- 20251010-1234-issue-270.yaml
- 20251010-1234-issue-270.json
- 20251010-1234-pr-309.yaml

ワークフロー

1. タスク開始時

# Step 1: セッション初期化
session:
  id: "session-1759552488828"
  device: "MacBook Pro 16-inch"
  timestamp: "2025-10-10T12:00:00Z"
  task: "Issue #270 Firebase Auth修正"

# Step 2: codex_prompt_chain作成
codex_prompt_chain:
  intent: "Firebase Auth invalid-credential エラー修正"
  plan:
    - "認証エラー原因特定"
    - "エラーハンドリング修正"
    - "E2Eテスト追加"
  implementation: []  # 空(実装時に追記)
  verification: []    # 空(検証時に追記)

2. 実装中

# Step 3: tool_invocations逐次追記
tool_invocations:
  - command: "git checkout -b fix/270-auth-bug"
    timestamp: "2025-10-10T12:05:00Z"
    status: "passed"

  - command: "code src/services/authService.ts"
    timestamp: "2025-10-10T12:10:00Z"
    notes: "認証ロジック修正開始"

  - command: "npm run lint"
    timestamp: "2025-10-10T12:20:00Z"
    status: "passed"
    notes: "ESLint通過"

3. タスク完了時

# Step 4: implementation/verification完成
codex_prompt_chain:
  intent: "Firebase Auth invalid-credential エラー修正"
  plan: [...]
  implementation:
    - "src/services/authService.ts: 認証ロジック修正"
    - "tests/e2e/auth.spec.ts: E2Eテスト追加"
  verification:
    - "ESLint: 0 errors"
    - "TypeScript: 0 errors"
    - "Quality score: 95/100"

# Step 5: memory_bank更新
memory_bank_updates:
  - section: "active_tasks"
    summary: "Issue #270完了"
    next_action: "PR #309レビュー待ち"

@memory-bank.mdc

構造

# @memory-bank.mdc

**保持期間**: 90日
**更新頻度**: タスク完了時

---

## Active Tasks

### Task: Issue #270 Firebase Auth修正
- Status: ✅ Completed
- Completed: 2025-10-10T12:40:00Z
- Quality Score: 95/100
- Next Action: PR #309レビュー待ち

---

## Known Issues

### Issue #270: Firebase Auth invalid-credential
- Resolution: authService.tsのエラーハンドリング改善
- Impact: 全ユーザーの認証成功率向上
- Resolved: 2025-10-10

---

## Technical Decisions

### Decision: Firebase Auth v10.x採用
- Date: 2025-10-08
- Reason: 最新セキュリティパッチ適用
- Impact: 認証フローの安定性向上

---

## Performance Metrics

### 2025-10-10
- AI Task成功率: 97%
- 平均実行時間: 3分
- 品質スコア平均: 92点

更新プロトコル

// scripts/update-memory-bank.ts
export class MemoryBankUpdater {
  async update(section: string, content: string): Promise<void> {
    const memoryBank = await this.readMemoryBank();

    // セクション検索
    const sectionIndex = memoryBank.indexOf(`## ${section}`);

    if (sectionIndex === -1) {
      // 新規セクション追加
      memoryBank += `\n\n## ${section}\n\n${content}`;
    } else {
      // 既存セクション更新
      memoryBank = this.replaceSection(memoryBank, section, content);
    }

    await this.writeMemoryBank(memoryBank);
  }

  async cleanup(retentionDays: number = 90): Promise<void> {
    const memoryBank = await this.readMemoryBank();
    const cutoffDate = new Date();
    cutoffDate.setDate(cutoffDate.getDate() - retentionDays);

    // 古いエントリ削除
    const cleaned = this.removeOldEntries(memoryBank, cutoffDate);

    await this.writeMemoryBank(cleaned);
  }
}

Quality Gates

品質ゲート定義

ゲート条件承認者
PRD承認.ai/prd.md チェックボックスが全てONユーザー
ARCH承認.ai/arch.md チェックボックスが全てONユーザー
テストパス主要テストが成功コードオーナー
品質スコアReviewAgent評価 ≥ 80点自動判定

ゲート検証

// scripts/quality-gate.ts
export class QualityGate {
  async verify(task: Task): Promise<boolean> {
    // 1. PRD承認チェック
    const prdApproved = await this.checkPRDApproval();

    // 2. ARCH承認チェック
    const archApproved = await this.checkARCHApproval();

    // 3. テスト成功チェック
    const testsPass = await this.checkTests();

    // 4. 品質スコアチェック
    const qualityScore = await this.getQualityScore(task);

    return (
      prdApproved &&
      archApproved &&
      testsPass &&
      qualityScore >= 80
    );
  }
}

Handoff Summary Template

ハンドオフ要約

タスク完了時に次のフォーマットで要約を作成:

## Handoff Summary

### 状態
- Task: Issue #270 Firebase Auth修正
- Status: ✅ Completed
- Quality Score: 95/100

### 対象ブランチ/コミット
- Branch: fix/270-auth-bug
- Commit: abc123def456
- PR: #309 (Draft)

### 未完了作業
- なし

### 推奨次ステップ
1. PR #309のレビュー
2. mainブランチへのマージ
3. 本番環境デプロイ

### 備考
- 認証フローの安定性が向上
- E2Eテスト100%成功
- セキュリティスキャン通過

自動化

LDD自動記録

// agents/base-agent.ts
export abstract class BaseAgent {
  protected async recordLDD(action: LDDAction): Promise<void> {
    const logFile = this.getLDDLogFile();

    // tool_invocation記録
    await this.appendToolInvocation(logFile, {
      command: action.command,
      workdir: action.workdir,
      timestamp: new Date().toISOString(),
      status: action.status,
      notes: action.notes
    });

    // memory_bank更新
    if (action.updateMemoryBank) {
      await this.updateMemoryBank(action.section, action.summary);
    }
  }

  protected getLDDLogFile(): string {
    const date = new Date().toISOString().split('T')[0];
    const time = new Date().toISOString().split('T')[1].slice(0, 5).replace(':', '');
    return `.ai/logs/${date}-${time}-${this.taskId}.yaml`;
  }
}

定期クリーンアップ

# .github/workflows/ldd-cleanup.yml
name: LDD Log Cleanup

on:
  schedule:
    - cron: '0 0 * * 0'  # 毎週日曜0時

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - name: 古いログ削除(90日以上)
        run: |
          find .ai/logs/ -type f -mtime +90 -delete
          npm run memory-bank:cleanup

ログ分析

統計データ抽出

# 成功率集計
jq '.tool_invocations[] | select(.status == "passed")' .ai/logs/*.json | wc -l

# 平均実行時間
jq '.tool_invocations[].duration_ms' .ai/logs/*.json | \
  awk '{sum+=$1; count++} END {print sum/count "ms"}'

# エラー頻度
jq '.tool_invocations[] | select(.status == "failed") | .command' .ai/logs/*.json | \
  sort | uniq -c | sort -nr

ダッシュボード連携

// scripts/dashboard-generator.ts
export class DashboardGenerator {
  async generateFromLDD(): Promise<Dashboard> {
    // 全ログファイル読込
    const logs = await this.readAllLogs();

    // 統計算出
    const stats = {
      totalTasks: logs.length,
      successRate: this.calculateSuccessRate(logs),
      avgDuration: this.calculateAvgDuration(logs),
      qualityScoreAvg: this.calculateQualityScoreAvg(logs)
    };

    // ダッシュボード生成
    return this.generateDashboard(stats);
  }
}

ベストプラクティス

1. intent は明確に

# Good
intent: "Firebase Auth invalid-credential エラーを修正し、E2Eテストを追加する"

# Bad
intent: "バグ修正"  # 不明確

2. plan は5-7語で簡潔に

# Good
plan:
  - "認証エラー原因特定"
  - "エラーハンドリング修正"
  - "E2Eテスト追加"

# Bad
plan:
  - "Firebase Authenticationの認証フローにおいて発生しているinvalid-credentialエラーの根本原因を特定するために、ログファイルとスタックトレースを詳細に分析し..."  # 長すぎ

3. tool_invocations は全実行を記録

# Good: すべてのコマンドを記録
tool_invocations:
  - command: "git checkout -b fix/270"
  - command: "npm run lint"
  - command: "npm run test"
  - command: "git commit"

# Bad: 一部のみ記録
tool_invocations:
  - command: "git commit"  # 途中経過が不明

関連ドキュメント


次のステップ


最終更新: 2025-10-10 バージョン: 2.0.0 管理者: AI Operations Lead