specflow
実行可能な契約によるスペック駆動開発
description の原文を見る
Spec-driven development with executable contracts
SKILL.md 本文
Specflow スキル
仕様が自動的に強制される開発。要件をコントラクト(契約)に変換して、違反時にビルドを失敗させます。
コア ループ
Spec --> [Pre-Flight] --> Contract --> Test --> Code --> Verify
- ID付きの要件を記述する(AUTH-001 MUST、J-CHECKOUT-001)
- プリフライト シミュレーションを実行 — コード作成前に壊れた仕様を検出
- 禁止/必須パターン付きのコントラクト YAML を生成
- ソースコード違反をスキャンするテストを生成
- コントラクトを満たすコードを実装
- 違反 = ビルド失敗 = PR ブロック
アクティベーション時
このスキルがアクティブな場合、Claude Code は以下を実行します:
- ファイル修正前に:
docs/contracts/*.ymlのコントラクト スコープに当てはまるかを確認。該当する場合、コントラクトを読み、すべてのnon_negotiableルールを尊重してください。 - 作業終了前に: コントラクト テスト(
npm test -- contracts)とジャーニー テストを実行。テストが失敗した場合、作業は完了していません。 - 新機能作成時に: コード実装前に、仕様(REQ ID付き)、コントラクト YAML、テスト ファイルを生成。
- コントラクト違反が報告された場合: コントラクト ルールを読んで理由を理解し、コードを修正。テストを回避しないでください。
non_negotiableルールを決して修正しないでください — ユーザーが明示的にoverride_contract: <contract_id>と言う場合を除く。- チケットを specflow 準拠として受け入れる前に: プリフライトが実行され、
passed、passed_with_warnings、または人間が承認したoverride:*ステータスを返していることを確認。blocked、stale、またはプリフライト セクション欠落のチケットは準拠していません。
プリフライト ゲート
コード作成前に壊れた仕様を検出する読み取り専用シミュレーション。プリフライトはパイプラインの 2 つのポイントで実行されます:
2 つのスコープ
| スコープ | トリガー | レンズ |
|---|---|---|
| チケット | specflow チケットとして作成または編集された場合 | レンズ 1-5 |
| ウェーブ | dependency-mapper と sprint-executor の間、すべてのウェーブ チケット同時実行時 | レンズ 1-6(レンズ 6: 並行ユーザー シナリオを含む) |
トリガー フレーズ(チケット スコープ)
以下のすべてが、毎回フォーマット後シミュレーションを呼び出します:
- "write this as a specflow ticket"
- "update this ticket as a specflow ticket"
- "edit this ticket as a specflow ticket"
- "make this ticket specflow-compliant"
- specflow-writer がチケット本文を作成または変更する指示
チケットがフォーマットとシミュレーションの両方がクリーンに完了するまで、specflow 準拠ではありません。
simulation_status 列挙型
passed — CRITICAL 調査結果なし
passed_with_warnings — P1 調査結果あり(ただし承認済み)
blocked — 未解決の CRITICAL 調査結果; チケットはウェーブに入無い
stale — チケットまたは参照されたコントラクト最後のシミュレーション後に更新
override:[reason] — 人間によるオーバーライド適用; ウェーブ実行可
この列挙型外の値は waves-controller によって blocked として扱われます。フィールドは直接解析 — 正規表現なし、解釈なし。
ウェーブ ゲート ロジック
dependency-mapper 完了後、sprint-executor 実行前:
blockedまたはstaleのチケット → ウェーブ一時停止、調査結果サマリー出力、停止- 列挙型外の値 →
blockedとして扱われ、停止 passed、passed_with_warnings、またはoverride:*のすべてのチケット → sprint-executor 実行
オーバーライド
override_preflight: [ticket-id] reason: [reason text]
チケットに simulation_status: override:[reason] を設定。docs/preflight/overrides.md にチケット ID、理由、RFC 3339 UTC タイムスタンプ、ユーザーとともに記録。board-auditor はオーバーライドを異なる方法で表示(⚠️OVERRIDE プレフィックス)し、最後のコントラクト更新より古いオーバーライドをフラグします。
プリフライトが実行しないこと
- ソース ファイル、コントラクト YAML、マイグレーションを修正しない
- テストまたは Playwright を実行しない
- チケットを修正しない(それは heal-loop の job です)
- 外部 API を呼び出さない
- チケットを準拠と判定しない — 調査結果を返す; specflow-writer がステータスを適用
コントラクト 強制
コントラクト タイプ
| タイプ | ファイル パターン | 強制者 | タイミング |
|---|---|---|---|
| アーキテクチャ | feature_architecture.yml | パターン スキャン(Jest/Vitest) | ビルド前 |
| フィーチャー | feature_*.yml | パターン スキャン(Jest/Vitest) | ビルド前 |
| セキュリティ | security_defaults.yml | パターン スキャン | ビルド前 |
| アクセシビリティ | accessibility_defaults.yml | パターン スキャン | ビルド前 |
| ジャーニー | journey_*.yml | Playwright E2E | ビルド後 |
コントラクト YAML 構造
contract_meta:
id: auth_feature
version: 1
covers_reqs: [AUTH-001, AUTH-002]
rules:
non_negotiable:
- id: AUTH-001
title: "API endpoints require authMiddleware"
scope: ["src/routes/**/*.ts"]
behavior:
forbidden_patterns:
- pattern: /router\.(get|post).*\/api\//
message: "Route missing authMiddleware"
required_patterns:
- pattern: /authMiddleware/
message: "Must use authMiddleware"
auto_fix:
strategy: "add_import"
import_line: "import { authMiddleware } from '@/middleware/auth'"
パターン セマンティクス
- forbidden_patterns: スコープ内のファイルでいかなる場合もマッチしてはいけません。見つかった場合、違反。
- required_patterns: スコープ内の少なくとも 1 つのファイルでマッチする必要があります。ない場合、違反。
違反 出力フォーマット
CONTRACT VIOLATION: AUTH-001 - API route missing authMiddleware
File: src/routes/users.ts
Line: 42
Match: router.get('/api/users', async (req, res) => {
オーバーライド プロトコル
non_negotiable ルールをオーバーライドできるのは人間だけ。ユーザーは以下を言う必要があります:
override_contract: <contract_id>
オーバーライド時: どのルールが破られているかを説明、結果について警告、コントラクトを永続的に更新するべきかを確認。
デフォルト セキュリティ ゲート(SEC-001 ~ SEC-005)
これらのパターンは、すべての src/**/*.{ts,js,tsx,jsx} ファイル(テスト除外)で non_negotiable として強制されます。
SEC-001: ハードコード化されたシークレット不可
禁止パターン:
/(password|secret|api_key|apikey|token)\s*[:=]\s*['"][^'"]{8,}['"]/i
/sk_live_[a-zA-Z0-9]{20,}/
/sk_test_[a-zA-Z0-9]{20,}/
/-----BEGIN (RSA |EC )?PRIVATE KEY-----/
/ghp_[a-zA-Z0-9]{36}/
/xoxb-[0-9]{10,}-[a-zA-Z0-9]{20,}/
修正: process.env.VAR_NAME を使用してください。
SEC-002: SQL 文字列連結不可
禁止パターン:
/query\s*\(\s*['"`].*\$\{/
/query\s*\(\s*['"`].*\+\s*\w/
/execute\s*\(\s*['"`].*\$\{/
修正: パラメータ化クエリを使用($1、$2)。
SEC-003: サニタイズされていない innerHTML 不可
禁止パターン:
/dangerouslySetInnerHTML\s*=\s*\{\s*\{\s*__html:(?!\s*(sanitize|DOMPurify|purify))/
/\.innerHTML\s*=(?!\s*['"`]<)/
修正: レンダリング前に DOMPurify でサニタイズ。
SEC-004: eval() または Function コンストラクタ不可
禁止パターン:
/\beval\s*\(/
/new\s+Function\s*\(/
修正: JSON.parse または安全な代替案を使用。
SEC-005: パス トラバーサル不可
禁止パターン:
/readFile(Sync)?\s*\(\s*(?!path\.join|path\.resolve|__dirname)/
/writeFile(Sync)?\s*\(\s*(?!path\.join|path\.resolve|__dirname)/
修正: path.join(__dirname, 'safe-dir', path.basename(input)) を使用。
デフォルト アクセシビリティ ゲート(A11Y-001 ~ A11Y-004)
src/**/*.{tsx,jsx} ファイルで強制。
A11Y-001: 画像は代替テキストが必須
禁止: /<img\s+(?![^>]*\balt\s*=)[^>]*\/?>/
A11Y-002: ボタンはアクセス可能なラベルが必須
禁止: /<button(?![^>]*aria-label)[^>]*>\s*<(?:svg|img|[A-Z]\w*)[^>]*\/?\s*>\s*<\/button>/
A11Y-003: フォーム入力はラベルが必須
禁止: /<input(?![^>]*(?:aria-label|aria-labelledby|id\s*=))[^>]*>/
A11Y-004: 正の tabIndex 不可
禁止: /tabIndex\s*=\s*\{?\s*[1-9]/
エージェント振る舞い(要約版)
プリフライト シミュレーター
実行タイミング: チケットが specflow 準拠として受け入れられる前; 各ウェーブ実行前(dependency-mapper と sprint-executor 間)。
推奨モデル: sonnet
プロセス:
- スコープ(
ticketまたはwave)とチケット本文、contracts_dir付きの JSON 入力を受け取る - レンズ実行前に
docs/contracts/のすべてのファイルをロード(証明: ロード済みファイルをすべてリスト) - レンズを順に実行 — チケット スコープではレンズ 1-5、ウェーブ スコープではレンズ 1-6:
- レンズ 1: 依存関係順 — すべてのアップストリーム依存関係はウェーブまたはスキーマに存在?
- レンズ 2: 共有状態 — 同時実行の書き込み、グローバル状態がユーザー単位スコープであるべき?
- レンズ 3: スキーマ実態確認 — 参照されるすべてのフィールド、列、エンドポイント、コントラクト ID が実際に存在?
- レンズ 4: タイミングと間隔仮定 — ポーリング間隔、タイムアウト、SLA 閾値がコントラクトと一致?
- レンズ 5: 部分的な失敗状態 — ステップ N+1 失敗時のロールバック、クリーンアップ、冪等性が不足?
- レンズ 6: 並行ユーザー シナリオ(ウェーブ スコープのみ) — 競合状態、不足しているロック、セッション単位で分離されていない共有状態?
- 各チケット本文の
## Pre-flight Findingsセクションに調査結果を記述(specflow-writer による書き込み用) - すべての調査結果に対してレンズ帰属付きの構造化レポートを返す
- P2 調査結果をブロッキングなしで
docs/preflight/[ticket-id]-[timestamp].mdに記述
このエージェントは読み取り専用です。 ソース ファイル、コントラクト YAML、マイグレーションを修正することはありません。
スペック ライター
実行タイミング: 新機能の受け入れ基準、Gherkin、コントラクトが必要。
プロセス:
- ドメインを理解 — 既存コード、スキーマ、イシューを読む
- スコープを定義(In Scope / Not In Scope)
- データ コントラクトを完全な実行可能 SQL で設計
- 不変式を定義(I-DOMAIN-NNN)
- Gherkin シナリオを生成(happy path、エッジ ケース、エラー パス)
- 受け入れ基準をテスト可能なチェックボックスとして記述
- すべての UI フィーチャー用にユーザー ジャーニーを定義
- コントラクト YAML を作成、CONTRACT_INDEX.yml を更新
出力: Gherkin、データ コントラクト、ジャーニー参照、コントラクト YAML ファイル付きの GitHub イシュー。
コントラクト バリデーター
実行タイミング: 実装後、チケット クローズ前。
プロセス:
- チケット セクション(スコープ、データ コントラクト、Gherkin、受け入れ基準)を解析
- 各 Given/When/Then ステップのコード パスをトレース
- データ コントラクトを実際のマイグレーションに対して検証
- UI 向けイシューのジャーニー カバレッジをチェック
- 不変式が強制されることを確認(DB 制約、アプリ ロジック、または両方)
- PASS / PARTIAL / FAIL ステータス付きの検証レポートを生成
重要ルール: UI ありだがジャーニー コントラクトなしのイシューは PARTIAL が最高、決して PASS ではありません。
テスト ランナー
実行タイミング: 実装後、チケット クローズまたは PR 作成前。
プロセス:
- テスト フレームワークを検出(Playwright、Jest、Vitest、Cypress)
- 詳細出力付きでテストを実行
- 結果を解析、失敗を分類(ロケーター、アサーション、ネットワーク、認証、不安定、セットアップ)
- 失敗をソース ファイルにマッピング、根本原因候補付き
- サマリー、失敗、スキップ理由、再実行コマンド付きレポートを生成
必須報告: テスト実行先、どのテスト、合格/失敗数、スキップ理由付きです。
自己修復フィックス ループ
実行タイミング: コントラクト テストが失敗。オーケストレーター呼び出し、ユーザー直接呼び出しではない。
スコープ: フィックスを生成するのに十分な YAML コンテキスト付きのコントラクト違反のみ。ジャーニー テスト、ビルド エラー、auto_fix ヒントなし禁止パターン除外。
プロセス:
- 違反出力を解析(ルール ID、ファイル、行、マッチ済みテキスト)
- コントラクト ルール読み込み、パターン、auto_fix ヒント、例を抽出
- 違反ファイルを読み込み、コンテキストを理解
- auto_fix またはユーザー required_patterns から推測して修正戦略を決定
- 最小限の修正を生成(最も小さい可能な変更)
- 修正を適用、特定コントラクト テストを再実行
- 合格: 報告、継続。失敗: 再試行(最大 3 回)
- 排列後: 最後に失敗した試行を復元、試行されたすべての戦略でエスカレート
修正戦略: add_import、remove_pattern、wrap_with、replace_with
モデル ルーティング
最適なモデル ティアにタスクをルーティング、コスト効率向上(約 40-60% 削減)。
| ティア | タスク タイプ |
|---|---|
| Haiku | コンプライアンス監査、パターン マッチング検証、テスト実行と解析、カバレッジ確認、イシュー クローズ |
| Sonnet | スペック生成、コントラクト YAML 作成、テスト コード生成、依存関係マッピング、コンポーネント ビルディング、オーケストレーション |
| Opus | 深いフィックス推論(heal-loop)、複雑なアーキテクチャ分析 |
.specflow/config.json でオーバーライド:
{
"model_routing": {
"default": "sonnet",
"overrides": {
"heal-loop": "opus",
"test-runner": "haiku"
}
}
}
クオリティ ゲート
作業が完了と見なされる前に、4 つのゲートすべてが合格する必要があります。
ゲート 1: コントラクト テスト
npm test -- contracts
パターン スキャンはソースコード内の禁止/必須パターンをチェック。違反はビルドをブロック。
ゲート 2: ジャーニー テスト
npx playwright test
E2E テストはユーザー フロー エンドツーエンドで動作。リリース前にクリティカル ジャーニーが合格する必要があります。
ゲート 3: セキュリティ デフォルト
SEC-001 ~ SEC-005 は OWASP Top 10 パターンをスキャン。Non_negotiable。
ゲート 4: アクセシビリティ デフォルト
A11Y-001 ~ A11Y-004 は WCAG AA 違反をスキャン。Non_negotiable。
完了の定義
| レベル | 意味 | リリース影響 |
|---|---|---|
critical | コア ユーザー フロー | リリースをブロック(失敗時) |
important | キー フィーチャー | リリース前に修正すべき |
future | 計画フィーチャー | なしでリリース可 |
クリティカル ジャーニーが失敗または not_tested の場合、「リリース準備完了」を報告しないでください。
信頼度階層化修正パターン
修正パターンは .specflow/fix-patterns.json に保存、歴史的成功率でスコア化。
| ティア | 信頼度 | 振る舞い |
|---|---|---|
| Platinum | >= 0.95 | 即座に自動適用 |
| Gold | >= 0.85 | 自動適用、レビュー用コミット メッセージにフラグ |
| Silver | >= 0.75 | 提案のみ、自動適用しない |
| Bronze | < 0.70 | 学習のみ、分析向けにトラック |
スコア ルール: 新パターンは 0.50(Silver)で開始。成功時 +0.05、失敗時 -0.10。90 日未使用後 -0.01/週減衰。0.30 以下: アーカイブ。
パターン エントリ フォーマット:
{
"id": "fix-sec-001-hardcoded-secret",
"contract_rule": "SEC-001",
"violation_signature": "Hardcoded secret detected",
"fix_strategy": "replace_with",
"fix_template": {
"find": "const KEY = \"sk_live_...\"",
"replace_pattern": "const KEY = process.env.STRIPE_SECRET_KEY"
},
"confidence": 0.50,
"tier": "silver"
}
呼び出し
/specflow フル自動ループ: スペック、コントラクト、テスト、実装、検証
/specflow verify 既存コントラクトに対するコントラクト検証のみ
/specflow spec 現在のイシューまたはフィーチャー用に REQ ID 付きスペック生成
/specflow heal 失敗したコントラクト テストでフィックス ループ実行
/specflow status フル実行ダッシュボード(5 つのビジュアライゼーションすべて)を描画
/specflow compile CSV ジャーニーを YAML コントラクト + Playwright スタブにコンパイル
/specflow(フル ループ)
docs/contracts/が存在するか確認。なければ作成、デフォルト テンプレートをインストール。- コンテキスト用に既存スペック、コントラクトを読む。
- スコープ内の各フィーチャー/イシューについて: a. プレーン英語説明から REQ ID を生成 b. 禁止/必須パターン付きコントラクト YAML を作成 c. コントラクト テスト ファイルを作成 d. コントラクトを満たすコードを実装 e. コントラクト テストを実行 — 違反を修正 f. 該当する場合、ジャーニー テストを実行
- レポート: 対象 REQ、合格ジャーニー、DOD ステータス。
/specflow verify
docs/contracts/*.ymlからすべてのコントラクトをロード- 各 non_negotiable ルールについて、スコープ ファイルをパターン違反スキャン
- ファイル:行参照付き違反をレポート
- DOD ステータスをレポート(クリティカル ジャーニー合格?)
/specflow spec
- フィーチャーについて英語でユーザーにインタビュー
- REQ ID を生成(AUTH-001、SEC-001、J-CHECKOUT-001)
- コントラクト YAML を作成
- テスト スタブを作成
- 何が作成されたかのサマリーを出力
/specflow heal
- コントラクト テストを実行、失敗をキャプチャ
- 各違反について: a. ルール ID、ファイル、行を解析 b. auto_fix ヒント用のコントラクト YAML を読む c. 最小限の修正を適用 d. 再テスト
- レポート: 修正、エスカレート、または排列。
/specflow compile
- CSV ジャーニー ファイルを見つける(ユーザーが パスを提供、またはジャーニー ヘッダー付き
*.csvを検索) - CSV を検証: journey_id フォーマット、順序ステップ、オーナー存在、クリティカル yes/no
node scripts/specflow-compile.cjs <csv-file>を実行- レポート: コンパイル済みジャーニー、生成コントラクト、テスト スタブ生成
- CSV + 生成ファイル コミットをユーザーに通知
/specflow status
すべての 5 つの必須ビジュアライゼーション付きフル実行ダッシュボードを描画:
- EXECUTION TIMELINE — 現在地、完了内容、次の内容
- ENFORCEMENT MAP — テスト対象、メカニズム、タイミング(信頼レイヤー)
- DEPENDENCY TREE — 実行順、ブロック関係
- PARALLEL AGENT MODEL — 現在、誰が何を実行中
- SPRINT SUMMARY TABLE — 完了ウェーブ全体の累積合計
このコマンドはウェーブ実行中の任意の時点で機能。フル ビジュアライゼーション テンプレートは agents/waves-controller.md を参照。
クイック リファレンス
コア ループ: Spec --> [Pre-Flight] --> Contract --> Test --> Code --> Verify
REQ ID フォーマット: AUTH-001(MUST)、AUTH-010(SHOULD)、J-AUTH-LOGIN
コントラクト ファイル: docs/contracts/feature_*.yml、journey_*.yml
テスト ファイル: src/__tests__/contracts/*.test.ts、tests/e2e/*.spec.ts
コマンド: npm test -- contracts、npx playwright test
オーバーライド: override_contract: <contract_id>
プリフライト: simulation_status: passed | passed_with_warnings | blocked | stale | override:[reason]
PF オーバーライド: override_preflight: <ticket-id> reason: <reason text>
ファイル ロケーション
新規プロジェクトで Specflow をセットアップする際、この構造を作成してください:
docs/
contracts/
feature_architecture.yml # ARCH
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- Hulupeep
- リポジトリ
- Hulupeep/Specflow
- ライセンス
- MIT
- 最終更新
- 2026/4/22
Source: https://github.com/Hulupeep/Specflow / ライセンス: MIT