Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/agent-memory/atomic-executor/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
- [VS18 build/test toolchain paths](project_vs18_build_toolchain_paths.md) — use VS **18** full-framework msbuild.exe (not .dotnet-sdk, dies on
- [Repo-local SDK install + nullable Rebuild](project_repo_sdk_and_nullable_rebuild.md) — .dotnet-sdk install needs pwsh7; csharpier check/format
- [vstest TestCaseFilter OR-vs-pipe + fresh-worktree bootstrap](project_vstest_testcasefilter_or_operator_and_env_setup.md) — vstest rejects `OR`,
- [Analyzer version skew on fresh worktree](project_analyzer_version_skew_fresh_worktree.md) — analyzer build can fail CS0006 when csproj `<Analyzer
- [Analyzer version skew on fresh worktree](project_analyzer_version_skew_fresh_worktree.md) — CS0006 kills EVERY build (not just the analyzer gate), empties `<Test>/bin/Debug`, and a caller may forbid the fix
- [SecurityCodeScan incompatible with Roslyn 5.6](project_securitycodescan_roslyn56_incompat.md) — SecurityCodeScan.VS2019 5.6.7 throws
- [Missing VSTO runtime breaks baseline gates](project_missing_vsto_runtime_breaks_baseline_gates.md) — HISTORICAL, not reproducing 2026-08-08; build
- [New sln member surfaces MSB3277](project_new_sln_member_surfaces_msb3277_pin_divergence.md) — wiring an unbuilt legacy test project into the sln
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,56 @@
---
name: analyzer-version-skew-fresh-worktree
description: Fresh TaskMaster worktree fails first analyzer build with CS0006 (missing Meziantou/Sonar/BannedApi analyzer DLLs) — csproj Analyzer Include paths lag packages.config; install the old versions into gitignored packages/
description: Fresh TaskMaster worktree fails EVERY build (not just the analyzer gate) with CS0006 — 16 csproj <Analyzer Include> paths lag packages.config; it recurs after each Dependabot analyzer bump and blocks the whole plan, so surface it at P0-T13
metadata:
type: project
---

On a clean TaskMaster worktree, the first `msbuild TaskMaster.sln ... /p:EnableNETAnalyzers=true` fails with `error CS0006: Metadata file '..\packages\Meziantou.Analyzer.3.0.101\...\Meziantou.Analyzer.dll' could not be found` (also SonarAnalyzer.CSharp.10.27.0.140913 and Microsoft.CodeAnalysis.BannedApiAnalyzers.3.3.4).
On a clean TaskMaster worktree, the first `msbuild TaskMaster.sln ... /t:Rebuild` fails with
`error CS0006: Metadata file '..\packages\<Analyzer>.<oldVersion>\...\<X>.dll' could not be found`.

**Why:** This is a pre-existing repo-wide skew on `origin/main` (commits like 097f0ba2 "Bump the analyzers-dev-deps group"): `packages.config` was bumped to newer analyzer versions (Meziantou 3.0.123, BannedApi 5.6.0, Sonar 10.29.0.143774) but the hand-written `<Analyzer Include>` DLL paths in 16 first-party csproj files still reference the OLD versions. On dev/CI machines the old analyzer package folders linger in `packages/`; a clean-worktree restore installs only the current `packages.config` versions, so the old folders are absent -> CS0006.
**Why:** pre-existing repo-wide skew. `packages.config` and the `<Import>`/`<Error>` restore-check lines are
bumped by Dependabot ("Bump the analyzers-dev-deps group"), but the hand-written `<Analyzer Include>` DLL
paths in **16** first-party csproj files still name the OLD versions. On dev/CI machines the old package
folders linger in the gitignored `packages/`; a clean-worktree restore installs only the current
`packages.config` versions, so the old folders are absent.

**How to apply:** Do NOT edit the 16 csproj files (out of scope, huge churn). Install the missing OLD analyzer versions into the gitignored `packages/` folder with the winget nuget.exe: `nuget install Meziantou.Analyzer -Version 3.0.101 -OutputDirectory packages` (repeat for `Microsoft.CodeAnalysis.BannedApiAnalyzers 3.3.4` and `SonarAnalyzer.CSharp 10.27.0.140913`). This touches no tracked files. Also required on a fresh worktree before any build: `pwsh ./scripts/vscode/Install-RepoDotNetSdk.ps1` then `./.dotnet-sdk/dotnet.exe tool restore` (for csharpier 1.2.6) and `pwsh ./scripts/vscode/Invoke-Restore.ps1` (nuget restore). csharpier via repo SDK: `./.dotnet-sdk/dotnet.exe tool run csharpier format|check .`.
Observed instances (the pair moves with each bump; re-measure, do not assume):
- 2026-08 @ `61edc19` (epic/quickfiler-bug-family-integration): `<Analyzer Include>` names
`Meziantou.Analyzer.3.0.156` + `Roslynator.Analyzers.4.16.0`; restore installs `3.0.174` + `4.16.1`.
AsyncFixer 2.1.0, BannedApiAnalyzers 5.6.0, SonarAnalyzer.CSharp 10.32.0.713 all agree — only 2 skew.
- earlier: Meziantou 3.0.101, BannedApi 3.3.4, Sonar 10.27.0.140913.

**Blast radius is the whole solution, not just the analyzer gate.** `<Analyzer Include>` is unconditional, so
the plain nullable Rebuild (`/p:TreatWarningsAsErrors=true`, no analyzer properties) fails identically. Only
`VBFunctions` and `UtilitiesCS` emit the 10 diagnostics; the other 13 projects fail transitively on the broken
project reference. `SVGControl` / `SVGControl.Test` are the only projects that build (they carry no stale
reference). Consequence: `<Test>/bin/Debug` is EMPTY, so any full-suite or scoped vstest task and any coverage
baseline is unreachable, and every "analyzer Rebuild returns EXIT_CODE: 0" acceptance in the plan is
unsatisfiable. Diagnose it at the first analyzer gate rather than at the first test run.

**How to apply:**
1. Verify it is pre-existing, not yours: `git status --porcelain -- '*.csproj' '*/packages.config'` must be
empty; then `ls -d packages/Meziantou* packages/Roslynator*` vs
`grep -n "Analyzer Include" <proj>.csproj`. The `<Import>` at csproj line ~3 shows the NEW version while
the `<Analyzer Include>` block shows the OLD one — that contrast is the fingerprint.
2. Remedy that touches no tracked file: install the missing OLD versions into the gitignored `packages/`
(`nuget install Meziantou.Analyzer -Version <old> -OutputDirectory packages`, likewise Roslynator).
3. **But check the delegation prompt first.** A caller may explicitly forbid this — the #498 execution
directive said "If a restore still produces `error CS0006` from skewed analyzer package versions, report it
rather than working around it." In that case record the red baseline truthfully with `ExpectedExitCode: 1`
and stop at the first task that needs a built assembly, rather than provisioning the packages.
4. The durable fix is upstream: update the 16 `<Analyzer Include>` version strings in the same commit as the
`packages.config` bump. Worth an issue; it recurs on every analyzer bump.

**Resolved instance, 2026-08-26 @ `61edc19` (#498).** After the orchestrator provisioned the two missing
gitignored package dirs, the SAME analyzer and nullable Rebuild recipes went from `EXIT_CODE: 1` / 10 CS0006
to `EXIT_CODE: 0`, 0 errors, 5 warnings (all the uncoded `System.Reactive.PackagesConfigCheck.targets`
packages.config advisory, on QuickFiler/TaskMaster/ToDoModel/UtilitiesCS/UtilitiesCS.Test). `git status
--porcelain -- packages` stayed empty, so the ownership gate was untouched. All 9 test assemblies then
existed and the full suite ran 6482/6482 green at 84.78% repo line rate.

**Never carry a CS0006 baseline forward as the plan's baseline.** Under a Baseline-Comparison Rule, a
non-zero Phase-0 analyzer/nullable baseline permanently DEGRADES the Phase-8 gates into gates that cannot
fail, and licenses every intermediate "analyzer Rebuild returns 0" check to pass while compiling nothing.
If the provisioning gap is later fixed, re-run both gates and OVERWRITE the artifacts, deleting the
`ExpectedExitCode: 1` line — the field is what normalizes a red row to `pass` in PR-body collection.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: sln-csproj-edit-crlf-preserve
description: git-bash sed strips CRLF when editing TaskMaster.sln/.csproj; use perl -0777 with explicit \r\n to preserve line endings on VS solution/project files
description: git-bash sed strips CRLF when editing TaskMaster.sln/.csproj AND CRLF plan .md files; use perl -0777 with explicit \r\n, or re-add \r after the sed pass
metadata:
type: project
---
Expand All @@ -20,3 +20,10 @@ terminators") and `git diff --stat` (expect only the intended N-line delta, not
Note the many `.csproj` files here are actually LF already, so a simple `sed` start-address using
`.` for the literal backslash works for `<ProjectReference Include=..\X\Y.csproj>` deletions —
but always re-check the `file` type before trusting sed on a CRLF file.

**This also bites plan `.md` files.** Atomic plans written by `atomic-planner` are CRLF, and every
`[P#-T#]` check-off is a `sed -i` pass, so the first check-off silently converts the whole plan to LF and
turns a 9-line change into whole-file churn. Cheapest reliable idiom, run immediately after each check-off
sed: `sed -i 's/$/\r/' <plan>.md`, then confirm with `file <plan>.md` (expect "with CRLF line terminators")
and `git diff --stat` (expect insertions == deletions == number of boxes ticked). Doing this per check-off
rather than once at the end keeps the diff readable if the run is interrupted.
Loading
Loading