- name
- backlog-planner
- description
- agent-project の charter(プロジェクト憲章)と観点メモを、人がレビューできる粒度のバックログへ分解します。既存タスクと墓標を入力に取り、重複を出しません。agent-project の plan から呼ばれる場合に使用してください。
- metadata
- {"version":"1.0.0","tier":"experimental","category":"planning","tags":["agent-project","backlog","planning","acceptance-criteria"]}
# backlog-planner — 「エージェントが書き、人が直す」バックログ
## 概要
charter(+観点メモ)を、**人がタスクグラフ作成前にレビューできる粒度**のバックログへ分解する。
**なぜ人が読める粒度が要るのか**: 従来の分解は `title` と `verify`(1 行のシェルコマンド)しか
出さなかった。人はそれを見ても「このタスクが何をするのか」「なぜ要るのか」「どこを触るのか」が
分からず、計画レビューが実質的に機能しない。判断できないものは承認するしかない。
このスキルは、レビューに要る材料をタスク自身に持たせる:
**why(なぜ)・作業概要(何をどこまで)・scope(変更範囲)・risks(リスク)・
受入基準(何をもって完了とするか)・規模感。**
受入基準(`acceptance`)は `backlog-verifier` が settle 時に証跡付きで判定する一次表現である
(書式の正典は `tools/agent-project/backlog.md.example`)。**ここで書かれたものが、そのまま
done の根拠になる。**
## 入出力契約
`scripts/prompt.py` は **プロンプトを組み立てるだけ**(LLM は呼ばない)。実行・予算管理・
失敗トリアージは agent-project 側が持つ(`backlog-verifier` と同じ形)。
```
echo '<入力 JSON>' | python3 scripts/prompt.py
→ プロンプト本文を stdout に出力
```
### 入力 JSON
| キー | 内容 |
|---|---|
| `charter` | 憲章の本文(目標・制約・前提・成果物・受入条件・利用可能なリポジトリ) |
| `owns` | どの repo がどのパスを担当するか(書込先 workspace 選定の根拠) |
| `granularity` | `coarse`(既定・ユーザーストーリー相当) / `fine` / `finest` |
| `rules` | `rules.md`(プロジェクト恒常ルール)の抜粋 |
| `repo_context` | `context/<repo>.md`(repo-map)の抜粋。**作業概要の「変更対象」はこれを根拠に書く** |
| `existing` | 同一バージョンのバックログ `[{id, title, status, edited, summary, reason?}]`。現役(保留・実行中・レビュー中を含む)に加え、archive の却下済み(`status=="rejected"`・`reason` は却下理由)も直近分が載る。**タイトルが違っても意図が同じ・似ているタスクは出力しない**のがこのスキルの主要な責務。`edited=="human"` は人が確定させたもの |
| `tombstones` | 墓標 `[{title, reason}]`(人が却下・削除したタスク) |
| `notes` | 観点メモの本文(`distill-notes` のときのみ) |
| `retry` | 前回出力の欠落セクション(再要求時のみ) |
| `produced` | **この分解で既に出したタスクの題** `[str]`。1 件ずつ出させる契約(`contract: single`)で、同じ・似たものを出さないための入力であり、`after` の参照先でもある |
| `contract` | 出力契約。`single`(既定)=タスク 1 件ずつ / `array`=配列で一括。**器で決まる**——判断は agent-project が定義(`json_object_only`)に問い合わせて持ち、このスキルは写しを持たない |
### 出力
**`contract: single`(既定)**: タスク spec の **JSON オブジェクト 1 件のみ**(配列にしない)。
**もう出すものが無ければ `{"done": true}`** を返す——件数の制御は agent-project 側が持ち、
`done` か上限(`_PLAN_MAX_ITEMS`)まで 1 件ずつ訊きに来る。
必須項目 6 つ × 複数タスクを 1 回の配列で出させると、ローカル CLI の起動形
(`--format json`=オブジェクトしか返せない)と衝突して 0 件になる
(2026-08-31 の実測: 5 回中 4 回)。
**`contract: array`**: タスク spec の **JSON 配列 1 回**(自由文の器=クラウド CLI ほか向け。
配列を返せる器に 1 件ずつを課すと、タスク K 件に K+1 回の呼び出しを払う)。
キーは:
| キー | 必須 | 内容 |
|---|---|---|
| `title` | ● | タスクの題 |
| `why` | ● | charter のどの目標に効くか(1〜2 文) |
| `desc` | ● | **作業概要の配列**: 変更対象(リポジトリと主要ファイル/モジュールの見込み)・作業ステップ・影響範囲を1要素1項目で記述 |
| `scope` | ● | 変更してよいリポジトリ・ファイル・モジュールの配列 |
| `risks` | ● | 実装・運用上のリスクと対策の配列。該当なしは `["なし"]` |
| `acceptance` | ● | **受入基準の配列**(自然文 3〜7 項目) |
| `size` | ● | `S` / `M` / `L` |
| `workspace` | ● | 唯一の書込先 repo 名(`owns` を持つもの) |
| `refs` | | 読むだけの参照 repo |
| `out_of_scope` / `hints` | | やらないこと / 実装の手がかり |
| `after` | | 先行タスクの `title`(single は **`produced` にある題**・array は同じ配列内の題のみ・循環不可) |
| `verify` | | 書けるなら決定的シェルコマンド(**書けないなら省く**。無理に書かせない) |
| `cohort_items` | | 同じ手順を多対象に繰り返すときの対象一覧(`{item}` 展開) |
## 不変条件(agent-project 側が機械的に強制する)
0. **`contract: single` では 1 件ずつ受け取る**。agent-project が `produced` を伸ばしながら
`done` か上限まで呼び、集めるのは本体(`split` → `map` と同じ形)。`array` では配列 1 回
1. **必須セクション欠落は 1 回だけ再要求**(その 1 件について) → なお欠落なら `status: draft` で投入し、
欠落項目を票に書く。**捨てない**(沈黙で落とすと、charter が悪いのかスキルが壊れたのか
人が切り分けられない)
2. **墓標(完全一致)は投入されない**。類似は投入されるが needs に注記が付く
3. **既存タスクとの重複は投入側でも Jaccard 照合で弾かれる**(スキルは差し替え可能なので、
投入側の護りは外さない)
4. `edited: human` のタスクは**再提案しない**(人の記述 > エージェント提案)
## 意図の抑止はこのスキルの責務
投入側のタイトル照合(Jaccard・墓標の完全一致)は**言い換え・粒度変更の再提案を捕まえられない**。
「人が却下・保留した意図」「仕掛かり中の意図」と重なるタスクを出さない判断は、`existing`
(却下済みは却下理由付き)を読んだこのスキルが行う——分解は人の明示操作でしか走らないため、
ここで出したものはそのまま人のレビュー面に並ぶ。迷ったら出さない側に倒し、出すなら why に
既存・却下済みとどう違うのかを書くこと。
## カスタマイズ
上位のスキル置き場(プロジェクトの `.github/skills/backlog-planner/`)に同名スキルを置けば
全面的に差し替えられる。設定 `planner_skill` でスキル名自体も変えられる。
スキルが見つからないときは agent-project の組み込みプロンプト(同じ出力契約)へ落ちる
——計画が止まるとプロジェクトが 1 歩も進まないので、スキルは必須にしない。
View on GitHub