unslop について
unslopは、コードの確認済みノイズを振る舞いを変えずに取り除くエージェントスキルです。19種類のパターンと差分に沿った手順を示し、安全な整理と別途扱う変更を区別します。
主な機能
- 0119種類のコードノイズパターン
- 02振る舞いを変えない整理方針
- 03差分に沿った確認手順
- 04検証ガイダンス
- 05番号付きパターンで指摘を整理
活用シーン
- 01差分内の冗長なコメントや名前の整理
- 02不要なラッパーや防御処理の特定
- 03整理と振る舞い変更の切り分け
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ howells/ skills --skill unslopインストール後、Claude Code で/unslopを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
Unslop
deslop に対応するコード側のツールです。同じ発想ですが、対象は異なります。deslop は文章から不自然な癖を取り除き、unslop はコードから取り除きます。
エージェントが書いたコードには、特徴的な痕跡があります。バグではありません。型チェックに通り、テストもパスし、動作します。ただし、モデルが必要以上に念入りに書いたために存在する、なくてもよい儀式的なコードが含まれており、そのコストを次に読む人が負うことになります。
あらゆる判断を決めるルールは、動作を一切変えないことです。 痕跡を取り除いても、テストは変更なしでパスします。整理によってプログラムの動作が変わるなら、それはこのスキルの対象ではありません。失敗を隠すフォールバックは fail-fast の対象であり、頭の中で全体を把握できないほど大きなファイルは componentize の対象です。動作の変更を整理に紛れ込ませるのではなく、その旨を伝えて先に進んでください。
あるものを痕跡と判断する前に、周辺のコードを読んでください。ローカルの慣習や抽象化の目的は重要です。呼び出し元が1つだけのラッパーでも、意味のある操作に名前を付けていたり、有用な境界を保っていたりすることがあります。以下の一覧は、調査するパターンを示すものであり、自動的に削除するためのものではありません。確認済みのノイズを取り除くために必要な最小限の変更を優先し、好みに合わせて隣接するコードまで書き換えないでください。
痕跡
指摘では番号を挙げてください。レビュー担当者が個別の事例ではなく、パターンを確認できます。
コメントと名前
- 説明だけのコメント。
// loop over the users、// Phase 1: build the cards。コードを読めばわかります。各処理に必要なドキュメントは、アサーション文字列かログ行だけです。 - シグネチャを言い換えただけのドキュメントコメント。 「@param userId - the user id」のようなものです。型にない情報が何も追加されていないなら、削除してください。シンボルがエクスポートされていて、ホバー時に役立つ説明を付ける価値があるなら、削除ではなく
marginaliaの対象です。 - コメントアウトされた代替案。 「念のため」残してある別の方法です。Git に残っています。
- 過度に明示的な名前。
userDataObject、handleClickEventHandler、configurationOptionsMap、あるいは型名で繰り返しているような名前、たとえばUserShape、UserInterfaceです。名詞を使ってください。
儀式的なコード
- 呼び出し元が1つだけのラッパー。 ちょうど1か所から呼び出され、処理の過程で何も追加しない関数、クラス、モジュールです。インライン化してください。
- 実装が1つしかないインターフェース。 登場しなかった2つ目の実装のために書かれたものです。
- 誰も渡さないオプション。 デフォルト値しか使われないパラメーター、有効なキーが1つだけの設定オブジェクト、状態が1つしかない機能切り替えです。
- 対称性のためだけのコード。 空の
else、到達できないdefault:、何もしないfinally、待機するだけのラッパーです。 - 定数を1つだけ置くファイル。 境界そのものが目的である場合を除き、使用箇所に置いてください。
防御的なノイズ
10. 冗長な防御的処理。 存在しないはずの値に対する null チェック、コンパイラーがすでに型を絞り込んだ後の実行時 typeof、あるいは同じエラーを再スローするだけの try/catch です。その経路が信頼できることを確認してください。型注釈だけでは、実行時の入力は検証されません。境界での検証、および有意義な情報の追加や後処理を行う catch は残してください。エラーを握りつぶす catch や代替値を返す catch は、取り除くと動作が変わる場合、fail-fast に該当します。
11. 冗長なアサーション。 型エラーを黙らせるためだけの as any、as unknown as T、型の絞り込みで適切に処理できるのに使われる非 null アサーション !、既知の値を unknown や広範なレコード型に代入してから、もともとの型へ再アサーションする処理です。別のアサーションではなく、正しい型や型の絞り込みを使ってください。不一致の修正に実行時の変更が必要な場合は、その旨を報告してください。
12. 標準ライブラリの再実装。 すでに標準ライブラリにあるのに、独自に groupBy、chunk、debounce、日付フォーマッターを実装することです。呼び出し側に対して、タイミング、デフォルト値、エラー、ロケール、エッジケースを含め、同等の意味になることを確認してから置き換えてください。そうでなければ、変更せずに報告してください。
13. 冗長な非同期処理。 呼び出し側を追跡し、Promise の返却、拒否の動作、スケジューリングを維持できる場合に限り、async 構文を取り除いてください。await のない async 関数も Promise を返し、例外を拒否に変換します。また、通常の値を await しても、後続処理は一時停止します。構文が不要に見えるというだけで、どちらも冗長とは限りません。確信が持てない変更は、推測で行わず報告してください。
出力と残すもの
公開済み CLI の出力、エラーメッセージ、ログは、スクリプト、ユーザー、モニタリングが利用する可視の契約です。別途変更が依頼されていない限り、変更しないでください。クリーンアップのためだけにスナップショットを更新しないでください。互換性を確認できない変更は報告してください。
- 装飾的なコンソール出力。 絵文字、罫線文字、✅/❌ による状況演出、ログや CLI 出力のバナー見出しです。
- 祝辞の文言。 「Successfully completed!」「All done!」などです。結果を報告するか、何も表示しないでください。
- スタックを言い換えるエラーメッセージ。 何が失敗したのか、呼び出し側がどうすべきかを伝えてください。スタックはすでに表示されています。
- 不要な足場コード。 担当者のいない
TODOのプレースホルダー、サンプルブロック、本番経路に入り込んだモック、スタブ、フィクスチャです。 - 付随的なモックの詳細だけを検証するテスト。 アサーションが何を守るものかを確認してください。呼び出し回数や引数は、重複書き込みの防止など、実際の契約である場合があります。有意義なやり取りの検証は残してください。動作を何も証明しないテストは、カバレッジをひそかに削除したり、依頼の範囲外でテストを書き直したりせず、報告してください。
制御フロー
- 不要なネスト。 早期リターンを使うと読みやすくなる、新たに導入された
if/elseの階層です。実行順序、副作用、後処理、返却値が変わらない場合に限って平坦化してください。ロジックを明確に表現している場合や、周囲のコードに適合している場合は、ネストをそのまま残してください。
手順
ワークフローの規模を差分に合わせます。小規模な整理であれば、対象範囲、理由、検証は簡潔にし、個別のタスクリストは任意とします。
- 対象範囲を定めます。 既定では差分、つまりマージベースに対するブランチ、または作業ツリーを対象にします。リポジトリ全体の一括確認は別の作業であり、依頼されていないコードにも手を入れることになるため、実施する場合は明示が必要です。
- 関連する検証を選びます。 変更される可能性のある動作を挙げ、それを検出できる既存のチェックのうち、最も範囲の狭いものを使います。コメントのみの変更では、差分と該当するドキュメントチェックを確認します。無関係なベースラインの失敗は記録し、安全に独立して進められる作業を続けます。リポジトリで必須とされる最終チェックは維持し、ワークスペース全体を対象とする段階的なチェックは始めません。
- カタログに照らして差分を確認します。 周辺コードを読み、ローカルの慣習を把握したうえで、確認できた該当箇所ごとに、該当する指摘番号と
file:lineを記した項目を1つずつ記録します。読みながら書き換えてはいけません。確認と編集を同時に行うと、論点を見失い、改善作業に脱線します。 - 指摘を「削除」と「委譲」に分類します。 動作を維持できるものはすべて「削除」です。プログラムの動作を変えるものは「委譲」とし、担当するスキルを明記します。「委譲」はその場で実施してはいけません。
- 削除を適用し、影響を受ける契約を検証します。 選んだチェックを実行し、該当する場合は戻り値、副作用、タイミングを確認します。テストの成功は同等性を裏付けますが、証明するものではありません。結果の変化を調査し、不安定な失敗や既存の失敗と区別したうえで、動作を変える削除は元に戻します。
- 報告します。 小規模な整理では、変更内容、別の作業に委譲した事項、チェックの実施前後の結果を1~3文で伝えます。指摘の説明に必要な場合は、指摘番号とファイルの場所を記載します。指摘番号ごとの件数は、監査で求められた場合や、大きな差分で件数が役立つ場合に限って記載します。
これは何ではないか
- スタイルの一括調整ではありません。フォーマットはリポジトリのフォーマッターに従います。
- リファクタリングではありません。モジュール間でロジックを移動したり、パッケージを切り出したりする作業は
componentizeです。 - 強化作業ではありません。フォールバックを削除して明示的に失敗させるのは
fail-fastであり、意図的に動作を変える作業です。 - リンターではありません。理由が示されていない型アサーション、引数や戻り値での
unknown、モジュールのモック、Reflectによるプロパティアクセスなど、すべてのファイルで機械的に確認できるルールは、リポジトリのリンター設定に含めます。howells-lintは、これらのルールを含む@howells/lintを設定します。リンターにルールが読み込まれていない場合は、個々の箇所を手作業で指摘せず、その問題を委譲します。 - レビューではありません。正確性に関わるバグは別の作業です。見つけた場合は報告し、手を加えずに残します。