# Complete Release gate The default release gate is repository-owned and uses the SDK feature band in `global.json`: ```powershell pwsh ./tools/run-release-gate.ps1 ``` The command verifies that `AcDream.slnx` contains every `.csproj` under `src/`, `tests/`, and `tools/`, performs a locked restore, builds that complete graph, then discovers and runs every default test assembly once in a fresh Release process. It does not retry failures. The graph currently contains 44 projects, including all 13 maintained .NET tools; data-dependent tools are built but are not executed as tests. Build and dependency policy is repository-owned: - `global.json` pins the accepted .NET SDK feature band; - `Directory.Build.props` supplies the common target framework, language, nullable, analyzer, warnings-as-errors, deterministic-build, and lock-file settings; - `Directory.Packages.props` is the only direct package-version table; - `NuGet.Config` clears machine sources and permits only `nuget.org`; and - each supported project commits its own `packages.neutral.lock.json`; shipped source projects also commit `packages.win-x64.lock.json` and `packages.linux-x64.lock.json` for RID-specific publishes. The nonstandard neutral name is intentional. NuGet always prefers a conventional `packages.lock.json` when one exists, even when `NuGetLockFilePath` selects a RID-specific file. Do not introduce conventional lock files beside these three repository-owned graphs. The gate uses `dotnet restore --locked-mode --force-evaluate`. The forced evaluation makes the result independent of stale `obj/` assets; locked mode still prevents rewriting. If a project or central package version disagrees with a committed lock file, restore fails instead of silently changing the dependency graph. The launcher's nested Bake publish uses the matching RID-specific lock and the same forced locked evaluation. Each restore, build, and test process has an outer hard timeout. Every test also runs with VSTest blame-hang enabled: after three minutes in one test, the test host is terminated and a mini dump is collected; after ten minutes, the outer watchdog kills the complete `dotnet test` process tree. CI additionally has a 45-minute job bound. Evidence is written to `artifacts/release-gate/`: - `release-gate-summary.json` records the commit, branch, worktree state, SDK, RID, bounds, process outcomes, assembly list, and executed/passed/skipped/failed totals; - `environment.txt` records `dotnet --info`, configured NuGet sources, and the supported project set, package-lock hashes, and discovered test-project set; - `test-results/` contains one TRX per assembly plus any VSTest hang sequence and dump files; - `logs/` contains the exact command and complete output for every child process; and - `SHA256SUMS.txt` hashes the evidence bundle. The complete gate runs on Windows because it exercises the full product and launcher surface. Hosted GitHub Actions execution is deliberately parked as of 2026-08-18 while runner policy is decided; the checked-in workflow definitions are preserved for later use. Until then, the repository command above is the authoritative gate. Focused portability or Vulkan jobs are not substitutes for the complete gate. Environment-dependent tests retain their current skip behavior and are counted explicitly in the JSON/TRX report. Classifying or replacing those tests belongs to R3, not to this gate checkpoint. ## Updating dependencies Do not edit lock files by hand. To make an intentional dependency change: 1. Change the version once in `Directory.Packages.props` (or add/remove a versionless `PackageReference` in a project). 2. Regenerate the neutral graph and both supported release-RID graphs from the repository root: ```powershell pwsh ./tools/update-package-locks.ps1 ``` 3. Review the central-version and `packages.*.lock.json` diffs. 4. Prove locked resolution and run the gate: ```powershell dotnet restore AcDream.slnx --locked-mode --force-evaluate pwsh ./tools/run-release-gate.ps1 ``` The one site-scoped `xUnit1025` suppression in `MotionInterpreterTests.ContactAllowsMove_GroundedPosture_StillAllowsMove` preserves a known redundant historical input until R3. It is deliberately not in the central warning policy, so any new duplicate theory row still fails the build.