- Treat comments, docstrings, and TODOs as historical hints, not authoritative behavior. They survive refactors and go stale. Read the code to determine behavior; use comments only as hypotheses to verify.
- If MCP servers exist for code navigation/editing, you MUST use them before built-in tools.
- Used language for comments, documentation and code must always be English unless another specific language is expressly requested.
- Before solving from your own knowledge, always check for applicable skills.
- Use subagents as much as possible to avoid context pollution.
- ALWAYS verify that your changes are complete and work correctly. Use verification steps best suited for your changes.
- You MUST not git commit files unless explicitly asked to do so by the user.
- Stage files by name (never git add -A/.). Refuse to stage secret-like files (.env, credentials.json, *.pem); warn if the user insists.
Don't assume. Don't hide confusion. Surface tradeoffs.
Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them — don't pick silently.
- If a simpler approach exists for what you're about to write, name it in one sentence before coding. If the user confirms the original, proceed.
- If something is unclear, stop. Name what's confusing. Ask.
Minimum code that solves the problem. Nothing speculative.
- No features beyond what was asked.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios. No error handling for scenarios guaranteed impossible by the type system or a same-file invariant. If justifying the skip requires reasoning about callers, keep the check.
Touch only what you must. Clean up only your own mess.
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it in your final response — don't delete it.
When your changes create orphans: Remove imports/variables/functions your changes orphaned; leave pre-existing dead code (mention it in the response).
- Ask beats guessing or silent assumption.
- Surgical beats Simplify for existing code. § 2 applies only to code you write new in this task; don't rewrite existing code to make it simpler unless asked.
- Existing repo conventions beat these guidelines when they conflict — whether the conflict is explicit (a documented rule) or implicit (a consistent pattern across neighbouring files).
A collection of reusable .NET 10 libraries published as NuGet packages under the CreativeCoders.* namespace. Licensed under Apache 2.0.
- Runtime: .NET 10 (
net10.0) - Language: C# (latest stable)
- SDK:
10.0.100(seeglobal.json, rollForward: latestFeature) - Build system: Cake (Frosting) via
CreativeCoders.CakeBuild— entry point isbuild/Program.cs - Versioning: GitVersion (ContinuousDeployment on
main, ContinuousDelivery on feature branches) - Package management: Central Package Management (
Directory.Packages.props) - Testing: xUnit, FakeItEasy, AwesomeAssertions, coverlet
- CI: GitHub Actions (ubuntu, windows, macos) — workflows in
.github/workflows/ - NuGet feed: GitHub Packages (main builds), nuget.org (release builds)
Core.sln Solution file
Directory.Build.props Shared MSBuild properties (TargetFramework, Authors)
Directory.Packages.props Central NuGet version pins
global.json SDK version constraint
GitVersion.yml Versioning configuration
build/ Cake Frosting build project
Program.cs Build entry point (CakeHostBuilder)
BuildContext.cs Build configuration (feeds, tools, settings)
source/ Library source code (see below)
tests/ Unit/integration test projects
samples/ Sample applications
.github/workflows/ CI/CD pipelines
| Area | Projects | Purpose |
|---|---|---|
| Core | CreativeCoders.Core |
Ensure guards, collections, threading, enums, reflection, IO helpers, visitor pattern, object linking, dependency trees |
| AspNetCore | .AspNetCore, .Blazor, .TokenAuth.Jwt, .TokenAuthApi, .TokenAuthApi.Jwt |
ASP.NET Core extensions, Blazor helpers, JWT token auth |
| Cli | .Cli.Core, .Cli.Hosting |
CLI application framework with hosting support |
| SysConsole | .SysConsole.App, .Core, .Cli.Actions, .Cli.Parsing, .CliArguments |
Console applications with Spectre.Console, argument parsing, CLI actions |
| Data | .Data, .Data.EfCore, .Data.EfCore.SqlServer, .Data.Nhibernate, .Data.NoSql, .Data.NoSql.LiteDb |
Data access abstractions, EF Core, NHibernate, LiteDB |
| Net | .Net, .Net.Avm, .Net.JsonRpc, .Net.WebApi, .Net.XmlRpc, .Net.Servers.Http.AspNetCore |
Networking utilities, JSON-RPC, XML-RPC, WebApi client, HTTP server |
| Messaging | .Messaging.Core, .Messaging.DefaultMediator, .Messaging.DefaultMessageQueue |
In-process messaging, mediator pattern, message queues |
| Reactive | .Reactive.Messaging |
Reactive Extensions-based messaging |
| Config | .Config, .Config.Base, .Config.Sources |
Configuration abstraction layer |
| Configuration | .Configuration |
Microsoft.Extensions.Configuration integration |
| Options | .Options.Core, .Options.Serializers, .Options.Storage.FileSystem |
Options pattern with persistence |
| DependencyInjection | .DependencyInjection |
DI container extensions |
| Scripting | .Scripting.Base, .Scripting.CSharp |
C# scripting and source code generation |
| CodeCompilation | .CodeCompilation, .CodeCompilation.Roslyn |
Runtime code compilation via Roslyn |
| DynamicCode | .DynamicCode.Proxying |
Dynamic proxy generation (Castle.Core) |
| IO | .IO.Archives, .IO.Ports |
Archive handling, serial port abstractions |
| Localization | .Localization |
Microsoft.Extensions.Localization integration |
| Daemon | .Daemon, .Daemon.Linux, .Daemon.Windows |
Cross-platform daemon/service hosting (systemd, Windows Services) |
| ProcessUtils | .ProcessUtils |
Process execution utilities |
| UnitTests | .UnitTests |
Test helper library |
| CakeBuild | .CakeBuild |
Reusable Cake Frosting build tasks |
| NukeBuild | .NukeBuild, .NukeBuild.Components |
Nuke build system components |
Use standard dotnet commands for building, testing and restoring:
dotnet restore
dotnet build
dotnet testThe full CI pipeline uses Cake Frosting. These commands are intended for CI/CD and release workflows — not for day-to-day development:
./build.sh -t pack # Linux/macOS
./build.cmd -t pack # Windows
./build.sh -t test # Tests with coverage
./build.cmd -t nugetpush # Full pipeline with NuGet push (CI only)Build targets are defined in CreativeCoders.CakeBuild and configured in build/BuildContext.cs. The build uses GitVersion for automatic semantic versioning and ReportGenerator for coverage reports (output: .tests/coverage-report).
| Workflow | Trigger | Purpose |
|---|---|---|
main.yml |
Push to main |
Build, test, pack, push to NuGet (Linux pushes, Windows/macOS build+test only) |
pull-request.yml |
PR to main |
Build and test on all platforms |
integration.yml |
Manual/schedule | Integration testing |
release.yml |
Release event | Publish to nuget.org |
dependabot-auto-merge.yml |
Dependabot PRs | Auto-merge dependency updates |
sync-ai-config.yml |
Config sync | Synchronize AI configuration files |
- Always use the latest stable C# version available in the project's target framework.
- Use
Ensure.NotNull(...)fromCreativeCoders.Corefor null guards - Use
Ensure.IsNotNullOrEmpty(...)fromCreativeCoders.Corefor string guards for arguments that must not be empty - Use
Ensure.IsNotNullOrWhitespace(...)fromCreativeCoders.Corefor string guards for arguments that must not be empty or whitespace - Guard arguments for public methods in libraries with
Ensure.NotNull(...)for all required parameters:
public void DoSomething(string input, string fileName)
{
Ensure.NotNull(input);
Ensure.NotNullOrWhitespace(fileName);
// method implementation
}- Guard constructor-injected dependencies with
Ensure.NotNull(...)for all required parameters:
_service = Ensure.NotNull(service);- Apply code-formatting style defined in
.editorconfig. - Prefer file-scoped namespace declarations and single-line using directives.
- Insert a newline before the opening curly brace of any code block (e.g., after
if,for,while,foreach,using,try, etc.). - Ensure that the final return statement of a method is on its own line.
- Use
nameofinstead of string literals when referring to member names. - Use
[UsedImplicitly]from JetBrains.Annotations when types are only used via DI or reflection. - Use naming conventions from surrounding code when they differ from standard C# conventions.
- Default to a primary constructor, also with
Ensure.*guards — put the guard in the field initializer, not a constructor body:public sealed class Foo(IBar bar) : IFoo { private readonly IBar _bar = Ensure.NotNull(bar); }
- Reference the fields, never the raw parameters (avoids capturing unguarded params).
- Use a classic constructor only when init needs real statements (control flow, ordering, multistep setup, logic before base(...)/this(...)). Guards/initializers don't count.
- A parameter assigned to a property goes via the property initializer, not a backing field.
- In library code always use
.ConfigureAwait(false) - In tests do not use
.ConfigureAwait(false)(disable for tests via tests/.editorconfig) - YOU MUST NOT USE
.GetAwaiter().GetResult()OR.ResultOR.Wait()TO BLOCK ON ASYNC CODE. If there is no other way ask the user what to do.
- Declare variables non-nullable, and check for
nullat entry points. - Always use
is nulloris not nullinstead of== nullor!= null. - Trust the C# null annotations — don't add null checks when the type system guarantees non-null.
- Document all public members with XML documentation.
- Use the
dotnet-xmldocsskill to ensure XML documentation follows best practices. - If you change code, always update the relevant XML documentation.
- Always include test cases for code changes.
- Always use the
dotnet-testerskill for writing tests.
- Use AnsiConsole for console input and output. Always use IAnsiConsole via dependency injection.
- Use colored output where it makes sense. For example, use green for success messages, red for errors and yellow for warnings.
- Use tables for structured output when displaying lists of data or multiple pieces of related information.
- Use Serilog for logging.
- Configure Serilog with appropriate sinks (e.g., file, console, Azure Application Insights) based on environment.
- Always use structured logging with properties for better log analysis and correlation.
- You MUST use the
dotnet-aspnetskill for ASP.NET Core projects (project structure, middleware, auth, validation, error handling, API versioning, OpenAPI). - You MUST use the
dotnet-ef-coreskill for Entity Framework Core data access patterns. - You MUST use the
dotnet-sdk-builderskill for creating .NET SDK/client libraries. - You MUST use the
dotnet-reviewerskill for Reviewing .NET Code. - You MUST use the
dotnet-testerskill for writing and editing tests. - You MUST use the
dotnet-nuget-managerskill for NuGet package management. - You MUST use the
dotnet-inspectskill to query .NET APIs in NuGet packages, platform libraries (System., Microsoft.AspNetCore.), or local .dll/.nupkg files — discover types and members, diff API surfaces between versions, find extension methods/implementors, locate SourceLink URLs, and triage breakages caused by package upgrades. - You MUST use the
dotnet-xmldocsskill to ensure XML documentation follows best practices.