mcpField
S
slopwatch

slopwatch

github.com/wshaddixテスト・品質8677 回インストール35 週間前に更新
リポジトリ

slopwatch について

slopwatchは、問題を隠す近道がコード変更に含まれていないか確認する、.NET向けスキルです。特にLLMによる変更を対象とし、ベースライン、設定可能なルール、フック、CI検査を使うCLI手順を説明します。

主な機能

  1. 01無効化されたテストと警告抑制の検出
  2. 02空のcatchブロックとテスト遅延の検出
  3. 03プロジェクト設定とパッケージ版上書きの確認
  4. 04ベースラインによる既存問題の切り分け
  5. 05フックとCI検査への対応

活用シーン

  1. 01LLMによるC#やプロジェクトファイルの変更確認
  2. 02ローカル分析で新たな近道を阻止
  3. 03CIパイプラインでslop検査を実行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wshaddix/dotnet-skills --skill slopwatch

インストール後、Claude Code で/slopwatchを入力して読み込まれたか確認します。

詳細

Slopwatch:.NET 向け LLM 不正防止ツール

このスキルを使用するタイミング

このスキルは常に使用してください。 LLM(Claude を含む)が次のファイルに変更を加えるたびに:

  • C# ソースファイル(.cs)
  • プロジェクトファイル(.csproj)
  • Props ファイル(Directory.Build.props、Directory.Packages.props)
  • テストファイル

slopwatch を実行して、変更によって「slop」が持ち込まれていないことを検証してください。


Slop とは?

「Slop」とは、根本的な問題を実際に解決せずに、テストを通過させたりビルドを成功させたりするために LLM が使う近道を指します。これは報酬ハッキングの一種で、LLM が実際の修正ではなく、見かけ上の成功を優先します。

よくある Slop のパターン
パターン例問題点
テストの無効化[Fact(Skip="flaky")]修正する代わりに失敗を隠します
警告の抑制#pragma warning disable CS8618問題を修正せずにコンパイラーを黙らせます
空の catch ブロックcatch (Exception) { }エラーを握りつぶし、バグを隠します
恣意的な遅延await Task.Delay(1000);競合状態を覆い隠し、テストを遅くします
プロジェクトレベルでの抑制<NoWarn>CS1591</NoWarn>プロジェクト全体で警告を無効にします
CPM の回避インラインの Version="1.0.0"集中型パッケージ管理を損ないます

これらのパターンは決して受け入れないでください。 LLM が slop を持ち込んだ場合は、その変更を却下し、適切な修正を求めてください。


インストール

ローカルツールとして(推奨)

.config/dotnet-tools.json に追加します:

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "slopwatch.cmd": {
      "version": "0.3.3",
      "commands": ["slopwatch"],
      "rollForward": false
    }
  }
}

次に復元します:

dotnet tool restore
グローバルツールとして
dotnet tool install --global Slopwatch.Cmd

初回セットアップ:ベースラインを作成する

既存のプロジェクトで slopwatch を使用する前に、ベースラインを作成します:

# Initialize baseline from existing code
slopwatch init

# This creates .slopwatch/baseline.json
git add .slopwatch/baseline.json
git commit -m "Add slopwatch baseline"

ベースラインが必要な理由: レガシーコードには、既存の問題が含まれている場合があります。ベースラインを作成することで、slopwatch は新たに持ち込まれた slop のみを検出します。


使用方法

基本的な分析
# Analyze current directory for slop
slopwatch analyze

# Analyze specific directory
slopwatch analyze -d ./src

# Strict mode -- fail on warnings too
slopwatch analyze --fail-on warning

# JSON output for tooling integration
slopwatch analyze --output json

# Show performance stats
slopwatch analyze --stats
ベースラインの更新(まれ)

slop が本当に正当化できるものであり、その理由が文書化されている場合に限り、更新してください:

slopwatch analyze --update-baseline

妥当な理由:サードパーティライブラリによってパターンが強制される場合、意図的なレート制限の遅延(テストの不安定さによるものではない場合)、変更できない生成コード。正当化する理由を説明するコードコメントを必ず追加してください。


設定

.slopwatch/slopwatch.json を作成してカスタマイズします:

{
  "minSeverity": "warning",
  "rules": {
    "SW001": { "enabled": true, "severity": "error" },
    "SW002": { "enabled": true, "severity": "warning" },
    "SW003": { "enabled": true, "severity": "error" },
    "SW004": { "enabled": true, "severity": "warning" },
    "SW005": { "enabled": true, "severity": "warning" },
    "SW006": { "enabled": true, "severity": "warning" }
  },
  "exclude": [
    "**/Generated/**",
    "**/obj/**",
    "**/bin/**"
  ]
}
厳格モード(LLM セッションに推奨)
{
  "minSeverity": "warning",
  "rules": {
    "SW001": { "enabled": true, "severity": "error" },
    "SW002": { "enabled": true, "severity": "error" },
    "SW003": { "enabled": true, "severity": "error" },
    "SW004": { "enabled": true, "severity": "error" },
    "SW005": { "enabled": true, "severity": "error" },
    "SW006": { "enabled": true, "severity": "error" }
  }
}

検出ルール

ルール深刻度検出対象
SW001Error無効化されたテスト(Skip=、Ignore、#if false)
SW002Warning警告の抑制(#pragma warning disable、SuppressMessage)
SW003Error例外を握りつぶす空の catch ブロック
SW004Warningテスト内の恣意的な遅延(Task.Delay、Thread.Sleep)
SW005Warningプロジェクトファイル内の slop(NoWarn、TreatWarningsAsErrors=false)
SW006WarningCPM の回避(VersionOverride、インラインの Version 属性)
Slopwatch が問題を検出した場合
❌ SW001 [Error]: Disabled test detected
   File: tests/MyApp.Tests/OrderTests.cs:45
   Pattern: [Fact(Skip="Test is flaky")]
  1. 理由を理解する — LLM が近道を選んだ理由を確認します
  2. 適切な修正を求める — 問題点を具体的に伝えます
  3. 修正を検証する — 別の slop が持ち込まれていないことを確認します

ビルドを成功させるためにテストを無効化してはいけません。 根本的な問題を修正してください。


Claude Code フックとの統合

すべての編集を自動的に検証するフックとして slopwatch を追加します。.claude/settings.json を作成または更新します:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "slopwatch analyze -d . --hook",
            "timeout": 60000
          }
        ]
      }
    ]
  }
}

--hook フラグは次の動作をします:

  • Git で変更されたファイルのみを分析します(大規模なリポジトリでも高速です)
  • エラーを読みやすい形式で stderr に出力します
  • 警告またはエラーがある場合は編集をブロックします(終了コード 2)
  • Claude はエラーを確認し、すぐに修正できます

CI/CD との統合

GitHub Actions
jobs:
  slopwatch:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'

      - name: Install Slopwatch
        run: dotnet tool install --global Slopwatch.Cmd

      - name: Run Slopwatch
        run: slopwatch analyze -d . --fail-on warning
Azure Pipelines
- task: DotNetCoreCLI@2
  displayName: 'Install Slopwatch'
  inputs:
    command: 'custom'
    custom: 'tool'
    arguments: 'install --global Slopwatch.Cmd'

- script: slopwatch analyze -d . --fail-on warning
  displayName: 'Slopwatch Analysis'

基本理念:新たな Slop は一切許容しない

  1. ベースラインでレガシーの問題を記録する — 既存の問題を認識しつつ、切り分けます
  2. 新たな slop をブロックする — 新しい近道があれば、ビルドまたは編集を失敗させます
  3. 例外には正当な理由が必要 — ベースラインを更新する必要がある場合は、その理由を記録します
  4. LLM も例外ではない — 人間が書いたコードにも AI が生成したコードにも、同じルールを適用します

クイックリファレンス

# First time setup
slopwatch init
git add .slopwatch/baseline.json

# After every LLM code change
slopwatch analyze

# Strict mode (recommended)
slopwatch analyze --fail-on warning

# With stats (performance debugging)
slopwatch analyze --stats

# Update baseline (rare, document why)
slopwatch analyze --update-baseline

# JSON output for tooling
slopwatch analyze --output json

# Hook mode (for Claude Code integration)
slopwatch analyze -d . --hook

オーバーライドする場合(ほとんどありません)

ベースラインを更新するか、ルールを無効にする正当な理由は次のとおりです。

シナリオ対応必須事項
サードパーティがパターンを強制するベースラインを更新理由を説明するコードコメント
生成されたコード(編集不可)除外リストに追加設定に記載
意図的なレート制限による遅延ベースラインを更新コードコメント(テスト内ではなく)
レガシーコードのクリーンアップベースラインを一度だけ更新PR の説明

正当ではない理由:

  • 「テストが不安定」→ 不安定さを修正する
  • 「警告が煩わしい」→ コードを修正する
  • 「自分の環境では動く」→ 競合状態を修正する
  • 「後で修正する」→ 今すぐ修正する

エージェント向けの注意事項

  • slopwatch の検出結果を抑制しないでください。 slopwatch が問題を検出した場合は、コードを修正してください。
  • 最後だけでなく、コードを変更するたびに実行してください。
  • Claude Code のフックでは、単独の analyze ではなく --hook フラグを使用してください。
  • ベースラインは何でも入れる場所ではありません。 項目を追加するには、理由を記録する必要があります。
  • グローバルツールよりローカルツールを優先してください。 .config/dotnet-tools.json を使用してください。

参考資料

コメント