CRMAPIGenerator — Project SKILL
This file is read by every kalamos agent that touches the CRMAPIGenerator codebase. Its purpose: tell the agent what it needs to know about this project before it starts work, so that no agent ever has to re-derive project context from scratch.
What this project is
CRMAPIGenerator is a code-generation tool that produces strongly-typed C# wrapper classes around Microsoft Dynamics 365 CRM on-premises Web API endpoints. Output is .NET Framework 4.6.2-compatible C# that downstream solutions can reference as NuGet packages.
The repo is structured as a multi-project .NET solution. Templates and
generation logic live under Templates/ and Generators/; integration
tests under Tests/. CI runs on master via GitHub Actions.
Tech stack (verified facts, last updated 2026-04-28)
| Concern | Choice |
|---|---|
| Language | C# 9, target .NET Framework 4.6.2 (Org Service SDK constraint) |
| Build | MSBuild via dotnet build (NOT msbuild directly — the agent should always invoke through dotnet CLI) |
| Test framework | xUnit + Moq for plugin unit tests; integration tests use Testcontainers + a Postgres mock CRM |
| Package manager | NuGet via PackageReference (NOT packages.config — old style is forbidden in this repo) |
| Lint/format | dotnet format is required before commit |
| CI | GitHub Actions, workflow at .github/workflows/ci.yml |
| CRM SDK version | Microsoft.Xrm.Sdk 9.x (matches D365 v9.1 on-prem) |
Build and test commands (memorize these)
# From repo root:
dotnet restore # restore packages (run after dependency change)
dotnet build -maxcpucount:2 -nodeReuse:false # build (low parallelism + no MSBuild zombie nodes per ADR-025)
dotnet test --filter Category!=Integration # unit tests only
dotnet test # full suite incl. integration (slow)
dotnet format --verify-no-changes # check formatting (CI gate)The MSBUILDDISABLENODEREUSE=1 env var is set on the kalamos container
(per ADR-025 §“Compose patch shipped”). This is mandatory and prevents
zombie MSBuild worker processes from accumulating across agent runs.
Known gotchas (the things that have burned us before)
See [[CSProj-Duplicate-PackageReference-Trap]], [[NuGet-v3-vs-v6-Resolution]],
[[Integration-Tests-Hit-Live-CRM-Without-Filter]], and the full
wiki/concepts/ listing for the running set. Some highlights:
- The Templates/ csproj has historically had duplicate
PackageReferencelines forNewtonsoft.Jsonintroduced via merge conflicts. Build fails opaquely; the fix is dedupe before retry. See[[CSProj-Duplicate-PackageReference-Trap]]. dotnet testwithout--filter Category!=Integrationwill hit a live CRM endpoint and either fail the suite or, worse, mutate test data. Always filter unless you’ve explicitly set up a mock.- NuGet resolution under v3 is flaky for
Microsoft.Xrm.Sdk 9.xtransitive deps on this codebase. If you seeNU1605or downgrade warnings, switch to NuGet v6+ (dotnet nuget list sourceand ensure v3 is removed). - The
masterbranch was rolled back on 2026-04-26 from55d6e3fto2187a36after a batch of agent-generated retry-PRs were merged with failing CI. This is the “yellow banner trap”: the GitHub “Compare & pull request” banner is not a kalamos pipeline signal. Only merge PRs that the Shipper agent has opened with green CI.
Do / don’t for agents on this project
DO:
- Always read the Builder’s prior scratchpad on this issue (in
plugin_statewhile issue is in_progress, orwiki/syntheses/issue-X.mdafter close) before writing code - Cite the specific file:line of any decision in a code comment that traces back to a wiki page (e.g.,
// per [[CSProj-Duplicate-PackageReference-Trap]]) - Use the existing test infrastructure under
Tests/— don’t write new test fixtures unless explicitly asked - Run
dotnet formatbefore committing - Open PRs from
agent/<issue-id>branches only; never push tomaster
DON’T:
- Don’t merge any PR yourself — the Shipper agent owns merging, and only after green CI
- Don’t run
dotnet buildwithout-maxcpucount:2 -nodeReuse:false(CPU starvation per ADR-025 §C) - Don’t modify the
.csprojPackageReferenceversions to “fix” a build failure without first checking[[NuGet-v3-vs-v6-Resolution]] - Don’t write new files under
Templates/matching a name that already exists — kalamos’s case-insensitive filesystem on the VPS will conflict - Don’t write integration tests that hit a real CRM. If the test would need one, ask in the issue thread instead
How to evolve this SKILL
Anything in this file becomes outdated. When you hit a new gotcha, don’t edit this file directly — that breaks the “agents don’t write SKILL.md” rule. Instead:
- Capture the lesson in your run’s scratchpad
- On issue close, the Librarian agent rolls it up into
wiki/concepts/orwiki/comparisons/ - The next time RefactorAgent runs (Sunday 02:00), it reviews the new lesson and proposes a SKILL.md edit as a PR
- A human reviews and merges
- SKILL.md updated; next agent session-start picks it up
Same applies to outdated entries: flag them in your scratchpad with a contradiction note, the Librarian creates a ## Contradictions section in the relevant wiki page, RefactorAgent surfaces it for human review.