| name | dotnet-slopwatch |
| description | Two-layer slop prevention for .NET: code-level detection via Slopwatch CLI (SW-xxx) and architectural anti-pattern catalog (SLOP-xxx). Use when: validating LLM-generated C# code, checking for layer boundary violations, or integrating anti-slop quality gates into CI/CD.
|
| metadata | {"author":"RyoMurakami1983","tags":["dotnet","quality","llm","anti-cheat","slopwatch"],"invocable":false} |
Slopwatch: LLM Anti-Cheat for .NET
Two-layer slop prevention system for .NET projects:
- Code-Level (SW-xxx) — Automated detection via Slopwatch CLI tool (disabled tests, empty catches, warning suppression)
- Architecture-Level (SLOP-xxx) — Anti-pattern catalog requiring human/LLM judgment (layer violations, responsibility leaks)
When to Use This Skill
Use this skill when:
- Validating LLM-generated C# code changes for reward hacking patterns
- Checking whether Presentation layer code contains domain logic that belongs in Application/Domain layers
- Setting up Slopwatch as a Claude Code post-edit hook
- Integrating anti-slop quality gates into GitHub Actions or Azure Pipelines
- Establishing a baseline for existing .NET projects with technical debt
- Reviewing architecture decisions in layered .NET applications (DDD, Clean Architecture)
Related Skills
crap-analysis — Identify high-risk code combining complexity with low coverage
modern-csharp-coding-standards — The coding standards Slopwatch helps enforce
dotnet-local-tools — Manage Slopwatch as a versioned local tool
Core Principles
- Zero Tolerance for New Slop — Existing issues are baselined; new shortcuts are blocked unconditionally (基礎と型)
- Fix, Don't Suppress — Every flagged pattern requires a proper fix, not a workaround (温故知新)
- LLMs Are Not Special — Same quality rules apply to human and AI-generated code (ニュートラル)
- Baseline Isolates Legacy — Pre-existing debt is acknowledged but separated from new changes (余白の設計)
Workflow: Install & Use Slopwatch
Step 1 — Install Slopwatch
Add to .config/dotnet-tools.json as a local tool:
{
"version": 1,
"isRoot": true,
"tools": {
"slopwatch.cmd": {
"version": "0.3.4",
"commands": ["slopwatch"],
"rollForward": false
}
}
}
dotnet tool restore
Values: 継続は力(ツールをバージョン管理し再現可能に)
Step 2 — Establish Baseline
Create a baseline of existing issues before using Slopwatch on a project:
slopwatch init
git add .slopwatch/baseline.json
git commit -m "chore: add slopwatch baseline"
Legacy code may have pre-existing patterns. The baseline ensures only new slop is caught.
Values: 余白の設計(レガシーを認め、新規の品質を守る)
Step 3 — Run After Every Code Change
slopwatch analyze
slopwatch analyze --fail-on warning
When Slopwatch flags an issue, do not ignore it:
- 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
❌ SW001 [Error]: Disabled test detected
File: tests/MyApp.Tests/OrderTests.cs:45
Pattern: [Fact(Skip="Test is flaky")]
→ "Fix the flaky test's timing issue, don't disable it."
Values: 基礎と型(根本原因の修正が型)
Step 4 — Integrate with AI Coding Assistant
4a: Automatic Hook (Claude Code)
Add Slopwatch as a post-edit hook in .claude/settings.json. The --hook flag analyzes only git-dirty files, outputs errors to stderr, and fails on warnings by default:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "slopwatch analyze -d . --hook",
"timeout": 60000
}
]
}
]
}
}
4b: On-Demand (Copilot CLI)
Ask @dotnet-shihan to run slopwatch. The agent executes slopwatch analyze via shell and interprets results:
@dotnet-shihan slopwatch を実行して
@dotnet-shihan 近道してないかチェックして
The agent references this skill and the SLOP-xxx catalog during code reviews automatically.
Values: 成長の複利(自動ガードレールで品質を仕組み化)
Step 5 — Add to CI/CD Pipeline
Use as a quality gate in GitHub Actions:
jobs:
slopwatch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- run: dotnet tool install --global Slopwatch.Cmd
- run: slopwatch analyze -d . --fail-on warning
Values: 基礎と型(品質ゲートを基盤に組み込む)
Code-Level Detection Rules (SW-xxx)
Automated rules enforced by the Slopwatch CLI tool.
| Rule | Severity | Pattern | Example |
|---|
| SW001 | Error | Disabled tests | [Fact(Skip="flaky")], #if false |
| SW002 | Warning | Warning suppression | #pragma warning disable CS8618 |
| SW003 | Error | Empty catch blocks | catch (Exception) { } |
| SW004 | Warning | Arbitrary delays | await Task.Delay(1000); in tests |
| SW005 | Warning | Project file slop | <NoWarn>CS1591</NoWarn> |
| SW006 | Error | Package version override | Inline Version="1.0.0" bypassing CPM |
Architectural Slop Patterns (SLOP-xxx)
Design-level anti-patterns requiring human or LLM judgment. These cannot be detected by static analysis alone — they require understanding of architectural intent.
SLOP-001: Layer Boundary Violation
Severity: Error
Symptom: Upper layer (Presentation/ViewModel) uses string.Split, Substring, or Regex to reconstruct domain values from a concatenated string received from a lower layer.
Why It's Dangerous:
- Relies on implicit assumptions about string format (delimiters, order, escaping)
- Domain knowledge leaks into Presentation layer ("product type codes can contain hyphens")
- Fragile under change: format changes break Presentation code silently
Example:
var parts = compositeCode.Split('-');
var productType = parts[2];
Product type AL-6XN contains a hyphen, so naive splitting destroys the value.
record ComparisonRow(
string CategoryCode,
string ProductType,
string LotNumber
);
Prescription: If the upper layer needs data that isn't in the response, extend the lower layer's response — never reconstruct domain values by parsing strings.
Checklist:
Decision Rule: "Does this Split require knowledge of domain structure to write?" → Yes = SLOP-001 violation. No = legitimate UI formatting.
Values: 基礎と型(DDD layer boundaries are foundational — violating them creates hidden fragility)
Good Practices
1. Strict Mode for LLM Sessions
What: Elevate all rules to error severity during AI-assisted coding.
Why: LLMs are more likely to introduce slop than humans — higher guard rails are justified.
Values: 基礎と型(厳格な型でスロップを排除)
2. Baseline on First Use
What: Always run slopwatch init before first analyze on existing projects.
Why: Without a baseline, every legacy issue triggers false positives, eroding trust in the tool.
Values: 余白の設計(既存の技術的負債を認識して分離)
Common Pitfalls
1. Updating Baseline to Silence Warnings
Problem: Running --update-baseline whenever Slopwatch flags an issue.
Solution: Only update baseline for genuinely justified exceptions (third-party constraints, generated code). Document the reason in a code comment.
2. Disabling Rules Instead of Fixing Code
Problem: Setting "enabled": false for noisy rules.
Solution: Fix the underlying code. If a rule produces false positives, report it upstream; don't disable the guard rail.
Anti-Patterns
"We'll Fix It Later"
What: Accepting slop with a plan to revisit.
Why It's Wrong: "Later" never comes. The shortcut becomes permanent technical debt.
Better Approach: Fix the actual problem now. If time-constrained, create a tracked issue and keep the guard rail active.
Slop-Fixing with More Slop
What: Fixing a disabled test by adding Task.Delay(2000) instead of fixing the race condition.
Why It's Wrong: Replaces one slop pattern (SW001) with another (SW004).
Better Approach: Identify and fix the root cause (race condition, timing dependency, shared state).
Quick Reference
slopwatch init
git add .slopwatch/baseline.json
slopwatch analyze
slopwatch analyze --fail-on warning
slopwatch analyze -d . --hook
slopwatch analyze --update-baseline
slopwatch analyze --output json
Override Decision Table
| Scenario | Action | Requirement |
|---|
| Third-party forces pattern | Update baseline | Code comment explaining why |
| Generated code (not editable) | Add to exclude list | Document in config |
| Intentional rate limiting | Update baseline | Code comment, not in test |
| "Test is flaky" | ❌ Never override | Fix the flakiness |
| "Warning is annoying" | ❌ Never override | Fix the code |
Resources