dotnet-slopwatch
.NETコード変更時に、テスト無効化や警告抑制など、LLMの報酬ハッキングにつながる手抜きをSlopwatchで検出し、問題の隠蔽を防ぐための品質チェックを自動化するSkill。
📜 元の英語説明(参考)
Use Slopwatch to detect LLM reward hacking in .NET code changes. Run after every code modification to catch disabled tests, suppressed warnings, empty catch blocks, and other shortcuts that mask real problems.
🇯🇵 日本人クリエイター向け解説
.NETコード変更時に、テスト無効化や警告抑制など、LLMの報酬ハッキングにつながる手抜きをSlopwatchで検出し、問題の隠蔽を防ぐための品質チェックを自動化するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o dotnet-slopwatch.zip https://jpskill.com/download/8710.zip && unzip -o dotnet-slopwatch.zip && rm dotnet-slopwatch.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/8710.zip -OutFile "$d\dotnet-slopwatch.zip"; Expand-Archive "$d\dotnet-slopwatch.zip" -DestinationPath $d -Force; ri "$d\dotnet-slopwatch.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
dotnet-slopwatch.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
dotnet-slopwatchフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Slopwatch: .NET 向け LLM アンチチート
この Skill を使用するタイミング
この Skill は常に使用してください。 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.2.0",
"commands": ["slopwatch"],
"rollForward": false
}
}
}
次に、復元します。
dotnet tool restore
グローバルツールとして
dotnet tool install --global Slopwatch.Cmd
初回セットアップ: ベースラインの確立
既存のプロジェクトで slopwatch を使用する前に、現在の問題のベースラインを作成します。
# 既存のコードからベースラインを初期化する
slopwatch init
# これにより .slopwatch/baseline.json が作成されます
git add .slopwatch/baseline.json
git commit -m "Add slopwatch baseline"
なぜベースラインが必要なのですか? レガシーコードには既存の問題がある可能性があります。ベースラインは、slopwatch が 新しい slop の導入のみを検出し、既存の技術的負債を検出しないようにします。
LLM セッション中の使用法
すべてのコード変更後
LLM によって生成されたコードの変更後、slopwatch を実行します。
# 新しい問題を分析する (ベースラインを使用)
slopwatch analyze
# 厳密モードを使用する - 警告でも失敗する
slopwatch analyze --fail-on warning
Slopwatch が問題を検出した場合
無視しないでください。 代わりに:
- LLM がショートカットを使用した理由を理解する
- 適切な修正を要求する - 何が問題なのかを具体的に示す
- 修正が別の slop を導入していないか検証する
# 例: LLM がテストを無効にした
❌ SW001 [Error]: Disabled test detected
File: tests/MyApp.Tests/OrderTests.cs:45
Pattern: [Fact(Skip="Test is flaky")]
# 正しい応答: 実際の修正を求める
"このテストは修正されずに無効化されました。なぜ不安定なのかを調査し、根本的なタイミング/競合状態の問題を修正してください。"
ベースラインの更新 (まれ)
slop が 本当に正当化され、文書化されている場合にのみ、ベースラインを更新してください。
# 現在の検出をベースラインに追加する (控えめに使用してください!)
slopwatch analyze --update-baseline
正当化の例:
- サードパーティライブラリがパターンを強制する (例: 特定の警告を抑制する必要がある)
- レート制限のための意図的な遅延 (テストの不安定さではない)
- 修正できない生成されたコード
ベースラインを更新するときは、コードコメントで理由を文書化してください。
Claude コードフックの統合
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 統合
slopwatch を品質ゲートとして CI パイプラインに追加します。
GitHub Actions
jobs:
slopwatch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.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'
検出ルール
| ルール | 重要度 | 何を検出するか |
|---|---|---|
| SW001 | エラー | 無効化されたテスト (Skip=, Ignore, #if false) |
| SW002 | 警告 | 警告の抑制 (#pragma warning disable, SuppressMessage) |
| SW003 | エラー | 例外を握りつぶす空の catch ブロック |
| SW004 | 警告 | テスト内の恣意的な遅延 (Task.Delay, Thread.Sleep) |
| SW005 | 警告 | プロジェクトファイルの slop (NoWarn, TreatWarningsAsErrors=false) |
| SW006 | 警告 | CPM バイパス (VersionOverride, インライン Version 属性) |
構成
.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": [
"**/ 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Slopwatch: LLM Anti-Cheat for .NET
When to Use This Skill
Use this skill constantly. Every time an LLM (including Claude) makes changes to:
- C# source files (.cs)
- Project files (.csproj)
- Props files (Directory.Build.props, Directory.Packages.props)
- Test files
Run slopwatch to validate the changes don't introduce "slop."
What is Slop?
"Slop" refers to shortcuts LLMs take that make tests pass or builds succeed without actually solving the underlying problem. These are reward hacking behaviors - the LLM optimizes for apparent success rather than real fixes.
Common Slop Patterns
| Pattern | Example | Why It's Bad |
|---|---|---|
| Disabled tests | [Fact(Skip="flaky")] |
Hides failures instead of fixing them |
| Warning suppression | #pragma warning disable CS8618 |
Silences compiler without fixing issue |
| Empty catch blocks | catch (Exception) { } |
Swallows errors, hides bugs |
| Arbitrary delays | await Task.Delay(1000); |
Masks race conditions, makes tests slow |
| Project-level suppression | <NoWarn>CS1591</NoWarn> |
Disables warnings project-wide |
| CPM bypass | Version="1.0.0" inline |
Undermines central package management |
Never accept these patterns. If an LLM introduces slop, reject the change and require a proper fix.
Installation
As a Local Tool (Recommended)
Add to .config/dotnet-tools.json:
{
"version": 1,
"isRoot": true,
"tools": {
"slopwatch.cmd": {
"version": "0.2.0",
"commands": ["slopwatch"],
"rollForward": false
}
}
}
Then restore:
dotnet tool restore
As a Global Tool
dotnet tool install --global Slopwatch.Cmd
First-Time Setup: Establish a Baseline
Before using slopwatch on an existing project, create a baseline of current issues:
# Initialize baseline from existing code
slopwatch init
# This creates .slopwatch/baseline.json
git add .slopwatch/baseline.json
git commit -m "Add slopwatch baseline"
Why baseline? Legacy code may have existing issues. The baseline ensures slopwatch only catches new slop being introduced, not pre-existing technical debt.
Usage During LLM Sessions
After Every Code Change
Run slopwatch after any LLM-generated code modification:
# Analyze for new issues (uses baseline)
slopwatch analyze
# Use strict mode - fail on warnings too
slopwatch analyze --fail-on warning
When Slopwatch Flags an Issue
Do not ignore it. Instead:
- Understand why the LLM took the shortcut
- Request a proper fix - be specific about what's wrong
- Verify the fix doesn't introduce different slop
# Example: LLM disabled a test
❌ SW001 [Error]: Disabled test detected
File: tests/MyApp.Tests/OrderTests.cs:45
Pattern: [Fact(Skip="Test is flaky")]
# Correct response: Ask for actual fix
"This test was disabled instead of fixed. Please investigate why
it's flaky and fix the underlying timing/race condition issue."
Updating the Baseline (Rare)
Only update the baseline when slop is truly justified and documented:
# Add current detections to baseline (use sparingly!)
slopwatch analyze --update-baseline
Justification examples:
- Third-party library forces a pattern (e.g., must suppress specific warning)
- Intentional delay for rate limiting (not test flakiness)
- Generated code that can't be modified
Document why in a code comment when updating baseline.
Claude Code Hook Integration
Add slopwatch as a hook to automatically validate every edit. Create or update .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "slopwatch analyze -d . --hook",
"timeout": 60000
}
]
}
]
}
}
The --hook flag:
- Only analyzes git dirty files (fast, even on large repos)
- Outputs errors to stderr in readable format
- Blocks the edit on warnings/errors (exit code 2)
- Claude sees the error and can fix it immediately
CI/CD Integration
Add slopwatch to your CI pipeline as a quality gate:
GitHub Actions
jobs:
slopwatch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.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'
Detection Rules
| Rule | Severity | What It Catches |
|---|---|---|
| SW001 | Error | Disabled tests (Skip=, Ignore, #if false) |
| SW002 | Warning | Warning suppression (#pragma warning disable, SuppressMessage) |
| SW003 | Error | Empty catch blocks that swallow exceptions |
| SW004 | Warning | Arbitrary delays in tests (Task.Delay, Thread.Sleep) |
| SW005 | Warning | Project file slop (NoWarn, TreatWarningsAsErrors=false) |
| SW006 | Warning | CPM bypass (VersionOverride, inline Version attributes) |
Configuration
Create .slopwatch/slopwatch.json to customize:
{
"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/**"
]
}
Strict Mode (Recommended for LLM Sessions)
For maximum protection during LLM coding sessions, elevate all rules to errors:
{
"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" }
}
}
The Philosophy: Zero Tolerance for New Slop
- Baseline captures legacy - Existing issues are acknowledged but isolated
- New slop is blocked - Any new shortcut fails the build/edit
- Exceptions require justification - If you must update baseline, document why
- LLMs are not special - The same rules apply to human and AI-generated code
The goal is to prevent the gradual accumulation of technical debt that occurs when LLMs optimize for "make the test pass" rather than "fix the actual problem."
Quick Reference
# 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
When to Override (Almost Never)
The only valid reasons to update baseline or disable a rule:
| Scenario | Action | Required |
|---|---|---|
| Third-party forces pattern | Update baseline | Code comment explaining why |
| Generated code (not editable) | Add to exclude list | Document in config |
| Intentional rate limiting delay | Update baseline | Code comment, not in test |
| Legacy code cleanup | One-time baseline update | PR description |
Invalid reasons:
- "The test is flaky" → Fix the flakiness
- "The warning is annoying" → Fix the code
- "It works on my machine" → Fix the race condition
- "We'll fix it later" → Fix it now