# Next Task

> develop/tasks.jsonから未着手タスクを1件選んで実行し、develop/tasks.json・develop/progress.mdを更新してコミットする。ユーザーが「次のタスクを進めて」「tasks.jsonのタスクをやって」と言ったとき、または/loopと組み合わせて全タスク完了までの自動進行に使う。

- Skill: `sinnlosses/next-task` (Agent Skill)
- Install (CLI): `npx skillmds@latest add sinnlosses/next-task`
- Raw SKILL.md: https://api.skillmd.com/api/skills/sinnlosses/next-task/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: sinnlosses (https://skillmd.com/u/sinnlosses)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/sinnlosses/next-task

---


`develop/tasks.json` を1サイクルぶん前に進める。フィールドの定義・`difficulty` の意味・
evidence の書き方・アーカイブのトリガーは `task-workflow` スキルの `WORKFLOW.md`
（以下「正典」）にあるのでここでは繰り返さない。このスキルは**1タスク分**を実行して終わる。
全件 `done` になるまで繰り返したい場合は `/loop /next-task` として使う（`/loop` 側が
続行/停止を判断する）。

## このプロジェクトの設定（CLAUDE.md の「## タスク運用」節）

!`sed -n '/^## タスク運用/,/^## /p' CLAUDE.md 2>/dev/null | grep . || echo '（「## タスク運用」節が無い。CLAUDE.md の他の節に書かれた検証コマンドを探す。無ければ /setup-tasks で節を用意する）'`

以下で**検証コマンド**・**整形コマンド**と書いたところは、この節の値に読み替える。
値が `なし` なら、そのコマンドは走らせず、タスク本文の「## 完了条件」だけで受け入れを
判定して、その旨を報告に書く。**節が無い場合は「なし」と決めつけない**——まだ節に移して
いないだけで、CLAUDE.md の別の節に「変更後は必ず〜を通す」と書いてあることが多い。
それも無いときだけ、検証コマンド無しで進める。アーカイブの置き場
（`docs/history/`）と予算は規約で固定（正典「ファイル配置と CLAUDE.md」）。
`develop/tasks.json` が無いプロジェクトなら、タスク運用を始めていない旨を報告して終了する
（勝手にファイルを作らない）。

## タスク本文を読み込まない

1タスクの `task` 本文は数KBある。**1件を選ぶために全件の本文を読まない**。選ぶのに要る値
（`status`・`dependencies`・`difficulty`・`loopable`・`summary`）は全部 `status.py` の TSV に
出るので、**本文を読むのは選んだ1件だけ**にする。`develop/progress.md` も同じで、このスキルが
するのは「完了したこと」の先頭への追記だけなので、全文を読まない（判定は `status.py` の
`progress` 行が出す）。

`/list-tasks` と同じ方針。tasks.json が数万文字まで育つ運用なので、ここを守るかどうかで
1サイクルのコンテキスト消費が一桁変わる。

## スクリプトが動かないとき

`status.py` / `archive.py` は `python3` を使う。**`python3` が無い・エラーで落ちる環境では、
tasks.json を全文読んで代用しない。** 節約の仕組みが死んでいることに気づけないまま、
毎サイクル数万文字を読む状態になるため。

**止まる理由は2つあり、報告先が違う。** 混同すると、直すべき場所と違うところを指してしまう:

| 出力 | 何が起きたか | すること |
| --- | --- | --- |
| `INVALID\t<path>\t<理由>` | `tasks.json` が読めない（JSONが壊れている、配列ではない） | **データの不備**。理由をそのまま報告して終了する。**直しに行かない**（運用中のデータなので、中身を確かめずに書き換えると進行中のタスクを失う） |
| `MISSING`・`EMPTY`・`INVALID`・TSV のいずれでもない出力 | `python3` が無い、スクリプトが traceback で落ちた | **環境の故障**。`python3` が使えない旨とエラー出力を報告して終了する |

どちらも `/loop` 側は「続行不要」の合図として扱う。なお TSV の末尾に出る `missing_field` 行は
**止まる理由にはならない**（フィールドが欠けたタスクを `?` で出したという報告で、一覧としては
成立している）。該当があれば完了報告に添える。

## 手順

1. **見渡す**: 一覧と判定はスクリプトが出す。**`develop/tasks.json` を Read ツールで開いたり
   `cat` したりしない**（理由は下の「タスク本文を読み込まない」）。

   ```bash
   python3 ${CLAUDE_SKILL_DIR}/../task-workflow/scripts/status.py develop/tasks.json
   ```

   `MISSING` ならタスク運用を始めていない旨を報告して終了する。`EMPTY` なら登録されている
   タスクは0件。`INVALID` なら `tasks.json` が読めない（上の「スクリプトが動かないとき」）。
   TSVの読み方は `/list-tasks` と同じ（列は `id / status / difficulty /
   loopable / dependencies / 着手可否 / passes / summary`）。

   末尾の `archive` 行（`tasks.json` の判定）か `progress` 行（`progress.md` の判定）が
   `YES` なら、**着手前にアーカイブする**（正典「いつ移すか（トリガー）」）。転記は判断を
   含まないので手で書き写さず、スクリプトに任せる:

   ```bash
   python3 ${CLAUDE_SKILL_DIR}/../task-workflow/scripts/archive.py develop/tasks.json
   ```

   出力の `MOVED` 行に、移したタスクIDとファイルサイズの前後が出る。完了報告にそのまま載せる。

   あわせて `develop/direction.md` を節ごとに見る（正典「指示メモ」の2節）。**節見出しが
   1つも無い（この変更より前に作られた）ファイルは、全体を `## ユーザーから` とみなす**
   （後方互換）:

   ```bash
   # ## ユーザーから の行数
   awk '/^## ユーザーから/{f=1;next} /^## /{f=0} f' develop/direction.md | grep -v '^\s*$' | wc -l
   # 節見出しが無ければ代わりにこちらの行数を「## ユーザーから」として扱う
   grep -v '^#' develop/direction.md | grep -v '^\s*$' | wc -l

   # ## エージェントのドラフト の行数
   awk '/^## エージェントのドラフト/{f=1;next} /^## /{f=0} f' develop/direction.md | grep -v '^\s*$' | wc -l
   ```

   `## ユーザーから` に中身があれば**未タスク化の指示が残っている**。`READY` なタスクが
   あるならそちらを止めず、`READY` が0件のときだけ手順2でその場でタスク化する
   （正典「指示メモ」）。
   `## エージェントのドラフト` の行数は「未承認のドラフトが溜まっている」という状態であって、
   `/plan-tasks` を急かす理由にはしない（正典「指示メモ」の承認ゲート）。それぞれの行数を
   完了報告に添える（手順2・「完了報告のフォーマット」で使う）。

2. **選ぶ**: まず手順1のTSVに `status` が `doing` の行が無いか見る。あれば**前回セッションの
   異常終了で着手途中のまま残ったタスク**なので、`READY` を選ぶより先にそちらを扱う。
   `doing` は自動では拾い直さない（`status.py` の `着手可否` 列も `doing` には `READY` を
   出さない）。作業ツリーに何が残っているか分からない状態でサブエージェントに委譲すると、
   「本文だけで作業が完結する」という前提（正典「difficulty に応じたモデルの切り替え方」）が
   崩れるため。該当タスクIDを添えて「`T-xxx` が `doing` のまま残っている。作業ツリーを
   確認してから再開するか判断してほしい」と報告して終了する（他に `READY` があっても、
   まずここで止まる。`/loop` 側はこれを「続行不要」の合図として扱う）。
   `doing` の行が無ければ、TSVで `着手可否` が `READY` の行から1件選ぶ（`status: "todo"` かつ
   依存が全て解決済み。`tasks.json` に存在しない依存＝アーカイブ済み＝完了扱いは
   スクリプトが織り込み済み）。`READY` が無ければ（全件 done、または残りが全て `BLOCKED:`）、
   手順1で見た `## ユーザーから` の中身の有無で分かれる（`## エージェントの
   ドラフト` だけに中身がある場合は「中身が無い」側で扱う。正典「指示メモ」）:
   - **`## ユーザーから` に中身がある → ここで止めず、その場でタスク化して続ける。**
     `plan-tasks` スキルを読み、その手順2〜8（確かめる・分解する・書く・登録する・
     指示メモを移す・コミット）を**ファイル入口（`## ユーザーから`）の分だけ**に対して
     実行する。**手順の正典は `/plan-tasks` なのでここには書き写さない。** `/loop` から
     回っている最中でも触ってよいのはこの節だけで、会話入口と `## エージェントのドラフト`
     には従来どおり触らない（正典「指示メモ」）。タスク化のコミットはまだブランチを切る前
     （デフォルトブランチ）で済ませ、`done` のコミットとは分ける（1タスク＝1コミット。
     正典「コミットメッセージ」）。済んだら手順1のTSVを取り直し、`着手可否` が `READY` の
     行から1件選んで手順3へ進み、そのまま1サイクルを終える（選び方はこの手順の上と同じで、
     `/loop` から回っているときは `loopable: "N"` を選ばないところまで変わらない）。
     **タスク化しても `READY` が1件も生まれなければ**（登録したものが全て `loopable: "N"`、
     依存で全て `BLOCKED:` など）、登録したタスクIDと `READY` が無い理由を添えて報告して
     終了する
   - `## ユーザーから` に中身が無い → 「進められるタスクが無い」とだけ報告して終了する
     （`## エージェントのドラフト` に未承認の行があれば、件数だけ添える）

   報告して終了したときは、どちらも `/loop` 側はこれを「続行不要」の合図として扱う。

   選んだら、**その1件の本文だけ**を読む:

   ```bash
   python3 -c "import json,sys; print([t for t in json.load(open('develop/tasks.json')) if t['id']==sys.argv[1]][0]['task'])" T-XXX
   ```

   **`/loop` から回されているときは `loopable` が `"N"` のタスクを選ばない**
   （正典「loopable」。フィールドが無いタスクは `"Y"` 扱い）。残りが `"N"` だけになったら
   「ユーザーの判断が必要なタスクのみが残っている」と、そのタスクIDを添えて報告して終了する
   （`/loop` 側はこれを「続行不要」の合図として扱う）。**ユーザーが直接 `/next-task` を
   呼んだときは `"N"` も選んでよい**。その場合は着手前に、ユーザーの判断が要る点を先に確認する。

3. **ブランチ**: 既定は選んだタスクの `feature/T-<タスクID>` ブランチを切って作業する
   （例: `T-008` を選んだら `git switch -c feature/T-008`。デフォルトブランチから分岐する）。
   プロジェクトの `CLAUDE.md`「## タスク運用」節の `- ブランチ:` 行がこの既定と違う運用を
   書いていれば、そちらに従う（正典「ファイル配置と CLAUDE.md」）。

4. **`doing` にする**: 選んだタスクの `status` を `"todo"` から `"doing"` に書き換える。
   `develop/tasks.json` の対象タスク1件だけを編集し、`passes`・`evidence` など他のフィールドは
   触らない。**この変更はコミットしない**（作業ツリー上にだけ置く。理由と、`done` へ変わる
   タイミングは正典「tasks.json のフィールド」の `status` の行）。

5. **実行**: Agentツールで、選んだタスクの `difficulty` と同じモデルを指定した
   サブエージェントに委譲する（正典「difficulty に応じたモデルの切り替え方」）:
   - `haiku` / `sonnet` / `opus` のいずれでも委譲する。**メインセッションが今どのモデルで
     動いているかは判断材料にしない**（メインと一致していても委譲する。理由は正典
     「なぜ一致していても委譲するのか」）
   - `tasks.json` の `task` 本文だけで作業が完結するよう、対象ファイル・完了条件・
     **検証コマンド**を通すことを明記して渡す（サブエージェントはまっさらな文脈で起動する）
   - **`task` 本文を prompt に貼り付けない。** タスクIDと、手順2で使ったのと同じ読み取り
     コマンドを渡してサブエージェント側に読ませる（貼ると本文がメインの出力トークンになる。
     正典「difficulty に応じたモデルの切り替え方」）
   - **`develop/tasks.json` はコミットしないことを明記して渡す。** 手順4で当該タスクの
     `status` を `doing` に書き換えた直後の状態で委譲が始まるため、サブエージェントが
     `git add -A` のような一括ステージングを行うと `doing` のままコミットされてしまう
     （記録は手順7でメイン側が行う）
   - ユーザーへの確認が必要な判断・会話中の文脈に依存する判断は委譲しない。これは
     モデル選択とは別の軸の話で、登録時の見立ては `loopable` に入っている。着手して
     初めて分かった場合は `loopable` を `"N"` に直し、委譲せずユーザーに預けて次のタスクへ進む
   - 着手後に想定より判断が重いと分かったら、`difficulty` を上げてから改めて進める

6. **受け入れ**: 委譲した場合は完了報告をそのまま信用せず、自分で差分（`git diff`）を確認し、
   **整形コマンド**があれば実行してから**検証コマンド**を実行して通ることを確かめる。
   検証コマンドが「なし」なら、タスク本文の完了条件を1つずつ目視で確かめ、報告に
   「検証コマンド未設定」と書く。方針からズレた実装（例: コメントの動機がすり替わっている、
   命名が既存規約と衝突する）があればその場で直してから次に進む。

7. **記録してコミット**: `develop/tasks.json` の対象タスクの `status` を `"doing"` から
   `"done"` に書き換え、`passes`/`evidence` も更新する（evidence は3行以内、後から検証できる
   形で。正典「良いevidenceの書き方」）。`develop/progress.md` の「完了したこと」に、
   **そのタスクの小節を1つ、節の先頭に足す**（`### YYYY-MM-DD 何をしたか（T-xxx）` の形で、
   中身は1〜2文）。**既にある小節に混ぜず、上に積む**——並びが「新しい順」であることに
   アーカイブが依存していて、下に足すとスクリプトが `ERROR` を返して止まる
   （正典「progress.md の構成」）。

   1タスク＝1コミットとし、件名の先頭にタスクIDを置く（正典「コミットメッセージ」）。
   手順4の `doing` への書き換えはコミットしていないので、ここでの差分は `todo` → `done`
   の1回ぶんになる。コミットメッセージの末尾は現在のセッションの
   attribution 指示（Co-Authored-By 等）に従う。

8. **マージ**: 作業ブランチをデフォルトブランチへ**ふつうの `git merge`** で取り込む
   （`git switch main && git merge feature/T-XXX`）。main がブランチの分岐後に進んで
   いなければ fast-forward で取り込まれ（コミットは増えない）、進んでいればマージコミットが
   できる。どちらでもよい。成功したら作業ブランチを削除する（`git branch -d feature/T-XXX`）。

   **コンフリクトが起きたら**、黙って解消しようとせず、コンフリクトしたファイルを報告して
   ユーザーに預けて終了する（`resolving-merge-conflicts` スキルで解消できる。`/loop` は
   これを「続行不要」の合図として扱う）。作業ブランチは削除せずに残す。

   **検証コマンドを通す位置**: fast-forward で済んだ場合は再実行しない（手順6で通した結果の
   まま main の内容が作業ブランチの到達点と同一になるため）。**マージコミットができた場合は、
   main で検証コマンドをもう一度通す**（両側の変更が初めて同居する状態になるため。正典
   「ファイル配置と CLAUDE.md」の「ブランチ運用」）。**これが落ちたら**main を壊れたまま
   放置せず、マージ直前の `HEAD` へ `git reset --hard` して main を元に戻す（作業ブランチには
   同じコミットが残っているので作業は失われない）。**reset の前に `git status --short` を見て、
   自分が作ったのではない未コミットの変更が無いことを確かめる**（あれば reset せず報告だけする）。検証コマンドの出力と main を巻き戻した旨を
   報告してユーザーに預けて終了する（`/loop` はこれを「続行不要」の合図として扱う）。作業
   ブランチは削除しない。

9. **push はしない**: 外部への反映は明示的に頼まれたときだけ行う。このスキルはローカルのマージまでで止める。

## 完了報告のフォーマット

最後に必ず次を1行ずつ示す（`/loop` が続行判断に使う）:

- 今回 done にしたタスクID
- 検証コマンドの結果（ファイル数・テスト件数。「なし」なら、完了条件を目視で確かめたこと）
- 残りの `todo` 件数（0なら「全タスク完了」と明言する）。うち `loopable: "N"` が
  何件かも添える（`/loop` では進まないので、ユーザーが自分で呼ぶ必要があるため）
- このサイクルで手順2の分岐に入ってタスク化したなら、登録したタスクIDと、そのコミットが
  `done` のコミットとは別であること
- 未タスク化の指示（`develop/direction.md`）の有無。節ごとの行数を分けて書く
  （`## ユーザーから` / `## エージェントのドラフト`）。タスク化した場合は移したあとの行数

