dotnet-cop
SkillDev toolsPre-merge code review for .NET 10 pull requests. Ground truth: Minimal API + IModule (reflection-based isolation) + hexagonal per module (Application/Core/Infrastructure) + EF Core CRUD. Optional additive: DDD / CQRS / event sourcing per module. Diffs current branch against a target branch, applies .NET-specific checklists (Minimal API endpoints, modular isolation, ports & adapters, EF Core + schema-per-module + RLS, C# strictness, xUnit v3 only), runs dotnet build + dotnet format --verify-no-changes, and emits a tiered report (verbose for juniors, terse for seniors). Auto-loads project AGENTS.md rules. Use when user runs /cop-review, says "pre-merge review", or invokes dotnet-cop.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the dotnet-cop skill
What this skill tells your AI
The instructions your AI receives, as published by fmflurry/settings-opencode in skills/dotnet-cop/SKILL.md and read by ahel’s review.
Pre-merge review. Compares HEAD vs origin/<target>. .NET-aware. Project-aware (reads AGENTS.md). Tooling-aware (runs dotnet build + dotnet format --verify-no-changes).
When to Activate
- Selected by
code-reviewerfor .NET guidance during/cop-review - User runs
/cop-review <target>on a .NET repo - dotnet-cop specialist is explicitly invoked
Inputs
| Arg | Required | Default | Meaning |
|---|---|---|---|
<target> | yes | — | Target branch (e.g. main, develop, release/x) |
--level | no | auto | junior (verbose teaching) or senior (terse). Auto = senior. |
--scope | no | all | Comma list: minimal-api,isolation,ports-adapters,ef-core,csharp,result,ddd + optional cqrs,event-sourcing |
--no-tools | no | false | Skip dotnet build + format check (static review only) |
Hard Rules
- Read-only. Never patch code. Output report only.
- Diff window:
git merge-base HEAD origin/<target>..HEAD. Never review changes already on target. - Confidence ≥ 80%. Skip uncertain findings. Use
❓ q:instead of speculative🔴 bug:. - Project rules win.
AGENTS.mdoverrides this skill. Re-read on every run; do not cache between sessions. - dotnet-clean-architecture ground truth: load [[dotnet-clean-architecture]] SKILL.md before flagging architecture code. Do not invent APIs or patterns.
- No fluff. No "great work", no restating what the diff already shows.
Pipeline
1. Parse args -> target, level, scope
2. git fetch <remote> <target> (silent; --quiet)
3. base = git merge-base HEAD <remote>/<target>
4. changed = git diff --name-status base..HEAD
5. Load <repo>/AGENTS.md (if exists) -> project rules
6. For each changed file:
- Skim full file (not just hunk) for context
- Apply relevant sub-checklists by path/role:
*Module.cs / *Extensions.cs -> modular-isolation.md
*Endpoint.cs (Minimal API) -> minimal-api.md
Core/Ports/Incoming/*.cs -> ports-adapters.md
Core/Ports/Outgoing/*.cs -> ports-adapters.md
Infrastructure/Adapter/*.cs -> ports-adapters.md
*DbContext.cs / Migrations/** -> ef-core.md
*.cs (any) -> csharp-strict.md
- If --scope includes ddd && Core/ domain code changed: load [[dotnet-ddd]] (review-checklist.md); defer deep CQRS/ES to optional-cqrs.md / optional-event-sourcing.md
- If --scope includes cqrs && module signals use: optional-cqrs.md
- If --scope includes event-sourcing && module signals use: optional-event-sourcing.md
7. If !--no-tools:
- dotnet build --nologo -clp:ErrorsOnly (the solution if one exists, else the relevant project(s) — fail fast)
- dotnet format --verify-no-changes (capture exit code)
8. Aggregate findings -> render via output-format.md
Severity
| Tag | Meaning | Action |
|---|---|---|
| 🔴 bug | broken behavior, runtime crash, data loss | BLOCK merge |
| 🟠 sec | security risk (unvalidated input, leaked secret, tenant-data leak) | BLOCK merge |
| 🟡 risk | works today, fragile tomorrow (N+1, missing filter, scope violation) | Fix before merge |
| 🟢 arch | violates mandatory architecture rule (SoT) or AGENTS.md-escalated opt-in rule | Fix before merge |
| 🔵 nit | style, naming, micro-optim | Optional |
| ❓ q | genuine question | Author decides |
Promote to BLOCK if AGENTS.md flags the category as mandatory.
Sub-pages (read on demand)
- [[dotnet-cop-minimal-api]] — endpoint mapping, route groups, ProblemDetails, FluentValidation at boundary, no business logic in handlers.
- [[dotnet-cop-modular-isolation]] — module boundaries, no direct cross-module type references (hard blocker), communication via ports/events, reflection-based module discovery, per-module language autonomy.
- [[dotnet-cop-ports-adapters]] — hexagonal: Core defines ports, Infrastructure implements adapters; dependency direction; no EF entities leaking into Core.
- [[dotnet-cop-ef-core]] — DbContext per context/projection (hard blocker on shared DbContext), schema-per-module isolation, FORCE RLS mandatory on all context-schema tables, query splitting, N+1 prevention.
- [[dotnet-cop-result]] — business errors returned as
Result/Result<T>, never thrown;Errordefined in Domain; no HTTP coupling in Domain/Application. - [[dotnet-ddd]] (ddd scope) — DDD tactical patterns (entities, value objects, aggregates, repositories) and strategic design for domain-layer code. Deep CQRS/ES enforcement defers to [[dotnet-cop-optional-cqrs]] and [[dotnet-cop-optional-event-sourcing]].
- [[dotnet-cop-optional-cqrs]] (opt-in) — commands/queries, handlers, CQRS pattern. Only when module signals use.
- [[dotnet-cop-optional-event-sourcing]] (opt-in) — event-sourced aggregates, immutable events, append-only event store. Only when module signals use.
- [[dotnet-cop-output-format]] — junior vs senior render templates.
- [[dotnet-cop-enforcement]] — BLOCK vs WARN severity checklist (load always). SoT rules listed first; opt-in rules clearly marked.
AGENTS.md Loading
Always:
test -f AGENTS.md && cat AGENTS.md
test -f .agent/AGENTS.md && cat .agent/AGENTS.md
Parse rule blocks. Where this skill and AGENTS.md disagree, AGENTS.md wins. Cite the AGENTS.md line in the finding: (AGENTS.md §<section>).
Output Contract
Single markdown document, sections in fixed order:
- Summary — target, base SHA, head SHA, files changed, finding counts by severity.
- Blockers (🔴 / 🟠 / 🟢-when-AGENTS-mandates) — sorted by severity, then file path.
- Should-fix (🟡) — same sort.
- Optional (🔵 / ❓) — collapsible.
- Tooling — dotnet build summary, dotnet format summary.
- Verdict —
APPROVE/APPROVE-WITH-CHANGES/BLOCK.
See [[dotnet-cop-output-format]] for full templates.
Boundaries
- Does not write code fixes. Suggestions only.
- Does not run integration or unit tests by default (delegate to the
tddworkflow /tdd-guide). - Does not approve PRs in GitHub/Azure. Author posts the report manually.
- Does not auto-fix formatting. Reports format violations only.
- If no diff (HEAD == base), exit early with "no changes to review".
Signals
- GitHub stars
- 171
- Forks
- 10
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
dotnet-cop- Source
- github.com/fmflurry/settings-opencode