Spec Driven(仕様駆動開発)をspec-kitで試してみる 2
前回は「仕様駆動開発が本命。でも自前実装は大変だから既存ソリューションのSpec Kitを利用することにした」と言うところまでお話しました。
早速Spec Kitの基本から見ていきます。
インストールと初期設定
uvxをインストールし、
curl -LsSf https://astral.sh/uv/install.sh | sh
spec-kitのインストールと初期設定。既存プロジェクトに導入するためここではプロジェクト指定を--here
としています。
cd cognito-example/
uvx --from git+https://github.com/github/spec-kit.git specify init --here
下記のような状態になりました
~/repositories/cognito-example$ tree -a
.
├── .claude
│ └── commands
│ ├── constitution.md
│ ├── implement.md
│ ├── plan.md
│ ├── specify.md
│ └── tasks.md
├── .specify
│ ├── memory
│ │ └── constitution.md
│ ├── scripts
│ │ └── bash
│ │ ├── check-implementation-prerequisites.sh
│ │ ├── check-task-prerequisites.sh
│ │ ├── common.sh
│ │ ├── create-new-feature.sh
│ │ ├── get-feature-paths.sh
│ │ ├── setup-plan.sh
│ │ └── update-agent-context.sh
│ └── templates
│ ├── agent-file-template.md
│ ├── plan-template.md
│ ├── spec-template.md
│ └── tasks-template.md
└── cognito-example.code-workspace
基本のワークフロー
Spec Kitのコマンドは2025/09/21時点で5つ。READMEからそのまま引き写しますが、下記のようになっています。
Command | Description |
---|---|
/constitution | Create or update project governing principles and development guidelines |
/specify | Define what you want to build (requirements and user stories) |
/plan | Create technical implementation plans with your chosen tech stack |
/tasks | Generate actionable task lists for implementation |
/implement | Execute all tasks to build the feature according to the plan |
ref: https://raw.githubusercontent.com/github/spec-kit/refs/heads/main/README.md
これらは想定する作業順番通りに並んでいます。 まずconstitution(開発の原則)を規定します。
その後は一連の流れで、specification(要求定義) -> planning(実装計画) -> tasks(タスクへの分解)-> implementation (各タスクの実装)と進めるようになっています。
この流れはDetailed processとして公式READMEに紹介されているためご確認ください。
https://github.com/github/spec-kit?tab=readme-ov-file#-detailed-process
constitutionの作成
では早速検証してみます。
READMEと同じコマンドを打っておきます。
/constitution Create principles focused on code quality, testing standards, user experience consistency, and performance requirements
プロジェクトの開発の原則が定められます。意識の高いプロジェクトの進め方です。このコマンドにより.specify\memory\constitution.md
が生成されます。これはプロジェクト共通の指針を規定するものですから、初回およびその後のアップデートで更新されることはあっても、各機能の実装ごとに毎回コマンドを打つことはないでしょう。
より具体的なガイドラインは別建て
すばらしい進め方と思います……が、より具体的な開発ポリシーや開発標準、例えばコーディングガイドラインなどは作られませんでした。作るよう指定すれば作られるかもしれませんが、そのための仕組みが特別に用意されているわけでもないなら品質に期待できないでしょう。これらは別に自前で用意するほうがよいと思います。
またこのようなドキュメントは、constitution.mdに同梱する方法と、別に作成してconstitution.md内にパスを書いておく方法があると思いますが、今のところ複数の理由で後者がよいと思います。第一に、必須ドキュメントをすべて同梱するとあまりに肥大化するため実用に耐えません。第二に、Spec Kitはまだ公開されたばかりで大きく変更される可能性が高く、あまりconstitution.mdを作りこんでも頻繁な変更に振り回される恐れがあります。もしかすると別のツールに乗り換えることもありえます。
specificationの作成
次にSpecificationを作成します。日本語が使えるかも気になったので、日本語で指定してみました。
/specify AWSのAPI GatewayとCognitoを用いたメンバーズサイトのサンプルを作成したい。
無事gitブランチ001-aws-api-gateway
が切られ、specs/001-aws-api-gateway/spec.mdが作成されました。
内容の確認が必要です。特に受け入れチェック条件リストにチェックがついていない状態は、Specificationに問題が残っていることを意味しているので、調べて修正しました。
## Review & Acceptance Checklist
*GATE: Automated checks run during main() execution*
### Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
### Requirement Completeness
- [ ] No [NEEDS CLARIFICATION] markers remain
- [ ] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Scope is clearly bounded
- [ ] Dependencies and assumptions identified
---
## Execution Status
*Updated by main() during processing*
- [x] User description parsed
- [x] Key concepts extracted
- [x] Ambiguities marked
- [x] User scenarios defined
- [x] Requirements generated
- [x] Entities identified
- [ ] Review checklist passed (has clarifications needed)
planningの作成
下記プロンプトを発行しました。
/plan サンプルサイト作成のため、共通定義、フロントエンド、バックエンド、インフラ用のそれぞれ必要なコードや定義を用意する。それぞれの利用技術は下記の通り。
### 共通定義
- Typespec(OpenAPIを用いたrequest/responseのコード自動出力)
- directory: `/shared`
### Backend
- 言語: Golang
- 実行環境: Lambda(コンテナ利用)
- そのほかの主要依存ソリューション: AWS Cognito, AWS API Gateway
- directory: `/backend`
### Frontend
- 言語: NextJS(SSG)
- 実行環境: S3 + CloudFront
- そのほかの主要依存ソリューション: Route 53, AWS ACM
- directory: `/frontend`
### Infrastructure
- 言語: Terraform
- 実行環境: ローカル実行(本来CIで実行すべきだが今回はオミットする)
- directory: `/infrastructure`
specs/001-aws-api-gateway/plan.mdほかがspecs/001-aws-api-gateway/以下に作成されました。
:~/repositories/cognito-example/specs/001-aws-api-gateway$ tree
.
├── contracts
│ └── api.tsp
├── data-model.md
├── plan.md
├── quickstart.md
├── research.md
└── spec.md
api.tspはshared/に置くものですが、どうも既定の動作のようなので、いったん置きます。
ちなみにこの作業は二度目行っています。一度目に失敗したためです。必要なplan.mdが作られず、必要ないコードが別の場所に作成され、とどうしようもなかったため、シンプルに削除しました。ロールバックは生成AI活用の欠かせないテクニックです。
最後にConstitution Checkに通っていることも確認しました。
Tasks
/tasks
コマンドを打ちます。これはプロンプト不要のようです。
/tasks
100の大量タスクが作成されました。
## Phase 3.1: Setup
- [ ] T001 Create project structure with backend/, frontend/, shared/, and infrastructure/ directories
- [ ] T002 Initialize Go module in backend/ with go.mod (Go 1.24+)
- [ ] T003 [P] Initialize NextJS 15+ project in frontend/ with TypeScript strict mode
- [ ] T004 [P] Initialize TypeSpec project in shared/ with npm and TypeSpec dependencies
- [ ] T005 [P] Initialize Terraform 1.12.1+ configuration in infrastructure/
- [ ] T006 [P] Configure Go linting with golangci-lint in backend/.golangci.yml
- [ ] T007 [P] Configure ESLint and Prettier in frontend/.eslintrc.js and .prettierrc
- [ ] T008 [P] Configure terraform fmt and tflint in infrastructure/
## Phase 3.2: Tests First (TDD) ⚠️ MUST COMPLETE BEFORE 3.3
**CRITICAL: These tests MUST be written and MUST FAIL before ANY implementation**
### Contract Tests (from api.tsp)
- [ ] T009 [P] Contract test POST /auth/register in backend/tests/contract/test_auth_register.go
- [ ] T010 [P] Contract test POST /auth/login in backend/tests/contract/test_auth_login.go
- [ ] T011 [P] Contract test POST /auth/refresh in backend/tests/contract/test_auth_refresh.go
- [ ] T012 [P] Contract test POST /auth/logout in backend/tests/contract/test_auth_logout.go
- [ ] T013 [P] Contract test POST /auth/forgot-password in backend/tests/contract/test_auth_forgot_password.go
- [ ] T014 [P] Contract test POST /auth/reset-password in backend/tests/contract/test_auth_reset_password.go
- [ ] T015 [P] Contract test GET /profile in backend/tests/contract/test_profile_get.go
- [ ] T016 [P] Contract test PUT /profile in backend/tests/contract/test_profile_update.go
- [ ] T017 [P] Contract test GET /content in backend/tests/contract/test_content_list.go
- [ ] T018 [P] Contract test GET /content/{path} in backend/tests/contract/test_content_get.go
- [ ] T019 [P] Contract test GET /health in backend/tests/contract/test_health.go
### Integration Tests (from quickstart.md scenarios)
- [ ] T020 [P] Integration test visitor registration flow in backend/tests/integration/test_registration_flow.go
- [ ] T021 [P] Integration test member login flow in backend/tests/integration/test_login_flow.go
- [ ] T022 [P] Integration test content access control in backend/tests/integration/test_content_access.go
- [ ] T023 [P] Integration test session management (refresh/logout) in backend/tests/integration/test_session_management.go
- [ ] T024 [P] Integration test password reset flow in backend/tests/integration/test_password_reset.go
- [ ] T025 [P] Frontend test registration component in frontend/tests/components/RegisterForm.test.tsx
- [ ] T026 [P] Frontend test login component in frontend/tests/components/LoginForm.test.tsx
- [ ] T027 [P] Frontend test member content protection in frontend/tests/components/ProtectedContent.test.tsx
## Phase 3.3: Core Implementation (ONLY after tests are failing)
### TypeSpec Contract Generation
- [ ] T028 Generate Go types from TypeSpec in shared/contracts/api.tsp → backend/generated/
- [ ] T029 Generate TypeScript types from TypeSpec in shared/contracts/api.tsp → frontend/src/generated/
- [ ] T030 Generate OpenAPI 3.0 specification from TypeSpec → shared/generated/openapi.yaml
### Data Models (from data-model.md)
- [ ] T031 [P] MemberProfile model mapping in backend/models/member.go
- [ ] T032 [P] Session token handling types in backend/models/session.go
- [ ] T033 [P] ContentResource model in backend/models/content.go
- [ ] T034 [P] Error response models in backend/models/errors.go
### Services Layer
- [ ] T035 [P] Cognito service wrapper in backend/services/cognito_service.go
- [ ] T036 [P] JWT validation service in backend/services/jwt_service.go
- [ ] T037 [P] Content service in backend/services/content_service.go
- [ ] T038 [P] Profile service in backend/services/profile_service.go
### API Handlers (Lambda Functions)
- [ ] T039 POST /auth/register handler in backend/handlers/auth_register.go
- [ ] T040 POST /auth/login handler in backend/handlers/auth_login.go
- [ ] T041 POST /auth/refresh handler in backend/handlers/auth_refresh.go
- [ ] T042 POST /auth/logout handler in backend/handlers/auth_logout.go
- [ ] T043 POST /auth/forgot-password handler in backend/handlers/auth_forgot_password.go
- [ ] T044 POST /auth/reset-password handler in backend/handlers/auth_reset_password.go
- [ ] T045 GET /profile handler in backend/handlers/profile_get.go
- [ ] T046 PUT /profile handler in backend/handlers/profile_update.go
- [ ] T047 GET /content handler in backend/handlers/content_list.go
- [ ] T048 GET /content/{path} handler in backend/handlers/content_get.go
- [ ] T049 GET /health handler in backend/handlers/health.go
### Lambda Container Configuration
- [ ] T050 Create Dockerfile for Go Lambda in backend/Dockerfile
- [ ] T051 Configure Lambda handler entry points in backend/main.go
### Frontend Components
- [ ] T052 [P] Create authentication context provider in frontend/src/contexts/AuthContext.tsx
- [ ] T053 [P] Create registration form component in frontend/src/components/RegisterForm.tsx
- [ ] T054 [P] Create login form component in frontend/src/components/LoginForm.tsx
- [ ] T055 [P] Create profile display component in frontend/src/components/ProfileDisplay.tsx
- [ ] T056 [P] Create protected route wrapper in frontend/src/components/ProtectedRoute.tsx
- [ ] T057 [P] Create content list component in frontend/src/components/ContentList.tsx
### Frontend Services
- [ ] T058 [P] API client service with token handling in frontend/src/services/api.ts
- [ ] T059 [P] Authentication service in frontend/src/services/auth.ts
- [ ] T060 [P] Content service in frontend/src/services/content.ts
### Frontend Pages
- [ ] T061 [P] Home page (public) in frontend/src/pages/index.tsx
- [ ] T062 [P] Registration page in frontend/src/pages/register.tsx
- [ ] T063 [P] Login page in frontend/src/pages/login.tsx
- [ ] T064 [P] Member dashboard in frontend/src/pages/dashboard.tsx
- [ ] T065 [P] Profile page in frontend/src/pages/profile.tsx
- [ ] T066 [P] Password reset page in frontend/src/pages/reset-password.tsx
## Phase 3.4: Infrastructure & Integration
### Terraform Modules
- [ ] T067 [P] Cognito User Pool module in infrastructure/modules/cognito/main.tf
- [ ] T068 [P] API Gateway with Cognito authorizer in infrastructure/modules/api_gateway/main.tf
- [ ] T069 [P] Lambda functions module in infrastructure/modules/lambda/main.tf
- [ ] T070 [P] S3 bucket for frontend hosting in infrastructure/modules/s3/main.tf
- [ ] T071 [P] CloudFront distribution module in infrastructure/modules/cloudfront/main.tf
- [ ] T072 [P] Route 53 and ACM certificates in infrastructure/modules/dns/main.tf
### Environment Configuration
- [ ] T073 Terraform variables for dev environment in infrastructure/environments/dev/terraform.tfvars
- [ ] T074 Terraform backend configuration in infrastructure/backend.tf
- [ ] T075 Main Terraform configuration in infrastructure/main.tf
### Build and Deploy Configuration
- [ ] T076 Backend build script in backend/scripts/build.sh
- [ ] T077 Frontend build configuration in frontend/next.config.js (with output: 'export')
- [ ] T078 Lambda deployment packaging script in backend/scripts/package.sh
### Integration Points
- [ ] T079 Configure CORS in API Gateway for frontend origin
- [ ] T080 Set up CloudFront behaviors for static assets caching
- [ ] T081 Configure API Gateway custom domain with Route 53
- [ ] T082 Implement structured logging with correlation IDs in backend/middleware/logging.go
## Phase 3.5: Polish & Validation
### Unit Tests
- [ ] T083 [P] Unit tests for JWT validation in backend/tests/unit/test_jwt_validation.go
- [ ] T084 [P] Unit tests for input validation in backend/tests/unit/test_input_validation.go
- [ ] T085 [P] Unit tests for error handling in backend/tests/unit/test_error_handling.go
- [ ] T086 [P] Frontend unit tests for auth context in frontend/tests/contexts/AuthContext.test.tsx
### Performance Optimization
- [ ] T087 Implement Lambda cold start optimization (lazy loading)
- [ ] T088 Configure CloudFront caching rules (no-cache HTML, cache static assets)
- [ ] T089 Optimize container image size (<1GB) in backend/Dockerfile
### Security Hardening
- [ ] T090 [P] Configure security headers in CloudFront
- [ ] T091 [P] Implement rate limiting in API Gateway
- [ ] T092 [P] Add input sanitization middleware in backend/middleware/sanitization.go
### Documentation
- [ ] T093 [P] API documentation from OpenAPI spec in docs/api.md
- [ ] T094 [P] Deployment guide in docs/deployment.md
- [ ] T095 [P] Update CLAUDE.md with project specifics
### Validation & Testing
- [ ] T096 Run quickstart.md validation scenarios
- [ ] T097 Performance testing with hey tool (<500ms API, <2s page load)
- [ ] T098 Security scan with dependency vulnerability tools
- [ ] T099 End-to-end testing of complete user journey
- [ ] T100 Terraform plan validation (no drift)
ディレクトリ構成やファイル構成が記述されていることに気づきます。しかし今回は既定のスタイルがすでにあるので、このままでは使えません。そのためドキュメント.specify/memory/backend-constitution.md
を作成し、これをCursorに渡しつつ修正してもらいました。
またリンターや静的解析も本来の開発体制より大分簡略化されています。このあたりは完全にツール任せにできず、まだまだ自分で作りこむ作業が必要そうです。
## プロジェクトのディレクトリ設計
```
cmd/
server/
main.go // サーバ起動
internal/
api/
gen.go // oapi-codegen で生成
download/ // “ダウンロード”モジュールの場合。
handler.go // HTTPハンドラ
usecase.go // ビジネスロジック(サービス層的役割)
repository.go // 永続化
entity.go // ドメインモデル
README.md // 設計を記載
mock.go // モック用のコードを入れる
…
middleware/ // 認証・ロギングなど共通処理
authentication.go
utility/ // 汎用ユーティリティ
```
- ただしモジュール内のファイルは、コードを単一ファイルにまとめるのが不適切な場合は、タイプをSuffixとして別ファイルとする。(e.g., ordering_repository.go, catalog_repository.go)
- ミドルウェアとユーティリティは機能名.goでよい。
Implementation
/implement
コマンドを打ちます。Taskが実行されます。
大量の成果物が出来上がりましたが、残念ながら品質が低く、利用に耐えないと判断せざるを得ませんでした。これはあまりにも粒度の大きなSpecificationを指定したことにも問題があります。反省点は総括に述べています。
ただ、作成されたタスクを順に実行する手法はとても素晴らしく、これによって通常なら途中で止まってしまうであろう作業が最後まで完遂されました。問題は任せる粒度が大きすぎたことにあると考えます。
総括
残念ながら今回のチャレンジは失敗例となりました。
しかし原則を決め、specification(要求定義) -> planning(実装計画) -> tasks(タスクへの分解)-> implementation (各タスクの実装)とブレイクダウンしていく手法はとても優れていると感じます。大枠この先もこの流れを大きく変える必要はないのではないでしょうか。
また今回の実験で課題もいくつか見えてきました。
- 粒度が過大。今回オールインワンで実施しましたが、これはある程度大きな開発プロジェクトになると厳しいと考えざるを得ません。どうしてもそれぞれの指定が雑になりますし、コード量も過大でレビューが困難です。Specificationを小さく区切る必要があります。問題はどう区切るか。検討課題です。
- AIに与える情報の不足。これは形としては開発ドキュメント(MCP経由でもかまいませんが)の不足として現れます。constitution.mdを生成してくれましたが、実際の開発に必要になる知見はずっと広範囲かつ深遠です。この程度では全く足りないのです。人がチェックすることでフォローする、と言っても、これを全て手動でチェックしなければならないのは大変です。そもそもチェックする人にしたところで、基準が分からないとなると個々人の裁量でてんでばらばらに実施せざるを得ないので全体で見ると支離滅裂な作りになることが避けられません。開発ドキュメントをもっと拡充させる必要があります。
- constitution.mdの肥大化。constitution.mdはおそらくすべての作業で参照されるプロンプトの一部として使われるのだと思われます。ここに大量の情報を入れておくと、作業に必要ない情報が大量にプロンプトに含まれることなるでしょう。それは費用の肥大化と精度の低下をもたらします。できれば渡す情報は必要になった時に必要なだけ渡したいところです。これは上記の情報不足の解決とも密接に関わります。開発プロジェクトに必要な全情報を全部constitution.mdに同梱するわけにいかないので、Just In Time式でコンテキストを渡せないと、情報をそろえることが困難なのです。
これらの課題は実務でspec kitを使いたい以上、解決しないわけにいきません。そこでなんとかならないかをさらに調べていきたいと思います。
Show Text to Sharegithub/spec-kitを試してみます Spec Driven(仕様駆動開発)をspec-kitで試してみる 2 https://www.tricrow.com/ai/spec-kit2.html