mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-11 12:14:30 +08:00
- 修复 AsyncLogAppender 在队列已被后台线程提前清空时 Flush 仍可能超时失败的问题 - 新增 AsyncLogAppender 已处理队列场景的稳定回归测试并重新验证 GFramework.Core.Tests - 更新 analyzer-warning-reduction 的 tracking 与 trace 记录 PR267 failed-test follow-up
29 KiB
29 KiB
Analyzer Warning Reduction 追踪
2026-04-21 — RP-015
阶段:PR #267 failed-test follow-up 收口(RP-015)
- 触发背景:
- 用户指出“测试好像挂了”,按
$gframework-pr-review重新抓取当前分支 PR #267 的 review / checks / CTRF 评论 - PR 评论里同时存在一次
2143 passed / 0 failed与一次1 failed的 CTRF 报告;失败用例为AsyncLogAppenderTests.ILogAppender_Flush_Should_Raise_OnFlushCompleted_Only_Once
- 用户指出“测试好像挂了”,按
- 复核过程:
- 先跑定向单测时该用例可以单独通过,因此继续核对 PR head commit 与本地整包测试,避免把旧评论误判成当前状态
- 在
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-restore --disable-build-servers下成功复现相同失败,确认问题仍存在于当前代码,而不是单纯的 PR 评论残留 - 同时发现当前沙箱内如果用 shell 循环反复启动
dotnet test,会触发MSBuildnamed pipePermission denied的环境噪音;后续验证改为单次命令并显式加--disable-build-servers
- 根因结论:
AsyncLogAppender.Flush()只依赖后台消费循环在处理完某个条目后检查_flushRequested- 当调用方执行
Flush()前,后台线程已经把最后一个条目消费完并离开检查点时,Flush()会一直等到默认超时, 最终通过OnFlushCompleted发出一次Success=false的错误完成通知
- 实施修复:
- 为
AsyncLogAppender增加“当前是否仍有条目在途处理”的状态跟踪 - 抽出
TrySignalFlushCompletion(),让Flush()在请求发出后先做一次即时完成判定;后台循环在每次处理结束后也复用 这条判定路径 - 在
AsyncLogAppenderTests中新增Flush_WhenEntriesAlreadyProcessed_Should_Still_ReportSuccess,稳定覆盖 “调用 Flush 前队列已被后台线程清空”的场景
- 为
- 验证结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-restore --disable-build-servers --filter "FullyQualifiedName~AsyncLogAppenderTests"- 结果:
15 Passed,0 Failed
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-restore --disable-build-servers- 结果:
1607 Passed,0 Failed
- 结果:
- 当前结论:
- PR #267 的 failed-test 信号不是纯粹的历史评论噪音,而是当前实现里仍存在的时序竞态
- 修复后该竞态已被稳定回归测试覆盖,当前
GFramework.Core.Tests整包通过
- 下一步建议:
- 若继续 analyzer warning reduction 主题,恢复到
MA0016/MA0002低风险批次
- 若继续 analyzer warning reduction 主题,恢复到
2026-04-21 — RP-014
阶段:PR #267 review follow-up 收口(RP-014)
- 使用
gframework-pr-review抓取当前分支 PR #267 的 latest head review threads、outside-diff comment、nitpick comment、 MegaLinter 摘要与测试报告,并确认本轮除了 6 条 open thread 之外,还存在 1 条 outside-diff 与 1 条 nitpick 需要一并复核 - 本地复核后确认仍成立的项:
AsyncLogAppender的显式接口实现ILogAppender.Flush()会在调用Flush()后再次手动触发OnFlushCompleted, 导致接口路径重复通知Architecture.PhaseChanged、CoroutineExceptionEventArgs与ArchitecturePhaseCoordinator.EnterPhase的 XML/注释契约仍未完全同步CoroutineSchedulerTests的异常事件测试缺少测试级超时docs/zh-CN/core/architecture.md与docs/zh-CN/core/lifecycle.md仍缺少明确的PhaseChanged迁移说明ai-planactive tracking 中RP-013的9 Warning(s)需要明确是相对RP-009/RP-011的 warnings-only 基线收敛
- 实施最小修复:
- 删除
ILogAppender.Flush()中重复的完成事件触发,只保留Flush(TimeSpan?)内的单一通知源 - 为接口调用路径补充单次完成通知回归测试,并为协程异常事件测试增加
WaitAsync(TimeSpan.FromSeconds(3)) - 补齐
Architecture.PhaseChanged、CoroutineExceptionEventArgs与ArchitecturePhaseCoordinator.EnterPhase的契约文档 - 在
docs/zh-CN/core/architecture.md与docs/zh-CN/core/lifecycle.md中加入phase => ...迁移到(_, args) => ...的说明 - 更新
ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md的恢复点、基线描述与验证结果
- 删除
- 验证结果:
dotnet restore GFramework.Core.Tests/GFramework.Core.Tests.csproj -p:RestoreFallbackFolders="" -nologo- 结果:通过;host Windows
dotnet首次验证前补齐了缺失的Meziantou.Analyzer 3.0.48
- 结果:通过;host Windows
dotnet build GFramework.Core/GFramework.Core.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -nologo- 结果:
9 Warning(s),0 Error(s)
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-restore --filter "FullyQualifiedName~CoroutineSchedulerTests.Scheduler_Should_Raise_OnCoroutineException_With_EventArgs|FullyQualifiedName~AsyncLogAppenderTests.Flush_Should_Raise_OnFlushCompleted_With_Sender_And_Result|FullyQualifiedName~AsyncLogAppenderTests.ILogAppender_Flush_Should_Raise_OnFlushCompleted_Only_Once|FullyQualifiedName~ArchitectureLifecycleBehaviorTests.InitializeAsync_Should_Raise_PhaseChanged_With_Sender_And_EventArgs" -m:1 -p:RestoreFallbackFolders="" -nologo- 结果:
4 Passed,0 Failed
- 结果:
- 当前结论:
- PR #267 里当前仍成立的 CodeRabbit 高信号项已在本地收口
- 修复内容没有改变
EventHandler<TEventArgs>迁移方向,只是补齐行为、文档与恢复信息
- 下一步建议:
- 恢复到
MA0016/MA0002主批次,默认先看LoggingConfiguration、FilterConfiguration与CollectionExtensions
- 恢复到
2026-04-21 — RP-013
阶段:MA0046 事件签名批次收口(RP-013)
- 依据
RP-012的下一步建议,本轮恢复到GFramework.Core的MA0046主批次,而不是继续停留在 PR review workflow 优化 - 本地 warnings-only 基线确认当前
GFramework.Corenet8.0仍有6个MA0046:Architecture.csArchitectureLifecycle.csArchitecturePhaseCoordinator.csAsyncLogAppender.csCoroutineScheduler.cs两处事件
- 方案选择:
- 不再保留
Action<...>事件签名,统一改为标准EventHandler<TEventArgs> - 为
Architecture、AsyncLogAppender新增放在GFramework.Core.Abstractions的事件参数类型 - 为
CoroutineScheduler新增放在GFramework.Core的事件参数类型,因为CoroutineHandle定义在 runtime 层,不适合反向放入 Abstractions Architecture相关事件采用Coordinator -> Lifecycle -> Architecturerelay,而不是直接透传底层事件,确保公开事件的 sender 始终是实际发布者,并避免引入新的MA0091
- 不再保留
- 同步适配:
- 更新
GFramework.Godot/Coroutine/Timing.cs的OnCoroutineFinished订阅签名 - 更新
ArchitectureLifecycleBehaviorTests、CoroutineSchedulerTests、AsyncLogAppenderTests以覆盖 sender / event args 契约 - 更新
docs/zh-CN/core/architecture.md与docs/zh-CN/core/lifecycle.md的PhaseChanged示例
- 更新
- 验证结果:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -nologo -clp:"Summary;WarningsOnly"- 结果:
9 Warning(s),0 Error(s);当前GFramework.Corenet8.0输出中已无MA0046
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureLifecycleBehaviorTests|FullyQualifiedName~CoroutineSchedulerTests|FullyQualifiedName~AsyncLogAppenderTests" -m:1 -p:RestoreFallbackFolders="" -nologo- 结果:
50 Passed,0 Failed
- 结果:
dotnet build GFramework.Godot/GFramework.Godot.csproj -c Release --no-restore -p:RestoreFallbackFolders="" -nologo- 结果:失败;当前 worktree 的
project.assets.json仍引用 Windows fallback package folder,尚未完成 Godot 独立编译验证
- 结果:失败;当前 worktree 的
- 当前结论:
MA0046已从 active 批次中移除- 剩余
GFramework.Corenet8.0warning 分布更新为:MA0016=5、MA0002=2、MA0015=1、MA0077=1 - 若继续本主题,下一步默认转入
MA0016批次;若继续触达 Godot,再先修复该项目 restore 资产
2026-04-21 — RP-012
阶段:PR review workflow 输出收窄增强(RP-012)
- 背景:上一轮虽然脚本已经能解析
outside_diff_comments,但直接把超长 JSON 打到终端时仍可能因为输出截断而漏看高价值 review 信号 - 本轮对
gframework-pr-review做了工作流级增强,而不是继续依赖 shell 重定向技巧:- 为
fetch_current_pr_review.py增加--json-output <path>,允许把完整 JSON 稳定写入文件 - 增加
--section,可只输出outside-diff、open-threads、megalinter等高信号文本摘要 - 增加
--path,允许把文本输出收窄到特定文件或路径片段 - 增加
--max-description-length,避免超长 comment/body 在 text 模式下刷屏 - 当 text 模式搭配
--json-output时,stdout 保持精简,并显式提示完整 JSON 文件路径
- 为
- 同步更新
SKILL.md:- 将“先落盘,再用
jq或--section/--path缩小范围”写成推荐机器工作流 - 补充按 section 和按路径聚焦的示例命令
- 将“先落盘,再用
- 预期收益:
- 不再要求操作者肉眼阅读整份长 JSON
- outside-diff、nitpick 和 open thread 都能成为一等可过滤输出
- 即使终端输出有 token/长度上限,完整结果仍可通过文件稳定回查
- 定向验证命令:
python3 -m py_compile .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py- 结果:通过;使用
PYTHONPYCACHEPREFIX=/tmp/codex-pycache规避__pycache__写入限制
- 结果:通过;使用
python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --help- 结果:通过;新增 CLI 选项均已出现在帮助输出中
dotnet build GFramework.Core/GFramework.Core.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -nologo- 结果:
0 Warning(s),0 Error(s)
- 结果:
- 下一步建议:
- 之后执行
$gframework-pr-review时,默认优先使用--json-output - 在 review 跟进阶段,先看
outside-diff、open-threads、megalinter三个 section,再决定是否需要打开完整 JSON
- 之后执行
2026-04-21 — RP-011
阶段:PR #265 outside-diff follow-up 补收口(RP-011)
- 用户补充指出 CodeRabbit 在
Some comments are outside the diff中还有GFramework.Core/Events/Event.cs的 minor finding: 默认 no-op 委托会被GetInvocationList()计入,导致GetListenerCount()在无监听器和单监听器场景分别返回1和2 - 本地复核确认该问题仍成立:
Event<T>当前字段初始化为_ => { }Event<T, TK>当前字段初始化为(_, _) => { }- 两个
Trigger(...)实现本身已是 null-safe,因此无需依赖占位委托规避空引用
- 实施最小修复:
- 移除两个事件字段的 no-op 初始委托,改为以
null表示“无监听器” - 保持
Register/UnRegister/Trigger的公开 API 和调用方式不变 - 在
EventTests中新增单参数与双参数GetListenerCount()回归测试,覆盖初始值、注册后和注销后的计数语义
- 移除两个事件字段的 no-op 初始委托,改为以
- 过程说明:
- 这条不是 skill 设计遗漏;
gframework-pr-review的目标本来就包含 latest review body 和 outside-diff 信号 - 上一轮是我在处理时漏看了这条 outside-diff item,且终端里展示的超长 JSON 输出被截断,未单独把
Event.cs项再抽出来复核
- 这条不是 skill 设计遗漏;
- 定向验证命令:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -nologo- 结果:
15 Warning(s),0 Error(s)
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~EventTests.EventT_GetListenerCount_Should_Exclude_Placeholder_Handler|FullyQualifiedName~EventTests.EventTTK_GetListenerCount_Should_Exclude_Placeholder_Handler" -m:1 -p:RestoreFallbackFolders="" -nologo- 结果:
2 Passed,0 Failed
- 结果:
- 下一步建议:
- 若继续 PR #265 follow-up,只接受当前本地仍成立的剩余 outside-diff 或 unresolved review 项
- 若没有新的有效 review 点,再恢复到
MA0046主批次
2026-04-21 — RP-010
阶段:PR #265 follow-up 收口(RP-010)
- 使用
gframework-pr-review抓取当前分支 PR #265 的 latest head review threads、CodeRabbit review body、MegaLinter 摘要与 CTRF 测试结果;确认最新 unresolved thread 只剩CoroutineScheduler零容量扩容边界 - 本地复核后确认两处仍成立的风险:
CoroutineScheduler.Expand()在_slots.Length == 0时会把容量从0扩到0,首次Run写槽位会越界Store.EnterDispatchScope()在_isDispatching = true之后、快照构建完成之前若抛异常,会留下永久的嵌套分发误判
- 实施最小修复:
- 将
Expand()调整为Math.Max(1, _slots.Length * 2),保持已有倍增策略,只补上零容量边界 - 为
EnterDispatchScope()增加快照阶段的异常回滚,确保_isDispatching与实际 dispatch 生命周期保持一致 - 新增回归测试覆盖零容量启动路径,以及 dispatch 快照阶段抛错后的可恢复性
- 将
- 当前 PR 信号复核结论:
- CTRF:最新评论显示
2135 passed / 0 failed - MegaLinter:唯一告警仍是 CI 中
dotnet-formatrestore 失败,未发现新的本地代码格式问题 - 旧 review body 中提到的
Store异常安全问题虽未表现为最新 open thread,但在本地代码中仍可成立,因此一并收口
- CTRF:最新评论显示
- 定向验证命令:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -nologo- 结果:
15 Warning(s),0 Error(s)
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~CoroutineSchedulerTests.Run_Should_Grow_From_Zero_Initial_Capacity|FullyQualifiedName~StoreTests.Dispatch_Should_Reset_Dispatching_Flag_When_Snapshot_Creation_Throws" -m:1 -p:RestoreFallbackFolders="" -nologo- 结果:
2 Passed,0 Failed
- 结果:
- 下一步建议:
- 若继续本主题,恢复到
MA0046主批次,不再停留在当前 PR follow-up - 若 PR review 还出现新线程,继续遵守“只修复当前本地仍成立的问题”的策略
- 若继续本主题,恢复到
2026-04-21 — RP-009
阶段:MA0048 批次收口(RP-009)
- 依据
RP-008的批处理策略,本轮继续从GFramework.Core的MA0048启动,但不采用重命名公共类型的高风险做法; 改为把同名不同泛型 arity 的家族收拢到与类型名一致的单文件中 - 具体调整:
- 将
AbstractCommand<TInput>与AbstractCommand<TInput, TResult>合并进AbstractCommand.cs - 将
AbstractAsyncCommand<TInput>与AbstractAsyncCommand<TInput, TResult>合并进AbstractAsyncCommand.cs - 将
AbstractQuery<TInput, TResult>合并进AbstractQuery.cs - 将
AbstractAsyncQuery<TInput, TResult>合并进AbstractAsyncQuery.cs - 将泛型
Event<T>/Event<T, TK>从EasyEventGeneric.cs迁移到Event.cs
- 将
- 首次构建暴露出合并后的
ICommand<TResult>/IQuery<TResult>命名空间歧义;随后改用GFramework.Core.Abstractions.*的限定名完成最小修正,没有引入行为改动 - 定向验证通过:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -nologo -clp:"Summary;WarningsOnly"- 结果:
15 Warning(s),0 Error(s);MA0048已从当前GFramework.Corenet8.0warnings-only 基线中清空
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~CommandExecutorTests|FullyQualifiedName~AbstractAsyncCommandTests|FullyQualifiedName~QueryExecutorTests|FullyQualifiedName~AbstractAsyncQueryTests|FullyQualifiedName~EventTests" -m:1 -p:RestoreFallbackFolders="" -nologo- 结果:
83 Passed,0 Failed
- 结果:
- 当前建议的下一批次顺序更新为:
- 第一优先级:
MA0046 - 第二优先级:
MA0016 - 顺手吸收:
MA0015、MA0077 - 单独评估:
MA0002
- 第一优先级:
2026-04-21 — RP-008
阶段:批处理策略切换(RP-008)
- 根据当前
GFramework.Corewarnings-only build 的剩余分布,后续不再默认沿用“单文件、单 warning family”的切片节奏, 改为按 warning 类型和数量优先级批量推进 - 当前数量基线:
MA0048 = 8MA0046 = 6MA0016 = 5MA0002 = 2MA0015 = 1MA0077 = 1
- 新的批处理规则:
- 先按类型选择主批次,而不是按单文件选切入点
- 若主批次数量不够,则允许顺手并入其他低冲突类型;
MA0015与MA0077只是当前明显的低数量尾项示例,不是限定范围 - 单次
boot的工作树改动规模控制在约100个文件以内,避免 recovery context 和 review 面同时膨胀 - 当 warning 类型或目录边界清晰且写集不冲突时,允许使用不同模型的 subagent 并行处理,但必须先定义独占 ownership
- 当前建议的下一批次顺序:
- 第一优先级:
MA0048 - 第二优先级:
MA0046 - 顺手吸收:其他低冲突类型,当前可见示例包括
MA0015、MA0077 - 单独评估:
MA0016、MA0002
- 第一优先级:
- 本轮仅更新 recovery strategy,不改生产代码;验证继续沿用当前基线构建:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -p:RestorePackagesPath=<linux-nuget-cache> -nologo -clp:"Summary;WarningsOnly"- 结果:
23 Warning(s),0 Error(s)
- 结果:
2026-04-21 — RP-007
阶段:CoroutineScheduler MA0051 收口(RP-007)
- 依据 active tracking 中“继续只选一个
GFramework.Core结构性切入点”的约束,本轮选择GFramework.Core/Coroutine/CoroutineScheduler.cs,因为剩余两个MA0051都集中在协程启动与完成清理路径,且已有CoroutineSchedulerTests、CoroutineSchedulerAdvancedTests覆盖句柄创建、取消、完成状态、标签分组和等待语义 - 将
Run拆分为:AllocateSlotIndexCreateRunningSlotRegisterCancellationCallbackRegisterStartedCoroutineCreateCoroutineMetadataResetCompletionTracking
- 将
FinalizeCoroutine拆分为:TryGetFinalizableCoroutineUpdateCompletionMetadataApplyCompletionMetadataReleaseCompletedCoroutineCompleteCoroutineLifecycle
- 保持取消回调只做跨线程入队、
Prewarm时机、统计记录文本、RemoveTag/RemoveGroup/WakeWaiters顺序以及OnCoroutineFinished的同步触发时机不变,只收缩主方法长度并补齐辅助方法意图注释 - 验证通过:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -p:RestorePackagesPath=<linux-nuget-cache> -nologo -clp:"Summary;WarningsOnly"- 结果:
23 Warning(s),0 Error(s);CoroutineScheduler.cs已不再出现在MA0051列表
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter FullyQualifiedName~CoroutineScheduler -p:RestoreFallbackFolders="" -p:RestorePackagesPath=<linux-nuget-cache> -nologo- 结果:
34 Passed,0 Failed
- 结果:
- 当前
MA0051主线已经在本主题下完成;下一步若继续,应先重新评估剩余MA0048、MA0046、MA0002、MA0016的 收敛价值与改动风险,再决定是否开启下一轮 warning family
2026-04-21 — RP-006
阶段:Store MA0051 收口(RP-006)
- 依据 active tracking 中“继续只选一个
GFramework.Core结构性切入点”的约束,本轮选择GFramework.Core/StateManagement/Store.cs,因为该文件的两个MA0051都集中在 dispatch / reducer snapshot 逻辑, 且已有StoreTests覆盖 dispatch、batch、history 和多态 reducer 匹配语义 - 在正式验证前先处理 WSL 环境噪音:当前 worktree 的
GFramework.Core/obj/project.assets.json是 Windows 侧 restore 产物,--no-restore构建会继续引用宿主 Windows fallback package folder;本轮先执行一次 Linux 侧dotnet restore GFramework.Core/GFramework.Core.csproj -p:RestoreFallbackFolders="" -p:RestorePackagesPath=<linux-nuget-cache> --ignore-failed-sources -nologo刷新资产文件,再继续 warnings-only build - 将
Dispatch拆分为:EnterDispatchScopeTryCommitDispatchResultExitDispatchScope
- 将
CreateReducerSnapshotCore拆分为:CreateExactReducerSnapshotCreateAssignableReducerSnapshotCollectReducerMatchesCompareReducerMatch
- 保持
_dispatchGate -> _lock的锁顺序、middleware 锁外执行、批处理通知折叠以及“精确类型 -> 基类 -> 接口 -> 注册顺序”的 reducer 稳定排序语义不变,只收缩主方法长度并补齐辅助方法意图注释 - 验证通过:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders="" -p:RestorePackagesPath=<linux-nuget-cache> -nologo -clp:"Summary;WarningsOnly"- 结果:
25 Warning(s),0 Error(s);Store.cs已不再出现在MA0051列表
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter FullyQualifiedName~StoreTests -p:RestoreFallbackFolders="" -p:RestorePackagesPath=<linux-nuget-cache> -nologo- 结果:
30 Passed,0 Failed
- 结果:
- 下一步保持同一节奏:只在
CoroutineScheduler.cs的Run/FinalizeCoroutine两个MA0051中继续,不与其他 warning 家族混做
2026-04-21 — RP-005
阶段:PauseStackManager MA0051 收口(RP-005)
- 按 active tracking 中“继续只选一个
GFramework.Core结构性切入点”的约束,本轮选择GFramework.Core/Pause/PauseStackManager.cs,因为该文件体量明显小于CoroutineScheduler和Store, 且已有稳定的PauseStackManagerTests覆盖暂停栈、跨组独立性、事件通知与并发Push/Pop行为 - 先用
warnings-only定向构建确认DestroyAsync与Pop仍分别命中MA0051,再把逻辑拆分为:TryBeginDestroyNotifyDestroyedGroupsTryPopEntryRemoveEntryFromStack
- 额外抽出
CreateHandlerSnapshot与NotifyHandlersSnapshot,统一普通通知与销毁补发路径的处理器排序和异常日志, 保持原有“锁内采集快照、锁外调用处理器与事件”的并发策略不变 - 为销毁路径新增
DestroyAsync_Should_NotifyResumedGroups,验证当多个暂停组在销毁前仍为暂停态时, 处理器和事件订阅者都会收到IsPaused=false的恢复信号 - 验证通过:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders= -nologo -clp:"Summary;WarningsOnly"- 结果:
27 Warning(s),0 Error(s);PauseStackManager.cs已不再出现在MA0051列表
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter FullyQualifiedName~PauseStackManagerTests -p:RestoreFallbackFolders=- 结果:
25 Passed,0 Failed
- 结果:
- 下一步保持原节奏:只在
CoroutineScheduler或Store中二选一继续,不与其他 warning 家族混做
2026-04-21 — RP-003
阶段:Architecture 生命周期 MA0051 收口(RP-003)
- 依据 active tracking 中“继续只选一个
GFramework.Core结构性切入点”的约束,选定GFramework.Core/Architectures/ArchitectureLifecycle.cs,因为文件体量适中且已有ArchitectureLifecycleBehaviorTests覆盖阶段流转、销毁顺序和 late registration 行为 - 先用
warnings-only定向构建确认ArchitectureLifecycle.InitializeAllComponentsAsync仍在报MA0051,随后把主流程拆成:CreateInitializationPlanInitializePhaseComponentsAsyncMarkInitializationCompleted
- 保持原有阶段顺序
Before* -> After*、批量日志文本和异步初始化策略不变,只压缩主方法长度 - 修正新增
InitializationPlan记录类型的 XML<param>名称大小写,避免引入文档告警 - 验证通过:
dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders= -nologo -clp:Summary;WarningsOnly- 结果:
29 Warning(s),0 Error(s);ArchitectureLifecycle.cs已不再出现在 warning 列表
- 结果:
dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter FullyQualifiedName~ArchitectureLifecycleBehaviorTests -p:RestoreFallbackFolders=- 结果:
6 Passed,0 Failed
- 结果:
2026-04-21 — RP-004
阶段:PR review follow-up(RP-004)
- 使用
gframework-pr-review抓取当前分支 PR #263 的最新 CodeRabbit review threads、MegaLinter 摘要与 CTRF 测试结果, 只接受仍能在本地工作树复现的 review 点 - 在
GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs中将TryCreateGeneratedRegistry的out参数改为[NotNullWhen(true)] out ICqrsHandlerRegistry?,移除三处null!抑制,保持激活失败时的日志文本与回退语义不变 - 修正 active trace 中重复的
## 2026-04-21二级标题,消除 CodeRabbit 报告的 markdownlintMD024 - 核实 PR 信号后确认:当前 CTRF 报告为
2134 passed / 0 failed;MegaLinter 唯一告警来自 CI 环境中的dotnet-formatrestore 失败,不是本地代码格式问题 - 验证通过:
dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:UseSharedCompilation=false -p:RestoreFallbackFolders=- 结果:
0 Warning(s),0 Error(s)
- 结果:
2026-04-21 — RP-002
阶段:CQRS MA0051 收口(RP-002)
- 依据 active tracking 中“先只选一个结构性切入点”的约束,选定
GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs作为低风险下一步,因为它已有稳定的 targeted test 覆盖 generated registry、reflection fallback、缓存和重复注册行为 - 将
TryRegisterGeneratedHandlers拆分为 registry 激活、批量注册和 fallback 结果构建三个辅助阶段,同时把GetReflectionFallbackMetadata的直接类型解析与按名称解析拆开,降低长方法复杂度但不改日志文本与回退语义 - 顺手修正
RegisterAssemblyHandlers内部调试日志的缩进,未改注册顺序、生命周期或服务描述符写入逻辑 - 验证通过:
dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:UseSharedCompilation=false -p:RestoreFallbackFolders=- 结果:
0 Warning(s),0 Error(s)
- 结果:
dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --filter FullyQualifiedName~CqrsHandlerRegistrarTests -p:RestoreFallbackFolders=- 结果:
11 Passed,0 Failed
- 结果:
- 新发现的环境注意事项:
- 当前 WSL worktree 下若不显式传入
-p:RestoreFallbackFolders=,Linuxdotnet会读取不存在的 Windows fallback package folder 并导致ResolvePackageAssets失败 - sandbox 内运行
dotnet会因 MSBuild named-pipe 限制失败;需要在提权上下文中执行 .NET 验证
- 当前 WSL worktree 下若不显式传入
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 | sortdotnet 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
下一步
- 若继续 analyzer warning reduction,优先回到
GFramework.Core剩余MA0051热点,并继续保持“单 warning family、单切入点”的节奏 - 后续所有 WSL 下的 .NET 定向验证命令继续显式附带
-p:RestoreFallbackFolders=,避免把环境问题误判成代码回归