メインコンテンツまでスキップ

スキルメタデータ仕様(Issue #68 設計)

River Review のスキルは YAML フロントマターでメタデータを持ち、ローダー/ランナーがそれを元に選択・実行します。本仕様は、JSON Schema と TypeScript 型、ランナー実装の土台となるフィールド定義をまとめたものです。

1. 目的

  • スキル選択・ルーティングをメタデータだけで機械的に行えるようにする。
  • JSON Schema / TypeScript 型を実装する際の「真実の源泉」として参照できるようにする。
  • ランナー・ローダーが将来拡張(モデル選択、依存ツール呼び出しなど)しやすい粒度で設計する。

2. 現状の基本項目(skills/* を棚卸し)

現在のスキルで使われているキーと役割は以下のとおり。

FieldTypeRequired役割
idstringyesスキルの一意な ID(rr-<phase>-<slug>-### 推奨)。リネームや移動でも不変。
namestringyesレビュー出力などに表示する人間向け名称。
descriptionstringyesスキルが何をチェックするかの短い説明。
categoryenum (core | upstream | midstream | downstream)yesStream Architecture 上の分類。core は全ストリーム共通。
phaseenum (upstream | midstream | downstream) | enum[]optional互換性のために保持。category があればそちらを優先し、core は全フェーズ配列に展開される。
applyTostring[]yes*チェック対象ファイルの glob。ランナーが対象ファイルを絞り込むために使用。
path_patternsstring[]optionalapplyTo のエイリアス。trigger.path_patterns もサポート。
triggerobjectoptionalphase/applyTo をまとめるトリガーコンテナ。trigger.files/trigger.path_patterns はエイリアス。
tagsstring[]optionalスキルの分類タグ(例: security, performance)。
severityenum (info | minor | major | critical)optional重大度。出力の強調や並び替えに利用。

3. 拡張項目(今回設計)

将来のモデル選択や入力準備を見据えて、無理なく実装できる粒度の項目を定義する。

FieldTypeRequired目的・ユースケース許容値の例
inputContextenum string[]optionalスキルが前提とする入力ソース。ランナーが必要なコンテキストを用意し、揃わない場合にスキップする判断材料に使う。diff, fullFile, tests, adr, commitMessage, repoConfig
outputKindenum string[]optional (default: ["findings"])スキルが返す主な出力カテゴリ。UI での整列・集約や後段処理の分岐に利用。複数指定で兼用も可能。findings, summary, actions, tests, metrics, questions
modelHintenum stringoptionalモデル選択のコスト/精度指針。ランナーが上限トークンやコスト制約に合わせてモデルを選ぶ際のヒントにする。cheap, balanced, high-accuracy
dependenciesenum string[]optionalスキルが依存するツール/リソース。実行前に満たせない場合はスキップやデグレードを判断する。code_search, test_runner, adr_lookup, repo_metadata, coverage_report, tracing
prioritynumberoptional実行順序のヒント(数値が小さいほど先に実行)。LLM プランナーが無効なときの並び替えに利用。0, 10

outputKind の各値(解釈の揺れを防ぐための目安):

  • findings: コードの指摘・改善点(デフォルト)
  • summary: レビュー全体の要約
  • actions: 実装者が取るべき具体的な行動やコマンド
  • questions: 実装者への確認事項や未解決の問い
  • metrics: 複雑度・カバレッジなどの計測値
  • tests: 生成したテストやテストケース提案

補足:

  • enum は実装時に固定リスト化する前提。列挙にない値を許可する必要が生じた場合は custom:<name> のような prefix で拡張する運用を想定。
  • 依存ツールは runner/loader 側で実装可否が明確な単位(コード検索・テスト実行・ADR 検索など)にとどめる。

4. TypeScript インタフェース例

実装時にそのまま利用できる形の例。

type Phase = 'upstream' | 'midstream' | 'downstream';
type StreamCategory = 'core' | Phase;
type Severity = 'info' | 'minor' | 'major' | 'critical';

type InputContext = 'diff' | 'fullFile' | 'tests' | 'adr' | 'commitMessage' | 'repoConfig';

type OutputKind = 'findings' | 'summary' | 'actions' | 'tests' | 'metrics' | 'questions';

type ModelHint = 'cheap' | 'balanced' | 'high-accuracy';

type Dependency =
| 'code_search'
| 'test_runner'
| 'adr_lookup'
| 'repo_metadata'
| 'coverage_report'
| 'tracing';

export interface SkillMetadata {
id: string;
name: string;
description: string;
category: StreamCategory;
phase: Phase | Phase[]; // Derived from category (core => all phases)
applyTo: string[];
path_patterns?: string[]; // Alias for applyTo (kept for forward compat)
tags?: string[];
severity?: Severity;
inputContext?: InputContext[];
outputKind?: OutputKind[]; // default ['findings']
modelHint?: ModelHint;
dependencies?: Dependency[];
}

5. JSON Schema 実装メモ

  • categorycore/upstream/midstream/downstream のいずれか必須。core は Runner 内で全フェーズに展開される。
  • phaseseverity は既存どおり enum 固定。
  • inputContexttype: array, items.enum を上記リストで固定、minItems: 1, uniqueItems: true を推奨。
  • outputKind も同様に array + enum + minItems: 1。フィールド自体を省略した場合のみランナー側で ['findings'] をデフォルトとし、フィールドが存在する場合は空配列を許可しない。
  • path_patternsapplyTo のエイリアス。trigger 内でも同名キーを許可する。
  • modelHint は単一 enum。必須にはしない。
  • dependencies は array + enum + uniqueItems: true。未実装ツールを防ぐため列挙外は許可しない運用を基本とし、例外は custom:* を許容する場合のみ pattern を追加する。
  • additionalProperties: false を維持してスキーマドリフトを防止。

6. サンプル frontmatter(Before/After)

Before(現行フィールドのみ)

---
id: code-quality-sample
name: 'Sample Code Quality Pass'
description: 'Checks common code quality and maintainability risks.'
category: midstream
phase: midstream
applyTo:
- 'src/**/*.ts'
- 'src/**/*.js'
- 'src/**/*.py'
tags:
- style
- maintainability
- midstream
severity: 'minor'
---

After(拡張フィールドを追加)

---
id: code-quality-sample
name: 'Sample Code Quality Pass'
description: 'Checks common code quality and maintainability risks.'
category: midstream
phase: midstream
applyTo:
- 'src/**/*.ts'
- 'src/**/*.js'
- 'src/**/*.py'
tags:
- style
- maintainability
- midstream
severity: 'minor'
inputContext:
- diff
- fullFile
outputKind:
- findings
- actions
modelHint: balanced
dependencies:
- code_search
---

After(trigger コンテナを使う例)

---
id: code-quality-sample
name: 'Sample Code Quality Pass'
description: 'Checks common code quality and maintainability risks.'
category: midstream
trigger:
phase: midstream
files:
- 'src/**/*.ts'
tags:
- style
- maintainability
- midstream
severity: 'minor'
inputContext:
- diff
- fullFile
outputKind:
- findings
- actions
modelHint: balanced
dependencies:
- code_search
---

7. 実装者向けメモ

  • ランナーは phase / applyTo と合わせて、inputContext が満たせないスキルを事前にスキップする(例: ADR 未取得時は adr を要求するスキルを除外)。
  • outputKind を使って UI/出力整形を分ける(例: summary は上部、actions は ToDo として並べる)。
  • modelHint はフェーズやコスト上限と組み合わせてモデル選択する。最初は 3 段階の enum だけで十分。
  • dependencies は runner/loader が提供できるツールのチェックリストと突き合わせ、未対応なら graceful skip か fallback を選択する。
  • enum の粒度を増やしたくなった場合は実装前に合意する(特に outputKinddependencies)。