/sdd-stack
入力: $ARGUMENTS. あなたはスタックに関するインタビューを実施し、ユーザーがサマリーを確認した後にのみファイルに書き込みます。
0. 質問の前に: 事実を調査する
環境の事実はあなたの仕事であり、ユーザーに質問してはいけません。以下の情報を確認するか(またはサブエージェントに委任してください):
- 既存のマニフェストとコード (
package.json,pyproject.toml,go.mod,Dockerfile,.github/workflows/, トップレベルのディレクトリ); .agents/specs/stack.mdとarchitecture.md(既に記入済みで--revisarがない場合は、サマリーを表示し不足分のみ質問);.specify/memory/constitution.md(既に決定された制約、例: LGPD、単一データベース);sddkit suggest --json(検出されたスタック).
コードで既に決定されていることは、質問ではなく「決定済み」として扱います。
1. 方法
- スキル
grillingが.agents/skills/にインストールされている場合 → そのメソッドに従ってください(決定木の境界をラウンドで進み、各質問に推奨回答を提示し、境界が空になるまで続ける)。 - インストールされていない場合 → 同じ形式: 各ラウンドで、前提条件がすでに満たされているすべての質問を、番号付きで提示します。各質問は以下の形式です:
❓ **Q1 — <タイトル>**: <質問、2〜4の選択肢と各選択肢のトレードオフを1行で>
➡️ <推奨とその理由を1〜2行で>
各質問は、「はい」と答えれば推奨を受け入れるように記述してください。退屈で枯れた技術を優先し、最先端ではなくチームが既に知っているものを選んでください。強い理由がない限り、プロジェクト全体で1つの言語を選び、スコープを満たす最小限の部品(サービスが増えるごとに運用コストが増加)を選んでください。回答が以前の回答や憲法と矛盾する場合は、その点を指摘し、どちらを優先するか質問してください。
2. スタックの決定木
以下の依存順序に従って進めます。該当しないブランチはスキップしてください(例: UIなし → フロントエンドの質問なし)。
- プロダクト: 何か(Webアプリ、API、モバイルアプリ、デスクトップ、CLI、ライブラリ、ワーカー)、誰が使うか、想定されるスケール(ユーザー数、データ量、ピーク時)、制約(LGPD、オフライン、コスト、納期)。
- チーム: チームが習得している言語、誰がメンテナンスするか。
- 形式: モジュラーモノリス、パッケージ単位のモノレポ、分離されたサービス。非同期が必要な箇所。
- 言語とランタイム(メジャーバージョン): 例: TypeScript/Node 22, Python 3.12。
- フロントエンド(UIがある場合): フレームワーク(React/Next, Vue/Nuxt, Svelte, Astro…)、レンダリング方式(SPA, SSR, 静的)、コンポーネントライブラリとスタイル(MUI, shadcn+Tailwind…)、サーバーステート(TanStack Query…)、i18n、アクセシビリティ。
- モバイル/デスクトップ(該当する場合): ネイティブ、React Native/Expo、Flutter、Tauri、Electron。
- バックエンド/API: フレームワーク(Express, Fastify, NestJS, Hono, FastAPI, Django…)、スタイル(REST, GraphQL, tRPC)、契約とバリデーション(Zod, Pydantic, OpenAPI)。
7b. バックエンドのパラダイム(バックエンドがある場合のみ; 決してフロントエンドには適用しない。フロントエンドはフレームワークの慣習に従う):
- スタイル: OOP + SOLID(不変条件を持つエンティティ、インターフェースに依存するサービス)、関数型(純粋関数、不変データ、エッジでの副作用)、またはプラグマティック(シンプルなモジュール、2つ以上の実装がある場合のみ抽象化 —
ponytailのデフォルト)。 - アーキテクチャ: シンプルなレイヤー(controller → service → repository)、Clean/Hexagonal(フレームワークに依存しないドメイン、ポートとアダプター)、またはDDD(境界付けられたコンテキスト、集約)。ドメインが耐えられる最もシンプルなものを推奨: Clean/DDD は豊かなビジネスルールがある場合のみ。
- どのディレクトリがバックエンドか(例:
server/**,services/**,modules/**)。これによりパラダイムの適用範囲がバックエンドに限定されます。
- スタイル: OOP + SOLID(不変条件を持つエンティティ、インターフェースに依存するサービス)、関数型(純粋関数、不変データ、エッジでの副作用)、またはプラグマティック(シンプルなモジュール、2つ以上の実装がある場合のみ抽象化 —
- データ: データベース(PostgreSQL, MySQL, MongoDB, SQLite)、ORM/アクセス(Prisma, Drizzle, SQLAlchemy…)、マイグレーション、キャッシュ。
- 非同期: キュー/ジョブ(BullMQ, Celery, pg-boss…)、イベント、リアルタイム(WebSocket/SSE)。
- 認証と認可: プロバイダーまたは自前実装、セッション/JWT、ロール/権限。
- 外部連携: 決済(PIX…)、メール、AI(Anthropic SDK…)、MCP。
- ホスティングと運用: 動作環境(Vercel、Docker VPS、マネージドクラウド)、環境、シークレット、可観測性(ログ、エラー、メトリクス)。
- 品質: テスト(ユニット、統合、Playwright を使った E2E)、lint/フォーマット、型チェック、CI(GitHub Actions)、コミット(Conventional Commits/commitlint)。
3. 確認
境界が空になったら、サマリーをテーブル(レイヤー · 選択 · バージョン · 理由 · 破棄した代替案)で表示し、「これで決定ですか?」と質問します。「はい」の前に何も書き込まないでください。
4. 記録
.agents/specs/stack.md: 内容([PREENCHERマーカーを含む)を以下で置き換えます:## コンポーネント別— 各レイヤーの技術、メジャーバージョン、主要ライブラリをパッケージ名(例:react,@prisma/client,bullmq,fastapi)で記述:sddkitはこれらの名前を使用してロールとスキルを提案します;## インフラストラクチャ— データベース、キュー、キャッシュ、ホスティング、CI、可観測性;## 決定事項— 各重要な選択の理由と破棄した代替案(本日の日付)。
.agents/specs/architecture.md:## 概要セクション(コンポーネントとその通信方法; 3つ以上のコンポーネントがある場合は mermaid ダイアグラム)を記入し、[PREENCHERを削除します。既にコードがある場合は、## コードマップも記入します(エリアごとに1行: 入力、キーディレクトリ、テスト)。他のセクションはコードができた時点で記入します。- バックエンドのパラダイム(7b で決定され、かつ「プラグマティック」でない場合):
.agents/specs/coding-standards.md:## バックエンド — パラダイムセクションに、スタイル、アーキテクチャ、バックエンドのディレクトリ、3〜5の具体的なルール(各ルールに短い例付き)、およびルールを強制するツール(下記)を記述します。フロントエンドはこのセクションに従わないことを明記します。- sddkit のメモリ(エージェントがすべてのセッションでスコープを認識できるように):
sddkit memory add "パラダイム <スタイル>/<アーキテクチャ> はバックエンドのみ (<ディレクトリ>); フロントエンドはフレームワークの慣習に従う" -t paradigma sddkit memory add "バックエンドでは、coding-standards.md の 'バックエンド — パラダイム' セクションが、インターフェースとレイヤーに関する ponytail に優先する" -t paradigma sddkit memory add "<最も重要な具体的ルール>" -t paradigma-backend --paths "<バックエンドのディレクトリ>" - スキル(カタログからオプション、バックエンドロール
api,data,event-module,queue-workerによってのみロードされる): OOP/SOLID →sddkit add solid; Clean/Hexagonal →sddkit add clean-architecture; DDD →sddkit add domain-driven-design。関数型: 汎用的な良いスキルはありません。coding-standards.mdのルールと lint がその役割を果たします。 - 決定論的な強制(バックエンドディレクトリのみに制限された lint; まだコードがない場合、
/sdd-featureのセットアップ最初のタスクになります):- レイヤー/Clean/Hexagonal/DDD:
dependency-cruiserまたはeslint-plugin-boundaries(TypeScript)、import-linter(Python) — ドメインはインフラストラクチャやフレームワークをインポートしません; - TypeScript での関数型: ESLint の
files: ["<バックエンドディレクトリ>"]ブロック内でeslint-plugin-functionalを使用(クラス、ミューテーション、letの禁止); - OOP: OOP を強制する linter はありません。上記のレイヤールールとコードレビューを使用します。
- レイヤー/Clean/Hexagonal/DDD:
- 憲法: 譲れない制約が生じた場合(例: 「PostgreSQL が唯一の真実の情報源」)、テキストを提案し
/speckit-constitutionを提案します — 憲法を直接編集しないでください。 - ユーザーにターミナルで以下を実行するように指示します:
sddkit init # 宣言されたスタックを読み取り、それに基づくロールとスキルを提供(既存のものは削除されません) sddkit doctor
最終レポート(8行以内)
スタック決定内容(レイヤーごとに1行) · バックエンドパラダイムとその強制方法 · 作成されたファイル · 憲法に提案された制約 · 次のステップ(sddkit init、その後 /sdd-feature)