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)

ConcernChoice
LanguageC# 9, target .NET Framework 4.6.2 (Org Service SDK constraint)
BuildMSBuild via dotnet build (NOT msbuild directly — the agent should always invoke through dotnet CLI)
Test frameworkxUnit + Moq for plugin unit tests; integration tests use Testcontainers + a Postgres mock CRM
Package managerNuGet via PackageReference (NOT packages.config — old style is forbidden in this repo)
Lint/formatdotnet format is required before commit
CIGitHub Actions, workflow at .github/workflows/ci.yml
CRM SDK versionMicrosoft.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 PackageReference lines for Newtonsoft.Json introduced via merge conflicts. Build fails opaquely; the fix is dedupe before retry. See [[CSProj-Duplicate-PackageReference-Trap]].
  • dotnet test without --filter Category!=Integration will 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.x transitive deps on this codebase. If you see NU1605 or downgrade warnings, switch to NuGet v6+ (dotnet nuget list source and ensure v3 is removed).
  • The master branch was rolled back on 2026-04-26 from 55d6e3f to 2187a36 after 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_state while issue is in_progress, or wiki/syntheses/issue-X.md after 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 format before committing
  • Open PRs from agent/<issue-id> branches only; never push to master

DON’T:

  • Don’t merge any PR yourself — the Shipper agent owns merging, and only after green CI
  • Don’t run dotnet build without -maxcpucount:2 -nodeReuse:false (CPU starvation per ADR-025 §C)
  • Don’t modify the .csproj PackageReference versions 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:

  1. Capture the lesson in your run’s scratchpad
  2. On issue close, the Librarian agent rolls it up into wiki/concepts/ or wiki/comparisons/
  3. The next time RefactorAgent runs (Sunday 02:00), it reviews the new lesson and proposes a SKILL.md edit as a PR
  4. A human reviews and merges
  5. 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.