decision-free-specs について
リファクタリング仕様書と計画書を対で作成し、実行モデルが設計判断をせずに進められるようにするスキルです。言語別のインベントリスクリプトでシンボルと依存関係を把握し、構成や検証手順を定めます。
主な機能
- 01スクリプトによるソース調査
- 02TypeScript・Python・Rust・Dart対応
- 03シンボルとインポーターの対応付け
- 04アーキテクチャ判断の明記
- 05検証工程付きの段階的計画
- 06コミットに基づく完了監査
活用シーン
- 01モデル実行向けの大規模リファクタ準備
- 02抽出前の公開シンボルと利用元の把握
- 03コミット単位のリファクタ手順作成
- 04計画した工程の完了状況の監査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thorinside/ skills --skill decision-free-specsインストール後、Claude Code で/decision-free-specsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
languages/README.mdlanguages/dart/inventory.pyNOTES.mdlanguages/dart/fixtures/expected.mdsample.dartlanguages/python/inventory.pyNOTES.mdlanguages/python/fixtures/expected.mdsample.pylanguages/rust/inventory.pyNOTES.mdlanguages/rust/fixtures/expected.mdsample.rslanguages/typescript/inventory.mjsNOTES.mdtemplates/conventions-example.mdprogram-readme-example.md詳細
意思決定不要のリファクタリング仕様
約27Bのローカルモデルがアーキテクチャに関する意思決定を一切せずに実行できるよう、specs/<target>/spec.md と plan.md のペアを作成します。計画にかかるコストの大部分、つまり各ファイルに何があるかを正確に把握する作業は、読み込み作業ではなくスクリプトで行います。計画モデル(あなた)がトークンを使うのは、パターンの選択、インターフェース表の作成、落とし穴の特定という判断だけです。
以下のワークフローは言語に依存しません。インベントリツール、抽出手順、復旧ルール、落とし穴など、言語固有の内容はすべてプラグインとして扱います。
| 言語 | 状況 | ツール |
|---|---|---|
| TypeScript / TSX | 利用可能 | languages/typescript/ |
| Python | 利用可能 | languages/python/ |
| Rust | 利用可能 | languages/rust/ |
| Flutter / Dart | 利用可能 | languages/dart/ |
計画を始める前に、対象言語の languages/<lang>/NOTES.md を読んでください。Python/Rust/Dart のツールはフィクスチャで検証済みです(Python は CPython の標準ライブラリファイルでも検証済みです)。新しいコードベースで初めて本番利用する際は、実際のファイルを1つ選び、インベントリ出力と手作業で照合してください。プラグインのない言語では、まずインベントリツールを作成してください(仕様と手順は languages/README.md を参照)。ファイルを手作業で読む方法に戻らないでください。それでは、このスキルが解消するはずのコストが再発します。
Step 0 — プログラムの初期設定(リポジトリでの初回利用時のみ)
リポジトリに specs/README.md と specs/conventions.md がない場合は、templates/program-readme-example.md と templates/conventions-example.md をもとに作成し、以下を適宜調整してください。このリポジトリの検証コマンド、対象言語のインポート/モジュールパス表(言語ごとの NOTES を参照)、実行者向けプロンプトテンプレートのリポジトリルートです。プログラムの README には、実行者との契約(プロンプトテンプレート、サンプリング設定、セッションごとに1ステップとするルール、失敗時の手順)を記載します。各仕様のフォルダーでこれを再記述しないでください。
Step 1 — スクリプトでインベントリを作成する(先にファイルを読まないでください)
リポジトリのルートから対象言語のインベントリツールを実行します。出力には、languages/README.md で定義された契約の各セクションが含まれます。すなわち、インポート、トップレベル宣言を漏れなく網羅した表(種類/名前/行/エクスポートの有無)、言語固有のシグナル(例:フック、API 呼び出し箇所、動的な文字列から組み立てられる識別子)、そして特に重要な情報として、他のどのファイルがこのモジュールをインポートし、どの名前をインポートしているかが出力されます(互換性を維持するために再エクスポートが必要な、重要なエクスポートを特定できます。テストファイルが3つのヘルパーをインポートしていることを初回の本番実行で検出したのは、この仕組みによるものです)。
インターフェース表を正確に作成するため、抽出して新しいユニットに移す予定の具体的なブロックだけ、ソースを直接読んでください。シンボルの特定にファイルを直接読むことは決してしないでください。
Step 2 — アーキテクチャを決める(これはあなたの役目です。決定した内容をすべて記録してください)
パターンの候補は、優先順位の高い順に次のとおりです。
- モデル抽出(常に実施):純粋な型/定数/ヘルパーをモデルモジュールに移します。
- リーフユニットの移動:ネストされた関数/コンポーネント/ウィジェットを、それぞれ独立したファイルに移します。そのまま移動してください。
- ブロック抽出(UI パネル、大きな match arm):完全なインターフェース表(props/パラメーター)がある場合に限ります。記載漏れは、言語ごとのコンパイラー駆動の復旧ルールで機械的に補えます。
- Strategy レジストリ:動作に関する差異が2種類以上ある場合に限ります(フィールドが異なる、検証方法が異なる、リクエスト形式が異なる場合など)。ラベルやスタイルの違いは、動作に関する差異ではありません。
- 共有抽出:同じシンボルが複数ファイルで重複していることがインベントリで判明した場合は、最初に実行する計画で重複を解消し、プログラム表に依存関係を記載します。
否定的な判断も spec.md に明記してください(「Strategy レジストリは作成しない — 差異はXのみなので、作成しないこと」「ドロワーは判断によりインラインのままにする」など)。記録されていない判断は、実行者が誤った判断をすることになります。
ステップ 3 — ドキュメントを作成する
対象フォルダーごとに:
- spec.md:ソースファイルとサイズ、パターンとその理由、対象ファイルツリー、網羅的なシンボルマップ表(シンボル → 移動先 → エクスポート済みか)、ブロック抽出がある場合はインターフェース表、依存関係の注記(言語別 NOTES に記載された正確なインポート/モジュールパス)、受け入れ基準。インベントリの「Imported by」セクションが空でなく、移動するエクスポートがある場合は、互換性のための再エクスポートを指定し、インポーターの名前を記載します。
- plan.md:前提条件(プラン間の依存関係を名前とステップで記載)、それぞれが新しいコンテキストでの 1 セッションに収まる番号付きステップ、ステップごとの正確なコミットメッセージ。ステップには、リポジトリの
specs/conventions.mdと異なる内容のみを記載します。
本番環境で学んだ厳守事項:
- ステップの順序は、純粋な移動を最初に、ユニットの移動を次に、ブロック抽出を最後にします。各ステップは個別にコミットでき、ステップ間でリポジトリが正常な状態を保つ必要があります。
- すべてのステップのタイトルを
STEP k of Nとし、プランの前文で N を明示します。最初の本番実行では、最も難しい対象のステップ 1/3 で実行者が停止し、プラン全体が完了したと報告しました。新しいコンテキストのセッションでも「続きのステップがある」と分かるように、ステップ見出しを付けてください。 - 各移動ステップの最後に残存チェックを記載します。移動したシンボルの正確な数と、ソースファイルにそれらの宣言が残っていないことを確認する機械的なアサーションを含めます(grep の形式は言語別 NOTES に記載されています)。本番環境で、27 個のシンボルを移動するリストから 1 個がひそかに漏れました。移動元に残っていても型チェックを通過する型があるため、コンパイラーでは検出できません。
- 行番号ではなく、シンボル名を基準にします。行番号は変わるためです。
- 下書きの「X の場合は質問/選択する」という記述はすべて不備です。今決めるか、「バージョン A をコピーし、差分を報告する。調整はしない」のような機械的なルールに置き換えます。
- 各ステップの検証ゲートは、リポジトリの規約に従います(フォーマット → 型チェック/ビルド → 同じ場所にあるテスト)。対象に同じ場所のテストファイルがある場合は、プランにそのファイル名を記載します。そのインポートが、互換性を保つべき範囲を正確に示します。
ステップ 4 — プログラムを更新してコミットする
- プログラムの README の表に行を追加します(サイズ、難易度、依存関係)。
- 仕様書の根拠となる重要な記述(重複するシンボル、インポーターの一覧)を抜き取り確認します。スクリプトで報告されますが、プランの正しさを左右するものは必ず確認してください。
- リポジトリの規約に従ってコミットします。
ステップ 5 — 実行者の出力を監査する(「すべて完了」を信じない)
プランに記載された正確なコミットメッセージが、完了マニフェストになります。実行者(またはそのオペレーター)がプログラムの完了を報告したら、それを信じる前に、期待値と実際の差分を確認してください。
grep -A2 "Commit message" specs/*/plan.md # expected messages
git log --format=%s <baseline>..HEAD # actual messages
期待されるメッセージはそれぞれ、1 コミットずつすべて含まれている必要があります。これにより検出できる本番環境での失敗例は、ステップがひそかにスキップされること(実行者が最も難しい対象で早々に停止した)や、2 つのステップが 1 つのコミットにまとめられることです(作業自体は存在していても、まとめられたステップごとの検証ゲートが実行されていないため、手動で再検証が必要です)。その後、プログラム全体の検証スイートを一度実行します。ステップごとのゲートで指定されていなかった、リファクタリングしたコードの近くにあるテストファイルも含めてください。
Substrate のセマンティック完了条件
このスキルを Substrate ランナーまたはワークフロージョブとして実行する場合、スキル固有またはワークフロー固有のステータスブロックを最初に出力します。最後の空でないアシスタント行は、SUBSTRATE_OUTCOME_V1= 宣言 1 つだけにしてください。
要求された仕様/プランに判断の余地がなく、期待されるファイルが存在し、必要な編集がすべてコミット済み(または現在のツリーがすでに要求を満たしていると確認済み)で、明記された検証に合格した場合にのみ、outcome: "succeeded" を使用します。作業が失敗した場合、ブロックされた場合、または人間による対応が必要な場合は、outcome: "failed" を使用します。changes.status: "committed" とコミット ID、または "alreadySatisfied" を使って、実際の Git の状況を正直に報告します。実際に合格したコマンドを報告してください。通常のプロセス終了だけからセマンティックな成功を推測しないでください。
SUBSTRATE_OUTCOME_V1={"version":1,"outcome":"succeeded","summary":"Authored and verified the decision-free spec program","evidence":{"changes":{"status":"committed","commitIds":["<commit>"]},"verification":{"status":"passed","commands":["<verification command>"]}}}
宣言を 2 つ出力したり、その後に何かを追加したりしないでください。Substrate ジョブ以外では、このプラットフォーム固有の行を追加しないでください。
Executor の設定(デフォルト。各リポジトリではプログラムの README が正式な基準です)
対象クラス:ローカルの約 27B 指示追従モデル(エージェント型コーディングの性能を重視し、Qwen3.6-27B を推奨)。温度 0.2、top_p 0.9 — 機械的な編集では決定性を重視します。新しいコンテキストのセッションごとに 1 ステップを実行します。1 つのステップで 2 回失敗した場合は、作業ツリーをリセットし、エラーとともに FAILED を報告して停止します。失敗するステップに対して、その場しのぎの対応をしてはいけません。