Merge pull request #255 from GeWuYou/fix/analyzer-warning-reduction-batch

docs(ai-plan): 迁移 analyzer 恢复文档到 ai-plan
This commit is contained in:
gewuyou 2026-04-19 16:20:43 +08:00 committed by GitHub
commit bac0b0151e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 544 additions and 3 deletions

View File

@ -12,6 +12,11 @@ help the current worktree land on the right recovery documents without scanning
## Active Topics
- `analyzer-warning-reduction`
- Purpose: track the analyzer warning reduction branch, including the current recovery point, remaining warning
hotspots, and the next safe warning-reduction slice.
- Tracking: `ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md`
- Trace: `ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md`
- `ai-plan-governance`
- Purpose: govern the `ai-plan/` directory model, startup index, and archive policy.
- Tracking: `ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md`
@ -27,6 +32,9 @@ help the current worktree land on the right recovery documents without scanning
## Worktree To Active Topic Map
- Branch: `fix/analyzer-warning-reduction-batch`
- Worktree hint: `GFramework-analyzer`
- Priority 1: `analyzer-warning-reduction`
- Branch: `feat/ai-first-config`
- Worktree hint: `GFramework-Ai-First-Config`
- Priority 1: `ai-first-config-system`

View File

@ -20,6 +20,7 @@
- 将"主题内 `archive/` 已存在"升级为"active todo/trace 过长时必须归档已完成且已验证阶段"的显式规则
- 让 active `todos/` / `traces/` 只保留当前恢复点、活跃事实、活跃风险、下一步与 archive 指针
- 将 `ai-plan-governance``ai-first-config-system``cqrs-rewrite` 的历史阶段从默认启动入口移出
- 将当前工作树遗留的 `local-plan` 示例迁入 `ai-plan/public/<topic>/`,验证治理规则对新 topic 迁移同样成立
### 已知风险
@ -43,6 +44,12 @@
- `ai-plan-governance` 的 RP-002 至 RP-004 历史
- `ai-first-config-system` 截至 `2026-04-17` 的详细跟踪与执行 trace
- `cqrs-rewrite` 截至 `RP-043` 的详细跟踪与执行 trace
- 已将当前工作树遗留的 analyzer warning reduction 恢复文档从 `local-plan/` 迁入:
- `ai-plan/public/analyzer-warning-reduction/todos/`
- `ai-plan/public/analyzer-warning-reduction/traces/`
- `ai-plan/public/analyzer-warning-reduction/archive/todos/`
- `ai-plan/public/analyzer-warning-reduction/archive/traces/`
- 已同步更新 `ai-plan/public/README.md`,将分支 `fix/analyzer-warning-reduction-batch` 映射到新 topic
- 已同步更新 `AGENTS.md``ai-plan/README.md``gframework-boot`,明确 active 文档不是追加式日志,已完成且已验证阶段必须归档
## 验证
@ -53,6 +60,9 @@
- `wc -l ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md ai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.md ai-plan/public/ai-first-config-system/todos/ai-first-config-system-tracking.md ai-plan/public/ai-first-config-system/traces/ai-first-config-system-trace.md ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md`
- 结果:通过
- 备注6 个 active 入口文件当前合计 `249` 行,已从治理前的 `3046` 行显著收短
- `find ai-plan/public/analyzer-warning-reduction -maxdepth 3 -type f | sort`
- 结果:通过
- 备注:新 topic 已按 `todos/``traces/` 与主题内 `archive/` 目录语义落位
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
- 结果:通过
- 备注:`GFramework.Cqrs.Abstractions``GFramework.Core.Abstractions` 构建通过,`0 warning / 0 error`
@ -64,6 +74,6 @@
## 下一步
1. 后续只要某个 active 主题积累了多个已完成且已验证阶段,就在同一变更里将其细节迁入该主题自己的 `archive/`
2. 若某个主题整体完成,再将整个主题目录移入 `ai-plan/public/archive/<topic>/`
3. 后续新增 topic 时,默认直接创建 `todos/``traces/``archive/`,不要再把历史阶段长期堆在 active 入口
1. 继续扫描是否还有遗留的 `local-plan` 或其他非 `ai-plan` 的 durable recovery 文档目录
2. 后续只要某个 active 主题积累了多个已完成且已验证阶段,就在同一变更里将其细节迁入该主题自己的 `archive/`
3. 若某个主题整体完成,再将整个主题目录移入 `ai-plan/public/archive/<topic>/`

View File

@ -28,3 +28,22 @@
1. 未来若 active 入口再次因为已完成阶段累积而膨胀,直接按同一模式归档,不再保留为追加式历史日志
2. 后续新增 topic 时,默认同步创建 `todos/``traces/``archive/` 目录
### 阶段:遗留 local-plan 迁移验证RP-005
- 复核当前工作树后确认,仍存在未纳入 `ai-plan/` 的遗留恢复目录 `local-plan/`
- 将 `local-plan` 中属于 analyzer warning reduction 主题的 tracking / trace 拆分迁入:
- `ai-plan/public/analyzer-warning-reduction/todos/`
- `ai-plan/public/analyzer-warning-reduction/traces/`
- `ai-plan/public/analyzer-warning-reduction/archive/todos/`
- `ai-plan/public/analyzer-warning-reduction/archive/traces/`
- 为新 topic 补齐 active 入口与 archive 历史,并更新 `ai-plan/public/README.md` 的 active topics 与 worktree 映射
- 删除旧 `local-plan` 文件,验证治理规则不仅适用于现有 topic也适用于从 worktree 遗留目录迁入的新 topic
- 额外完成验证:
- `find ai-plan/public/analyzer-warning-reduction -maxdepth 3 -type f | sort`
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
### 下一步
1. 后续若再发现 `local-plan` 一类目录,直接按 topic 归属迁入 `ai-plan/public/<topic>/`
2. 保持新 topic 的 active 入口精简,避免把迁移动作变成简单目录平移

View File

@ -0,0 +1,155 @@
# Analyzer Warning Reduction History
> 该文档于 `2026-04-19` 从旧 `local-plan/todos/analyzer-warning-reduction-tracking.md` 迁入,作为
> `ANALYZER-WARNING-REDUCTION-RP-001` 的历史跟踪归档保留。
## Legacy Tracking Content
## Goal
Reduce the currently surfaced Meziantou analyzer warnings from the repository build by prioritizing low-risk,
behavior-preserving fixes first, then reassessing whether larger refactors are justified for remaining long-method and
file-structure warnings.
## Current Recovery Point
- Recovery point: `ANALYZER-WARNING-REDUCTION-RP-001`
- Current phase: `Phase 1`
- Active focus:
- capture the current warning clusters with `dotnet build ... -t:Rebuild -clp:Summary;WarningsOnly`
- fix low-risk runtime and generator warnings that do not require architectural rewrites
- keep this tracking document and the paired trace synchronized with subagent scope, accepted fixes, and validation
- keep the current checkpoint test-green for the targeted regressions introduced by warning-reduction edits
## Planned Work
- [x] Read `AGENTS.md` and `.ai/environment/tools.ai.yaml` before choosing commands.
- [x] Confirm the current warning set still reproduces in a clean rebuild-oriented build invocation.
- [x] Group warnings into independent work slices before delegating.
- [x] Record delegated ownership boundaries for parallel subagent work.
- [x] Reduce low-risk warnings in `GFramework.Core` / `GFramework.Cqrs`.
- [x] Reduce low-risk warnings in `GFramework.Godot`.
- [x] Reduce low-risk warnings in source generator projects without broad generator rewrites.
- [x] Rebuild the affected projects and record the remaining warning hotspots.
- [x] Repair the targeted test regressions introduced by the current warning-reduction checkpoint.
- [x] Apply the current CodeRabbit follow-up fixes for module-install ordering, logging factory null-safety/disposal, and
Godot YAML directory enumeration contracts.
- [x] Apply the latest CodeRabbit follow-up fixes for failure-path module tracking, logger-name validation, and
brittle test replacement.
- [x] Apply the latest CodeRabbit follow-up fixes for null appender-entry validation and async doc-sample correctness.
- [ ] Decide whether any remaining `MA0051` / file-structure warnings are safe to tackle in the same round.
## Validation
Planned validation commands:
```bash
dotnet build GFramework.sln -c Release -t:Rebuild -nologo -clp:Summary;WarningsOnly
dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild -nologo -clp:Summary;WarningsOnly
dotnet build GFramework.Godot/GFramework.Godot.csproj -c Release -t:Rebuild -nologo -clp:Summary;WarningsOnly
dotnet build GFramework.Core.SourceGenerators/GFramework.Core.SourceGenerators.csproj -c Release -t:Rebuild -nologo -clp:Summary;WarningsOnly
```
Results:
- `dotnet build GFramework.Core.SourceGenerators/GFramework.Core.SourceGenerators.csproj -c Release --no-restore`
- passed with `0 Warning(s)` and `0 Error(s)`.
- `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release -t:Rebuild --no-restore -p:TargetFramework=net8.0 -p:UseSharedCompilation=false -nologo -clp:Summary;WarningsOnly`
- passed with `1 Warning(s)` and `0 Error(s)`.
- remaining warning:
- `GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs` `MA0051` long-method warning.
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -nologo -clp:Summary;WarningsOnly`
- first focused rebuild after the initial runtime-fix pass: `49 Warning(s)`, `0 Error(s)`.
- latest focused rebuild after the follow-up structural cleanup: `31 Warning(s)`, `0 Error(s)`.
- the remaining `net8.0` warnings are now concentrated in:
- generic/non-generic file-name collisions that cannot be fixed cheaply without API renames
- delegate-shape rules around specific callbacks
- a smaller set of long-method warnings
- a few collection-abstraction warnings on public configuration types
- `dotnet build GFramework.Godot/GFramework.Godot.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:UseSharedCompilation=false`
- worker validation reported a successful build after the Godot-owned fixes.
- remaining Godot-owned warnings reported by the worker:
- `GFramework.Godot/Setting/Data/LocalizationMap.cs` `MA0016` on the two public `Dictionary`-typed properties.
- broader direct `GFramework.Godot` builds still surface many `GFramework.Game` dependency warnings, so those results
should not be interpreted as unresolved Godot-owned work.
- `dotnet test GFramework.Core.Tests -c Release --filter "FullyQualifiedName~GetString_WithUnknownCompactFormatterArgs_ShouldIgnoreUnknownOptions|FullyQualifiedName~GetString_WithVariable_ShouldFormatCorrectly|FullyQualifiedName~GetString_WithMultipleVariables_ShouldFormatCorrectly|FullyQualifiedName~GetString_WithInvalidCompactFormatterArgs_ShouldFallbackToDefaultFormatting|FullyQualifiedName~GetString_WithCompactFormatterArgs_ShouldApplyOptions|FullyQualifiedName~GetString_WithCompactFormatter_ShouldFormatCorrectly|FullyQualifiedName~Ensure_Should_Create_ArgumentException_With_Message|FullyQualifiedName~RegisterCqrsHandlersFromAssemblies_WithNullAssemblyItem_Should_ThrowArgumentNullException"`
- passed with `0 Failed`, `8 Passed`, `0 Skipped`.
- regressions fixed in this validation step:
- `LocalizationString` placeholder formatting stopped replacing values after the regex switched to `RegexOptions.ExplicitCapture` while still reading unnamed capture groups.
- `ResultExtensions.Ensure` changed the observable `ArgumentException.Message` by adding a parameter name.
- `MicrosoftDiContainer.RegisterCqrsHandlersFromAssemblies` changed the null-item contract from `ArgumentNullException` to `ArgumentException`.
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~NumericExtensionsTests|FullyQualifiedName~ResultTests|FullyQualifiedName~ResultExtensionsTests|FullyQualifiedName~LoggingConfigurationTests"`
- passed with `0 Failed`, `101 Passed`, `0 Skipped`.
- covered the new review-driven fixes for:
- `NumericExtensions.Between` null contract enforcement
- `Result` default-value safety in `Equals` / `GetHashCode` / `ToString`
- `ResultExtensions.Ensure` parameter-name contract
- `ConfigurableLoggerFactory` longest-prefix logger-level selection
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~SettingsSystemTests|FullyQualifiedName~GodotLocalizationSettingsTests"`
- passed with `0 Failed`, `7 Passed`, `0 Skipped`.
- revalidated the `IApplyAbleSettings.ApplyAsync` rename through system and Godot localization callers.
- `dotnet build GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release`
- passed with `0 Error(s)`.
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~LoadAsync_Should_Use_Globalized_Res_Directory_Directly_When_Running_In_Editor"`
- passed with `0 Failed`, `1 Passed`, `0 Skipped`.
- used as the stable Godot-side smoke test after the review-driven changes to `SceneBehaviorBase`,
`AbstractArchitecture`, and `GodotYamlConfigEnvironment`.
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests|FullyQualifiedName~LoggingConfigurationTests"`
- narrowed to `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests" -m:1`
- passed with `0 Failed`, `3 Passed`, `0 Skipped`.
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~LoadAsync_Should_Use_Globalized_Res_Directory_Directly_When_Running_In_Editor"`
- passed with `0 Failed`, `1 Passed`, `0 Skipped`.
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~GodotLocalizationSettingsTests"`
- passed with `0 Failed`, `3 Passed`, `0 Skipped`.
- `dotnet build GFramework.sln -c Release`
- rerun serially as `dotnet build GFramework.sln -c Release -m:1`
- passed with `698 Warning(s)` and `0 Error(s)`.
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests" -m:1`
- latest follow-up rerun passed with `0 Failed`, `5 Passed`, `0 Skipped`.
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~AbstractArchitectureModuleInstallationTests" -m:1`
- passed with `0 Failed`, `1 Passed`, `0 Skipped`.
- now directly covers the contract that `InstallGodotModule` throws before `module.Install(...)` when `_anchor` is unavailable.
- `dotnet build GFramework.sln -c Release -m:1`
- latest follow-up rerun passed with `847 Warning(s)` and `0 Error(s)`.
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests" -m:1`
- latest null-appender validation rerun passed with `0 Failed`, `6 Passed`, `0 Skipped`.
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release -m:1`
- latest focused release build passed with `79 Warning(s)` and `0 Error(s)`.
## Known Risks
- Many warnings are duplicated across target frameworks, so a small source edit can remove multiple reported instances;
warning counts must be interpreted by unique source location, not only raw line count.
- Some warning families such as `MA0158` (`System.Threading.Lock`) are not obviously safe in the current multi-targeted
`net8.0;net9.0;net10.0` runtime modules and may require conditional compilation or a broader policy decision.
- Several `MA0051` findings sit in very large files such as `SchemaConfigGenerator.cs` and `YamlConfigLoaderTests.cs`;
these may require more refactoring than is appropriate for a warning-reduction pass.
- A subset of the remaining `MA0048` warnings come from generic/non-generic type families that share the same base type
name, so the analyzer cannot be satisfied by a trivial file move alone.
- The current checkpoint has only been revalidated against the eight known regression tests above; a broader test rerun
is still pending if the next batch expands the edit surface again.
- The `GodotYamlConfigEnvironment` default-directory enumeration fix depends on host file-system and Godot native API
behavior; if a deterministic unit test cannot be kept stable in this WSL test host, retain build plus loader-smoke
validation and document the gap explicitly.
- The `AbstractArchitecture.InstallGodotModule` ordering fix can be asserted in pure managed code, but attempting to
exercise `AbstractArchitecture.Initialize()` directly in the current Godot test host crashes the native test
process. Keep this fix covered by project build plus adjacent Godot smoke tests unless a more stable harness is
introduced.
- The install-ordering regression is now covered by a stable direct-call Godot test. The destroy-observation path still
lacks a dedicated automated assertion because intercepting `GD.PushError` reliably in the current .NET test host is
not yet practical.
- Parallel `dotnet test` / `dotnet build` executions against the Windows-backed worktree still trigger transient
`obj/bin` file-lock failures; keep validation serial with `-m:1` in this environment.
- A direct Godot test that calls `GodotYamlConfigEnvironment.Default.ReadAllBytes("res://missing")` currently crashes the
.NET test host in this environment, so the missing-file contract fix for the default Godot file API path is covered
by code review plus project build and adjacent loader tests rather than a dedicated failing-path unit test.
## Recommended Resume Step
1. Continue from `ANALYZER-WARNING-REDUCTION-RP-001` only if the next batch is willing to take on structural fixes such
as long-method splits, delegate-shape rewrites, or public configuration-surface refactors.
2. Preserve the review-follow-up contracts now covered by tests:
`NumericExtensions.Between` null checking, `Result` default-value safety, longest-prefix logger-level selection, and
the `IApplyAbleSettings.ApplyAsync` rename.
3. If the next batch wants stronger Godot validation for missing-path reads, investigate a harness that can safely
exercise `FileAccess.GetFileAsBytes` failure paths without crashing the test host before adding a dedicated test.

View File

@ -0,0 +1,265 @@
# Analyzer Warning Reduction History Trace
> 该文档于 `2026-04-19` 从旧 `local-plan/traces/analyzer-warning-reduction-trace.md` 迁入,作为
> `ANALYZER-WARNING-REDUCTION-RP-001` 的历史执行 trace 归档保留。
## Legacy Trace Content
## 2026-04-18
### Stage: Discovery
- Read `AGENTS.md` and `.ai/environment/tools.ai.yaml` before choosing commands.
- Confirmed the repository currently surfaces a large batch of Meziantou analyzer diagnostics during
`dotnet build GFramework.sln -c Release -nologo -clp:Summary;WarningsOnly`.
- Confirmed that `dotnet build ... -t:Rebuild` is required to force the compiler/analyzers to emit the warnings
reliably during project-level validation.
- Identified three independent work slices suitable for parallel handling:
- `GFramework.Core` plus closely related `GFramework.Cqrs` runtime warnings
- `GFramework.Godot` runtime warnings
- source generator warnings under `GFramework.Core.SourceGenerators`, `GFramework.Cqrs.SourceGenerators`, and
`GFramework.Godot.SourceGenerators`
### Current Recovery Point
- `ANALYZER-WARNING-REDUCTION-RP-001`
### Stage: Delegation
- Delegated `GFramework.Godot/**` low-risk warning reduction to worker `Newton`.
Scope:
- runtime-focused analyzer fixes only
- no edits outside `GFramework.Godot/**` except `GFramework.Godot.Tests/**` if validation strictly needs it
- avoid broad refactors and preserve behavior
- Delegated source generator low-risk warning reduction to worker `Aristotle`.
Scope:
- only `GFramework.Core.SourceGenerators/**`, `GFramework.Cqrs.SourceGenerators/**`, and
`GFramework.Godot.SourceGenerators/**`
- explicitly exclude `GFramework.Game.SourceGenerators/**`
- prioritize string-comparison, parameter-name, file/type-name, and localized method-splitting fixes
### Stage: Main-Thread Focus
- Reserved `GFramework.Core/**` and `GFramework.Cqrs/**` for the main thread because they dominate the current warning
surface and form the primary validation path.
- Confirmed the current worktree already contains an unrelated git status entry:
- `AD GFramework.Core/Directory.Build.props`
This file is not part of the current warning-reduction edit scope and must not be reverted.
### Stage: Implementation
- Applied low-risk runtime fixes across `GFramework.Core/**` and `GFramework.Cqrs/**`, including:
- `ConfigureAwait(false)` on context-independent asynchronous hot paths
- `StringComparer.Ordinal` / `StringComparison.Ordinal` for string-keyed collections and comparisons
- invariant-formatting fixes for logging/statistics paths
- targeted `ArgumentException` / `ArgumentNullException` overload cleanup
- localized file-structure cleanup for cache/config helper types
- Split a few file/type mismatches that were cheap to resolve without API churn:
- `GFramework.Cqrs/Internal/WeakTypePairCache.cs`
- `GFramework.Core/Logging/AppenderConfiguration.cs`
- `GFramework.Core/Logging/FilterConfiguration.cs`
- `GFramework.Core/Logging/ConfigurableLoggerFactory.cs`
- `GFramework.Core/Resource/ResourceCacheEntry.cs`
### Stage: Worker Results
- Worker `Aristotle` completed the source-generator slice and landed:
- `MA0006` string-comparison cleanup
- `MA0048` fix by renaming `LoggerDiagnostic.cs` to `LoggerDiagnostics.cs`
- localized `MA0015` cleanup
- small `MA0051` splits in `AutoRegisterModuleGenerator.cs` and `EnumExtensionsGenerator.cs`
- Worker `Newton` completed the Godot slice and landed:
- `ConfigureAwait(false)` cleanup where context capture was unnecessary
- string-comparison / comparer fixes
- invariant formatting and argument-overload cleanup
- file split for `GodotYamlConfigEnvironment` and `GodotYamlConfigDirectoryEntry`
- explicit observation of an async result in `AbstractArchitecture`
- Accepted residual worker findings:
- `GFramework.Core.SourceGenerators/Rule/ContextAwareGenerator.cs` still has a broader `MA0051` refactor remaining.
- `GFramework.Godot/Setting/Data/LocalizationMap.cs` still has two `MA0016` warnings on public `Dictionary`-typed
properties that were intentionally left unchanged to avoid public-surface / serialization impact.
### Stage: Validation
- Ran:
- `dotnet build GFramework.Core.SourceGenerators/GFramework.Core.SourceGenerators.csproj -c Release --no-restore`
- `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release -t:Rebuild --no-restore -p:TargetFramework=net8.0 -p:UseSharedCompilation=false -nologo -clp:Summary;WarningsOnly`
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -nologo -clp:Summary;WarningsOnly`
- `dotnet build GFramework.Godot/GFramework.Godot.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:UseSharedCompilation=false`
- Results:
- `GFramework.Core.SourceGenerators`: `0 Warning(s)`, `0 Error(s)`
- `GFramework.Cqrs` (`net8.0` rebuild): `1 Warning(s)`, `0 Error(s)`
- `GFramework.Core` (`net8.0` rebuild):
- intermediate focused rebuild: `49 Warning(s)`, `0 Error(s)`
- latest focused rebuild: `31 Warning(s)`, `0 Error(s)`
- `GFramework.Godot`: worker-reported success after the Godot-owned fixes; broader direct builds still include a
large inherited `GFramework.Game` warning set from dependencies
### Stage: Regression Repair
- After the checkpoint commit, reproduced the user-reported test regressions from the current branch instead of
resuming warning cleanup blindly.
- Isolated the failures to three behavior changes:
- `LocalizationString` enabled `RegexOptions.ExplicitCapture` but still read unnamed capture groups, so every
localization placeholder fell back to the original token text.
- `ResultExtensions.Ensure` started constructing `ArgumentException` with a parameter name, which changed the
externally observed message contract covered by tests.
- `MicrosoftDiContainer.RegisterCqrsHandlersFromAssemblies` rejected null assembly items with `ArgumentException`
instead of the previously expected `ArgumentNullException`.
- Repaired the regressions by:
- switching the localization placeholder regex to named capture groups and reading those names explicitly
- restoring the message-only `ArgumentException` construction in `Ensure`
- restoring `ArgumentNullException` for null assembly entries in CQRS registration
- Revalidated with:
- `dotnet test GFramework.Core.Tests -c Release --filter "FullyQualifiedName~GetString_WithUnknownCompactFormatterArgs_ShouldIgnoreUnknownOptions|FullyQualifiedName~GetString_WithVariable_ShouldFormatCorrectly|FullyQualifiedName~GetString_WithMultipleVariables_ShouldFormatCorrectly|FullyQualifiedName~GetString_WithInvalidCompactFormatterArgs_ShouldFallbackToDefaultFormatting|FullyQualifiedName~GetString_WithCompactFormatterArgs_ShouldApplyOptions|FullyQualifiedName~GetString_WithCompactFormatter_ShouldFormatCorrectly|FullyQualifiedName~Ensure_Should_Create_ArgumentException_With_Message|FullyQualifiedName~RegisterCqrsHandlersFromAssemblies_WithNullAssemblyItem_Should_ThrowArgumentNullException"`
- Result:
- `8 Passed`, `0 Failed`, `0 Skipped`
### Stage: Review Follow-Up
- Applied a focused batch of review-driven fixes across `GFramework.Core`, `GFramework.Cqrs`, `GFramework.Godot`,
`GFramework.Game`, and the paired docs:
- completed missing XML exception contracts for public APIs such as `UiPageBehaviorFactory.Create<T>` and
`ResourceManager.LoadAsync<T>` / `PreloadAsync<T>`
- aligned `NumericExtensions.Between` with its documented null contract
- removed duplicate XML documentation on `WaitForTask`
- made `Result` safe for `default(Result)` in equality, hashing, and string formatting
- restored Godot main-thread affinity by removing `ConfigureAwait(false)` from scene/module paths that touch node APIs
- observed async destroy failures in `AbstractArchitecture` instead of discarding them silently
- made `ConfigurableLoggerFactory.Dispose` idempotent under concurrent calls and switched logger-level lookup to
longest-prefix matching
- corrected CQRS weak-cache XML exception docs and weak-type-pair cache remarks
- changed `IApplyAbleSettings.Apply` to `ApplyAsync` and updated implementations, callers, tests, and settings docs
- fixed `GodotYamlConfigEnvironment` so Godot-path byte reads now throw on engine-reported read/open errors instead of
silently returning an empty byte array
### Stage: Review Follow-Up Validation
- Ran:
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~NumericExtensionsTests|FullyQualifiedName~ResultTests|FullyQualifiedName~ResultExtensionsTests|FullyQualifiedName~LoggingConfigurationTests"`
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~SettingsSystemTests|FullyQualifiedName~GodotLocalizationSettingsTests"`
- `dotnet build GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release`
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~LoadAsync_Should_Use_Globalized_Res_Directory_Directly_When_Running_In_Editor"`
- Results:
- `GFramework.Core.Tests`: `101 Passed`, `0 Failed`
- `GFramework.Game.Tests`: `7 Passed`, `0 Failed`
- `GFramework.Godot.Tests` build: succeeded
- targeted `GFramework.Godot.Tests` smoke test: `1 Passed`, `0 Failed`
- Validation caveat:
- parallel `dotnet test` invocations against the Windows-backed worktree caused transient file-lock failures in
shared `obj/bin` outputs, so the final validation was rerun serially.
- a dedicated test for `GodotYamlConfigEnvironment.Default.ReadAllBytes("res://missing")` was attempted but removed
because the native Godot file API crashes the test host in this environment before managed assertions can observe
the failure.
### Current Remaining Hotspots
- `MA0051` long methods in:
- `GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs`
- `GFramework.Core/Architectures/ArchitectureLifecycle.cs`
- `GFramework.Core/Coroutine/CoroutineScheduler.cs`
- `GFramework.Core/Pause/PauseStackManager.cs`
- `GFramework.Core/StateManagement/Store.cs`
- `MA0048` file/type mismatches in generic/non-generic families and multi-type files such as:
- `AbstractCommand*`
- `AbstractAsyncCommand*`
- `AbstractQuery*`
- `EasyEventGeneric.cs`
- `MA0046` delegate-shape warnings in architecture/coroutine/logging callbacks.
- `MA0016` collection-abstraction warnings on some public logging configuration properties.
### Immediate Next Step
1. Stop at `ANALYZER-WARNING-REDUCTION-RP-001` for this batch unless the next round explicitly wants to take on the
remaining structural refactors.
2. If the next round resumes from this point, keep the restored localization / `Ensure` / CQRS registration test
contracts intact while tackling the remaining analyzer hotspots.
### Stage: Review Follow-Up Batch 2
- Applied the current CodeRabbit follow-up fixes across `GFramework.Godot`, `GFramework.Core`, `GFramework.Cqrs`, and
`GFramework.Game.Tests`:
- moved `AbstractArchitecture.InstallGodotModule` anchor validation ahead of `module.Install(this)` so a missing
`SceneTree` anchor fails before any module-side effects occur
- normalized `ConfigurableLoggerFactory` configuration collections when JSON deserialization yields `null`
- merged `GetLogger(..., minLevel)` with `_config.MinLevel` using the stricter level and updated the XML contract
- added a compatibility disposal path for `AsyncLogAppender`
- made `GodotYamlConfigEnvironment` return `null` for inaccessible non-Godot directories and always call
`ListDirEnd()` for Godot directory iteration
- completed the missing XML exception contract on `WeakTypePairCache.GetValueOrDefaultForTesting`
- added XML summaries to the modified public `GodotLocalizationSettingsTests` methods
- Added focused regression tests for:
- `ConfigurableLoggerFactory` null-collection normalization
- caller `minLevel` lower-bound behavior
- factory disposal of `AsyncLogAppender`
- Planned validation for this batch:
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests|FullyQualifiedName~LoggingConfigurationTests"`
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~LoadAsync_Should_Use_Globalized_Res_Directory_Directly_When_Running_In_Editor"`
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~GodotLocalizationSettingsTests"`
- `dotnet build GFramework.sln -c Release`
- Attempted to add a direct `AbstractArchitecture` regression test for the anchor-ordering change, but the current
Godot .NET test host crashes when initializing that runtime path. Removed the unstable test and kept the code change
covered by project build plus existing Godot loader smoke validation instead.
### Stage: Review Follow-Up Batch 2 Validation
- First attempted to run the targeted tests and solution build in parallel, but the Windows-backed worktree reproduced
the known `obj/bin` file-lock failures (`CS2012`, `MSB3026`, `MSB3883`). Switched all remaining validation to serial
invocations with `-m:1`.
- Ran:
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests" -m:1`
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~GodotLocalizationSettingsTests" -m:1`
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~LoadAsync_Should_Use_Globalized_Res_Directory_Directly_When_Running_In_Editor" -m:1`
- `dotnet build GFramework.sln -c Release -m:1`
- Results:
- `GFramework.Core.Tests`: `3 Passed`, `0 Failed`
- `GFramework.Game.Tests`: `3 Passed`, `0 Failed`
- `GFramework.Godot.Tests` targeted smoke: `1 Passed`, `0 Failed`
- `GFramework.sln` release build: `698 Warning(s)`, `0 Error(s)`
### Stage: Review Follow-Up Batch 3
- Applied the latest review-driven fixes across `GFramework.Godot`, `GFramework.Core`, `GFramework.Cqrs`, and
`GFramework.Core.Tests`:
- recorded Godot modules in `_extensions` immediately after `module.Install(this)` so failed attach paths still
participate in later teardown
- tightened `ConfigurableLoggerFactory.GetLogger` with explicit `name` null validation
- aligned the `minLevel` XML contract with the actual override precedence semantics
- added inline comments to the two-level weak cache `GetOrAdd` hot path
- replaced the reflection-based `AsyncLogAppender` disposal test with an observable post-disposal logger behavior
assertion
- Added a stable Godot-specific regression test that directly invokes `InstallGodotModule(...)` without going through
`Initialize()`, avoiding the native crash path while still covering the anchor-before-install contract.
- Documented the remaining test gap:
- the destroy-observation path introduced by `ObserveDestroyAsync` still lacks a dedicated automated assertion because
capturing `GD.PushError` deterministically in the current Godot .NET test host is not yet practical.
### Stage: Review Follow-Up Batch 3 Validation
- Ran:
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests" -m:1`
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~AbstractArchitectureModuleInstallationTests" -m:1`
- `dotnet build GFramework.sln -c Release -m:1`
- Results:
- `GFramework.Core.Tests`: `5 Passed`, `0 Failed`
- `GFramework.Godot.Tests` targeted install-ordering test: `1 Passed`, `0 Failed`
- `GFramework.sln` release build: `847 Warning(s)`, `0 Error(s)`
### Stage: Review Follow-Up Batch 4
- Applied the latest review-driven fixes across `GFramework.Core`, `GFramework.Core.Tests`, and the Godot settings docs:
- made `ConfigurableLoggerFactory` reject `appenders` entries deserialized as `null` with an explicit
`InvalidOperationException` instead of deferring to an unclear downstream failure
- extended the constructor XML docs to describe that validation contract explicitly
- added a focused regression test for `appenders: [null]`
- fixed the `docs/zh-CN/godot/setting.md` audio examples so both `SetMasterVolume` samples compile while awaiting
`audioSettings.ApplyAsync()`
### Stage: Review Follow-Up Batch 4 Validation
- Ran:
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ConfigurableLoggerFactoryTests" -m:1`
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release -m:1`
- Results:
- `GFramework.Core.Tests`: `6 Passed`, `0 Failed`
- `GFramework.Core` release build: `79 Warning(s)`, `0 Error(s)`

View File

@ -0,0 +1,52 @@
# Analyzer Warning Reduction 跟踪
## 目标
继续以“优先低风险、保持行为兼容”为原则收敛当前仓库的 Meziantou analyzer warnings并在首轮大规模清理完成后
判断剩余结构性 warning 是否值得在下一轮继续推进。
## 当前恢复点
- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-001`
- 当前阶段:`Phase 1`
- 当前焦点:
- 已将旧 `local-plan/` 迁入 `ai-plan/public/analyzer-warning-reduction/`active 入口只保留当前恢复信息
- 基于现有剩余热点,评估 `MA0051``MA0048``MA0046` 与少量 `MA0016` 是否适合继续在同一主线上处理
- 若继续推进,优先选择不引入 API rename、公共契约漂移或 Godot 宿主不稳定测试的切入点
## 当前状态摘要
- 已完成 `GFramework.Core``GFramework.Cqrs``GFramework.Godot` 与部分 source generator 的低风险 warning 清理
- 已完成多轮 CodeRabbit follow-up 修复,并用定向测试与项目/解决方案构建验证了关键回归风险
- 当前剩余 warning 已集中到长方法、文件/类型命名冲突、delegate 形状和少量公共集合抽象接口问题
## 当前活跃事实
- 当前主题仍是 active topic因为剩余结构性 warning 是否继续推进尚未决策
- `RP-001` 的详细实现历史、测试记录和 warning 热点清单已归档到主题内 `archive/`
- 当前工作树分支 `fix/analyzer-warning-reduction-batch` 已在 `ai-plan/public/README.md` 建立 topic 映射
## 当前风险
- 结构性重构风险:剩余 `MA0051``MA0048` 可能要求较大的文件拆分或类型重命名
- 缓解措施:只在下一轮明确接受结构调整成本时再继续推进,不在恢复点模糊的情况下顺手扩面
- 测试宿主稳定性风险:部分 Godot 失败路径在当前 .NET 测试宿主下仍不稳定
- 缓解措施:继续优先使用稳定的 targeted test、项目构建和相邻 smoke test 组合验证
- 多目标框架 warning 解释风险:同一源位置会在多个 target framework 下重复计数
- 缓解措施:继续以唯一源位置和 warning 家族为主要决策依据,而不是只看原始 warning 总数
## 活跃文档
- 历史跟踪归档:[analyzer-warning-reduction-history-rp001.md](../archive/todos/analyzer-warning-reduction-history-rp001.md)
- 历史 trace 归档:[analyzer-warning-reduction-history-rp001.md](../archive/traces/analyzer-warning-reduction-history-rp001.md)
## 验证说明
- `RP-001` 的详细 warning 清理、回归修复与定向验证命令均已迁入主题内历史归档
- active 跟踪文件只保留当前恢复点、活跃事实、风险与下一步,不再重复保存已完成阶段的长篇历史
## 下一步
1. 若要继续该主题,先读 active tracking再按需展开历史归档中的 warning 热点与验证记录
2. 从 `MA0051``MA0048``MA0046` 中只选一个结构性切入点继续,不要在同一轮同时扩多个风险面
3. 若本主题确认暂缓,可保持当前归档状态,不需要再恢复 `local-plan/`

View File

@ -0,0 +1,32 @@
# Analyzer Warning Reduction 追踪
## 2026-04-19
### 阶段local-plan 迁移收口RP-001
- 复核当前工作树后确认:`local-plan/` 仅保存 analyzer warning reduction 主题的 durable recovery state不应继续作为
worktree-root 遗留目录存在
- 按 `ai-plan` 治理规则建立 `ai-plan/public/analyzer-warning-reduction/` 主题目录,并补齐:
- `todos/`
- `traces/`
- `archive/todos/`
- `archive/traces/`
- 将旧 `local-plan` 中的详细 tracking / trace 迁入主题内历史归档,保留 `RP-001` 的完整实现与验证上下文
- 新建精简版 active tracking / trace 入口,并在 `ai-plan/public/README.md` 中建立
`fix/analyzer-warning-reduction-batch` -> `analyzer-warning-reduction` 的 worktree 映射
- 删除旧 `local-plan` 文件,避免 `boot` 或后续协作者继续从过时目录恢复
- 验证通过:
- `find ai-plan/public/analyzer-warning-reduction -maxdepth 3 -type f | sort`
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
### Archive Context
- 历史跟踪归档:
- `ai-plan/public/analyzer-warning-reduction/archive/todos/analyzer-warning-reduction-history-rp001.md`
- 历史 trace 归档:
- `ai-plan/public/analyzer-warning-reduction/archive/traces/analyzer-warning-reduction-history-rp001.md`
### 下一步
1. 后续若继续 analyzer warning reduction只从 `ai-plan/public/analyzer-warning-reduction/` 进入,不再恢复 `local-plan/`
2. 若 active 入口再次积累多轮已完成且已验证阶段,继续按同一模式迁入该主题自己的 `archive/`