0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub Spec Kit の `/speckit.converge` を試す:実装のズレを検出して改修タスク化できるか

0
Posted at

はじめに

GitHub Spec Kit には、仕様から実装までを段階的に進めるためのコマンド群があります。

基本的な流れは、ざっくり言うと次のようなものです。

/speckit.constitution
/speckit.specify
/speckit.plan
/speckit.tasks
/speckit.implement

この流れに加えて、実装後のコードと仕様・計画・タスクのズレを確認するためのコマンドとして、/speckit.converge があります。

公式の Installation Guide では、/speckit.converge は “Assess codebase against artifacts and append remaining tasks” と説明されています。
また、公式リポジトリの templates/commands/converge.md を見ると、spec.md / plan.md / tasks.md を意図のソースとして読み、現在のコードベースとの差分を確認し、残作業があれば tasks.md に Convergence Phase として追記する、という動作が定義されています。

参考:

ただ、ドキュメントを読んだだけだと、実際にどの程度検出できるのかは分かりにくいです。

そこで今回は、小さな Todo API を題材にして、あえて実装を壊したうえで、/speckit.converge がそのズレを検出し、tasks.md に追加タスクとして記録できるかを試しました。

さらに、その追加タスクを /speckit.implement に渡して、正常に改修できるかも確認しました。

今回確認したこと

今回確認したのは、次の4点です。

1. 実装後のズレを /speckit.converge が検出できるか
2. 検出したズレを tasks.md に追加タスクとして append できるか
3. 追加されたタスクを /speckit.implement で修復できるか
4. 修復後に /speckit.converge で No gaps found になるか

検証は小規模な Todo API に限定しています。
そのため、この記事の内容は「今回の小さな題材ではこう動いた」という実験ログとして読んでください。

使用環境

主な環境は以下です。

項目 バージョン
macOS 26.5.1
Spec Kit 0.11.3
Claude Code 2.1.19
VSCode 1.127.0
Python 3.14.2
FastAPI 0.139.0
pytest 9.1.1

Spec Kit のバージョンは、.specify/init-options.json.specify/integration.jsonspecify --version で 0.11.3 と確認しました。検証は 2026-07-04 に実施しています。

補足すると、requirements.txt はバージョンをピン留めしていません。上記の Python / FastAPI / pytest は、今回の .venv に実際に入ったバージョンです。

題材にした Todo API

今回の題材は、FastAPIで作った小さな Todo API です。

主な機能は以下です。

POST /todos
  - Todoを作成する
  - titleは必須
  - priorityは任意
  - due_dateは任意
  - 作成直後は completed=false

GET /todos
  - Todo一覧を取得する
  - priorityでフィルタできる

PATCH /todos/{todo_id}/complete
  - 指定したTodoを完了状態にする

また、due_date については、実行時刻に依存しないように固定の REFERENCE_DATE を使う設計にしました。

今回の記事で主に見るのは、PATCH /todos/{todo_id}/complete に対応する complete_todo の挙動です。

正常な実装

正常な complete_todo は次のような実装です。

def complete_todo(todo_id: int) -> Todo | None:
    todo = _todos.get(todo_id)
    if todo is None:
        return None
    updated = todo.model_copy(update={"completed": True})
    _todos[todo_id] = updated
    return updated

指定された Todo が存在する場合、その Todo の completedTrue に更新し、保存したうえで返します。
存在しない場合は None を返し、API側で 404 Not Found に変換します。

この状態では、テストはすべて成功していました。

18 passed

意図的に壊した実装

次に、complete_todo をあえて次のように変更しました。

def complete_todo(todo_id: int) -> Todo | None:
    return _todos.get(todo_id)

この実装だと、Todoが存在する場合にそのまま返すだけです。

つまり、APIとしては PATCH /todos/{todo_id}/complete が呼べて、Todoも返ってきます。
しかし、肝心の completed=True への更新が行われません。

「APIは動いているように見えるが、仕様として期待される状態変更が行われていない」というズレを作った形です。

pytest の結果

この状態で pytest -q を実行すると、完了更新に関するテストだけが失敗しました。

17 passed / 1 failed

失敗したのは、指定した Todo だけが completed=True になることを確認するテストです。

FAILED tests/test_todos.py::test_fr008_fr009_complete_only_target_todo

ここでのポイントは、アプリ全体が壊れたわけではなく、完了更新の要求に関係する部分だけが失敗していることです。

/speckit.converge を実行する

この状態で、余計な説明は付けずに /speckit.converge を実行しました。

/speckit.converge

結果として、complete_todocompleted=True に更新していないことが検出されました。

検出結果の要旨は以下です。

pytest -q → 17 passed / 1 failed

新規の乖離を 1 件検出

app/store.py の complete_todo が completed=True へ更新せず、
Todo をそのまま返している。

PATCH /todos/{id}/complete が 200 を返しても完了状態が変わらない。

関連:
- FR-008
- FR-009
- User Story 3
- SC-003

gap-type: partial
severity: HIGH

今回のケースでは、APIや関数自体は存在しています。
しかし、要求されている状態更新が一部満たされていません。

そのため、missing ではなく partial として検出されたのは妥当だと感じました。

tasks.md に追加されたタスク

/speckit.converge の結果、tasks.md の末尾に新しい Convergence Phase が追加されました。

実際には Phase 10: Convergence として、T024 が追加されました。

要旨は以下です。

- [ ] T024 [US3] app/store.py の complete_todo(todo_id) を修正する。
  指定された Todo が存在する場合、その Todo の completed を True に更新し、
  保存したうえで更新後の Todo を返すようにする。
  関連: FR-008, FR-009, US3, SC-003

重要なのは、既存タスクを書き換えるのではなく、append-onlyで新しいタスクとして追記された点です。

完了済みだった既存タスクを未完了に戻すのではなく、次のように扱われていました。

実装後に発見されたズレを、追加の是正タスクとして記録する

この挙動は、実装後の差分管理として分かりやすいです。

/speckit.implement で修復する

次に、追加された T024 のみを対象にして /speckit.implement を実行しました。

指示としては、T024以外の仕様・テスト・既存タスクには触れず、complete_todo の修正だけを行うようにしました。

修復後の complete_todo は、次のように正常な実装に戻りました。

def complete_todo(todo_id: int) -> Todo | None:
    todo = _todos.get(todo_id)
    if todo is None:
        return None
    updated = todo.model_copy(update={"completed": True})
    _todos[todo_id] = updated
    return updated

その後、テストはすべて成功しました。

18 passed

最後にもう一度 /speckit.converge

修復後、最後にもう一度 /speckit.converge を実行しました。

結果は以下です。

No gaps found
pytest -q: 18 passed
Result: Converged

また、ギャップがない場合は tasks.md に空の Convergence Phase を追加することもありませんでした。
これは余計な差分が増えないので、自然な挙動だと思います。

分かったこと

今回の小さな検証では、/speckit.converge について以下が確認できました。

1. 実装と仕様・タスクのズレを検出できた
2. pytestの失敗結果と実装内容をもとに、ズレを特定できた
3. FR / User Story / Success Criteria に紐づけて説明できた
4. tasks.md に append-only で追加タスクを作成できた
5. 追加タスクを /speckit.implement に渡して修復できた
6. 修復後に No gaps found / Converged まで確認できた

特に印象的だったのは、単に「テストが失敗しています」と言うだけではなく、次のように仕様・タスク側の文脈に結びつけてくれた点です。

complete_todo が completed=True に更新していない
FR-008/009 と US3 に関係する
gap-type は partial
severity は HIGH

注意点・限界

一方で、今回の検証だけで過剰に一般化するのは危険です。

今回確認できたのは、あくまで小規模な Todo API における1つの欠陥注入です。

未検証のことも多くあります。

- テストが存在しない欠落をどこまで検出できるか
- 大規模なコードベースでどこまで正確に検出できるか
- 仕様自体が間違っている場合にどうなるか
- 複数の欠陥が同時にある場合にどこまで切り分けられるか
- バグ報告や改修履歴まで含めたトレーサビリティを管理できるか

また、今回の実験は Claude Code / VSCode 上で行っています。
利用するエージェントや実行環境によって挙動が変わる可能性もあります。

まとめ

今回の検証では、/speckit.converge は小規模な Todo API に対して、仕様・タスクと実装・テストのズレを検出し、tasks.md に追加タスクとして append できました。

さらに、その追加タスクを /speckit.implement に渡すことで、該当箇所を修復し、最終的に /speckit.convergeNo gaps found になることも確認できました。

つまり、少なくとも今回の範囲では、/speckit.converge は単なるチェックコマンドというより、次のようなループの一部として機能していました。

実装後のズレを検出する
↓
是正タスクとして記録する
↓
implementで修復する
↓
再度convergeで収束確認する

Spec Kitを使う場合、/speckit.implement で終わりにするのではなく、実装後に /speckit.converge を挟むことで、仕様と実装のズレを見直すプロセスを作れそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?