Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
245 changes: 228 additions & 17 deletions .agents/skills/drive/SKILL.md

Large diffs are not rendered by default.

505 changes: 505 additions & 0 deletions .agents/skills/health/SKILL.md

Large diffs are not rendered by default.

142 changes: 142 additions & 0 deletions .agents/skills/phase-issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
name: phase-issue
description: Phase-N tracking issue を生成する。cross-session handoff context、決定事項表、PR ごとのタスク、DoD、Phase N+1 outlook を含む構造化された issue body を組み立てて gh issue create で起票する。引数で全項目を渡す非対話モードと、不足分を補う対話モード(Claude Code companion)に対応する。
---

# phase-issue - Phase-N tracking issue 生成

ozzy-labs で繰り返し発生する Phase-N tracking issue(cross-session handoff context + 決定事項表 + PR ごとのタスク + DoD + Phase N+1 outlook)の構造をハードコードし、引数または対話で集めた内容から決定論的に issue body を組み立てる。`gh issue create --body-file` で起票するか、`--draft` 指定時は stdout に出力する。

このスキル単体で起票まで完結する。drive 連携や Phase 番号の自動採番は行わない(スコープ外)。

## 入力

```text
phase-issue <phase-number> "<title>"
--description "..." (project description; プロジェクト概要)
--refs "owner/repo1,owner/repo2" (参考実装。カンマ区切り)
--donts "..." (やってはいけないこと。改行区切り)
--decisions-file <path> (決定事項 YAML/Markdown ファイル)
--tasks-file <path> (PR ごとのタスクファイル)
--dod "..." (Definition of Done。改行区切り)
--outlook "..." (Phase N+1 outlook)
--related "..." (関連 issue/PR/ADR。改行区切り)
--label "<label>" (issue label。既定: "chore")
--repo "<owner/repo>" (起票先リポ。省略時はカレントリポ)
--draft (起票せず stdout に body を出力)
```

### 必須引数

- `<phase-number>`: 整数(例: `0`, `1`, `2`)
- `<title>`: 引用符でくくった文字列(例: `"agentic-watch foundation"`)

### 任意引数の取り扱い(非対話モード)

canonical SKILL.md は **非対話前提** で動作する。任意引数が不足している場合、対応するセクションは body から **省略**する(プレースホルダーでは埋めない)。「不明分は対話で集めたい」場合は Claude Code companion(`SKILL.claude-code.md`)を使う。

`--decisions-file` および `--tasks-file` が指定された場合、ファイル内容をそのまま該当セクションに転記する(解析・整形はしない。ユーザー側で markdown 整形済みであることを期待する)。

## ハードコードされた章立て

issue body は以下の章立てで構築する。**順序は固定**で、変更しない:

```markdown
# Phase {{N}}: {{title}}

## Cross-session handoff

このセクションは新しいセッション/エージェントが本 issue を読んだだけで作業を引き継げるよう、必要な context を集約する。

- **プロジェクト概要:** {{description}}
- **参考実装:** {{refs (linked)}}
- **やってはいけないこと:** {{donts (bulleted)}}

## 決定事項

{{decisions-file の内容、または "(TBD)"}}

## タスク(PR ごと)

{{tasks-file の内容、または "(TBD)"}}

## Definition of Done

{{dod (bulleted)}}

## Phase {{N+1}} outlook

{{outlook、または "(未定)"}}

## 関連

{{related (bulleted)}}
```

### セクションごとの整形ルール

- **Cross-session handoff:**
- `--description` がない場合は `(未記入)` ではなく **行ごと省略**(bulleted item を出さない)
- `--refs` はカンマ区切りを bulleted list に展開し、`owner/repo` は `https://github.com/owner/repo` に linkify する
- `--donts` は改行区切りを bulleted list に展開する
- 3 項目すべてが空の場合、`## Cross-session handoff` セクション自体を省略する
- **決定事項 / タスク(PR ごと):** ファイルが指定されない場合、セクション本文を `(TBD)` とする(セクション自体は残す)。Phase issue で **決定事項とタスクは骨格** に当たるため、未記入でもプレースホルダーを残して後追いを促す
- **DoD:** 改行区切りを `- [ ] item` 形式の checkbox list に展開する。空の場合 `(TBD)` とする
- **Phase N+1 outlook:** 文字列をそのまま転記する。空の場合 `(未定)` とする
- **関連:** 改行区切りを bulleted list に展開する。`#N` / `owner/repo#N` / URL いずれも許容(linkify はせず原文を保持)。空の場合セクションを省略する

### マーカーブロック注記

cross-session handoff の冒頭に以下の HTML コメントを必ず埋め込む。これは将来 phase-issue で再生成・更新する際の anchor として機能する:

```markdown
<!-- phase-issue:v1 phase=N -->
```

`v1` は本スキルが生成する body のフォーマットバージョン。schema を変える場合は bump する。

## 手順

### 1. 引数解析

1. `<phase-number>` と `<title>` を取得する。どちらも必須。欠落時はエラーを表示して中断する
2. オプションを解析する。同じオプションが複数回指定された場合は最後のものを採用する
3. `--decisions-file` / `--tasks-file` が指定された場合、ファイルの存在と読み取り可否を確認する。失敗時はエラーを表示して中断する

### 2. body 組み立て

1. ハードコードされた章立てに従って body を組み立てる
2. プレースホルダー `{{N}}` / `{{title}}` / `{{N+1}}` を実値で置換する
3. 各セクションの整形ルールに従い、空セクションは省略 / TBD / 未定 を適切に出し分ける
4. マーカーブロックを cross-session handoff の冒頭に挿入する

### 3. 起票または stdout 出力

- `--draft` 指定時:
- body を stdout に出力する
- `gh` コマンドは呼び出さない
- `--draft` 未指定時:
- body を一時ファイルに書き出す
- `gh issue create --title "Phase {{N}}: {{title}}" --label "<label>" --body-file <tmp>` を実行する
- `--repo` が指定されていれば `--repo` 引数を gh に渡す
- 起票成功時は issue URL を表示する

### 4. 完了報告

```text
phase-issue 完了:
タイトル: Phase <N>: <title>
起票先: <repo>
Issue: <URL> (--draft 指定時は "(stdout に出力)")
```

## 注意事項

- 引数で渡されない任意項目は body から省略するか TBD で埋める。Claude が想像で内容を補完しない
- `gh` CLI が未認証の場合はエラーメッセージを表示して中断する
- `--draft` モードでは外部副作用なし(ファイル書き込みも `gh` 呼び出しもない)
- title は double quote でくくる前提。コマンド側のシェルエスケープは呼び出し元の責任
- canonical SKILL.md は非対話前提。対話的に項目を集めたい場合は Claude Code companion を使う
- **過去 issue からの style 学習はしない**: 章立ては SKILL.md 内に固定する(学習機構は実装複雑度に対し対価が小さい)
- **Phase 番号の自動採番はしない**: `<phase-number>` は呼び出し元が明示する
- **drive 連携はしない**: phase-issue は起票で完結する。生成された issue の分割・実装は別途 drive で回す
213 changes: 187 additions & 26 deletions .agents/skills/review/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
name: review
description: コード変更や PR をレビューし、問題点・改善案を報告する。PR 番号または空(ワーキングツリー)を受け取る
description: コード変更や PR を 11 観点(perspectives)でレビューし、JSON 構造化出力 + 人間可読レポートで報告する。quick / deep モードを切替可能。PR 番号またはワーキングツリー差分を入力に取る
---

# review - コードレビュー
# review - 多観点コードレビュー

コードの変更や PR をレビューし、問題点・改善案を報告する
差分を 11 観点(perspectives)でレビューし、Critical / Warning / Info に分類して JSON + 人間可読レポートで報告する。[ADR-0025](https://github.com/ozzy-labs/handbook/blob/main/adr/0025-skills-review-multi-perspective.md) の hybrid 方式(quick: 単一エージェント / deep: 観点並列サブエージェント)を採用する

## 入力

Expand All @@ -17,50 +17,211 @@ description: コード変更や PR をレビューし、問題点・改善案を
- 変更がなければ `git diff main...HEAD` でブランチ差分を取得
- それでも変更がなければ、レビュー対象がない旨を伝えて終了する

## オプション

- `--axes=<axis,...>`: 適用観点を明示指定(自動選別を上書き、`default_enabled: false` 観点も明示時のみ有効化)
- `--deep`: deep モードで実行(観点ごとにサブエージェント並列起動。Claude Code 環境のみ。他アダプタでは quick にフォールバック)

## 観点(11 軸)

観点定義は `perspectives/<axis>.md` を SSOT とする。frontmatter で `category` / `applies_when` / `skip_when` / `default_enabled` / 検査項目 / severity ガイド / `exit_criteria.drive_loop` を宣言する。

| category | axis | 既定 |
| --- | --- | --- |
| required | correctness, security, conventions | 常に適用 |
| design | architecture, compatibility, maintainability | applies_when マッチ時 |
| quality | testing, performance, observability | applies_when マッチ時 |
| ux | usability, documentation | applies_when マッチ時 |

### 観点選別ロジック

`--axes` 未指定時は以下の順で適用観点を決定する:

1. `category: required` → 常に適用(`applies_when` / `skip_when` を無視)
2. `default_enabled: false` → `--axes` で明示指定された場合のみ適用(experimental 観点用、現状なし)
3. `skip_when.diff_only_in` がマッチ(全変更ファイルが指定 glob 集合の部分集合)→ 不適用(最優先のスキップ条件)
4. `applies_when` のいずれかの glob にマッチ → 適用(OR)
5. それ以外 → 不適用

`--axes=security,architecture` のように明示指定した場合は、その観点のみを適用する(`applies_when` / `skip_when` を無視)。

`skip_when` でサポートする初期キーは `diff_only_in` のみ。未定義キーは reader が無視する(forward-compat)。

## 手順

### 1. コンテキスト収集
### 1. 適用観点の決定

差分に含まれるファイルの周辺コードを確認し、変更の意図と影響範囲を把握する:
1. 差分から変更ファイル一覧を抽出する
2. `perspectives/` 配下の全観点 MD を Read し、frontmatter を解釈する
3. 上記の観点選別ロジックで適用観点リストを決定する
4. 適用観点リストを最初に表示する:

- 変更されたコンポーネント・ページの全体像を確認
- インポート元やエクスポート先を確認
- 変更に関連するドキュメントファイルを特定する
```text
適用観点 (5/11):
required: correctness, security, conventions
design: architecture
ux: documentation
```

### 2. レビュー実施

以下の観点で差分を分析する:
#### quick モード(デフォルト)

- **正確性:** ロジックの誤り、エッジケース
- **セキュリティ:** インジェクション、機密情報の露出
- **パフォーマンス:** 不要なレンダリング、画像最適化
- **コーディング規約:** コーディング規約との整合性
- **ドキュメント整合性:** コード変更がドキュメントに正しく反映されているか
単一エージェントが適用観点を順に走査する。各観点について:

### 3. レポート出力
1. 該当 `perspectives/<axis>.md` を Read(既に読み込み済みの場合は省略)
2. 検査項目・severity ガイドに従って差分をレビュー
3. findings を内部 JSON バッファに追加

3 段階の深刻度で分類する:
すべての観点を走査し終えたら集約に進む。

- **Critical** — 修正が必要(バグ、セキュリティ脆弱性)
- **Warning** — 修正を推奨(パフォーマンス問題、規約違反)
- **Info** — 任意の改善提案(リファクタリング、可読性向上)
#### deep モード(`--deep`)

各指摘には以下を含める:
観点ごとに `Agent({subagent_type: "code-reviewer"})` を **並列起動** する。各 subagent は対応する `perspectives/<axis>.md` を Read し、JSON で findings を返す。

呼び出しプロンプトの形式:

```text
[Critical] ファイル名:行番号
問題: <問題の説明>
理由: <なぜ問題なのか>
提案: <具体的な修正案>
axis: <axis-name>
mode: deep
context:
base: <base-ref>
head: <head-ref>
pr_number: <N (optional)>

<diff>
```

レポート末尾にサマリーを記載:
並列起動は **1 メッセージ複数 tool call** で行う。subagent からは slash command を呼べないため、観点 MD の Read と JSON 出力のみで完結させる。

deep モードは Claude Code 環境のみで利用可能。他アダプタ(codex-cli / gemini-cli)では quick にフォールバックする(adapter 別の挙動は `SKILL.<adapter>.md` で吸収)。

### 3. 集約

#### 重複統合

- 同一 `file:line` に複数観点が同じ issue を出した場合、1 件に統合し `axes` を併記する
- 同一 `file:line` で観点が異なるが issue 文言が同じ場合(例: security と correctness が両方「未サニタイズ入力」を指摘)も統合対象

#### 観点間衝突

- 原理的トレードオフ(例: security ↔ DX、observability ↔ performance)は **conflicts セクション** に別記し、severity を付けず判断委ねとする

#### グルーピング

レポートは「観点 → severity → ファイル」順でグループ化する。

### 4. JSON 構造化出力

内部表現は **必ず JSON**。findings はすべて JSON で保持し、PR コメント・標準出力は JSON からレンダラを通して人間可読フォーマットに変換する。

#### Schema (version "1")

```json
{
"version": "1",
"mode": "quick" | "deep",
"axes_applied": ["security", "correctness", "..."],
"findings": [
{
"axis": "security",
"severity": "critical" | "warning" | "info",
"file": "src/x.ts",
"line": 42,
"issue": "...",
"why": "...",
"suggestion": "...",
"axes_merged": ["security", "correctness"]
}
],
"conflicts": [
{
"axes": ["security", "usability"],
"file": "src/y.ts",
"line": 10,
"description": "..."
}
],
"summary": {
"by_axis": {
"security": {"critical": 0, "warning": 1, "info": 0}
},
"total": {"critical": 0, "warning": 1, "info": 3}
}
}
```

`axes_merged` と `conflicts` は任意フィールド(重複統合・観点間衝突がある場合のみ)。

#### Version migration policy

- `version` は単調増加の整数(文字列)。本 ADR で `"1"` を確立する
- reader 側(drive など)は `version` が現状コードの上限と一致する場合のみ機械判定を行う
- 未対応 version の場合は `unknown_review_version` として fail-soft 終了し、JSON を無視して人間可読部分のみ扱う
- 互換破壊変更は `version` を bump し、reader は最低 N-1 まで読める実装を維持する

### 5. レポート出力

#### 人間可読フォーマット

```text
レビュー結果:
レビュー結果 (mode: <quick|deep>, axes: <list>):

## correctness
[Critical] src/foo.ts:42
問題: <issue>
理由: <why>
提案: <suggestion>

## security
[Warning] .github/workflows/release.yaml:10
問題: ...

...

## conflicts
[security ↔ usability] src/y.ts:10
<description>

## サマリー
Critical: N 件
Warning: N 件
Info: N 件

by_axis:
correctness: C0 W0 I1
security: C0 W1 I0
...
```

#### PR コメントへの埋め込み(PR レビュー時)

人間可読レポートの末尾に JSON を **HTML コメント** として埋め込む(drive がこれを再読する):

```markdown
... 人間可読レポート ...

<!-- review-json:v1
{
"version": "1",
...
}
-->
```

PR レビューの場合、レポート全体を `gh pr comment <N> --body "<レポート>"` で PR にコメントとして投稿する。

### 6. 過去 PR コメントとの互換(resume)

drive が過去に投稿したコメントには JSON 埋込みがない場合がある。reader は次のように扱う:

- `<!-- review-json:v1 ... -->` を含むコメント → JSON を解析して機械判定
- JSON 不在のコメント → **legacy comment** として扱い、新規 review pass の trigger として無視する(過去コメントは消さない)
- `<!-- review-json:v<unknown> ... -->` → `unknown_review_version` として無視(fail-soft)

## 注意事項

- `Critical` を 1 件でも報告する場合は明確な悪影響(バグ・脆弱性等)の根拠を示す
- 観点の severity 判定は対応する `perspectives/<axis>.md` の severity ガイドに従う。観点を超えて勝手に重要度を上げ下げしない
- deep モードは観点数 × 並列度ぶんのトークンを消費する。drive のオーケストレーションモードでは強制的に quick にフォールバック(コスト管理)
- `Info` は提案のみ。drive の review loop では `Info` を修正対象としない
Loading
Loading