🤩

目にやさしい仕様駆動開発「spec-workflow-mcp」がもたらすブルーベリー効果

に公開


この記事は、LayerX Tech Advent Calendar 2025 の 2日目の記事です。

https://tech.layerx.co.jp/entry/tech-advent-calendar-2025

初日は @frkake さんの「OCR技術の変遷と日本語対応モデルの性能検証」と、@izumin5210 さんの「思考を減らしコードに集中するための tmux, Neovim 設定」の豪華二本立てでした。

こんにちは、@su8/denchuです。

クラナドは人生。電柱が好きです。現在、マサイ族の驚異的な視力を瞳に宿せると噂の「とあるブルーベリーのサプリメント」(諸説あり)が空前絶後の流行りをみせているバクラク勤怠チームで、ソフトウェアエンジニアをしています。


平均視力は3.0~8.0と推測され、中には12.0の数値を出すマサイ族もいるらしい。12...?

本記事では、大量のドキュメントレビューで目の疲れを感じやすい仕様駆動開発(SDD)に対して、いわば「仕様駆動開発におけるブルーベリー」とも言える「spec-workflow-mcp」について取り上げます。

そのブルーベリー効果を最大限にお伝えするために、記事は次のような構成にしました。

まず「AIコーディング時代の『見えない問題』」と「仕様駆動開発」について説明をし、その後、spec-workflow-mcp が仕様駆動開発を支援するなかで課題をどのように解決するのかを、サンプルTODOアプリケーションを題材にした実際のフローを追いながら見ていきます。具体例を通じて、より深い理解を目指します。

ところで、本記事の文章中には、「ブルーベリー」の言葉の波間にまぎれこむように「ハル・ベリー」がひとり潜んでいます。ぜひ、検索機能に頼らずに探してみてください(?)。

閑話休題、本題に入りましょう。

AI コーディング時代の「見えない問題」

2025年2月、Andrej Karpathy(OpenAI 共同創設者、元 Tesla AI リーダー)は X(旧 Twitter)で新しいコーディングスタイルに言及した。

There's a new kind of coding I call "vibe coding", where you fully give in to the vibes, embrace exponentials, and forget that the code even exists. It's possible because the LLMs (e.g. Cursor Composer w Sonnet) are getting too good.

— Andrej Karpathy (@karpathy) 2025年2月3日

「Vibe Coding」と名付けられたこのスタイルは、「完全に雰囲気に身を任せ、指数関数的な可能性を受け入れ、コードの存在すら忘れる」というものだ。LLMが十分に優れているため可能になったと彼は説明する。AI の提案をすべて受け入れ、エラーメッセージをそのまま AI にコピー&ペーストして修正させる。

しかし、わずか8ヶ月後の2025年10月、Karpathy 自身がこの手法の限界を認めた。彼のプロジェクト nanochat は、完全に手書きコードで実装された。

Good question, it's basically entirely hand-written (with tab autocomplete). I tried to use claude/codex agents a few times but they just didn't work well enough at all and net unhelpful, possibly the repo is too far off the data distribution.

— Andrej Karpathy (@karpathy) 2025年10月14日

「基本的に完全に手書き(タブ補完あり)です。Claude/Codex エージェントを何度か試しましたが、まったくうまく機能せず、むしろ役に立ちませんでした。おそらくこのリポジトリはデータ分布から大きく外れているためでしょう」。

Karpathy が指摘したのは、LLM の学習データの偏りという技術的限界だ。データ分布から外れた独自のアーキテクチャやドメインでは、AI エージェントは機能しない。

そして、これは氷山の一角に過ぎない。AI コーディングの課題は技術的限界だけではない。仮に AI が完璧にコードを生成できたとしても、開発プロセスそのものに構造的な問題が存在する。本記事が舞台とするのは、この後者の問題だ。

次に挙げる 3 つの課題は、AI の技術的限界とは無関係に、Vibe Coding スタイルそのものに内在する問題である。

1. 意図の喪失

プロンプトでコードを生成した瞬間、開発者の意図はどこにも記録されない。「カート内の在庫切れ商品をユーザーに通知する」という指示で AI がコードを生成する。数日後、「在庫切れ商品の決済エラー」のバグ報告が上がる。真の意図は「通知して、カート内からの在庫切れ商品の自動削除」だったが、元のプロンプトはもう残っていない。Slack を遡ってようやく判明。明示的な仕様があれば防げた問題だった。

2. 進捗の不透明性

AI に実装を任せると、進捗が外から見えない。「認証機能の進捗は?」という質問に「AI が実装中です」としか答えられない。どこまで完成し、何が残っているのか、開発者自身も把握していない。従来の Jira や GitHub Issues は AI エージェントと乖離し、更新されない。

3. レビューの困難さ

AI が生成したコードをレビューするとき、何を基準にすればいいのか。「なぜこのタイミングで在庫を確保するのか?」という疑問に、実装者は「AI がそう実装したので」と答える。要求仕様が口頭や Slack に散在している状態では、レビュアーは推測するしかない。変数名は指摘できても、ビジネスロジックの妥当性は検証できない。

仕様駆動開発という回答

これらの問題に対する回答の一つが、仕様駆動開発(Spec-Driven Development、SDD)だ。コードを書く前に仕様を書き、それを人間と AI 双方の「真実の源泉(Single Source of Truth)」とする。

GitHub はこう表現している。「私たちは『コードが真実の源泉』から『意図が真実の源泉』へと移行している」(Spec-driven development with AI)。コードを書くことから意図を明確にすることへ開発者の仕事がシフトしていることを象徴した表現である。

SDD の3つの成熟度レベル

Birgitta Böckeler の分析によれば、SDD には段階的に進化する3つのレベルがある。

レベル 定義 実装イメージ
Spec-First ・実装前に仕様を作成
・AI 開発ワークフローで使用
・仕様とコード両方を編集
完成後、仕様は破棄
Spec-Anchored ・完成後も仕様を保持
・機能の進化と保守に継続使用
・仕様が長期的成果物
・進化時に既存仕様を改善
Spec-as-Source ・仕様がメインソース
・人間は仕様のみ編集
・コードは「生成済み - 編集禁止」
・現在 Tessl Framework のみ目指す

現実的な目標設定として、多くの開発チームが見定めるのは Spec-Anchored だろう。

理由は3つある。

第一に、Spec-First は仕様を破棄するため、前述の「意図の喪失」問題を解決できない。2ヶ月後にコードを見ても、なぜその実装にしたのかわからない。

第二に、Spec-as-Source は理想形だが、現在はツールの成熟を待つ必要がある。コードを一切編集できない制約は、多くのチームにとって現実的ではない。

そして、第三に、Spec-Anchored は、この両極端の間に位置する。仕様を長期的成果物として保持することで、意図の喪失を防ぎつつ、コードも直接編集できる柔軟性を保つ。6ヶ月後にバグ修正や機能追加が必要になったとき、仕様を見れば「なぜこの設計にしたのか」がわかる。そして、変更に応じて仕様も更新する。これは、ほとんどの開発チームが実践可能で、かつ実質的な価値を提供するアプローチだ。

「ウォーターフォールへの回帰」なのか?

仕様駆動開発という言葉を聞いて、「それはウォーターフォール開発に戻るということか?」という疑問を持つ人もいるだろう。確かにどちらも「仕様を重視」するが、決定的な違いがある。それは仕様の位置づけと更新のされ方だ。

仕様駆動開発は仕様を一次成果物として「継続的に回し続ける」開発モデルであり、ウォーターフォールは工程を順に「流す」管理モデルである。

観点 仕様駆動開発(Spec-driven) ウォーターフォール
基本思想 ・仕様(契約)が真実の源泉
・実装/テスト/ドキュメントを追従
・フェーズを順に完了
・要件→設計→実装→テスト
仕様の扱い ・生きた成果物
・変更される前提
・凍結されがち
・変更に手続きとコスト
進め方 ・反復・並行が前提
・Spec→実装→テスト→Spec 更新を循環
・直列が前提
・工程ゲートで品質/進捗管理
フィードバック ・仕様へ早期フィードバック
・モック/スタブ/契約テスト活用
・動くものが後段に寄る
・フィードバックが遅延
変更耐性 ・変更は起きる前提
・互換性ルールを仕組み化
・変更は例外扱い
・計画変更・手戻りとして処理
テストの位置 ・コントラクトテストで継続検証
・仕様準拠を自動チェック
・統合/受入が後段に寄る
・仕様齟齬の発見が遅い

すこしくだけて説明すると、同じ「仕様が先」でも、イメージは次のように異なるものである。

仕様駆動開発において、仕様は「漸進的に更新されるコンパス+地図」であり、その生きた仕様を中心に開発プロセスが循環する。

created by Nano Banana Pro

一方、ウォーターフォールでは、仕様は凍結された設計図であり、開発プロセスは工程として直列に進む。

created by Nano Banana Pro

重要な点として、ウォーターフォールにも「要件定義・基本設計」という仕様に相当する工程はある。だから「仕様がある=仕様駆動」ではない。仕様駆動の本質は、仕様を継続的に更新しつつ、CI/テスト/生成で「仕様準拠を強制できる形」に置くことだ。

AI コーディング時代の仕様駆動開発は、AI が仕様から実装を生成し、実装結果を仕様と照合し、仕様の変更を即座に実装に反映するサイクルを高速で回す。これはウォーターフォールの「設計完了後に実装開始」という直列プロセスとは根本的に異なる。

既存 SDD ツールの共通課題:レビューつらみて国立公園


こちらは雄大なヨセミテ国立公園 (photoAC)

SDD を実装するツールは急速に増えている。AWS Kiro、GitHub Spec Kit、cc-sdd などだ。

しかし、これらには共通の課題がある。それはレビュー負荷の増大である。

Birgitta Böckeler による Martin Fowler のブログでの分析が、この問題を率直に指摘している。

Kiro の例
小さなバグを修正しようとしたところ、「ハンマーでクルミを割る」ようなワークフローだった。要件ドキュメントがこの小さなバグを 4 つのユーザーストーリーと合計 16 の受け入れ基準に変換した。

Spec Kit の例
大量の Markdown ファイルが生成され、それらは相互に、また既存のコードと重複していた。著者は率直にこう述べている。「正直なところ、私はこれら全ての Markdown ファイルをレビューするより、コードをレビューしたい」。

つまり、SDD の理念は素晴らしいが、実装がテキストベースの Markdown ファイルの羅列では、レビュー体験が悪化する。開発者は大量の文書を読むために開発者になったわけではない、という嘆きだろう(うっ、あの日の記憶が...)。

まあ要するに「目に優しくない」のである。

spec-workflow-mcp の差別化要素


ブルーベリー、おひとついかがですか?

spec-workflow-mcp は「目に優しい」。

このひとことに尽きるといっても過言ではない。では、なにがそう言わしめるのか。それは、リアルタイム Webダッシュボード による視覚化である。

リアルタイム Webダッシュボード による視覚化

テキストファイルを読む代わりに、Webブラウザでダッシュボードを開くと、プロジェクトの全体像が視覚的に表示される。このダッシュボードこそが、spec-workflow-mcp がもたらすブルーベリー効果の核心である。

実際のダッシュボードを紹介する前に、ダッシュボードが提供する機能を簡単に整理すると次のようになる。

機能カテゴリ 提供される価値
プロジェクト概要 ・全 spec の一覧表示
・各 spec のステータス
・リアルタイム更新
ドキュメントビューア ・Requirements/Design/Tasks の構造化表示
・Steering Documents へのアクセス
・Markdown レンダリング
タスク進捗トラッキング ・視覚的な進捗バー
・詳細ステータス(pending/in-progress/completed)
・依存関係の可視化
実装ログ ・全タスク実装の検索可能なログ
・コード統計(追加/変更/削除行数)
承認ワークフロー ・レビュー統合
・フィードバックループ

この段階では、まだイメージが湧かず「ほう?」という感じであろう。

以降、実際のダッシュボードを見ていく。

実践例:ダッシュボードで見る開発フロー

ここでは、既存の TODO アプリに spec-workflow-mcp を導入し、期限設定機能を追加する例を見ていく。

シナリオ

シンプルな Next.js TODO アプリがすでに動作している状態を想定する。基本機能(タスクの追加・編集・削除・完了)は実装済みだ。まるで私が実装したかのように述べたが、Opus 4.5 で作成している。彼奴の戦闘力は530000である。


どことなく漂うブルーベリーカラー


ブルーベリー、おひとついかがですか?

ここに、新機能として「各タスクに期限を設定し、期限切れタスクを目立つようにする」機能を追加したい。

以上の機能追加を行うために、まず spec-workflow-mcp をセットアップする。

セットアップ

spec-workflow-mcp はバージョンアップが頻繁に行われているため、ここでは特定のバージョン(v2.0.9)を前提とする。

まず、ダッシュボードを起動する(MCP サーバーとは別プロセス)。

npx -y @pimzino/[email protected] --dashboard

デフォルトでは5000番ポートが使用されるが、既存プロセスと競合する場合は --port [任意のポート番号] を指定することで、明示的に特定ポートでダッシュボードプロセスが起動する。

npm ではなく、pnpm を用いている場合は次のようになる。

pnpm dlx @pimzino/[email protected] --dashboard

ターミナルに「Dashboard started at: http://localhost:5000」に類する表示が出力される。ブラウザでこの URL を開くと、次のような空のダッシュボードが表示される。

続いて、spec-workflow-mcp の管理対象とするプロジェクトを追加していく。こちらは、MCPサーバーとして機能するため、特定のAIエージェントに依存するものではない。本記事では Claude Code を前提とする。

Claude Code では、次のコマンドでプロジェクトを追加する。

cd [プロジェクトのパス]
current_path=$(pwd)
claude mcp add spec-workflow npx @pimzino/[email protected] -- "$current_path"

この時点では、MCPサーバーは未起動のため、ダッシュボードにはプロジェクトが何も表示されない。ダッシュボードにプロジェクトを表示させる(MCPサーバーを起動させる)ために、プロジェクトパスで Claude Code を起動する。

そうすると、次のようにプロジェクトが表示されることが確認できる。

ヘッダーに表示されているトグルから推測される通り、複数のプロジェクトを選択表示することができるようになっている。つまり、複数プロジェクトに対してMCPサーバーを登録し、各プロジェクトで Claude Code を起動すれば、一つのダッシュボードで複数プロジェクトの進捗を一括管理することができる。

この例は一つしかMCPサーバーが起動していないので選択肢は一つ

実は、以前のバージョンではマルチプロジェクトをサポートしていなかったのだが、2025年11月にマージされたPRによりサポートされた。実に嬉しい機能追加である。

参考までに、これらダッシュボードプロセスとMCPサーバーとの関係は、公式資料を引用すると次のように図解できる。


https://github.com/Pimzino/spec-workflow-mcp/blob/multi-project-support/docs/technical-documentation/architecture.md#high-level-components

セットアップが完了すれば、いよいよ機能開発を spec-workflow-mcp の 5つのフェーズ(Steering → Requirements → Design → Tasks -> Implementation)に沿って進めていく。

Steering フェーズ:プロジェクト方針の文書化

Steering Documents は、プロジェクト全体の方針・制約・ガイドラインを定義するドキュメントだ。既存プロジェクトに spec-workflow-mcp を導入する場合、まず Steering で現状を文書化することから始める。

本記事では Claude Code を前提に対して次のようなプロンプトを送信する。

この TODO アプリプロジェクトの steering documents を作成して

すると、spec-workflow-mcp がツールの機能を呼び出して、Steering Documents を作成する。何度かツール利用の許可を求められるが、基本的にすべて許可で問題ない。

どのツールを呼び出すべきかはMCPサーバーが判断することであるため覚える必要はないが、参考までにツールのカテゴリを表にまとめる(参照資料:Tool System (src/tools/))。

カテゴリ ツール名 説明
Workflow guides spec-workflow-guide 仕様駆動開発のワークフロー全体のガイド
steering-guide Steering Documents の作成と管理のガイド
Document creation create-spec-doc 新しい仕様ドキュメントの作成
create-steering-doc 新しい Steering ドキュメントの作成
Context loading get-spec-context 仕様ドキュメントのコンテキスト読み込み
get-steering-context Steering ドキュメントのコンテキスト読み込み
get-template-context テンプレートのコンテキスト読み込み
Status management spec-list 仕様ドキュメントの一覧表示
spec-status 仕様のステータス確認
manage-tasks タスクの管理と追跡
Approval workflow request-approval 承認リクエストの送信
get-approval-status 承認ステータスの確認
delete-approval 承認リクエストの削除

何度かツール利用を許可していると、次のようなメッセージが出力される。

現在、product.md の承認待ちです。ダッシュボードで承認をお願いします。

指示に従いダッシュボードを表示し、「承認」メニューを選択すると、次のような承認画面が表示される。

「レビューと表示」を選択すると、次のようなドキュメントが表示される。

ここからが「レビュー負荷」の軽減に貢献する部分である(すでにダッシュボードの見た目の時点で、気分的には軽減されているが)。

開発者は「Annotate」を選択した状態で、2種類のコメントを指示することができる。一つが「テキストを選択して指摘事項を入力」というもので、次のような画面になる。

特定の箇所に対して指摘事項がある場合に有用である。

もう一つが「全般コメントを追加」というもので、特定の箇所ではなく、ドキュメント全体に影響のあるような指摘事項がある場合に有用である。次のような画面になる。

これらの入力内容は、右側に一覧化される(内容は便宜的に適当なものにしている)。

そして、一通り指摘事項を入力したら、「修正を依頼」ボタンを押下する。

この段階ではステータスの変更がなされただけであり、修正作業は始まらない。修正作業を始める、もしくは、修正方針についてAIに相談するには、Claude Code に戻りやり取りをする。

修正を開始してほしい場合のプロンプト例

レビューしました。コメントに基づき修正を実施してください。

修正方針について相談したい場合のプロンプト例

レビューしました。修正を実施する前に、まずは方針を相談したいです。

修正事項が無くなるまでやり取りが進行したら、最後は「即時承認」ボタンを押下し、Claude Code に承認した旨を伝えて承認ワークフローを終了する。

Steering では product.md の他に2つのドキュメント(tech.md, structure.md)が作成されるため、同様にレビューと承認作業を行う。

最終的に、Steering で3つのドキュメントが作成されたことが確認できる(クリックすればマークダウンファイルのプレービューを閲覧できる)。

まだ第一段階の Steering フェーズであるが、ここまでの流れですでに「ブルーベリー」の効果を実感できるのではないだろうか。エディター上であってもマークダウンファイルのプレビューは可能であるが、修正事項を依頼するのは骨が折れる作業である。ダッシュボードを用いれば、これらの作業負荷が軽減される。


ええやん

仮に、Rawデータのマークダウンファイルを確認したくなった場合は、Steering により.spec-workflow/steering/ ディレクトリ配下に3つのドキュメント(product.md, tech.md, structure.md)が作成されているため、そちらを参照すればよい。

project-root/
├── .spec-workflow/              # All workflow data
│   ├── specs/                   # Specifications
│   │   └── feature-name/        # Individual spec
│   │       ├── requirements.md  # Phase 1
│   │       ├── design.md        # Phase 2
│   │       └── tasks.md         # Phase 3
│   ├── steering/                # Project guidance
│   │   ├── product.md           # Product vision         ⭐️
│   │   ├── tech.md              # Technical standards    ⭐️
│   │   └── structure.md         # Code organization      ⭐️
│   ├── approvals/               # Approval workflow data
│   │   └── spec-name/           # Per-spec approvals
│   └── 諸々.
└── [your project files]        # Existing project

Requirements フェーズ:期限設定機能の要件定義

次に、追加したい機能の要件を定義するために、Claude Code に次のようなプロンプトを送信する。

期限設定機能の spec を作成してください。

すると、要件ドキュメントに対する承認依頼が作成される。これは、Steering フェーズと同様のワークフローである。一貫性のある体験によりストレスが少ない(ないとは言わない)。

要件は、EARS(Easy Approach to Requirements Syntax)形式で記述される。

生成されたrequirements.md

Requirements Document

Introduction

期限設定機能は、TODO アイテムに期限日時を設定し、期限が近づいている、または過ぎているタスクを視覚的に識別できるようにする機能です。この機能により、ユーザーはタスクの優先順位を明確にし、時間管理を改善できます。

この機能は、product.md で示された「Future Vision」の「期限管理」に対応するものであり、ユーザーが期限を設定し、期限が近いタスクを把握できるようにすることで、生産性向上を実現します。

Alignment with Product Vision

この機能は以下の点でプロダクトビジョンに整合します:

  • ユーザーエクスペリエンスの向上: 期限の可視化により、タスクの緊急度を一目で把握可能
  • 生産性の向上: 期限管理によって計画的なタスク遂行をサポート
  • シンプルさの維持: 複雑な機能を避け、必要最小限の期限設定機能を提供
  • プライバシーファースト: すべてのデータはローカルストレージに保存

Requirements

Requirement 1: 期限日時の設定

User Story: TODO 作成・編集時にユーザーとして、タスクに期限日時を設定したい。そうすることで、いつまでにタスクを完了すべきかを明確にできる。

Acceptance Criteria

  1. WHEN ユーザーが TODO 作成フォームを開く THEN システムは期限日時入力フィールドを表示する SHALL
  2. WHEN ユーザーが期限日時を入力せずに TODO を作成する THEN システムは期限なしの TODO を作成する SHALL
  3. WHEN ユーザーが有効な期限日時を入力して TODO を作成する THEN システムは期限付きの TODO を作成し、ローカルストレージに保存する SHALL
  4. WHEN ユーザーが既存の TODO を編集する THEN システムは現在の期限日時を入力フィールドに表示する SHALL
  5. WHEN ユーザーが TODO 編集時に期限日時を変更する THEN システムは新しい期限日時で TODO を更新する SHALL
  6. WHEN ユーザーが TODO 編集時に期限日時をクリアする THEN システムは期限なしの状態に更新する SHALL

Requirement 2: 期限の視覚的表示

User Story: TODO 一覧を見るユーザーとして、各タスクの期限状態を視覚的に把握したい。そうすることで、優先的に取り組むべきタスクを素早く識別できる。

Acceptance Criteria

  1. WHEN TODO に期限が設定されている THEN システムは TODO アイテムに期限日時を表示する SHALL
  2. WHEN 期限まで 24 時間以上ある THEN システムは通常の表示スタイルで期限を表示する SHALL
  3. WHEN 期限まで 24 時間未満である THEN システムは警告色(オレンジ系)で期限を表示する SHALL
  4. WHEN 期限が過ぎている THEN システムは危険色(赤系)で期限を表示する SHALL
  5. WHEN TODO が完了状態である THEN システムは期限の警告表示を適用しない SHALL
  6. WHEN TODO に期限が設定されていない THEN システムは期限表示を省略する SHALL

Requirement 3: 期限による並び替え(オプション)

User Story: TODO 一覧を見るユーザーとして、期限が近い順にタスクを並び替えたい。そうすることで、緊急度の高いタスクに集中できる。

Acceptance Criteria

  1. WHEN TODO 一覧が表示される THEN システムはデフォルトで作成日時の降順(新しい順)で表示する SHALL
  2. IF 将来的にソート機能を実装する THEN システムは期限日時の昇順(期限が近い順)でソート可能にする SHALL
  3. IF 期限なしの TODO が存在する AND 期限ソートが有効 THEN システムは期限なし TODO を一覧の最後に配置する SHALL

Requirement 4: 期限情報の詳細表示

User Story: TODO 詳細パネルを見るユーザーとして、期限情報を詳しく確認したい。そうすることで、残り時間や期限の状態を正確に把握できる。

Acceptance Criteria

  1. WHEN ユーザーが TODO を選択する THEN システムは詳細パネルに期限日時を表示する SHALL
  2. WHEN 期限が設定されている THEN システムは「残り X 日」または「X 日超過」のような人間に読みやすい形式で表示する SHALL
  3. WHEN 期限まで 24 時間未満 OR 期限超過 THEN システムは詳細パネルでも警告色で表示する SHALL
  4. WHEN TODO に期限が設定されていない THEN システムは「期限なし」と表示する SHALL

Non-Functional Requirements

Code Architecture and Modularity

  • Single Responsibility Principle: 期限関連のロジックは専用のユーティリティ関数に分離する
  • Modular Design:
    • 型定義は src/types/todo.ts に追加
    • 期限判定ロジックは src/utils/dateUtils.ts に実装(新規作成)
    • 既存コンポーネントへの影響を最小化
  • Dependency Management:
    • 外部の日付ライブラリは使用しない(ネイティブ Date API のみ使用)
    • 既存の useTodos Hook を拡張
  • Clear Interfaces:
    • Todo インターフェースに dueDate?: string を追加
    • 日付フォーマット関数の型定義を明確化

Performance

  • レンダリングパフォーマンス: 期限判定は useMemo でメモ化し、不要な再計算を防ぐ
  • ストレージ効率: 期限は ISO 8601 形式の文字列として保存(既存の createdAt、updatedAt と同じ形式)
  • 初期ロード時間: 期限機能追加後も 2 秒以内の初期ロードを維持

Security

  • 入力検証: ユーザー入力の日付を検証し、無効な日付を拒否
  • XSS 対策: React の自動エスケープに依存(追加の対策不要)
  • データ整合性: 期限日時は常に有効な ISO 8601 形式で保存

Reliability

  • 下位互換性: 期限フィールドはオプショナル(dueDate?)とし、既存の TODO データとの互換性を保つ
  • エラーハンドリング:
    • 無効な日付入力時は適切なエラーメッセージを表示
    • 日付パース失敗時はフォールバック表示を提供
  • データ永続性: 期限情報も他のフィールドと同様に localStorage に確実に保存

Usability

  • 直感的な入力: HTML5 の <input type="datetime-local"> を使用し、ブラウザネイティブの日付ピッカーを活用
  • 視覚的フィードバック:
    • 期限の警告色は WCAG 2.1 AA 準拠のコントラスト比を確保
    • 色だけでなくアイコンやテキストでも状態を示す
  • レスポンシブ: 期限入力フィールドはモバイルデバイスでも使いやすいサイズと配置
  • アクセシビリティ:
    • 期限入力フィールドに適切な label を設定
    • スクリーンリーダー対応のための aria-label を追加
    • 期限状態をテキストでも明示(「期限超過」「あと 2 日」など)

一部を抜粋すると、次のような文章である。

Requirements
Requirement 1: 期限日時の設定
User Story: TODO 作成・編集時にユーザーとして、タスクに期限日時を設定したい。そうすることで、いつまでにタスクを完了すべきかを明確にできる。

Acceptance Criteria
WHEN ユーザーが TODO 作成フォームを開く THEN システムは期限日時入力フィールドを表示する SHALL
WHEN ユーザーが期限日時を入力せずに TODO を作成する THEN システムは期限なしの TODO を作成する SHALL
WHEN ユーザーが有効な期限日時を入力して TODO を作成する THEN システムは期限付きの TODO を作成し、ローカルストレージに保存する SHALL
WHEN ユーザーが既存の TODO を編集する THEN システムは現在の期限日時を入力フィールドに表示する SHALL
WHEN ユーザーが TODO 編集時に期限日時を変更する THEN システムは新しい期限日時で TODO を更新する SHALL
WHEN ユーザーが TODO 編集時に期限日時をクリアする THEN システムは期限なしの状態に更新する SHALL

EARSは、2009年にロールス・ロイス社(Rolls-Royce PLC)のアリスター・メイビン(Alistair Mavin)氏とそのチームによって開発された。初見では面喰らうような見た目であるが、慣れてしまえば読みやすい。

自然言語で記述される要求の曖昧さや矛盾を減らし、明確でテスト可能な要求を簡単に記述できるようにするための構文テンプレートを、エンジニアリングの道具箱の一つとして所持しておくと、いつか身を助けるかもしれない。

Steering と同様、承認可能な水準になるまでレビューと承認作業を行い、次の段階に進む。

Design フェーズ:技術設計

要件が固まったら、技術設計に進むために、Claude Code に次のようなプロンプトを送信する。

design フェーズを進めてください。

すると、もはやおなじみであろう、次のようなデザインドキュメントに対する承認依頼が作成される。

生成されたdesign.md

Design Document

Overview

期限設定機能は、TODO アイテムに期限日時フィールドを追加し、期限の状態(通常、警告、超過)を視覚的に表示する機能です。この機能は既存の TODO 管理システムに最小限の変更で統合され、ローカルストレージベースのアーキテクチャを維持します。

実装は以下の主要コンポーネントで構成されます:

  • 型定義の拡張: Todo インターフェースに dueDate フィールドを追加
  • 日付ユーティリティ: 期限状態の判定とフォーマット機能を提供する新規モジュール
  • UI コンポーネントの拡張: フォーム、リスト、詳細表示への期限フィールド追加
  • 状態管理の更新: useTodos Hook での期限データの処理

Steering Document Alignment

Technical Standards (tech.md)

この設計は以下の技術標準に従います:

  • TypeScript strict モード: すべての新規コードで型安全性を保証
  • React 19 のベストプラクティス: useCallback、useMemo を活用したパフォーマンス最適化
  • ローカルストレージ: すべてのデータはクライアントサイドに保存(tech.md の Data Storage に準拠)
  • ISO 8601 形式: 期限日時は既存の createdAtupdatedAt と同じ形式で保存
  • ネイティブ API 優先: 外部ライブラリを使用せず、ブラウザの Date API のみを使用

Project Structure (structure.md)

プロジェクト構造の規約に従います:

  • ファイル配置:
    • 型定義: src/types/todo.ts に追加
    • ユーティリティ: src/utils/dateUtils.ts を新規作成
    • コンポーネント: 既存の src/components/*.tsx を拡張
    • Hook: 既存の src/hooks/useTodos.ts を拡張
  • 命名規則:
    • ユーティリティ関数: camelCase (例: getDueDateStatus, formatDueDate)
    • 型定義: PascalCase (例: DueDateStatus)
    • 定数: UPPER_SNAKE_CASE
  • インポート順序: React → 型定義 → コンポーネント → Hooks → ユーティリティ

Code Reuse Analysis

Existing Components to Leverage

  • useTodos Hook (src/hooks/useTodos.ts):

    • createTodoupdateTodo 関数を拡張して dueDate フィールドを処理
    • 既存の localStorage 保存ロジックを再利用
    • 型定義 TodoInput を拡張
  • TodoForm コンポーネント (src/components/TodoForm.tsx):

    • 既存のフォーム構造に期限入力フィールドを追加
    • useState による状態管理パターンを踏襲
    • バリデーションとサブミット処理を拡張
  • TodoItem コンポーネント (src/components/TodoItem.tsx):

    • 既存の日付表示(createdAt)パターンを参考に期限表示を追加
    • 条件付きスタイリングのパターンを再利用
  • TodoDetail コンポーネント (src/components/TodoDetail.tsx):

    • 既存の詳細表示レイアウトに期限情報を追加
    • 日付フォーマット処理を統一

Integration Points

  • localStorage (STORAGE_KEY: "todos"):

    • 既存の JSON シリアライズ/デシリアライズ処理をそのまま使用
    • dueDate フィールドはオプショナルなので既存データとの互換性を保つ
  • 型システム (src/types/todo.ts):

    • Todo インターフェースを拡張
    • TodoInput 型を更新して期限入力をサポート

Architecture

Modular Design Principles

  • Single File Responsibility:
    • dateUtils.ts: 期限関連のロジックのみを担当
    • 既存コンポーネントは UI レンダリングに集中
  • Component Isolation:
    • 期限表示ロジックは dateUtils.ts に集約し、コンポーネントからは呼び出すのみ
  • Service Layer Separation:
    • ビジネスロジック(期限判定): dateUtils.ts
    • データ永続化: useTodos.ts
    • プレゼンテーション: 各コンポーネント
  • Utility Modularity:
    • 日付ユーティリティは独立したモジュールとして実装

Components and Interfaces

Component 1: dateUtils モジュール

  • Purpose: 期限日時に関するすべてのロジックを提供
  • ファイルパス: src/utils/dateUtils.ts (新規作成)
  • Interfaces:
    export enum DueDateStatus {
      NONE = 'none',           // 期限なし
      NORMAL = 'normal',       // 24時間以上
      WARNING = 'warning',     // 24時間未満
      OVERDUE = 'overdue'      // 期限超過
    }
    
    export function getDueDateStatus(dueDate: string | undefined, completed: boolean): DueDateStatus
    export function formatDueDate(dueDate: string): string
    export function getRelativeTimeText(dueDate: string): string
    
  • Dependencies: なし(ネイティブ Date API のみ)
  • Reuses: なし(新規モジュール)

Component 2: Todo 型の拡張

  • Purpose: 期限フィールドを追加した型定義
  • ファイルパス: src/types/todo.ts (既存ファイルを拡張)
  • Interfaces:
    export interface Todo {
      id: string;
      title: string;
      description: string;
      completed: boolean;
      createdAt: string;
      updatedAt: string;
      dueDate?: string;  // 新規追加(オプショナル)
    }
    
    export type TodoInput = Pick<Todo, "title" | "description" | "dueDate">;  // 拡張
    
  • Dependencies: なし
  • Reuses: 既存の Todo インターフェース

Component 3: TodoForm コンポーネントの拡張

  • Purpose: 期限入力フィールドの追加
  • ファイルパス: src/components/TodoForm.tsx (既存ファイルを拡張)
  • 追加する State:
    const [dueDate, setDueDate] = useState<string>("");
    
  • 追加する UI:
    • <input type="datetime-local"> フィールド
    • クリアボタン(オプション)
  • Dependencies: Todo, TodoInput
  • Reuses: 既存のフォーム構造、useState パターン

Component 4: TodoItem コンポーネントの拡張

  • Purpose: TODO アイテムに期限表示を追加
  • ファイルパス: src/components/TodoItem.tsx (既存ファイルを拡張)
  • 追加する機能:
    • 期限日時の表示
    • 期限状態に応じたスタイリング(色変更)
  • Dependencies: dateUtils (新規)、Todo
  • Reuses: 既存の日付表示ロジック、条件付きスタイリング

Component 5: TodoDetail コンポーネントの拡張

  • Purpose: 詳細パネルに期限情報を表示
  • ファイルパス: src/components/TodoDetail.tsx (既存ファイルを拡張)
  • 追加する機能:
    • 期限日時の詳細表示
    • 相対時間表示(「あと 2 日」など)
  • Dependencies: dateUtilsTodo
  • Reuses: 既存の詳細表示レイアウト

Component 6: useTodos Hook の拡張

  • Purpose: 期限フィールドの保存と読み込みをサポート
  • ファイルパス: src/hooks/useTodos.ts (既存ファイルを拡張)
  • 変更点:
    • createTodo 関数で dueDate を受け取る
    • updateTodo 関数で dueDate の更新をサポート
    • localStorage への保存時に dueDate を含める
  • Dependencies: TodoTodoInput
  • Reuses: 既存の localStorage ロジック

Data Models

Todo モデル(拡張)

export interface Todo {
  id: string;                 // UUID v4 形式
  title: string;              // タスクのタイトル
  description: string;        // タスクの詳細説明
  completed: boolean;         // 完了状態
  createdAt: string;          // 作成日時(ISO 8601)
  updatedAt: string;          // 更新日時(ISO 8601)
  dueDate?: string;           // 期限日時(ISO 8601、オプショナル)
}

DueDateStatus 列挙型(新規)

export enum DueDateStatus {
  NONE = 'none',              // 期限が設定されていない
  NORMAL = 'normal',          // 期限まで 24 時間以上
  WARNING = 'warning',        // 期限まで 24 時間未満
  OVERDUE = 'overdue'         // 期限超過
}

TodoInput 型(拡張)

export type TodoInput = Pick<Todo, "title" | "description" | "dueDate">;

Error Handling

Error Scenarios

  1. 無効な日付形式の入力

    • Handling:
      • datetime-local input の HTML5 バリデーションに依存
      • JavaScript で Date オブジェクトの isNaN チェック
    • User Impact:
      • フォーム送信時にエラーメッセージ表示
      • 「有効な日付を入力してください」
  2. 過去の日付の入力

    • Handling:
      • 警告は表示するが、入力自体は許可(ユーザーの意図を尊重)
      • 保存後、即座に「期限超過」状態として表示
    • User Impact:
      • オレンジまたは赤色で表示され、視覚的フィードバック
  3. 日付パースの失敗

    • Handling:
      • try-catch で Date オブジェクト生成をラップ
      • フォールバック: 「期限情報の表示エラー」
    • User Impact:
      • エラーメッセージではなく、「-」や「不明」と表示
      • コンソールに警告ログ
  4. 既存データとの互換性

    • Handling:
      • dueDate はオプショナルなので、未定義でも問題なし
      • getDueDateStatus は undefined を処理
    • User Impact:
      • 既存の TODO は「期限なし」として表示
      • シームレスな移行

Testing Strategy

Unit Testing

現在、テストフレームワークは未導入ですが、将来的に以下をテスト:

  • dateUtils モジュール:

    • getDueDateStatus: 各種期限状態の正しい判定
    • formatDueDate: 日付フォーマットの正確性
    • getRelativeTimeText: 相対時間表示の正確性
    • エッジケース: undefined、無効な日付、過去/未来の日付
  • useTodos Hook:

    • createTododueDate が正しく保存されるか
    • updateTododueDate が更新されるか
    • localStorage への保存/読み込みが正常に動作するか

Integration Testing

  • フォームからの TODO 作成フロー:

    1. 期限を設定して TODO 作成
    2. localStorage に保存される
    3. 一覧に正しく表示される
    4. 期限状態(通常/警告/超過)が適切に反映される
  • TODO 編集フロー:

    1. 既存 TODO の期限を変更
    2. 変更が localStorage に保存される
    3. 一覧と詳細表示が更新される

End-to-End Testing

  • ユーザーシナリオ 1: 期限付き TODO の作成:

    1. フォームを開く
    2. タイトル、説明、期限を入力
    3. 送信
    4. 一覧に期限が表示されることを確認
  • ユーザーシナリオ 2: 期限警告の表示:

    1. 24 時間未満の期限で TODO を作成
    2. オレンジ色で表示されることを確認
    3. 詳細パネルで「あと X 時間」と表示されることを確認
  • ユーザーシナリオ 3: 期限超過の表示:

    1. 過去の日付で TODO を作成
    2. 赤色で「期限超過」と表示されることを確認
  • ユーザーシナリオ 4: 期限のクリア:

    1. 期限付き TODO を編集
    2. 期限フィールドをクリア
    3. 保存後、期限表示がなくなることを確認

Implementation Notes

CSS スタイリング

期限状態に応じたスタイルを globals.css に追加:

.due-date-normal {
  color: var(--color-text-secondary);
}

.due-date-warning {
  color: #f59e0b; /* オレンジ */
  font-weight: 500;
}

.due-date-overdue {
  color: #ef4444; /* 赤 */
  font-weight: 600;
}

アクセシビリティ考慮事項

  • 期限入力フィールドに <label> を設定
  • 警告・超過状態をアイコン(⚠️、🔴)とテキストで併記
  • スクリーンリーダー用の aria-label を追加
  • キーボード操作のみで期限設定可能

パフォーマンス最適化

  • getDueDateStatus の結果を useMemo でメモ化
  • 一覧表示時の日付フォーマット処理を最小化
  • localStorage への保存は既存の useEffect 内で実行(追加の保存処理なし)

将来的な拡張性

この設計は将来的な機能拡張をサポートします:

  • 通知機能: 期限 X 時間前に通知
  • ソート機能: 期限順に並び替え
  • フィルター機能: 期限超過のみ表示
  • リマインダー: ブラウザ通知 API との統合
  • 繰り返しタスク: 定期的な TODO の自動生成

いい意味で変わり映えしない承認依頼であるが、承認可能な水準になるまでレビューと承認作業を行い、次の段階に進む。

Tasks フェーズ:実装タスクの分解

設計が完了したら、実装タスクを生成するために、Claude Code に次のようなプロンプトを送信する。

タスクを生成してください。

すると、もはやおなじみのおなじみであろう、次のような実装タスクに対する承認依頼が作成される。

生成されたtasks.md

Tasks Document

Phase 1: 型定義とユーティリティの実装

  • 1. Todo 型に dueDate フィールドを追加

    • File: src/types/todo.ts
    • Todo インターフェースに dueDate?: string を追加
    • TodoInput 型を更新して "dueDate" を含める
    • Purpose: 期限データの型安全性を確保
    • Leverage: 既存の Todo インターフェース
    • Requirements: Requirement 1(期限日時の設定)
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: TypeScript Developer specializing in type systems | Task: Extend the Todo interface in src/types/todo.ts to add optional dueDate field (string in ISO 8601 format) and update TodoInput type to include dueDate, following requirement 1 (期限日時の設定) from requirements.md | Restrictions: Do not modify existing fields, maintain backward compatibility with existing Todo data, dueDate must be optional, follow existing ISO 8601 pattern used in createdAt and updatedAt | Leverage: Existing Todo interface pattern, ISO 8601 date format convention | Success: Todo interface has dueDate?: string field, TodoInput includes dueDate in Pick type, TypeScript compilation succeeds without errors, existing code remains compatible | After implementation, use log-implementation tool with detailed artifacts (types modified) and mark task as complete in tasks.md
  • 2. 日付ユーティリティモジュールを作成

    • File: src/utils/dateUtils.ts (新規作成)
    • DueDateStatus enum を定義(NONE, NORMAL, WARNING, OVERDUE)
    • getDueDateStatus(dueDate, completed) 関数を実装
    • formatDueDate(dueDate) 関数を実装
    • getRelativeTimeText(dueDate) 関数を実装
    • Purpose: 期限判定とフォーマット処理のロジックを集約
    • Leverage: ネイティブ Date API
    • Requirements: Requirement 2(期限の視覚的表示), Requirement 4(期限情報の詳細表示)
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: Frontend Developer with expertise in date handling and utility functions | Task: Create dateUtils module at src/utils/dateUtils.ts implementing DueDateStatus enum and date utility functions (getDueDateStatus, formatDueDate, getRelativeTimeText) following requirements 2 and 4 from requirements.md and design.md Component 1 specification | Restrictions: Use only native Date API (no external libraries like date-fns or moment), handle undefined/invalid dates gracefully, completed todos should always return NONE status, times within 24 hours should be WARNING, past dates should be OVERDUE | _Leverage: Native Date API, ISO 8601 format from existing codebase | Requirements: Requirement 2, Requirement 4 | Success: DueDateStatus enum with 4 values defined, getDueDateStatus correctly categorizes dates based on 24-hour threshold and completion status, formatDueDate returns human-readable Japanese format, getRelativeTimeText returns "あとX日" or "X日超過" format, all functions handle edge cases (undefined, invalid dates) | After implementation, use log-implementation tool with detailed artifacts (functions created with signatures and purpose) and mark task as complete in tasks.md

Phase 2: 状態管理の拡張

  • 3. useTodos Hook を拡張して期限をサポート
    • File: src/hooks/useTodos.ts
    • createTodo 関数で dueDate を受け取り保存
    • updateTodo 関数で dueDate の更新をサポート
    • localStorage への保存時に dueDate を含める
    • Purpose: 期限データの永続化を実現
    • Leverage: 既存の localStorage ロジック、TodoInput 型
    • Requirements: Requirement 1(期限日時の設定)
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: React Developer with expertise in custom hooks and state management | Task: Extend useTodos hook in src/hooks/useTodos.ts to handle dueDate field in createTodo and updateTodo functions following requirement 1 and design.md Component 6 specification | Restrictions: Do not change existing localStorage key or format structure, maintain backward compatibility with existing todos without dueDate, preserve existing useCallback dependencies, follow existing patterns for createdAt/updatedAt | _Leverage: Existing localStorage logic in useEffect, existing createTodo/updateTodo patterns, TodoInput type from task 1 | Requirements: Requirement 1 | Success: createTodo accepts and saves dueDate field to new todos, updateTodo can modify dueDate including setting to undefined (clearing), localStorage correctly persists dueDate, existing todos load without errors (backward compatible) | After implementation, use log-implementation tool with detailed artifacts (functions modified, integration with localStorage) and mark task as complete in tasks.md

Phase 3: UI コンポーネントの拡張

  • 4. TodoForm に期限入力フィールドを追加

    • File: src/components/TodoForm.tsx
    • useStatedueDate 状態を追加
    • <input type="datetime-local"> フィールドを追加
    • フォーム送信時に dueDate を含める
    • 編集モード時に既存の dueDate を表示
    • Purpose: ユーザーが期限を入力できるようにする
    • Leverage: 既存のフォーム構造、useState パターン
    • Requirements: Requirement 1(期限日時の設定)
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: Frontend Developer specializing in React forms and user input | Task: Add due date input field to TodoForm component in src/components/TodoForm.tsx following requirement 1 and design.md Component 3 specification | Restrictions: Follow existing form structure and styling patterns, use HTML5 datetime-local input type, ensure proper label and accessibility (aria-label), maintain existing form validation patterns, support both create and edit modes | _Leverage: Existing useState pattern for title/description, existing useEffect for editingTodo, existing form structure and CSS classes | Requirements: Requirement 1 | Success: Form displays datetime-local input field with proper label "期限", dueDate state syncs with editingTodo prop in edit mode, form clears dueDate on successful submit (create mode), onSubmit passes dueDate in TodoInput object, input follows project styling conventions, accessible with keyboard navigation | After implementation, use log-implementation tool with detailed artifacts (component modified, UI fields added) and mark task as complete in tasks.md
  • 5. TodoItem に期限表示を追加

    • File: src/components/TodoItem.tsx
    • 期限が設定されている場合に期限日時を表示
    • dateUtilsgetDueDateStatusformatDueDate を使用
    • 期限状態に応じて色を変更(通常/警告/超過)
    • Purpose: 一覧で期限を視覚的に確認できるようにする
    • Leverage: dateUtils モジュール、既存の日付表示パターン
    • Requirements: Requirement 2(期限の視覚的表示)
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: Frontend Developer with expertise in React components and conditional styling | Task: Add due date display to TodoItem component in src/components/TodoItem.tsx following requirement 2 and design.md Component 4 specification | Restrictions: Use dateUtils functions from task 2, follow existing date display pattern (see createdAt display), apply conditional CSS classes based on DueDateStatus (normal/warning/overdue), do not show due date if undefined, do not apply warning styles if todo is completed | _Leverage: dateUtils.getDueDateStatus and formatDueDate from task 2, existing date display pattern with toLocaleDateString, existing conditional className pattern | Requirements: Requirement 2 | Success: Due date displays in Japanese format when set, color changes based on status (normal: default, warning: orange #f59e0b, overdue: red #ef4444), completed todos show due date without warning colors, no display when dueDate is undefined, follows existing component styling | After implementation, use log-implementation tool with detailed artifacts (component modified, integration with dateUtils) and mark task as complete in tasks.md
  • 6. TodoDetail に期限詳細表示を追加

    • File: src/components/TodoDetail.tsx
    • 期限日時の詳細表示を追加
    • dateUtilsgetRelativeTimeText を使用して相対時間表示
    • 期限状態に応じたスタイリング
    • Purpose: 詳細パネルで期限情報を詳しく確認できるようにする
    • Leverage: dateUtils モジュール、既存の詳細表示レイアウト
    • Requirements: Requirement 4(期限情報の詳細表示)
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: Frontend Developer specializing in React and detailed information display | Task: Add due date details section to TodoDetail component in src/components/TodoDetail.tsx following requirement 4 and design.md Component 5 specification | Restrictions: Use dateUtils functions (formatDueDate, getRelativeTimeText, getDueDateStatus), follow existing detail panel layout structure, show "期限なし" when dueDate is undefined, apply warning/overdue styling consistently with TodoItem, maintain existing component organization | _Leverage: dateUtils from task 2, existing detail section structure with labeled information, existing conditional styling pattern | Requirements: Requirement 4 | Success: Detail panel shows formatted due date with label "期限", displays relative time text ("あと2日" or "3日超過"), applies appropriate color styling based on status, shows "期限なし" when undefined, integrates seamlessly with existing detail layout | After implementation, use log-implementation tool with detailed artifacts (component modified, UI enhancements) and mark task as complete in tasks.md

Phase 4: スタイリングと最終調整

  • 7. 期限表示用の CSS スタイルを追加

    • File: src/app/globals.css
    • .due-date-normal, .due-date-warning, .due-date-overdue クラスを定義
    • WCAG 2.1 AA 準拠のコントラスト比を確保
    • レスポンシブ対応
    • Purpose: 期限状態を視覚的に区別できるようにする
    • Leverage: 既存の CSS Variables とスタイリングパターン
    • Requirements: Requirement 2(期限の視覚的表示)
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: Frontend Developer with expertise in CSS and accessibility | Task: Add due date status styling classes to globals.css following requirement 2 and design.md Implementation Notes CSS Styling specification | Restrictions: Follow existing CSS pattern and naming conventions, ensure WCAG 2.1 AA contrast ratio compliance, use colors specified in design (warning: #f59e0b, overdue: #ef4444), make responsive for mobile devices, integrate with existing theme variables if available | _Leverage: Existing CSS structure in globals.css, existing color scheme and styling patterns | Requirements: Requirement 2 | Success: Three CSS classes defined (.due-date-normal, .due-date-warning, .due-date-overdue), warning and overdue classes have accessible color contrast, styles work on mobile and desktop, integrates with existing design system | After implementation, use log-implementation tool with detailed artifacts (CSS classes added) and mark task as complete in tasks.md
  • 8. 動作確認と最終調整

    • Files: 全体の動作確認
    • 期限付き TODO の作成・編集・削除をテスト
    • 期限状態の視覚的表示を確認(通常/警告/超過)
    • 既存データとの互換性を確認
    • エッジケースのテスト(無効な日付、過去の日付など)
    • Purpose: 機能が要件通りに動作することを確認
    • Leverage: 全実装コンポーネント
    • Requirements: All
    • _Prompt: Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: QA Engineer with expertise in manual testing and edge case identification | Task: Perform comprehensive manual testing of due date feature covering all requirements, test user workflows and edge cases following all requirements from requirements.md | Restrictions: Test all acceptance criteria from requirements 1-4, verify backward compatibility with existing todos without dueDate, check mobile responsiveness, validate accessibility (keyboard navigation, screen reader), identify and document any bugs found | _Leverage: All implemented components from tasks 1-7, requirements.md acceptance criteria | Requirements: All requirements (1, 2, 3, 4) | Success: All acceptance criteria pass, create/edit/delete workflows work smoothly, visual indicators (colors) display correctly for all states, existing todos load without issues, no console errors, mobile and desktop display correctly, keyboard accessible | After implementation, use log-implementation tool with detailed artifacts (testing results, any bug fixes applied) and mark task as complete in tasks.md

承認後、ダッシュボードの「タスク」メニューをクリックすると、次のような画面が表示される。

タスク実装指示と進捗トラッキング

実装フェーズに入ると、ダッシュボードのさらなる真価が発揮される。

各タスクの実装を Claude Code に指示するには、ダッシュボードから指示プロンプトをコピーする。

この指示プロンプトをClaude Code に貼り付けて実行する。

今回の例でいえば、次のようなプロンプトが自動的に生成される。。

Implement the task for spec due-date-feature, first run spec-workflow-guide to get the workflow guide then implement the task: Role: TypeScript Developer specializing in type systems | Task: Extend the Todo interface in src/types/todo.ts to add optional dueDate field (string in ISO 8601 format) and update TodoInput type to include dueDate, following requirement 1 (期限日時の設定) from requirements.md | Restrictions: Do not modify existing fields, maintain backward compatibility with existing Todo data, dueDate must be optional, follow existing ISO 8601 pattern used in createdAt and updatedAt | _Leverage: Existing Todo interface pattern, ISO 8601 date format convention | Success: Todo interface has dueDate?: string field, TodoInput includes dueDate in Pick type, TypeScript compilation succeeds without errors, existing code remains compatible | After implementation, use log-implementation tool with detailed artifacts (types modified) and mark task as complete in tasks.md

作業中のタスクは、「保留中」から「進行中」にステータスが変更され、一目で作業中のタスクがわかる。

作業が完了すると、「進行中」から「完了」にステータスが変更され、一目で作業完了のタスクがわかる。

「タスク」メニューの上部のサマリ情報を見れば、現在の進捗状況を一目で把握することができる。

この進捗の可視化は、単なる見た目の問題ではない。心理的な効果がある。何も見えない状態で作業を続けると不安が生じるが、進捗バーが少しずつ埋まっていくのを見ると達成感がある。モチベーションが維持される。

一度にまとめてタスクの実装を指示することも可能である。

Task1 ~ Task8 をまとめて実装してください。

変更差分を確認するには、個人の好みもあるだろうが、私は difitをよく使っている。視認性に優れ、なおかつコメントをまとめて整理することができるので、とても便利である。

npx difit .

タスクの作業結果に満足いかない場合は、difit で整理した指摘事項を Claude Code に貼り付けて修正を依頼し、水準を調整すればよい。

すべてのタスクの実行が完了すると、期待通り「期日」機能が追加されていた。

ハル・ベリーのように美しい

期限表示が美しく実装されている。まさに理想的な仕上がりだ。

実装ログの活用

実装完了後、ダッシュボードの「実装ログ」メニューから各タスクの実装履歴を確認することができる。

直感的な UI を見れば、なにができるか一目でわかるため、説明は割愛する。

以上で、ダッシュボードの使い方の説明は終わりである。


長い記事なのにここまで読んでくれてありがとベリー。あともうちょっと。

仕様変更の発生

先の説明では、簡便化のために仕様変更の発生を含めなかったが、実際の開発では動作確認時に「こうしたほうがいいかも?」という仕様変更が発生することがあるだろう。その際は、MCPサーバーに仕様変更を指示することで、仕様を更新することができる。あわせて、デザインファイル等の影響するファイルの修正も行われる。

課題に対するブルーベリー効果

ここで、当初掲げていた3つの課題を再掲する。

  1. 意図の喪失
  2. 進捗の不透明性
  3. レビューの困難さ

果たして spec-workflow-mcp はこれらの課題を解決することができるのだろうか。

答えは「イエス」である。

1. 意図の喪失 → 意図の永続化

Requirements と Design を .spec-workflow/ に保存することで、「なぜこの実装なのか」が永続化される。6ヶ月後に仕様を読めば、設計の意図が即座に理解できる。

2. 進捗の不透明性 → 進捗の可視化

リアルタイムダッシュボードのタスク進捗バーにより、「どこまで進んでいるか」が一目瞭然である。プロジェクトマネージャーの質問にも具体的に答えられるだろう。

3. レビューの困難さ → レビュー体験の改善

Web ダッシュボードの構造化されたプレビューとアノテーション機能により、「テキストファイルの羅列」から「快適な閲覧体験」へ。ビジネスロジックの妥当性を検証できる本来のレビューが実現する。

spec-workflow-mcp の本質は、情報の提示方法が開発体験そのものを変えるという点にある。テキストエディタで .md を開く義務感ではなく、ブラウザで仕様を見たくなる自然な動機。この違いが、SDD を実践可能な手法へと変える。

まさしく、ブルーベリー。King of マサイ族と言えよう。

見える、見えるぞ。

その他

VSCode 拡張

spec-workflow-mcp は、Web ダッシュボードに加えて VSCode 拡張を提供している。
https://marketplace.visualstudio.com/items?itemName=Pimzino.spec-workflow-mcp

興味があれば利用してみるとよいだろう。

他ツールとの比較

比較記事は次に詳しい。
https://tech.algomatic.jp/entry/2025/09/22/143931

ここでは、spec-workflow-mcp の特異性として「ブルーベリー」効果を理解してもらえれば本懐である。

まとめ

おまえもマサイ族にならないか。


フリー素材ぱくたそ

以上、お読みくださりありがとうございました。


LayerX Tech Advent Calendar まだまだ続きます。

https://layerx.notion.site/6975c0901ea54ca9b609fafc3e8a35c3?v=2bccdd370bae80579556000cc2afc504

本日までの記事も当然ながら、明日以降の記事も乞うご期待ください。

LayerX

Discussion