Guidance for AI coding tools (Claude Code, GitHub Copilot, Cursor, Aider, Codex, etc.) working in this repo.
This is the canonical brief — always-on rules plus a routing table to everything else. GitHub Copilot reads this file natively. Claude Code reads CLAUDE.md, which imports this file and additionally lists each skill under .agents/skills/ by path, since Claude Code doesn't auto-discover that folder the way Copilot CLI does.
One topic, one home — anything that duplicates another layer gets deleted, not synced:
docs/adr/— the decision and why it was made. Immutable history; a superseded ADR says so and points at its replacement.docs/(everything else) — reference material and maintainer runbooks: the current "how it works" / "how to operate it"..agents/skills/— on-demand procedures: what an agent does for a specific task, loaded only when the task matches.- This file — the rules that apply to every session, plus the routing table below.
Fallout is a build automation system for C#/.NET — a hard-fork successor to NUKE, originally by Matthias Koch, now under new maintenance. The build is itself a C# console app (build/_build.csproj), so any framework change can be dogfooded by running ./build.ps1 (Windows) or ./build.sh (Linux/macOS). The rebrand from Nuke.* to Fallout.* has structurally landed; Nuke.* survives only as consumer transition shims under src/Shims/ — see docs/Migration/from-nuke.md.
Classic GitFlow, staying on semver 10.x — see ADR-0009 (replaces the calendar-versioning ADR-0004). GitHub Packages = test/preview/rc; nuget.org = production.
| Branch | Role | Publishes |
|---|---|---|
develop |
Integration trunk, default branch, sole preview lane. All work lands here, including breaking work gated behind [Experimental]. |
-preview → GitHub Packages only |
release/vX.Y |
Stabilizes the next release; cut from develop on demand, not ahead of time. Non-breaking fixes only after the cut. |
-rc.N → GitHub Packages |
main |
Production trunk; takes only release/vX.Y (GA) or hotfix/vX.Y.Z merges. |
GA tags → nuget.org (opt-in) + GitHub Packages + Releases |
support/v10 (+ hotfix/v10.x) |
Legacy line for versions before 10.4. Security/critical fixes only. |
Tags, same channels as main |
MAJOR stays 10 until a breaking change is actually needed — there's no fixed date for v11, and it's deferred as long as possible. Not-yet-stable public APIs ship behind [Experimental("FALLOUT0xx")] on any channel — see the marking-experimental-apis skill. Full model: docs/branching-and-release.md.
Active work — rebrand completion + plugin-architecture internal foundation (milestone #6), shipping as non-breaking 10.x releases. No public plugin SDK yet — see docs/roadmap.md.
- .NET SDK pinned in
global.json(currently10.0.100,rollForward: latestMinor). - Central package versions in
Directory.Packages.props— never add aVersion=to an individualPackageReference. - xUnit + FluentAssertions + Verify.Xunit for tests.
- Solution file is
fallout.slnx(new XML solution format, not.sln). - Dependency updates: handled by Dependabot (weekly grouped PRs). Adding a meaningful library? Add a row to docs/dependencies.md in the same PR.
./build.ps1 # default target = Pack
./build.ps1 Compile
./build.ps1 Test
./build.ps1 GenerateTools # regenerate tool wrappers from JSON
./build.ps1 --help # list all targets and parameters
# Or via dotnet directly when iterating on a single project
dotnet build fallout.slnx
dotnet test tests/Fallout.Common.Tests/Fallout.Common.Tests.csprojDo commit code generated by GenerateTools — the .Generated.cs files are checked in, and VerifyGeneratedTools fails CI if a .json spec edit isn't accompanied by regenerating and committing its wrapper.
-
At PR-creation time, use the
creating-a-prskill (.agents/skills/creating-a-pr/SKILL.md). It covers branching off a fork, creating the PR as a draft, and applying thetarget/vCurrent/target/vNextand changelog-category labels. Breaking changes get extra steps there — they targetdevelopbehind[Experimental("FALLOUT0xx")], never arelease/vX.Yormainproduction branch. Not optional — review will block a PR that skips this. -
Default to backwards compatibility. Prefer an additive change over a breaking one. Before changing a public signature, removing an API, renaming a package, or changing an on-disk format, ask: can this be additive instead? Prefer
[Obsolete], transition shims (src/Shims/+Fallout.SourceGenerators.TransitionShimGenerator),[Experimental("FALLOUT0xx")], feature flags, and extra overloads over a hard break — see themarking-experimental-apisskill for how to apply either attribute. When a break really can't be avoided, it follows rule 1's flow. See #262 for the broader discussion. -
Central package versions only — add to
Directory.Packages.props, neverVersion=inline. -
Tests next to code — every
src/Foohas atests/Foo.Testssibling. Mirror namespaces. -
Stay on xUnit + FluentAssertions + Verify. Don't introduce new test frameworks. Test names are short, present-tense descriptions of observable behavior (not method calls); test classes/files/projects use the
Specssuffix; mark Arrange/Act/Assert with Pascal-case comments — see CONTRIBUTING.md for the full convention with examples. -
No per-file license headers. The MIT notice lives in
LICENSEat the repo root — single source of truth. Don't reintroduce header preambles on new files. (Vendored third-party code undersrc/Persistence/Fallout.Persistence.Solution/keeps its own upstream Microsoft headers — leave those alone.) -
No conventional commits. Do not use
feat:,fix:,chore:,refactor:, or any other conventional-commit prefix on commit messages or PR titles. Write functional descriptions that explain what the commit or PR accomplishes — e.g. "Add retry logic to the HTTP tool wrapper". The only exception is the!suffix (e.g.fix(security)!: …), used purely as a breaking-change detection signal. -
Write terse, plain English — in chat responses, commit messages, PR/issue descriptions, and code comments alike. Lead with the point; bullets over prose; cut filler (no preamble, no hedging, no marketing tone). Many contributors read English as a second language, so:
- One idea per sentence. Split stacked clauses instead of joining them with em-dashes or semicolons.
- No idioms or figurative language ("blast radius", "ceiling", "shallow by design"). Say what you mean literally: "affects fewer consumers", "limit", "handles the common case only".
- Define or link repo jargon on first use — see the
plain-englishskill's glossary — don't assume the reader already knows the vocabulary. - Gloss a cross-reference in 3–5 words instead of a bare
#257. - Prefer short, common words — "use" not "leverage", "keep" not "preserve".
Full rules and examples: the
plain-englishskill, including issue/PR shape (Problem → Outcome → Acceptance criteria, anti-patterns). -
Never ping the former NUKE maintainer, Matthias Koch (GitHub handle
matkoch). He no longer maintains Fallout and does not want the notifications. Do not@-mention him (never write@before his handle, in any file or GitHub surface), add him as a reviewer/assignee, request his review, tag him in issue/PR/commit text, or add him as a commit co-author/Co-authored-by:trailer — from any AI tool. Credit NUKE's origin by name or a plain profile link — just never with a leading@(a bare@handleis what fires a mention).
| Path | What lives here |
|---|---|
src/ |
All production library projects (src/Fallout.<X>/Fallout.<X>.csproj). The exception is src/Shims/ — three transition shims for NUKE-era consumers. |
tests/ |
All test projects (tests/Fallout.<X>.Tests/Fallout.<X>.Tests.csproj), plus the shim test projects. |
vendor/ |
Vendored third-party source we maintain a fork of (vs-solutionpersistence, packaged as Fallout.VisualStudio.SolutionPersistence). |
build/ |
The build orchestrator (_build.csproj + Build.*.cs partial files) — the canonical example of how to consume the framework. |
docs/ |
Documentation site content, architecture notes, and ADRs. |
.agents/skills/ |
On-demand agent procedures (see the routing table below). |
.assets/ |
Images, icons, logos — anything binary and non-code. Don't reintroduce a top-level images/ folder. |
| Root | Solution file (fallout.slnx), shared MSBuild plumbing (Directory.Build.props/targets, Directory.Packages.props), AssemblyInfo.cs, project conventions (README.md/CONTRIBUTING.md/LICENSE/AGENTS.md/CLAUDE.md). |
Production code lives under src/, tests under tests/ — don't reintroduce a combined source/ tree (the previous monorepo layout); see docs/architecture.md for why. src/Fallout.Common/Tools/<Tool>/<Tool>.json files are the source of truth for tool wrappers; the .cs next to each is generated. Source generators (src/Fallout.SourceGenerators) produce per-target code at compile time — if a symbol seems missing, check whether it's generated.
| Doing this? | Use |
|---|---|
| Opening a PR, writing commits, picking a base branch | creating-a-pr skill |
| Writing any PR, commit, issue, or doc text | plain-english skill |
Adding/extending a Tools/<Tool>/<Tool>.json wrapper |
adding-a-tool-wrapper skill |
| Adding public API that isn't stable yet, or deprecating one | marking-experimental-apis skill |
Touching .github/workflows/** or build/Build.CI.GitHubActions.cs |
editing-ci-workflows skill |
| Tagging, publishing, hotfixing, or cutting a release branch | cutting-a-release skill |
Adding a rename/rewrite rule to fallout-migrate |
adding-a-migration-step skill |
| Understanding the branching/versioning model in depth | docs/branching-and-release.md, ADR-0009 |
| Understanding the repo layout / engine internals | docs/architecture.md, docs/engine-de-statification.md |
| Consumer-facing NUKE → Fallout migration | docs/Migration/from-nuke.md |
| Roadmap, milestones, open RFCs | docs/roadmap.md |
| Adding/auditing a third-party dependency | docs/dependencies.md |
| Repo jargon (shim, sentinel, canonical type, …) | plain-english skill (glossary section) |
| Contributor-facing flow (issues, PR review, merging) | CONTRIBUTING.md |
Skills live in .agents/skills/<skill>/SKILL.md, each with its own references/ for anything longer than a screenful.