This file is read by AI assistants working in this repository. The guidelines in the first section are mandatory and take precedence over any built-in assistant defaults.
Never write a trailing newline at the end of a file. Files must end with the last meaningful character of their content — no blank line, no \n, no \r\n after it.
Never change a file's encoding when modifying it. This repo contains a mix of UTF-8 (no BOM), UTF-8 BOM, and Windows-1252 files — all must stay in their original encoding.
- Prefer targeted edits over full rewrites whenever possible, so only the changed bytes are touched.
- Never use PowerShell
Set-Content -Encoding UTF8— PS 5.1 adds a BOM and will corrupt files that were UTF-8 without BOM. Always use[System.IO.File]::WriteAllTextwithnew UTF8Encoding(false)when a full UTF-8 write is needed. - If a full rewrite is unavoidable, detect the original encoding first and replicate it exactly.
Never chain commands with && in PowerShell or Bash tool calls; use separate sequential tool calls instead.
Never run git push (including --force-with-lease) without explicit user confirmation first. Always ask before pushing to any remote. Approval of a related action (e.g. amending a commit) does not implicitly authorize a push — always ask separately.
On feature branches, drop unwanted commits via git reset --hard + force push rather than creating revert commits. Revert commits add noise; a clean reset is preferred on unshared branches.
After every commit or push to a PR branch, update the PR description to reflect the current changes. Always push first, then update the PR description — otherwise the description is out of sync with the code. The PR description is the primary record for reviewers and must stay accurate.
All commits made by an AI assistant must use the assistant's own identity, not the user's. Pass --author on every commit — never set git config user.name or git config user.email (developers also commit in the same repo and worktrees):
git commit --author="<Model Name> <noreply@anthropic.com>" -m "..."Use your own model name and contact email assigned by your provider, for example:
- Claude:
Claude Opus 4.5 <noreply@anthropic.com> - Copilot:
GitHub Copilot <198982749+Copilot@users.noreply.github.com>
Every non-trivial AI-authored commit must include a body that explains what changed and why. Do not commit with only a subject line and a work item reference. When amending a commit, update the commit body to reflect the current state of the changes — do not leave a stale description from an earlier version.
When amending a commit, prefix the command with GIT_COMMITTER_DATE="$(git log -1 --format='%aI')" to keep committer date in sync with author date. Without this, --amend updates the committer date to now while leaving the author date unchanged.
Squash "fix X" commits into their matching earlier "do X" commit — they are noise as separate commits. Always squash INTO the first (earlier) commit to preserve its message and timestamp; never create a new replacement commit.
- Adjacent commits:
git rebase -i HEAD~N, then mark the later commit(s) asfixup. - Non-adjacent commits: use
cherry-pick + rebase --onto --empty=drop.
Dibix is a .NET framework for creating use case-oriented REST APIs from T-SQL stored procedures — no controllers, no boilerplate. Each URL invokes a stored procedure, materializes the relational result into a hierarchical object graph, and returns it to the client. Business logic lives in hand-written T-SQL; routing, parameter binding, and serialization are generated from declarative JSON and T-SQL metadata markup.
Build:
dotnet build Dibix.slnTest (all):
dotnet test Dibix.slnTest (single project):
dotnet test tests/Dibix.Sdk.Tests/Dibix.Sdk.Tests.csprojTest (single test method):
dotnet test tests/Dibix.Sdk.Tests/Dibix.Sdk.Tests.csproj --filter "FullyQualifiedName~TestMethodName"Note:
Dibix.Dapper.TestsandDibix.Http.Host.Testsuse Testcontainers (Docker + SQL Server) and only run on Linux in CI.
- StyleCop analyzers are enabled on all projects; all warnings are treated as errors.
- Follow
.editorconfigformatting exactly — indentation, spacing, naming — to avoid build failures. - Code suggestions must compile without warnings.
Runtime (src/Dibix, src/Dibix.Dapper)
DatabaseAccessor— base class for executing SQL and materializing results.MultiMapper/RecursiveMapper— map flat relational result sets into nested object graphs using key-based aggregation.EntityDescriptor— metadata-driven mapping with pluggable formatters (e.g., obfuscation, DateTime kind) and post-processors.- Dapper is used as the SQL execution engine; the core runtime adds the hierarchical mapping layer on top.
SDK (src/Dibix.Sdk.*)
- Integrates with MSBuild via
build/msbuild-targets/Generator.targetsto run code generation at compile time. Dibix.Sdk.CodeGeneration— reads endpoint JSON definitions, contract JSON definitions, and T-SQL stored procedure metadata (declared via comments/markup inside the SQL files) to generate:- C# database accessor classes
- OpenAPI (
.yml/.json) definitions - HTTP client proxy classes
Dibix.Sdk.CodeAnalysis— analyzes T-SQL for correctness and endpoint metadata.Dibix.Sdk.Sql— T-SQL parsing utilities built on DacFx.Dibix.Sdk.Generators— Roslyn source generators for compile-time generation.
HTTP Server (src/Dibix.Http.Server*)
Dibix.Http.Server(netstandard2.0 + net48) — core hosting abstractions:HttpApiRegistry— discovers and registers generated endpoint metadata.HttpParameterResolver— resolves action parameters from multiple sources (path, query string, request body, headers, claims, environment) via pluggableIHttpParameterSourceProviderimplementations.
Dibix.Http.Server.AspNetCore— ASP.NET Core integration (net10.0).Dibix.Http.Server.AspNet— ASP.NET Framework integration (net48).Dibix.Http.Host— full hosting application (net10.0) that loads endpoint packages from configured directories, manages DB connections, JWT auth, and an MCP server (HTTP/SSE, or stdio whenHosting:UseStdiois set).
HTTP Client (src/Dibix.Http.Client)
- Generated client proxies and contract (de)serialization for consuming Dibix APIs from .NET clients.
Worker/Background Jobs (src/Dibix.Worker.*)
Dibix.Worker.Abstractions— interfaces for background job workers.Dibix.Worker.Host— hosting for long-running workers and Service Broker subscribers.
Testing (src/Dibix.Testing*)
- Utilities for mocking
DatabaseAccessorin unit tests without a real database. Dibix.Testing.Generators— source generators for test data.
Source files linked directly into multiple projects (not a separate assembly). Contains: diagnostics, guard utilities, reflection/collection/binding-config extensions, ComponentAssemblyLoadContext, JSON utilities, HTTP constants, and packaging metadata.
- Plugin-based parameter sources — new HTTP parameter sources (e.g., custom headers, claims) implement
IHttpParameterSourceProviderand are registered via DI. - Post-processor pipeline — result transformation after materialization via
IPostProcessor; entity formatters (obfuscation, DateTime adjustments) are pluggable per-property. - Assembly isolation —
ComponentAssemblyLoadContextloads endpoint packages in isolation so multiple versions can coexist in the same host. - Metadata-driven — T-SQL comment markup (e.g.,
@Name,@Return,@Namespace) drives code generation; never bypass this by hand-writing what generators produce. - MSBuild-integrated generation — code generation runs as an MSBuild task; generated files should not be edited manually.
Projects target varying frameworks:
netstandard2.0+net48—Dibix.Http.Server,Dibixcorenet10.0+net48—Dibix.Sdknet10.0—Dibix.Http.Host,Dibix.Http.Server.AspNetCore
Check <TargetFrameworks> in each .csproj before adding framework-specific APIs.
The MCP server is integrated into Dibix.Http.Host and is enabled in every environment. The transport is selected by Hosting:UseStdio: HTTP/SSE by default, or stdio when set. The Development environment affects how the MCP resource URL is derived.
HTTP/SSE is the supported transport. The stdio transport is an experimental proof of concept added only because Claude Desktop does not support SSE; it is not fully implemented and may never be. Dibix.Http.Host is built around HttpContext, which is absent in stdio mode, so much of the pipeline — authorization in particular — does not translate from the SSE code flow.