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 側が機械的に強制する)
contract: singleでは 1 件ずつ受け取る。agent-project がproducedを伸ばしながらdoneか上限まで呼び、集めるのは本体(split→mapと同じ形)。arrayでは配列 1 回- 必須セクション欠落は 1 回だけ再要求(その 1 件について) → なお欠落なら
status: draftで投入し、 欠落項目を票に書く。捨てない(沈黙で落とすと、charter が悪いのかスキルが壊れたのか 人が切り分けられない) - 墓標(完全一致)は投入されない。類似は投入されるが needs に注記が付く
- 既存タスクとの重複は投入側でも Jaccard 照合で弾かれる(スキルは差し替え可能なので、 投入側の護りは外さない)
edited: humanのタスクは再提案しない(人の記述 > エージェント提案)
意図の抑止はこのスキルの責務
投入側のタイトル照合(Jaccard・墓標の完全一致)は言い換え・粒度変更の再提案を捕まえられない。
「人が却下・保留した意図」「仕掛かり中の意図」と重なるタスクを出さない判断は、existing
(却下済みは却下理由付き)を読んだこのスキルが行う——分解は人の明示操作でしか走らないため、
ここで出したものはそのまま人のレビュー面に並ぶ。迷ったら出さない側に倒し、出すなら why に
既存・却下済みとどう違うのかを書くこと。
カスタマイズ
上位のスキル置き場(プロジェクトの .github/skills/backlog-planner/)に同名スキルを置けば
全面的に差し替えられる。設定 planner_skill でスキル名自体も変えられる。
スキルが見つからないときは agent-project の組み込みプロンプト(同じ出力契約)へ落ちる
——計画が止まるとプロジェクトが 1 歩も進まないので、スキルは必須にしない。