templates/skills/languages/csharp/SKILL.md
Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
npx skillsauth add hivellm/rulebook C#Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
CRITICAL: Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
# Complete quality check sequence:
dotnet format --verify-no-changes # Format check
dotnet build # Build + compile check
dotnet test # All tests (100% pass)
dotnet test --collect:"XPlat Code Coverage" # Coverage (95%+ required)
# Security audit:
dotnet list package --vulnerable # Vulnerability scan
dotnet list package --outdated # Check outdated deps
CRITICAL: Use .NET 8+ with C# 12+.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisMode>All</AnalysisMode>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<!-- Package Metadata -->
<PackageId>Your.Package.Name</PackageId>
<Version>1.0.0</Version>
<Authors>Your Name</Authors>
<Company>Your Company</Company>
<Description>A short description of your package</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/your-org/your-project</PackageProjectUrl>
<RepositoryUrl>https://github.com/your-org/your-project</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>your;tags</PackageTags>
<!-- Documentation -->
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
CRITICAL: After implementing ANY feature, you MUST run these commands in order.
IMPORTANT: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures!
# Pre-Commit Checklist (MUST match .github/workflows/*.yml)
# 1. Format check (matches workflow - use --verify-no-changes!)
dotnet format --verify-no-changes
# 2. Build (MUST pass with no warnings - matches workflow)
dotnet build --no-incremental --warnaserror
# 3. Run all tests (MUST pass 100% - matches workflow)
dotnet test --no-build
# 4. Check coverage (MUST meet threshold)
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
# If ANY fails: ❌ DO NOT COMMIT - Fix first!
If ANY of these fail, you MUST fix the issues before committing.
Why This Matters:
dotnet format locally but dotnet format --verify-no-changes in CI = failure--warnaserror flag = warnings pass locally but fail in CIUse .editorconfig for consistent code style:
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.{cs,csx,vb,vbx}]
indent_size = 4
# C# Code Style Rules
[*.cs]
# Organize usings
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false
# this. preferences
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_qualification_for_method = false:warning
dotnet_style_qualification_for_event = false:warning
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
# Modifier preferences
dotnet_style_require_accessibility_modifiers = always:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning
# Expression preferences
csharp_style_var_for_built_in_types = true:warning
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_var_elsewhere = true:warning
# Pattern matching
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
# Null-checking preferences
csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning
# Code block preferences
csharp_prefer_braces = true:warning
csharp_prefer_simple_using_statement = true:warning
# Naming conventions
dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = warning
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
# Naming styles
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
Example test structure:
using Xunit;
namespace YourProject.Tests;
public class MyClassTests
{
[Fact]
public void Process_ValidInput_ReturnsExpectedResult()
{
// Arrange
var sut = new MyClass();
var input = "test";
// Act
var result = sut.Process(input);
// Assert
Assert.Equal("TEST", result);
}
[Theory]
[InlineData("")]
[InlineData(null)]
public void Process_InvalidInput_ThrowsArgumentException(string input)
{
// Arrange
var sut = new MyClass();
// Act & Assert
Assert.Throws<ArgumentException>(() => sut.Process(input));
}
}
<summary>, <param>, <returns>, <exception>Example:
namespace YourProject;
/// <summary>
/// Provides functionality for processing data.
/// </summary>
public class MyClass
{
/// <summary>
/// Processes the input string and converts it to uppercase.
/// </summary>
/// <param name="input">The input string to process.</param>
/// <returns>The processed string in uppercase.</returns>
/// <exception cref="ArgumentException">Thrown when input is null or empty.</exception>
/// <example>
/// <code>
/// var processor = new MyClass();
/// var result = processor.Process("hello");
/// // result is "HELLO"
/// </code>
/// </example>
public string Process(string input)
{
if (string.IsNullOrEmpty(input))
{
throw new ArgumentException("Input cannot be null or empty.", nameof(input));
}
return input.ToUpperInvariant();
}
}
project/
├── src/
│ └── YourProject/
│ ├── YourProject.csproj
│ ├── Class1.cs
│ └── ...
├── tests/
│ └── YourProject.Tests/
│ ├── YourProject.Tests.csproj
│ ├── Class1Tests.cs
│ └── ...
├── docs/ # Project documentation
├── .editorconfig # Code style configuration
├── Directory.Build.props # Shared MSBuild properties
├── Directory.Packages.props # Central package management
├── YourProject.sln # Solution file
├── README.md # Project overview (allowed in root)
├── CHANGELOG.md # Version history (allowed in root)
└── LICENSE # Project license (allowed in root)
? for nullable types! sparinglyExample:
public class UserService
{
private readonly ILogger<UserService> _logger;
public UserService(ILogger<UserService> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public User? FindUser(string? username)
{
if (string.IsNullOrEmpty(username))
{
return null;
}
// Implementation
return new User { Username = username };
}
public User GetUser(string username)
{
var user = FindUser(username);
return user ?? throw new InvalidOperationException("User not found");
}
}
async/await for I/O operationsConfigureAwait(false) in librariesTask or ValueTaskExample:
public class DataService
{
private readonly HttpClient _httpClient;
public async Task<string> FetchDataAsync(string url, CancellationToken cancellationToken = default)
{
var response = await _httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
}
}
Must include GitHub Actions workflows for:
Testing (dotnet-test.yml):
Linting (dotnet-lint.yml):
dotnet format --verify-no-changesdotnet build --no-incrementalPrerequisites:
NUGET_API_KEY to GitHub repository secretsPublishing Workflow:
Update version in .csproj
Update CHANGELOG.md
Run quality checks:
dotnet format --verify-no-changes
dotnet build --configuration Release
dotnet test --configuration Release
Pack: dotnet pack --configuration Release
Create git tag: git tag v1.0.0 && git push --tags
GitHub Actions automatically publishes to NuGet
Or manual publish: dotnet nuget push bin/Release/*.nupkg --api-key $NUGET_API_KEY --source https://api.nuget.org/v3/index.json
Publishing Checklist:
dotnet format)dotnet packSemantic Versioning:
Use <Version> in .csproj with SemVer:
research
Author a rulebook task spec interactively — research, draft, ask the user clarifying questions, confirm, then create the tasks in rulebook ready for /rulebook-driver. Use when the user wants to plan/spec a feature before implementing.
development
Behavioral guidelines to reduce common LLM coding mistakes — overcomplication, sloppy refactors, hidden assumptions, weak goals. Use when writing, reviewing, or refactoring code. Auto-applies; invoke explicitly via /karpathy-guidelines or 'follow karpathy discipline'.
data-ai
Autonomous AI agent loop for iterative task implementation (@hivehub/rulebook ralph)
data-ai
Use SQL Server for enterprise relational data storage with advanced features, high availability, and Windows integration.