add-feature について
既存の`.plain`仕様に機能を一つずつ追加するワークフロー型スキルです。意図の確認、焦点を絞った質問、段階的な編集、競合への対処、最後の整合性チェックを案内します。
主な機能
- 01編集前に機能の意図を確認
- 02反復ごとに焦点を絞った質問を一つ行う
- 03編集を専用の作成スキルに振り分け
- 04明示的な選択肢で競合を解決
- 05最後に仕様のヘルスチェックを実行
活用シーン
- 01既存の`.plain`プロジェクトに機能を追加
- 02段階的な質問で振る舞いを具体化
- 03意図の変更に合わせて関連仕様の整合性を維持
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ plainlang/ plain-forge --skill add-featureインストール後、Claude Code で/add-featureを入力して読み込まれたか確認します。
詳細
機能の追加
最初にルールを読み込んでください。 .plain ファイルを読む、編集する、または書き込む前に、load-plain-reference スキルを呼び出し、案内されたルールファイルを読んでください。この会話ですでに load-plain-reference が実行されている場合に限り、この手順を省略できます。
add-feature は、forge-plain に対応する継続的なループです。forge-plain がプロジェクト全体をゼロから立ち上げるのに対し、add-feature は既存の .plain 仕様一式に単一の機能を追加します。短い意図確認フェーズから始まり、その後、1つの機能に範囲を絞った作成ループを実行します。
コアのループ:1つの質問 → 1つの回答 → ディスクに書き込む
このループはフェーズ 0 の後に始まります。各反復は、1つの質問と、それに続く即時の書き込みで構成されます。
- 質問する —
AskUserQuestionで焦点を絞った質問を1つだけ行います。2つの質問をまとめてはいけません。考えられる回答のどれも、書き込み可能な1つのスニペットに直接対応するよう質問を組み立てます。つまり、自由回答形式の設計質問ではなく、単一の振る舞い、概念、属性、エッジケース、または制約について尋ねます。悪い例:「この機能はどのように動作するべきですか?」良い例:「ユーザーが空のタイトルを送信した場合、HTTP 400 でリクエストを拒否する、デフォルトのタイトルで受け付ける、それとも別の対応にするべきですか?」回答の範囲が予測できる場合は、具体的な選択肢に加えて自由記述の選択肢も提示します。 - すぐに作成する — ユーザーの回答を受け取ったらすぐに、ディスクにスニペットを書き込みます(どのスキルに振り分けるかについては 2b を参照してください)。「十分な」コンテキストが得られるまで待ってはいけません。先を急いで書き込むことがこの手順の要点です。最初の内容が間違っていることは想定内です。次の質問で修正でき、ユーザーは各ステップの後に、その時点の状態を正確に確認できます。
- 次の質問で調整する — 次の質問で、直前に書き込んだ内容を拡張または修正することもよくあります。
1回の呼び出しにつき1つの質問。ただし、トピックに必要なだけ掘り下げます。 「1つの質問」という制約が適用されるのは AskUserQuestion の呼び出しであり、トピックそのものではありません。回答が曖昧だったり、重要な選択肢が残っていたりする場合は、次の質問で同じトピックを掘り下げます。これはループの次の反復です。書き込めるほど具体的になる前に切り上げて、曖昧な回答をもとに書き込むよりも、焦点を絞った質問をもう1つする方がよいでしょう。
矛盾はその場で修正します。 後の回答によって、ディスク上のスニペットが修正されたり、矛盾したりする場合は、今すぐそのスニペットを編集します。古くなった意図をディスク上に残してはいけません。重要な変更については、次の質問で明確に示します。
入力
ユーザーからの機能リクエストです。「ダークモードを追加」のような一言から、詳細な説明まで、どのような内容でもかまいません。フェーズ 0 で機能意図の概要として確認し、フェーズ 2 で作成しながら振る舞いを具体化します。
フェーズ 0 — 機能の意図
references/phase-0-intent.md を読みます。そこにある5つの基本質問を1つずつ行い、ディスクには何も書き込まず、回答を機能意図の概要にまとめて、明示的な確認を得ます。回答が曖昧で要約できない場合は、焦点を絞った確認質問を1つまで行います。
確認済みの概要を後続のすべてのフェーズに引き継ぎます。先に進む前に、references/checklist.md のフェーズ 0 の項目をインラインで確認します。
フェーズ 1 — 範囲
ここは短く済ませます。目的は、機能全体を紙上で設計することではなく、最初の書き込み可能な質問をするのに十分な情報を得ることです。
- 確認済みの機能意図の概要を読みます。 既存のどの
.plainファイルに、この機能が含まれる可能性が最も高いかを特定します。 - 対象の
.plainファイルを読みます。importとrequiresの連鎖をたどり、モジュールのテスト用 plain ファイルも読みます。既存の定義、実装要件、機能仕様、テスト要件、シナリオを把握できるようにします。こうしておくことで、フェーズ 2 で影響が明らかになった際に、その影響を認識できます。 - 質問は1つだけで対象モジュールを選びます。 変更するファイルが本当に曖昧な場合に限ります。それ以外の場合は、この手順を省略してすぐに作成を始めます。
対象ファイルと、具体的な最初の質問が1つ明確になった時点で、フェーズ 1 を終了します。ここで方向づけの質問、範囲に関する質問、複数部分からなる設計質問をしてはいけません。
フェーズ 2 — 1問ずつのループ
質問を1つだけ行い、すぐに書き込むというサイクルを繰り返します。ユーザーが機能の要件はすべて網羅されたと伝えた時点で、ループを終了します。
2a. 質問を1つする
AskUserQuestion の呼び出しごとに、次のいずれか1つだけを対象とした、記述可能な質問を1つします。
- 動作 — 1つのトリガーとその結果。
- 概念 — 新しい概念、または既存の概念の属性1つ。
- 単一のエッジケース — 1つの無効な入力、空の状態、または境界値。
- 単一の制約 — 1つのビジネスルール、権限、順序、またはサイズ制限。
- 実装ガイダンス — 機能の構築方法を決めるポリシー(再試行、エラー処理、データ形式)、またはファイルやそのインポートですでに使われていないテクノロジー、ライブラリ、パターン。
- 検証 — 下記の 適合性ゲート を満たす場合のみ、この機能が動作することを証明する具体的な結果を1つ。
質問文に2つ目の質問を含めてはいけません。また、回答だけでは記述可能なスニペットにできない質問をしてはいけません。
2b. すぐに記述する
回答はそれぞれ適切な編集スキルに振り分けます。***plain セクションを手作業で作成してはいけません。
- 新しい概念 →
add-concept(***definitions***に追加し、参照する前に定義します)。 - 新しい機能仕様 →
add-functional-spec。これによりanalyze-if-func-spec-too-complexとanalyze-func-specsが実行されるため、そのまま任せます。機能仕様を手作業で作成してはいけません。 仕様が複雑すぎると報告された場合は、次のループでユーザーに分割するための追加質問をします。自分で分割してはいけません。 - 変更された機能仕様 → ステートメント行または
-の箇条書きをその場で編集し、add-test-scenariosを呼び出して、対応するテスト用プレーンファイルを新しい文面に合わせます。 - 新しい実装要件 →
add-implementation-requirement。回答が機能の構築方法(再試行またはエラー処理のポリシー、データ形式、ライブラリ、アーキテクチャパターンなど)を示しており、それがファイルやそのインポートにまだ含まれていない場合に使用します。 - 新しいテストシナリオ → 機能のテスト用プレーンファイルに対して
add-test-scenariosを使用します。適合性ゲート を満たし、回答が具体的な検証を示している場合に限ります。 - 新しいテスト要件 →
add-test-requirement。適合性テストが設定済みで、回答によって適合性テストの実行方法が変わる場合に限ります。
回答が以前のスニペットと矛盾する場合、または内容を詳しくする場合は、上記の 矛盾をその場で修正する に従い、今すぐそのスニペットを修正します。
2c. 競合にはその場で対処する
add-functional-spec(その解析ツール経由)が競合を報告した場合、または今書いたスニペットが既存の概念/機能仕様/実装要件/テスト要件/テストシナリオに抵触する(矛盾する、無効にする)か、追加変更を加える(意味を変える、動作を追加する)場合、次の質問ではその競合を扱います。質問には既存のスニペットを正確に示し、次の選択肢を提示します。
- (a) 維持 — 既存の仕様を維持し、今追加した内容を取り消すか、範囲を狭めます。
- (b) 拡張 — 質問文に提示した新しい文言を既存の仕様に組み込みます。
- (c) 置換 — 既存の仕様を置き換えます。
ユーザーが回答したら、その選択をすぐに適用します。概念を拡張する場合は、それを参照するすべての仕様を確認し、承認された範囲に限って各仕様をその場で更新します。以前の意図を黙って書き換えてはいけません。
2d. 次の対応を決める
機能の網羅が完了したか、ユーザーに確認します。はい → フェーズ3へ進みます。いいえ → 次の質問をして 2a に戻ります。
適合性ゲート
プロジェクトに、test_scripts/ 内に存在するスクリプトを指す有効な conformance-tests-script エントリを含む config.yaml がある場合に限り、***test reqs*** とテスト用プレーンファイルを作成します。このモジュールを対象とする config.yaml を確認し(複数パートからなるプロジェクトでは複数の場合があります)、参照先のスクリプトが存在することを確認します。適合性テストが設定されていない場合は、これら2つの作成経路を完全に省略します。概念、機能仕様、実装要件は通常どおり作成します。
フェーズ 3 — 最終レビュー
チェックの大半はループ内ですでに済んでいます。これは簡潔な整合性チェックで、最後の自動ステップは必ず plain-healthcheck です。
- 変更した
.plainファイルをすべて、最初から最後まで読みます。 - 次の点を確認します。
- 新しい概念はすべて、使用前に定義されていて、循環参照がないこと。
- 時系列の順序が全体を通して正しいこと。後に出てくる内容に依存する仕様がないこと。
- 機能仕様が言語に依存しないこと。
- すべての外部インターフェースが明示されていること(エンドポイントのパス、メソッド、CLI 引数、形式)。
- 新規または変更されたすべての機能に、その仕様から導かれるシナリオを含むテスト用 plain ファイルがあること。適合テストが有効な場合は、ファイルが存在し、少なくとも 1 つの適合シナリオを含むこと。
- 変更したファイルの最終差分を提示し、ユーザーの承認を得ます。
- ユーザーが変更を求めた場合は、1 問ずつのループにそのまま戻ります。一度に 1 つの質問、1 つの書き込み、1 つの修正を行います。ループを最初からやり直してはいけません。
plain-healthcheckを実行します。これがこのスキルで実行する最後のチェックです。すべてのconfig.yamlを検証し、すべてのトップモジュールでplain-parser checkを実行し、すべてのモジュールをルールに照らしてチェックします。そのため、プロジェクトがレンダリングに失敗する状態で機能が完成することはありません。FAILが返された場合は、番号付きリストの項目に対処します(修正対象は.plainファイル/config.yaml/スクリプトのみとし、生成コードは決して変更しません)。ループに戻って修正し、再実行します。PASSになるまで繰り返します。その後に限り、機能を<module>.plainとしてレンダリングする準備ができたことをユーザーに伝えます。- デフォルトのレンダラー:pyro。 pyro の
render-specスキル(/render-spec <module>.plain、または pyro が Claude Code プラグインとしてインストールされている場合は/pyro:render-spec <module>.plain)で<module>を今すぐ再レンダリングするか、ユーザーに尋ねます。ユーザーが同意した場合に限り実行します。このセッションでrender-specスキルが利用できない場合は、pyro がインストールされていないことを伝え、https://github.com/plainlang/pyro#installation を案内します。ユーザーは、ほかの ***plain レンダラーを使ってレンダリングしてもかまいません。
次の機能
1 つの機能が完了した後、ユーザーが次の機能を説明する場合があります。フェーズ 0 から再開します。継続的なループです。意図 → スコープ → 1 問ずつのループ → 最終レビュー → 意図 → …
エラー処理
- ユーザーの回答が以前の仕様と矛盾する場合 → 該当する箇所をその場で編集します。重要な変更は次の質問で明示します。
add-functional-specが「複雑すぎる」と報告した場合 → 仕様を分割するための追加質問をユーザーにします(次のループ反復で実施)。独断で分割してはいけません。- 競合/破壊的変更/拡張が見つかった場合 → 次の質問(2c)として取り上げ、先に解決します。
plain-healthcheckがFAILを返した場合 → 機能の完了を宣言してはいけません。列挙された.plain/config.yaml/スクリプトの項目をループで修正し、PASSになるまで再実行します。
検証チェックリスト
各反復で references/checklist.md のループブロックを実行し、機能の完了を宣言する前にフェーズ 3 でリスト全体を確認します。これはこのワークフローのセルフチェックであり、ワークフローの代わりにはなりません。仕様がディスク上にあり、明示的に承認された場合にのみ、項目は達成済みとみなされます。完了していないステップがあれば、終了前に実施します。
質問のスタイル
- 複文や入れ子の節より、短く直接的な文を優先します。
- 同じ意味が伝わる場合は、専門用語より平易な言葉を使います。
- 1 文につき 1 つの考えを述べます。節をコンマでつないだリストは、複数の文に分けます。
- 簡潔にするために詳細を省いてはいけません。ユーザーに必要な制約、エッジケース、選択肢はすべて保ち、必要に応じて文を分けます。