| name | project-placement-defaults |
| description | Use when creating, moving, or splitting projects in a repository that uses Purview.DotNetProjectSdk, especially for src/tests placement, test suffix naming, namespace alignment, and automatic project-reference behavior. |
Project placement defaults for Purview.DotNetProjectSdk
Use this skill whenever a task asks to add, move, split, or create a project in a repository that uses Purview.DotNetProjectSdk and you need placement, naming, and reference decisions to remain consistent with the SDK's automatic conventions.
Core principle
Preserve the host repository's existing layout first; only introduce new structure when no established pattern exists. In Purview-based repos, prefer layouts that let the SDK's naming and auto-reference rules work without extra overrides.
Placement heuristics
Use the repository's current structure as the source of truth, with these Purview-friendly defaults:
- Prefer source projects under
src/.
- Prefer test projects under
tests/.
- Place new projects beside similar projects (same language, layer, and test type).
- Keep one test type per project by default.
- Keep shared helper projects in explicit shared/shared-testing locations when those concepts exist.
When a repo has no clear structure, use these conservative defaults because they align well with the SDK's automatic project-reference search paths:
- Source/library projects under
src/
- Test projects under
tests/
- Integration/end-to-end tests in explicit sibling projects/folders such as
tests/Api.IntegrationTests/ or tests/Api.E2ETests/
Purview-specific naming rules
The SDK relies heavily on project names.
- Keep the
.csproj filename equal to its containing directory name unless DisableProjectFileNamingConventionCheck=true is explicitly used.
- Use conventional test suffixes such as
.UnitTests, .IntegrationTests, .E2ETests, .FunctionalTests, .ContractTests, and other supported *Tests suffixes.
- Keep shared helper projects on the SDK's exact recognized names when you want shared behavior:
- Shared projects:
Shared, SharedFramework, SharedInfrastructure, SharedInfra, SharedUtilities, SharedUtils, SharedLibrary, SharedLib, SharedHelpers
- Shared testing projects:
SharedTestingFramework, SharedTestingInfrastructure, SharedTestingInfra, SharedTestingUtilities, SharedTestingUtils, SharedTestingLibrary, SharedTestingLib, SharedTestingHelpers
- Do not invent near-miss names if you expect the SDK to classify the project automatically.
Test-type boundaries
Separate tests by behavior and dependency scope:
- Unit tests: isolate logic with minimal external dependencies.
- Integration tests: verify behavior across component boundaries (I/O, framework integration, build/evaluation behavior).
- End-to-end/system tests: verify full workflow behavior across the assembled system.
If specialized test categories exist (for example, analyzer diagnostics vs code-fix integration), keep category-specific tests in distinct projects/folders.
The SDK recognizes many test suffixes, including Unit, Integration, E2E, EndToEnd, Acceptance, Functional, Performance, Load, Smoke, Stress, Regression, Security, Chaos, Scenario, System, Threat, BlackBox, WhiteBox, Accessibility, Interactive, Environment, Architecture, and Contract.
Naming and namespace defaults
Align identities with existing repository conventions:
- Project names should follow prevailing patterns in sibling projects.
- Test project names should clearly indicate scope/type with recognized test suffixes.
NamespacePrefix should remain the root identity source for the repo.
RootNamespace usually flows from the logical project identity generated by the SDK; avoid custom namespace overrides unless required.
- When moving files between projects, update namespaces so they match the destination project's conventions.
Do not invent a new naming scheme when an existing one is already in use.
Project defaults
When creating a new project:
- Match the SDK/project style used by sibling projects.
- Reuse central dependency/version management if present.
- Add only dependencies required for the project's scope.
- Add the project to the repository solution/workspace entry point.
- Keep configuration consistent with neighboring projects (target frameworks, nullable, analyzers, warnings).
When working in a Purview-based repo, also assume:
TargetFramework defaults to net10.0 if not otherwise set.
- Test projects receive framework packages and coverage defaults from the SDK.
- Non-test projects receive SourceLink and telemetry defaults unless explicitly opted out.
Move/split workflow checklist
When splitting or relocating tests/projects:
- Create destination project/folder using established layout patterns.
- Move files physically.
- Update namespaces/imports/references for the destination.
- Verify the destination project name still produces the intended
TestingType, TargetProjectName, and RootNamespace.
- Remove stale dependencies from the source project.
- Update solution/workspace membership and project references.
- Run build and relevant tests.
Automatic project-reference behavior to preserve
The SDK automatically searches for project references based on naming and placement.
- Test projects probe for their target project in these relative locations:
../$(TargetProjectName)/$(TargetProjectName).csproj
../../$(TargetProjectName)/$(TargetProjectName).csproj
../src/$(TargetProjectName)/$(TargetProjectName).csproj
../../src/$(TargetProjectName)/$(TargetProjectName).csproj
- Non-test projects automatically look for sibling shared projects via
../Shared*/Shared*.csproj.
- Test projects automatically look for sibling shared-testing projects via
../SharedTesting*/SharedTesting*.csproj.
If you move projects away from these conventions, be prepared to add explicit project references.
Guardrails
- Prefer minimal, targeted diffs.
- Avoid cross-cutting renames unrelated to the move/split intent.
- Keep test intent unchanged while relocating.
- If structure is ambiguous, infer from nearest sibling projects and document the assumption in the change summary.
- When in doubt, preserve compatibility with the SDK's automatic naming, namespace, and project-reference behavior.