symmetric-dogfooding について
相互に依存する2つのリポジトリ間の連携を検証するスキルです。APIやデータ形式が個別に変化するプロジェクト向けに、依存関係の固定、双方向テスト、リリース前の調整手順を示します。
主な機能
- 01双方向の連携検証を構成
- 02境界となるAPIとデータ形式を記録
- 03リポジトリ間の依存バージョンを固定
- 04リリース前の検証手順を定義
活用シーン
- 01リポジトリ間のAPI互換性を確認
- 02リポジトリ間のデータ形式のずれを検出
- 03リリース前に連携上の問題を発見
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill symmetric-dogfoodingインストール後、Claude Code で/symmetric-dogfoodingを入力して読み込まれたか確認します。
同梱ファイルreferences/evolution-log.mdreferences/example-setup.md
詳細
対称的なドッグフーディング
2つのリポジトリがテストのために互いを利用し、下流で採用される前に双方が正しく連携することを確認する、双方向の統合検証パターンです。
自己進化型スキル:このスキルは使用を通じて改善されます。指示に誤りがある場合、パラメーターにずれが生じた場合、または回避策が必要だった場合は、先送りせず、すぐにこのファイルを修正してください。実際に再現できる問題がある場合にのみ更新してください。
パターンの概要
┌─────────────────────────────────────────────────────────────────┐
│ SYMMETRIC DOGFOODING │
│ │
│ Repo A ◄─────── mutual validation ───────► Repo B │
│ │
│ EXPORTS: EXPORTS: │
│ - Library/API - Library/API │
│ - Data structures - Data structures │
│ │
│ VALIDATES WITH: VALIDATES WITH: │
│ - Repo B real outputs - Repo A real outputs │
│ - Production-like data - Production-like data │
│ │
└─────────────────────────────────────────────────────────────────┘
このスキルを使う場面
次の場合にこのスキルを使います。
- 2つのリポジトリがプロデューサーとコンシューマーの関係にある
- APIが独立して進化しており、統合テストが必要である
- リポジトリ間でデータ形式にずれが生じる可能性がある
- 両方のリポジトリが活発に開発されている
TodoWrite タスクテンプレート
テンプレート A:2つのリポジトリ間で対称的なドッグフーディングを設定する
1. Identify integration surface (exports from A consumed by B and vice versa)
2. Document data formats, schemas, API signatures at boundary
3. Configure cross-repo dev dependencies in both repos
4. Pin versions explicitly (tags or SHAs, never main)
5. Create integration/ test directory in both repos
6. Write bidirectional validation tests (A validates with B outputs, B validates with A outputs)
7. Add validation tasks to the repo's task runner (moon.yml where the repo uses moon)
8. Document pre-release protocol in both CLAUDE.md files
9. Run full symmetric validation to verify setup
10. Verify against Symmetric Dogfooding Checklist below
テンプレート B:リリース前の検証
1. Run the validate-symmetric task in releasing repo
2. Check if other repo has pending changes affecting integration
3. If yes, test against other repo's feature branch
4. Document any failures in validation log
5. Fix integration issues before release
6. Update version pins after successful validation
7. Coordinate if breaking changes require simultaneous release
8. Verify against Symmetric Dogfooding Checklist below
テンプレート C:新しい統合ポイントを追加する
1. Identify new export/import being added
2. Update integration surface documentation
3. Add tests in both repos for new integration point
4. Run symmetric validation in both directions
5. Update version pins if needed
6. Verify against Symmetric Dogfooding Checklist below
対称的なドッグフーディングのチェックリスト
対称的なドッグフーディング作業の後は必ず、次の項目を確認してください。
- 両方のリポジトリに、相手のリポジトリをインポートする統合テストがある
- バージョンが明示的に固定されている(タグまたはコミット SHA)
- リリース前チェックリストにリポジトリ間の検証が含まれている
- 統合テストで実データを使っている(相手のリポジトリのモックではない)
- 破壊的変更の調整方法が文書化されている
- 検証タスクを単一のコマンドで実行できる
変更後のチェックリスト(自己保守)
このスキルを変更した後は、次の項目を確認してください。
- テンプレートが、対称的なドッグフーディングでよくあるシナリオを網羅している
- チェックリストが現在のベストプラクティスを反映している
- references/ の例が引き続き正確である
- 変更内容を evolution-log.md に追記する
実装ガイド
フェーズ 1:調査とマッピング
統合対象を特定します。
- Repo B が使用する Repo A のすべてのエクスポートを一覧にする
- Repo A が使用する Repo B のすべてのエクスポートを一覧にする
- データ形式、スキーマ、API シグネチャを文書化する
検証シナリオをマッピングします。
- Repo B のどの実データで Repo A の出力を検証できるか
- Repo A のどの実データで Repo B の出力を検証できるか
- 本番環境での使用時にのみ現れるエッジケースを特定する
フェーズ 2:依存関係の設定
リポジトリ間の開発用依存関係を設定します。
Python(uv/pip):
# Repo A pyproject.toml
[project.optional-dependencies]
validation = ["repo-b"]
[tool.uv.sources]
repo-b = { git = "https://github.com/org/repo-b", tag = "<tag>" } # SSoT-OK
# Repo B pyproject.toml
[project.optional-dependencies]
validation = ["repo-a"]
[tool.uv.sources]
repo-a = { git = "https://github.com/org/repo-a", tag = "<tag>" } # SSoT-OK
Rust(Cargo):
[dev-dependencies]
repo-b = { git = "https://github.com/org/repo-b", tag = "<tag>" } # SSoT-OK
Node.js:
{
"devDependencies": {
"repo-b": "github:org/repo-b#<tag>"
}
}
重要:タグまたはコミット SHA に固定してください。main/master ブランチは決して使用しないでください。
フェーズ 3:テスト基盤
両方のリポジトリにおけるディレクトリ構成:
repo-a/
└── tests/
├── unit/ # Internal tests
└── integration/ # Tests using repo-b real outputs
└── test_with_repo_b.py
repo-b/
└── tests/
├── unit/ # Internal tests
└── integration/ # Tests using repo-a real outputs
└── test_with_repo_a.py
双方向検証テストのパターン:
# repo-a/tests/integration/test_with_repo_b.py
"""Validate Repo A outputs work correctly with Repo B inputs."""
def test_a_output_consumed_by_b():
# Generate output using Repo A
a_output = repo_a.generate_data()
# Feed to Repo B - should work without errors
b_result = repo_b.process(a_output)
# Validate the round-trip
assert b_result.is_valid()
フェーズ 4:タスクの自動化
moon.yml の例(moon では : をプロジェクトとタスクの区切り文字として予約しているため、タスク ID には - を使用します)。
tasks:
validate-symmetric:
description: "Validate against partner repo"
script: "uv sync --extra validation && uv run pytest tests/integration/ -v"
validate-pre-release:
description: "Full validation before release"
deps: ["~:test-unit", "~:validate-symmetric"]
フェーズ 5:リリース前の手順
Repo A のリリース前:
- Repo A で
moon run :validate-symmetricを実行します(現在の Repo B に対するテスト) - Repo B に保留中の変更がある場合は、Repo B のブランチに対してもテストします
- 検証が成功したら、バージョンの固定を更新します
Repo B のリリース前:
- Repo B で
moon run :validate-symmetricを実行します(現在の Repo A に対するテスト) - Repo A に保留中の変更がある場合は、Repo A のブランチに対してもテストします
- 検証が成功したら、バージョンの固定を更新します
破壊的変更の調整:
- A で互換性を破る必要がある場合は、先に B を更新します
- B で互換性を破る必要がある場合は、先に A を更新します
- 密接に結合した変更では、同時リリースを検討します
アンチパターン
| アンチパターン | 問題 | 解決策 |
|---|---|---|
| 一方向のみ | バグの半分を見逃す | 必ず両方向をテストする |
| main ブランチの使用 | 不安定で、予期せず壊れる | タグまたは SHA に固定する |
| 小さな変更では省略する | 小さな変更が大きな破壊を招く | 常に完全な検証を実行する |
| 相手のリポジトリをモックする | 目的を損なう | 実際にインポートする |
| バージョンマトリックスを無視する | 本番環境で障害が気付かれないまま発生する | 互換性マトリックスを維持する |
参考資料
- example-setup.md - 実際の取引で使われているtrading-fitness/rangebar-pyの例
- evolution-log.md - スキルの変更履歴
外部資料:
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| 依存関係の解決に失敗する | バージョンのピン留めが古い | タグ/SHAのピン留めを最新の安定バージョンに更新する |
| ローカルではテストが通るが、CIでは失敗する | パートナーリポジトリのバージョンが異なる | 両方の環境でまったく同じバージョンをピン留めする |
| 破壊的変更を検出できない | 一方向のテストのみ実施している | 両方のリポジトリでvalidate-symmetricを実行する |
| 統合対象の範囲が不明確 | エクスポートが文書化されていない | テストを設定する前に、すべてのインポート/エクスポートを洗い出す |
| 変更対象が多すぎる | リリースが調整されていない | 破壊的変更を調整し、まずブランチでテストする |
| モックデータがバグを隠している | 実際のものではなくスタブを使っている | 統合には必ずパートナーリポジトリを実際にインポートする |
| バージョンの組み合わせが爆発的に増える | 組み合わせが多すぎる | サポート対象をN-1バージョンに制限し、明確に文書化する |
| 循環依存 | 両方のリポジトリが互いを必要としている | 検証にはoptional-dependenciesのみを使用する |
実行後の振り返り
このスキルの実行が完了したら、タスクを終了する前に振り返ります。
- 現在地を確認します。 — 編集する前に、このSKILL.mdの正式なパスを確認します。
- 何が失敗しましたか? — 原因となった指示を修正します。
- 予想以上にうまくいったことは何ですか? — 推奨プラクティスとして取り入れます。
- 実態とずれたものは何ですか? — 現状と一致しなくなったスクリプト、参考資料、依存関係を修正します。
- 記録します。 — きっかけ、修正内容、根拠を含むEvolution-logのエントリを追加します。
後回しにしてはいけません。次回の実行では、あなたが残したものが引き継がれます。