GFramework/ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
gewuyou 59ceb06f2d fix(cqrs): 收口 PR342 审查遗留问题
- 修复 NotificationFanOutBenchmarks 中 MediatR handler 绕过 HandleCore 的对照偏差

- 更新 README 与中文文档中的 notification publisher 示例和表格格式

- 同步 cqrs-rewrite tracking 与 trace 到 PR #342 审查恢复点和最新验证结果
2026-05-08 19:29:45 +08:00

58 KiB
Raw Blame History

CQRS 重写迁移跟踪

目标

围绕 GFramework 当前的双轨 CQRS 现状,继续完成以“去外部依赖、降低反射、收口公开入口”为目标的 CQRS 迁移与收敛。

当前恢复点

  • 恢复点编号:CQRS-REWRITE-RP-118
  • 当前阶段:Phase 8
  • 当前 PR 锚点:PR #342
  • 当前结论:
    • 当前 RP-118 已使用 $gframework-pr-review 复核 PR #342 latest-head reviewCodeRabbit 当前仍成立的是 NotificationFanOutBenchmarks 中 MediatR 分支绕过共享 HandleCore(...)GFramework.Cqrs/README.md 的 MD058 表格空行、以及恢复文档的 PR 锚点与 fan-out 历史值表述Greptile 额外指出的 UseTaskWhenAllNotificationPublisher() 示例多余 using GFramework.Cqrs.Notification; 也在本轮一并收口
    • 本轮不改 GFramework.Cqrs runtime 语义,只让 benchmark 的 MediatR handler 与其余对照分支共用同一组空值 / 取消检查,并把 README、中文文档与 cqrs-rewrite 恢复文档同步到当前 PR #342 上下文
    • 本轮按 NotificationFanOutBenchmarks short-job 复跑确认,对称化 MediatR handler 后当前 fixed 4 handler fan-out 结果约为 Mediator 3.598 ns / 0 B、baseline 7.033 ns / 0 BMediatR 257.533 ns / 1256 BGFramework.Cqrs 顺序 409.557 ns / 408 BTaskWhenAll 484.531 ns / 496 B
    • RP-117 留在“最近权威验证”中的固定 4 handler fan-out 数值属于早期 benchmark 记录,因此本轮选择显式补上 历史基线RP-112 标注,而不是把历史验证段落改写成新的 benchmark 结果,避免混淆恢复轨迹
    • 当前 RP-117 继续沿用 $gframework-batch-boot 50,但没有继续把 batch 推回 request dispatch 热路径:本轮先试了一刀“按运行时类型缓存 IContextAware 判定”的 dispatcher 微优化,随后按 RequestBenchmarks / RequestLifetimeBenchmarks 复跑确认 steady-state request 反而回落到约 71.824 ns,因此这组运行时代码已在同轮完全撤回,不保留负收益热点实验
    • 这一批改为只收口 notification publisher 的采用文档:GFramework.Cqrs/README.mddocs/zh-CN/core/cqrs.md 现在把 Sequential / TaskWhenAll / 自定义 publisher 三条策略放进同一张选择矩阵,明确 TaskWhenAll 的价值是“并行完成 + 聚合失败”,而不是 fixed fan-out publish 的性能升级开关
    • 当前分支相对 origin/main7ca21af9, 2026-05-08 16:12:20 +0800)的累计 branch diff 仍约为 12 files,远低于 $gframework-batch-boot 50 的停止阈值;因此这批继续保持 notification 采用边界内的低风险、可评审文档切片
    • 当前 RP-116 已继续沿用 $gframework-batch-boot 50,并把刚收口的 notification publisher 配置面补成对称的内置策略集合:SequentialNotificationPublisher 现在作为公开类型提供,组合根新增 UseSequentialNotificationPublisher(),不再只存在“一个显式并行策略 + 一个隐式默认回退”
    • 这一批让用户能够在文档、配置和测试里显式表达“我要顺序失败即停”与“我要并行等待全部完成”这两条内置语义,而不需要把默认顺序策略理解成 runtime 内部细节;这进一步降低了 notification publisher seam 的心智负担
    • 当前分支相对 origin/main 的累计 branch diff 提交 RP-115 后约为 11 files,仍明显低于 $gframework-batch-boot 50 的停止阈值;因此这批继续保持 notification 配置面内的低风险、可评审切片
    • 当前 RP-115 已继续沿用 $gframework-batch-boot 50,并把 notification publisher 线从“已具备 seam + benchmark 事实”继续收口到组合根配置面:新增 GFramework.Cqrs.Extensions.NotificationPublisherRegistrationExtensions,提供 UseNotificationPublisher(...) / UseNotificationPublisher<TPublisher>() / UseTaskWhenAllNotificationPublisher() 三个显式入口,避免用户再手写 Register<INotificationPublisher>(new ...)
    • 这一批同时把重复策略注册前移到组合根阶段显式阻止,并在回归里确认 UseTaskWhenAllNotificationPublisher() 经过默认 runtime 基础设施后仍会命中“失败不阻断其余 handler”的并行语义这让 notification publisher 的采用路径从“知道内部 seam 如何接线”收口为“知道该在容器里选哪条策略”
    • 用户文档现同步写明 TaskWhenAllNotificationPublisher 更适合“并行完成 + 统一观察失败”的语义诉求,而不是 fixed fan-out steady-state publish 优化;这与 RP-114 的 benchmark 结论保持一致,减少使用者把它误解成默认的性能升级开关
    • 当前 RP-114 已继续沿用 $gframework-batch-boot 50,并沿着 RP-113 刚落地的 notification publisher 能力切片继续补 benchmarkNotificationFanOutBenchmarks 现同时纳入 GFramework.Cqrs 默认顺序发布器与新内置 TaskWhenAllNotificationPublisher,用于量化“能力差距收口后,固定 4 handler fan-out 的成本变化”
    • RP-114 的 short-job 结果显示fixed 4 handler fan-out 下,默认顺序发布器约 427.453 ns / 408 B,内置 TaskWhenAllNotificationPublisher472.574 ns / 496 BMediatR225.940 ns / 1256 BNuGet Mediator concrete runtime 约 3.854 ns / 0 B;这说明当前内置并行 publisher 的主要价值是语义补齐,而不是 steady-state fan-out 性能收益
    • 这一批保持 runtime 公开 API 与 notification 语义不变,只扩 benchmark 对照口径与恢复文档;原因是 RP-113 已经把并行 publisher 能力落到 production path当前更高价值的是先证明它相对默认顺序发布器、MediatorMediatR 的成本位置,而不是立即继续扩第二个 publisher strategy
    • 当前分支相对 origin/main 的累计 branch diff 启动时为 9 files,仍明显低于 $gframework-batch-boot 50 的停止阈值;这一批继续保持单模块、低风险、可直接评审的 benchmark 边界
    • 当前 RP-113 已继续沿用 $gframework-batch-boot 50,并把 notification 线从 benchmark 对照推进到实际 runtime 能力:新增公开内置 TaskWhenAllNotificationPublisher,让 GFramework.Cqrs 在保留默认顺序发布器的同时,提供与 Mediator TaskWhenAllPublisher 对齐的并行 notification publish 策略
    • TaskWhenAllNotificationPublisher 当前语义明确为:零处理器静默完成,单处理器直接透传,多处理器并行启动并等待全部结束;它不保留默认顺序发布器的“首个异常立即停止”语义,而是把全部处理器的失败/取消结果收敛到同一个返回任务
    • 本轮同时补齐 CqrsNotificationPublisherTests 对新内置策略的回归,并更新 GFramework.Cqrs/README.mddocs/zh-CN/core/cqrs.md,把切换方式和语义边界写回用户可见文档;当前已提交 branch diff 仍明显低于 $gframework-batch-boot 50 的停止阈值
    • 这一批选择真正落一个内置 publisher strategy而不是继续加 notification benchmark 维度;原因是 RP-111 / RP-112 已经把 notification gap 量化清楚,下一步更高价值的是开始收口“能力差距”而不是继续重复建立对照数据
    • 当前 RP-112 已继续沿用 $gframework-batch-boot 50,并在 RP-111 的单处理器 notification 对照基础上补齐固定 4 handler 的 fan-out publish benchmark新增 NotificationFanOutBenchmarks,对比 baseline、GFramework.Cqrs、NuGet Mediator concrete runtime 与 MediatR
    • NotificationFanOutBenchmarks 当前 short-job 基线约为 baseline 8.302 ns / 0 BMediator 4.314 ns / 0 BMediatR 230.304 ns / 1256 BGFramework.Cqrs 434.413 ns / 408 B;这说明 notification fan-out 的差距已经不只体现在单处理器 publish而是在固定 4 处理器场景下依然保持相近量级
    • 本轮仍然只扩 benchmark 对照口径,没有直接修改 notification runtime 或 publisher 策略语义;原因是当前更高价值的事实是先量化“单处理器”和“固定 fan-out”两条 notification 路径的外部差距,再决定下一批是否值得切进 publisher strategy 或 runtime 热点
    • 当前 RP-111 已继续沿用 $gframework-batch-boot 50,并按 skill 规则重新以 origin/main 作为基线复核:origin/main = 7ca21af92026-05-08 16:12:20 +0800),本地 main = c2d22285 已落后,当前分支 feat/cqrs-optimizationorigin/main 的累计 branch diff 为 0 files / 0 lines;基于“上下文预算优先、单批可评审边界次之”的停止规则,本轮选择 NotificationBenchmarks 这一条仍缺 Mediator concrete runtime 对照的单模块 benchmark 切片,而不是为了对称性继续扩展 notification runtime seam
    • NotificationBenchmarks 现已从双方对照扩成三方对照:新增 NuGet Mediator source-generated concrete runtime 宿主与 PublishNotification_Mediator()BenchmarkNotification / BenchmarkNotificationHandler 也同步接上 Mediator 的 notification 合同;当前 short-job 基线约为 Mediator 1.108 ns / 0 BMediatR 97.173 ns / 416 BGFramework.Cqrs 291.582 ns / 392 B
    • 本轮只把“notification publish 的高性能外部对照”补齐到 benchmark 层,而没有直接新增 generated notification invoker/provider 或 runtime 语义调整;原因是 notification dispatch 现有反射委托本就只在首次命中时缓存,继续加一层 provider 对 steady-state publish 的收益信号不如先把 Mediator concrete runtime 对照补齐来得清晰
    • 当前 RP-110 已再次使用 $gframework-pr-review 复核 PR #341 latest-head reviewBenchmarkHostFactory 的 legacy runtime alias 防守式类型检查、benchmark 宿主定向 generated registry 激活、以及 CqrsDispatcher.SendAsync(...) 的 faulted ValueTask 失败语义在当前 head 均已实质收口;本轮仅继续接受仍然成立的 CodeRabbit nitpickSendAsync_Should_Return_Faulted_ValueTask_When_Handler_Is_Missing() 补齐 HasRegistration(...) / GetAll(...) 防御性 mock并删除 trace 中重复 本轮权威验证本轮下一步 段落
    • 当前 RP-109 已使用 $gframework-pr-review 复核 PR #341 latest-head reviewbenchmark 宿主改为定向激活当前场景的 generated registry避免同一 benchmark 程序集里的其他 registry 扩大冻结服务索引与 HasRegistration 基线;BenchmarkHostFactory 为 legacy runtime alias 注册补齐防守式类型检查与 stream lifetime 运行时注释;CqrsDispatcher.SendAsync(...) 在保留 direct-return 热路径的同时恢复 faulted ValueTask 失败语义,并补齐 generated registry 定向接线与 request fault 语义回归测试;.agents/skills/gframework-batch-boot/SKILL.md 的 MD005 缩进也已顺手修正
    • GFramework.Cqrs 已完成对外部 Mediator 的生产级替代,当前主线已从“是否可替代”转向“仓库内部收口与能力深化顺序”
    • dispatch/invoker 生成前移已扩展到 request / stream 路径,RP-077 已补齐 request invoker provider gate 与 stream gate 对称的 descriptor / descriptor entry runtime 合同回归
    • RP-078 已补齐 mixed fallback metadata 在 runtime 不允许多个 fallback attribute 实例时的单字符串 attribute 回退回归
    • RP-079 已补齐 runtime 缺少 generated handler registry interface 时的 generator 静默跳过回归
    • RP-080 已将基础 generation gate 回归扩展到 notification handler interface、stream handler interface 与 registry attribute 缺失分支
    • RP-081 已继续补齐基础 generation gate 的 logging 与 DI runtime contract 缺失分支
    • 当前 RP-082 已补齐基础 generation gate 的 request handler runtime contract 缺失分支
    • RP-083 已补齐 mixed direct / reflected-implementation request 与 stream invoker provider 发射顺序回归
    • RP-084 已引入独立 GFramework.Cqrs.Benchmarks 项目,作为持续吸收 Mediator benchmark 组织方式的第一落点
    • RP-085 已补齐 stream request benchmark对齐 Mediator messaging benchmark 的第二个核心场景
    • RP-086 已补齐 request pipeline 0 / 1 / 4 数量矩阵,开始把 benchmark 关注点从单纯 messaging steady-state 扩展到行为编排开销
    • RP-087 已补齐 request startup benchmark把 initialization 与 cold-start 维度正式纳入 GFramework.Cqrs.Benchmarks
    • 当前 RP-088 已补齐 request invoker reflection / generated-provider 对照,开始直接量化 dispatcher 预热 generated descriptor 的收益
    • 当前 RP-089 已补齐 stream invoker reflection / generated-provider 对照,使 generated descriptor 预热收益从 request 扩展到 stream 路径
    • 当前 RP-090 已收敛 PR #326 benchmark review统一 benchmark 最小宿主构建、冻结 GFramework 容器、限制 MediatR 扫描范围,并恢复 request startup cold-start 对照
    • 当前 RP-091 已把 benchmark 项目发布面隔离与包清单校验前移到 PRGFramework.Cqrs.Benchmarks 明确保持不可打包,publish.ymlci.yml 复用同一份 packed-modules 校验脚本
    • RP-092 已补齐 request handler Singleton / Transient 生命周期矩阵 benchmark并明确把 Scoped 对照留到具备真实显式作用域边界的宿主模型后再评估
    • RP-093 已把 GFramework.Core 的 legacy SendCommand / SendQuery 兼容入口收敛到底层统一 GFramework.Cqrs runtime同时补充 Mediator 未吸收能力差距复核
    • RP-094 已按 PR #334 latest-head review 收口 legacy bridge 的测试注册方式、模块运行时依赖契约、异步取消语义、XML 文档缺口与兼容文档回退边界
    • RP-095 已继续收口 PR #334 剩余 review把 legacy 同步 bridge 的阻塞等待统一切到线程池隔离 helper、补齐 ArchitectureContext / executor 共享 dispatch helper、修正 bridge fixture 的并行与容器释放约束,并为 runtime bridge 与 async void command cancellation 增补回归测试
    • RP-096 已再次使用 $gframework-pr-review 复核 PR #334 latest-head review确认仍显示为 open 的 AI threads 在本地代码中已无新增仍成立的运行时 / 测试 / 文档缺陷,剩余差异主要是 GitHub thread 未 resolve 的状态滞后
    • RP-097 已继续收口 PR #334 latest-head nitpickAsyncQueryExecutorTests / CommandExecutorTests 补齐可观察的上下文保留断言,并让 RecordingCqrsRuntime 在测试替身返回错误响应类型时抛出带请求/类型信息的诊断异常
    • 当前 RP-098 已再次使用 $gframework-pr-review 复核 PR #334 latest-head review并收口 LegacyCqrsDispatchHelper.TryResolveDispatchContext(...) 过宽吞掉 InvalidOperationException 的真实运行时诊断退化问题;现在仅把“上下文尚未就绪”视为允许 fallback 的信号,并为 fallback / 异常冒泡分别补齐回归测试
    • RP-099 已补齐 GFramework.Cqrs 的最小 stream pipeline seam新增 IStreamPipelineBehavior<,> / StreamMessageHandlerDelegate<,>RegisterCqrsStreamPipelineBehavior<TBehavior>()、dispatcher 侧 stream pipeline executor 缓存与 generated stream invoker 兼容回归,以及 Architecture 公开注册入口与对应文档说明
    • 当前 RP-100 已使用 $gframework-pr-review 复核 PR #339 latest-head review收口 RegisterCqrsStreamPipelineBehavior<TBehavior>() 的异常契约文档、为 StreamPipelineInvocation.GetContinuation(...) 补齐并发 continuation 缓存说明、抽取 MicrosoftDiContainer 的 CQRS 行为注册公共逻辑,并顺手修复当前 branch diff 内 ICqrsRequestInvokerProvider.cs 的 XML 缩进格式问题
    • 当前 RP-101 已按用户新增 benchmark 诉求收口 request 热路径:为 IIocContainer 新增不激活实例的 HasRegistration(Type)、让 dispatcher 在 0 pipeline 场景下跳过空行为解析,并为 MicrosoftDiContainer 的热路径查询补齐 debug-level 守卫,避免无效日志字符串分配
    • 当前 RP-102 已把 GFramework.Cqrs.BenchmarksMediator 对照组收口为官方 NuGet 引用(Mediator.Abstractions / Mediator.SourceGenerator 3.0.2),不再使用本地 ai-libs/Mediator project referenceRequestBenchmarks 现已新增 source-generated concrete Mediator 对照方法,并通过 RequestLifetimeBenchmarks 复核 hot path 收口后的新基线
    • 当前 RP-102 已将 BenchmarkDotNet.Artifacts/ 收口为默认忽略路径,并把 request steady-state / lifetime benchmark 复跑升级为 CQRS 性能相关改动的默认回归门槛;当前阶段目标明确为“持续逼近 source-generated Mediator,并至少稳定超过反射版 MediatR
    • 当前 RP-103 已使用 $gframework-pr-review 复核 PR #340 latest-head review修复 CreateStream_Should_Throw_When_Stream_Pipeline_Behavior_Context_Does_Not_Implement_IArchitectureContext 因 strict mock 未配置 HasRegistration(Type) 产生的 CI 失败,收紧 MicrosoftDiContainer.HasRegistration(Type) 到与 GetAll(Type) 一致的服务键可见性语义,补齐 IIocContainer.HasRegistration(Type) 的异常/XML 契约与 docs/zh-CN/core/ioc.md 的用户接入说明,并同步 benchmark 注释与 active tracking/trace 到当前 PR 锚点
    • 当前 RP-104 已继续沿用 $gframework-batch-boot 50 压 request 热路径:先把 CqrsDispatcher.SendAsync(...) 改成 direct-return ValueTask,移除 dispatcher 自身的 async/await 状态机;再让 MicrosoftDiContainer.HasRegistration(Type) 在冻结后复用预构建的服务键索引,避免每次命中零 pipeline request 都线性扫描全部描述符;本轮 benchmark 表明第一刀显著压低 steady-state / lifetime request第二刀在当前短跑下主要确认“无回退、收益不明显”
    • 当前 RP-105 已继续沿用 $gframework-batch-boot 50 压默认 request steady-state为 benchmark 最小宿主补齐 CQRS runtime / registrar / registration service 基础设施,让 RequestBenchmarks 不再只测反射路径,而是通过 handwritten generated registry + RegisterCqrsHandlersFromAssembly(...) 真实接上 generated request invoker provider本轮 benchmark 表明默认 request 路径进一步从约 70.298 ns / 32 B 压到约 65.296 ns / 32 BSingleton / Transient lifetime 也同步收敛到约 68.772 ns / 32 B73.157 ns / 56 B
    • 当前 RP-106 已把同一套 generated-provider 宿主收口扩展到 RequestPipelineBenchmarks:新增 handwritten GeneratedRequestPipelineBenchmarkRegistry,并让 RequestPipelineBenchmarks 改走 RegisterCqrsHandlersFromAssembly(...) + benchmark CQRS 基础设施预接线;本轮 benchmark 表明 0 pipeline steady-state 进一步收敛到约 64.755 ns / 32 B1 pipeline353.141 ns / 536 B4 pipeline 在短跑噪音下维持约 555.083 ns / 896 B
    • 当前 RP-107 已把默认 stream steady-state 宿主也切到 generated-provider 路径:新增 handwritten GeneratedDefaultStreamingBenchmarkRegistry,让 StreamingBenchmarks 改走 RegisterCqrsHandlersFromAssembly(...) 并在 setup/cleanup 清理 dispatcher cache同时将 gframework-boot / gframework-batch-boot 的默认停止规则改为“AI 上下文预算优先,建议在预计接近约 80% 安全上下文占用前收口”,不再把 changed files 误当作唯一阈值
    • 当前 RP-108 已补齐 stream handler Singleton / Transient 生命周期矩阵 benchmark新增 StreamLifetimeBenchmarksGeneratedStreamLifetimeBenchmarkRegistry,让 stream 生命周期对照沿用 generated-provider 宿主接线而不是退回纯反射路径;本轮 benchmark 表明 Singleton 下 baseline / GFramework.Cqrs / MediatR80.144 ns / 137.515 ns / 229.242 nsTransient 下约 77.198 ns / 144.998 ns / 228.185 ns
  • ai-plan active 入口现以 RP-108 为最新恢复锚点;PR #340PR #339PR #334PR #331PR #326PR #323PR #307 与其他更早阶段细节均以下方归档或说明为准

当前活跃事实

  • 当前分支为 feat/cqrs-optimization
  • 本轮 $gframework-batch-boot 50origin/main (4d6dbba6, 2026-05-08 11:13:33 +0800) 为基线;本地 main 仍落后,不作为 branch diff 基线
  • 当前已提交分支相对 origin/main 的累计 branch diff 为 14 files / 507 lines
  • 本批待提交工作树集中在 GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/README.md
  • 当前批次后的默认停止依据已改为 AI 上下文预算:若下一轮预计会让活动对话、已加载 recovery 文档、验证输出与当前 diff 接近约 80% 安全上下文占用,应在当前自然批次边界停止,即使 branch diff 仍有余量
  • GFramework.Cqrs.Benchmarks 作为 benchmark 基础设施项目,必须持续排除在 NuGet / GitHub Packages 发布集合之外
  • GFramework.Cqrs.Benchmarks 现已覆盖 request steady-state、pipeline 数量矩阵、startup、request/stream generated invoker以及 request handler Singleton / Transient 生命周期矩阵
  • GFramework.Cqrs.Benchmarks 当前以 NuGet 方式引用 Mediator.Abstractions / Mediator.SourceGenerator 3.0.2ai-libs/Mediator 只保留为本地源码/README 对照资料,不再参与 benchmark 项目编译
  • 当前 request steady-state benchmark 已形成 baseline / Mediator / MediatR / GFramework.Cqrs 四方对照:最新约 5.608 ns / 32 B5.445 ns / 32 B57.071 ns / 232 B64.825 ns / 32 B
  • 当前 request lifetime benchmark 已继续收敛:SingletonGFramework.Cqrs 最新约 69.275 ns / 32 BTransient 下约 74.301 ns / 56 B;相较 RP-104 前的 73.005 ns / 32 B74.757 ns / 56 B 仍维持同一收敛区间
  • 当前 request pipeline benchmark 已改为与默认 request steady-state 相同的 generated-provider 宿主接线路径:0 pipeline64.755 ns / 32 B1 pipeline353.141 ns / 536 B4 pipeline555.083 ns / 896 B
  • 当前 stream steady-state benchmark 也已切到 generated-provider 宿主接线路径baseline 约 5.535 ns / 32 BMediatR59.499 ns / 232 BGFramework.Cqrs66.778 ns / 32 B
  • 当前 stream lifetime benchmark 已补齐 Singleton / Transient 两档矩阵,并沿用 generated-provider 宿主接线:Singleton 下 baseline / GFramework.Cqrs / MediatR80.144 ns / 137.515 ns / 229.242 nsTransient 下约 77.198 ns / 144.998 ns / 228.185 ns
  • 本轮已验证旧 benchmark 劣化的两个主热点:0 pipeline 场景下仍解析空行为列表,以及容器查询热路径在 debug 禁用时仍构造日志字符串;两者收口后,GFramework.Cqrs request 路径不再出现额外数百字节分配
  • HasRegistration(Type) 现在只把“同一服务键已注册”或“开放泛型服务键可闭合到目标类型”视为命中,不再把“仅以具体实现类型自注册”的行为误判为接口服务已注册;该语义与 Get(Type) / GetAll(Type) 已重新对齐
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs 已同步适配 HasRegistration(Type) fast-path避免 strict mock 因缺少新调用配置而在上下文失败语义断言前提前抛出 Moq.MockException
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs 现连“handler 缺失但仍返回 faulted ValueTask”这条 request 失败语义回归也显式为 HasRegistration(Type) / GetAll(Type) 预留了防御性 mock不再依赖 dispatcher 先判空 handler、后探测 pipeline 的内部顺序
  • docs/zh-CN/core/ioc.md 已新增 HasRegistration(Type) 的使用语义、热路径用途与“按服务键而非可赋值关系判断”的示例说明
  • 当前 request steady-state 仍落后于 source-generated MediatorMediatR,但差距已从“额外数百字节分配 + 近 300ns”收敛到“零 pipeline fast-path 仍慢约 31ns / 3.6xMediator”;下一批若继续压 request dispatch应优先评估默认路径吸收 generated invoker/provider 的空间
  • 本轮 SendAsync(...) 的 direct-return ValueTask 改动已证明确实是有效热点:同样的短跑配置下,GFramework.Cqrs steady-state request 从约 83.823 ns 下探到 69-70 ns 区间
  • 冻结后 HasRegistration(Type) 服务键索引化在当前短跑下没有带来同等量级的可见收益,但也没有引入功能回退或额外分配;后续若继续压零 pipeline request应优先重新评估“默认 request 路径进一步吸收 generated invoker/provider”而不是继续堆叠同层级微优化
  • 默认 RequestBenchmarksRequestPipelineBenchmarksStreamingBenchmarks 现在都已通过 handwritten generated registry + 真实 RegisterCqrsHandlersFromAssembly(...) 宿主接线命中 generated invoker provider不再只代表纯反射 binding 路径
  • gframework-bootgframework-batch-boot 现明确把“上下文预算接近约 80%”视为默认优先停止信号branch diff files / lines 仅保留为次级仓库范围指标
  • 当前性能回归门槛已收紧为:只要改动触达 GFramework.Cqrs request dispatch、DI 热路径、invoker/provider、pipeline 或 benchmark 宿主,就必须至少复跑 RequestBenchmarks.SendRequest_*RequestLifetimeBenchmarks.SendRequest_*
  • 当前阶段的性能验收目标已明确为:默认 request steady-state 路径不要求超过 source-generated Mediator,但必须持续逼近它,并至少稳定快于基于反射 / 扫描的 MediatR
  • GFramework.Core 当前已通过内部 bridge request / handler 把 legacy ICommandIAsyncCommandIQueryIAsyncQuery 接到统一 ICqrsRuntime
  • 标准 Architecture 初始化路径会自动扫描 GFramework.Core 程序集中的 legacy bridge handler因此旧 SendCommand(...) / SendQuery(...) 无需改变用法即可进入统一 pipeline
  • CommandExecutorQueryExecutorAsyncQueryExecutor 仍保留“无 runtime 时直接执行”的回退路径,用于不依赖容器的隔离单元测试
  • LegacyCqrsDispatchHelper 现统一负责 runtime dispatch context 解析,以及 legacy 同步 bridge 对 ICqrsRuntime.SendAsync(...) 的线程池隔离等待
  • ArchitectureContextCommandExecutorQueryExecutor 的同步 CQRS/legacy bridge 入口不再直接在调用线程上阻塞 SendAsync(...).GetAwaiter().GetResult()
  • GFramework.Core.Tests 现通过 InternalsVisibleTo("GFramework.Core.Tests") 直接实例化内部 bridge handler不再依赖字符串反射装配测试桥接注册
  • 使用 LegacyBridgePipelineTrackerArchitectureContextTestsArchitectureModulesBehaviorTests 现都显式标记为 NonParallelizable
  • ArchitectureContextTests.CreateFrozenBridgeContext(...) 现把冻结容器所有权显式交回调用方,并在每个 bridge 用例的 finally 中释放
  • CommandExecutorModuleQueryExecutorModuleAsyncQueryExecutorModule 现改为 GetRequired<ICqrsRuntime>() 并在 XML 文档里显式声明注册顺序契约,避免 runtime 缺失时静默回退
  • LegacyAsyncQueryDispatchRequestHandlerLegacyAsyncCommandResultDispatchRequestHandlerLegacyAsyncCommandDispatchRequestHandler 现都通过 ThrowIfCancellationRequested() + WaitAsync(cancellationToken) 显式保留调用方取消可见性
  • 相对 ai-libs/Mediator当前仍未完全吸收的能力集中在五类facade 公开入口、telemetry、notification publisher 策略、生成器配置与诊断、生命周期/缓存公开配置面
  • 发布工作流已有 packed modules 校验,但 PR 工作流此前没有等价的 solution pack 产物名单校验
  • 本地 dotnet pack GFramework.sln -c Release --no-restore -o <temp-dir> 当前只产出 14 个预期包,未复现 benchmark .nupkg
  • PR #3342026-05-07 的 latest-head review 当前显示 CodeRabbit 10 / Greptile 5 个 open thread本轮再次复核后确认其中大部分仍是已实质修复但未 resolve 的 stale threadLegacyCqrsDispatchHelper.TryResolveDispatchContext(...) 的异常边界仍需要继续收口
  • benchmark 场景现统一通过 BenchmarkHostFactory 构建最小宿主GFramework 侧在 runtime 分发前显式 Freeze() 容器MediatR 侧只扫描当前场景需要的 handler / behavior 类型
  • RequestStartupBenchmarks 已恢复 ColdStart_GFrameworkCqrs 结果产出,不再命中 No CQRS request handler registered
  • BenchmarkDotNet 在当前 agent 沙箱里会因自动生成的 bootstrap 脚本异常失败;同一 dotnet run --no-build 命令在沙箱外执行通过,因此本轮以沙箱外结果作为 benchmark 权威验证
  • 已新增手动触发的 benchmark workflow默认只验证 benchmark 项目 Release build只有显式提供过滤器时才执行 BenchmarkDotNet 运行;过滤器输入现通过环境变量传入 shell避免 workflow_dispatch 输入直接插值到命令行
  • 远端 CTRF 最新汇总为 2311/2311 passedrun #1079, 2026-05-07
  • MegaLinter 当前只暴露 dotnet-formatRestore operation failed 环境噪音,尚未提供本地仍成立的文件级格式诊断
  • LegacyCqrsDispatchHelper.TryResolveDispatchContext(...) 现在只会把“Context 尚未设置”或“当前没有活动上下文”识别为可安全 fallback 的缺上下文信号;其他 InvalidOperationException 将继续向上传播,避免把真实运行时故障误判成 legacy 直执行场景
  • CommandExecutorTests 已新增“缺上下文继续 fallback”和“意外 InvalidOperationException 必须冒泡”的回归,防止后续再次放宽该异常过滤面
  • PR #334 当前 latest-head open AI feedback 经过本轮本地复核与修复后,应主要剩余待 GitHub 重新索引的状态差异或已实质关闭但未 resolve 的 thread
  • GFramework.Core.Tests 中 legacy bridge 的“保留上下文”回归现在同时断言 bridge request 类型与目标对象执行期观察到的 IArchitectureContext
  • RecordingCqrsRuntime 对非 Unit 响应已显式校验返回值类型;若测试工厂返回了 null 或错误装箱类型,异常会直接指出 request 类型与期望/实际响应类型
  • PR #339 当前 latest-head review 仍显示 2 个 CodeRabbit open thread 与 2 个 nitpick本轮本地复核后确认
    • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csPer_Behavior_Count 拼写已在当前 head 修正,属于 stale thread
    • GFramework.Core.Abstractions/Ioc/IIocContainer.cs 的流式行为注册入口此前确实缺少 <exception> / <remarks> 契约说明,现已补齐并同步到 IArchitecture / Architecture / ArchitectureModules
    • GFramework.Cqrs/Internal/CqrsDispatcher.csStreamPipelineInvocation.GetContinuation(...) 线程模型说明此前少于 request 对称路径,现已补齐并发 next() 时 continuation 缓存的语义边界
    • GFramework.Core/Ioc/MicrosoftDiContainer.cs 的 request / stream 行为注册逻辑此前存在重复实现,现已抽取共享私有 helper 以避免后续生命周期或校验逻辑漂移
  • 本地 dotnet format GFramework.Cqrs/GFramework.Cqrs.csproj --verify-no-changes 显示当前 diff 内仍有 GFramework.Cqrs/ICqrsRequestInvokerProvider.cs 的空白格式问题,本轮已修复;同一次命令报出的多条 CHARSET 提示集中在未触达的历史文件,不视为 PR #339 本轮新增 triage 结论

当前风险

  • 顶层 GFramework.sln / GFramework.csproj 在 WSL 下仍可能受 Windows NuGet fallback 配置影响,完整 solution 级验证成本高于模块级验证
  • 若后续新增 benchmark / example / tooling 项目但未同步校验发布面solution 级 dotnet pack 仍可能在 tag 发布前才暴露异常包
  • RequestStartupBenchmarks 为了量化真正的单次 cold-start引入了 InvocationCount=1 / UnrollFactor=1 的专用 job该配置会触发 BenchmarkDotNet 的 MinIterationTime 提示,后续若要做稳定基线比较,还需要决定是否引入批量外层循环或自定义 cold-start harness
  • 当前 benchmark 宿主仍刻意保持“单根容器最小宿主”模型;若要公平比较 Scoped handler 生命周期,需要先引入显式 scope 创建与 scope 内首次解析的对照基线
  • 当前 Mediator concrete runtime 对照已覆盖 steady-state request、单处理器 notification publish 与固定 4 handler notification fan-out若要把 Transient / Scoped 生命周期矩阵、stream 生命周期矩阵或更大 fan-out 矩阵也纳入同一组对照,需要按 Mediator 官方 benchmark 的做法拆分 compile-time lifetime / 场景配置,而不是在同一编译产物里混用多个 runtime 变量
  • 当前 stream 生命周期矩阵尚未接入 Mediator concrete runtime若要继续对齐 Mediator 官方 benchmark 的 compile-time lifetime 设计,需要为 stream 场景补专门的 build-time 配置,而不是在当前统一宿主里临时拼接
  • BenchmarkDotNet.Artifacts/ 现已加入仓库忽略规则;若后续确实需要提交新的基准报告,应显式挑选结果文件或改走文档归档,而不是直接纳入整个生成目录
  • 当前 GFramework.Cqrs request steady-state 仍慢于 MediatR;在“至少超过反射版 MediatR”这个阶段目标达成前,任何相关改动都不能只看功能 build/test 结果,必须附带 benchmark 回归数据
  • 仓库内部仍保留旧 Command / Query API、LegacyICqrsRuntime alias 与部分历史命名语义,后续若不继续分批收口,容易混淆“对外替代已完成”与“内部收口未完成”
  • 若继续扩大 generated invoker 覆盖面,需要持续区分“可静态表达的合同”与 PreciseReflectedRegistrationSpec 等仍需保守回退的场景
  • legacy bridge 当前只为已有 Command / Query 兼容入口接到统一 request pipeline若后续要继续对齐 Mediator,仍需要单独设计 stream pipeline、telemetry 与 facade 公开面,而不是把这次 bridge 当成“全部收口完成”
  • LegacyBridgePipelineTracker 仍是进程级静态测试辅助;虽然现在已在相关 fixture 清理阶段重置并补充线程安全说明,但若将来扩大并行 bridge fixture 数量,仍要继续控制共享状态扩散
  • stream pipeline 当前只在“单次建流”层面包裹 handler 调用;若后续需要 per-item 拦截、元素级重试或流内 metrics 聚合,仍需额外设计更细粒度 contract而不是把本轮 seam 直接等同于元素级 middleware
  • PR #339 在 GitHub 上仍有 1 个已本地失效但未 resolve 的 stale test-thread若后续 head 再次变化,需要重新抓取 latest-head review 确认未解决线程是否收敛
  • 若后续继续依赖 HasRegistration(Type) 做热路径短路,新增测试替身或 strict mock 时必须同步配置该调用,否则容易在真正业务断言之前被 mock 框架短路成环境性失败

最近权威验证

  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- --filter "*NotificationFanOutBenchmarks*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:本轮对称化 MediatR handler 后fixed 4 handler fan-out 对照约为 Mediator 3.598 ns / 0 B、baseline 7.033 ns / 0 BMediatR 257.533 ns / 1256 BGFramework.Cqrs 顺序 409.557 ns / 408 BTaskWhenAll 484.531 ns / 496 B
  • python3 scripts/license-header.py --check --paths GFramework.Cqrs.Benchmarks/Messaging/NotificationFanOutBenchmarks.cs GFramework.Cqrs/README.md docs/zh-CN/core/cqrs.md ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
    • 结果:通过
  • git diff --check
    • 结果:通过
    • 备注:仅剩 GFramework.sln 的历史 CRLF 提示,无本轮新增 diff 格式问题
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- --filter "*NotificationFanOutBenchmarks*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:历史基线(RP-112)固定 4 handler notification fan-out 对照约为 baseline 8.302 ns / 0 BMediator 4.314 ns / 0 BMediatR 230.304 ns / 1256 BGFramework.Cqrs 434.413 ns / 408 B
  • python3 scripts/license-header.py --check --paths GFramework.Cqrs.Benchmarks/Messaging/NotificationFanOutBenchmarks.cs GFramework.Cqrs.Benchmarks/README.md
    • 结果:通过
  • git diff --check
    • 结果:通过
    • 备注:仅剩 GFramework.sln 的历史 CRLF 提示,无本轮新增 diff 格式问题
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- --filter "*NotificationBenchmarks*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注notification publish 三方对照当前约为 Mediator 1.108 ns / 0 BMediatR 97.173 ns / 416 BGFramework.Cqrs 291.582 ns / 392 B
  • python3 scripts/license-header.py --check --paths GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs GFramework.Cqrs.Benchmarks/README.md
    • 结果:通过
  • git diff --check
    • 结果:通过
    • 备注:仅剩 GFramework.sln 的历史 CRLF 提示,无本轮新增 diff 格式问题
  • dotnet build GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release
    • 结果:通过,0 warning / 0 error
    • 备注:并行验证首轮曾因 buildtest 同时写入同一输出 DLL 触发 MSB3026 单次复制重试;改为串行重跑同一命令后稳定通过
  • dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsDispatcherContextValidationTests"
    • 结果:通过,6/6 passed
  • python3 scripts/license-header.py --check --paths GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
    • 结果:通过
  • git diff --check
    • 结果:通过
    • 备注:仅剩 GFramework.sln 的历史 CRLF 提示,无本轮新增 diff 格式问题
  • python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --format json --json-output /tmp/current-pr-review.json
    • 结果:通过
    • 备注:确认当前分支对应 PR #342latest-head 当前显示 CodeRabbit 4 / Greptile 3 open thread其中真正仍成立的是 benchmark handler 对称性、README / 中文文档示例与恢复文档锚点漂移,其余历史 thread 需要按当前 head 继续甄别
  • python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --json-output /tmp/current-pr-review.json
    • 结果:通过
    • 备注:确认当前分支对应 PR #340latest-head 当前显示 CodeRabbit 2 / Greptile 2 open threadCTRF 报告中唯一失败测试为 CreateStream_Should_Throw_When_Stream_Pipeline_Behavior_Context_Does_Not_Implement_IArchitectureContext
  • dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet build GFramework.Core/GFramework.Core.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet build GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~MicrosoftDiContainerTests"
    • 结果:通过,52/52 passed
  • dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~CqrsDispatcherContextValidationTests"
    • 结果:通过,4/4 passed
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注按新性能回归门槛复跑后steady-state request 对照约为 baseline 5.300 ns / 32 BMediator 4.964 ns / 32 BMediatR 57.993 ns / 232 BGFramework.Cqrs 83.823 ns / 32 B
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestLifetimeBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:按新性能回归门槛复跑后,SingletonGFramework.Cqrs / MediatR83.183 ns / 32 B vs 60.915 ns / 232 BTransient 下约 86.243 ns / 56 B vs 59.644 ns / 232 B
  • env GIT_DIR=... GIT_WORK_TREE=... python3 scripts/license-header.py --check
    • 结果:通过
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • python3 scripts/license-header.py --check --paths GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs GFramework.Cqrs.Benchmarks/README.md
    • 结果:通过
  • git diff --check
    • 结果:通过
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注steady-state request 对照约为 baseline 5.336 ns / 32 BMediator 5.564 ns / 32 BMediatR 53.307 ns / 232 BGFramework.Cqrs 64.745 ns / 32 B
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestLifetimeBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:Singleton 下 baseline / MediatR / GFramework.Cqrs4.309 ns / 51.923 ns / 67.981 nsTransient 下约 5.029 ns / 54.435 ns / 76.437 ns
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*StreamLifetimeBenchmarks*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:Singleton 下 baseline / GFramework.Cqrs / MediatR80.144 ns / 137.515 ns / 229.242 nsTransient 下约 77.198 ns / 144.998 ns / 228.185 ns
  • git diff --check
    • 结果:通过
    • 备注:当前仅保留 GFramework.sln 的历史 CRLF 警告,无本轮新增 diff 格式错误
  • dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~MicrosoftDiContainerTests"
    • 结果:通过,52/52 passed
  • dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~CqrsDispatcherCacheTests|FullyQualifiedName~CqrsDispatcherContextValidationTests"
    • 结果:通过,14/14 passed
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- --filter "*RequestBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:本轮两批热路径收口后的最新 steady-state request 对照约为 baseline 6.141 ns / 32 BMediator 6.674 ns / 32 BMediatR 61.803 ns / 232 BGFramework.Cqrs 70.298 ns / 32 B
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- --filter "*RequestLifetimeBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:最新 lifetime request 对照约为 Singleton 下 baseline / MediatR / GFramework.Cqrs = 4.706 ns / 52.197 ns / 73.005 nsTransient 下 = 4.571 ns / 50.175 ns / 74.757 ns
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • python3 scripts/license-header.py --check --paths GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs GFramework.Cqrs.Benchmarks/README.md
    • 结果:通过
  • git diff --check
    • 结果:通过
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:默认 steady-state request 对照现约为 baseline 5.013 ns / 32 BMediator 5.747 ns / 32 BMediatR 51.588 ns / 232 BGFramework.Cqrs 65.296 ns / 32 B
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestLifetimeBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:最新 lifetime request 对照约为 Singleton 下 baseline / MediatR / GFramework.Cqrs = 4.817 ns / 48.177 ns / 68.772 nsTransient 下 = 4.841 ns / 51.753 ns / 73.157 ns
  • env GIT_DIR=... GIT_WORK_TREE=... python3 scripts/license-header.py --check
    • 结果:通过
  • git diff --check
    • 结果:通过
    • 备注:仍仅保留 GFramework.sln 的历史 CRLF 警告,无本轮新增 diff 格式问题
  • dotnet pack GFramework.sln -c Release --no-restore -o /tmp/gframework-pack-validation -p:IncludeSymbols=false
    • 结果:通过
    • 备注:当前本地产物仅包含 14 个预期发布包,未生成 GFramework.Cqrs.Benchmarks.*.nupkg
  • bash scripts/validate-packed-modules.sh /tmp/gframework-pack-validation
    • 结果:通过
    • 备注:共享脚本确认 actual package set 与预期 14 个发布包完全一致
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~MicrosoftDiContainerTests"
    • 结果:通过,51/51 passed
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:最新 steady-state request 对照约为 baseline 5.969 ns / 32 BMediator 6.242 ns / 32 BMediatR 53.818 ns / 232 BGFramework.Cqrs 85.504 ns / 32 B
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestLifetimeBenchmarks.SendRequest_*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:SingletonGFramework.Cqrs / MediatR84.066 ns / 32 B vs 56.096 ns / 232 BTransient 下约 90.652 ns / 56 B vs 57.207 ns / 232 B
  • python3 scripts/license-header.py --check
    • 结果:通过
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestStartupBenchmarks*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过
    • 备注:ColdStart_GFrameworkCqrs 已恢复出数,最新本地输出约 220-292 usMediatR 对照约 575-616 us;当前仅剩 BenchmarkDotNet 对单次 cold-start 场景的 MinIterationTime 提示
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
    • 备注:用于验证本轮 request invoker / pipeline / stream invoker 调整与 benchmark workflow 改动后的 Release 编译结果
  • python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --format json --json-output /tmp/current-pr-review.json
    • 结果:通过
    • 备注:确认当前分支对应 PR #334CodeRabbit latest review 已 APPROVED,但 latest-head 仍显示 10 个 open thread、Greptile 仍显示 3 个 open thread本地逐项复核后未发现新的仍成立缺陷最新 CI 测试汇总为 2311/2311 passedMegaLinter 仅剩 dotnet-format restore 环境噪音
  • dotnet build GFramework.Core/GFramework.Core.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --json-output /tmp/current-pr-review.json
    • 结果:通过
    • 备注:确认当前分支对应 PR #339latest-head 显示 2 个 CodeRabbit open thread 与 2 个 nitpick本轮本地接受并修复的问题集中在流式行为注册入口 XML 契约、stream continuation 线程说明与 MicrosoftDiContainer 的重复注册逻辑,测试方法拼写线程已在当前 head 失效
  • dotnet format GFramework.Cqrs/GFramework.Cqrs.csproj --verify-no-changes
    • 结果:发现当前 diff 内 GFramework.Cqrs/ICqrsRequestInvokerProvider.cs 的空白格式问题;其余 CHARSET 提示集中在未触达的历史文件
  • dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet build GFramework.Core/GFramework.Core.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~CqrsDispatcherCacheTests"
    • 结果:通过,10/10 passed
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~ArchitectureModulesBehaviorTests"
    • 结果:通过,4/4 passed
  • env GIT_DIR=... GIT_WORK_TREE=... python3 scripts/license-header.py --check
    • 结果:通过
  • git diff --check
    • 结果:通过
  • dotnet build GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~CommandExecutorTests|FullyQualifiedName~AsyncQueryExecutorTests"
    • 结果:通过,19/19 passed
  • python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --json-output /tmp/current-pr-review.json
    • 结果:通过
    • 备注:确认当前分支对应 PR #334;最新 review 仍为 CodeRabbit APPROVED (2026-05-07T12:20:24Z)latest-head 显示 CodeRabbit 10 / Greptile 5 open thread本轮接受并修复的仍成立问题收敛到 LegacyCqrsDispatchHelper.TryResolveDispatchContext(...) 的过宽异常吞掉逻辑
  • dotnet build GFramework.Core/GFramework.Core.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet build GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~CommandExecutorTests|FullyQualifiedName~QueryExecutorTests"
    • 结果:通过,25/25 passed
  • python3 scripts/license-header.py --check
    • 结果:通过
  • git diff --check
    • 结果:通过
  • python3 scripts/license-header.py --check
    • 结果:通过
  • git diff --check
    • 结果:通过
  • python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --format json --json-output <temporary-json-output>
    • 结果:通过
    • 备注:确认当前分支对应 PR #331,本轮 latest-head open AI feedback 已收敛到 dotnet pack --no-build、共享包校验脚本跨平台兼容性与 active 文档 PR 锚点同步
  • python3 scripts/license-header.py --check
    • 结果:通过
    • 备注:当前 WSL worktree 需要显式绑定 GIT_DIR / GIT_WORK_TREE 后运行
  • git diff --check
    • 结果:通过
  • dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestLifetimeBenchmarks*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1
    • 结果:通过(以沙箱外 --no-build 权威结果为准)
    • 备注:Singleton 下 baseline / MediatR / GFramework 均值约 5.633 ns / 58.687 ns / 301.731 nsTransient 下约 5.044 ns / 52.274 ns / 287.863 ns
  • python3 scripts/license-header.py --check
    • 结果:通过
    • 备注:当前 WSL worktree 需要显式绑定 GIT_DIR / GIT_WORK_TREE
  • git diff --check
    • 结果:通过
  • dotnet build GFramework.Core/GFramework.Core.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureContextTests|FullyQualifiedName~CommandExecutorTests|FullyQualifiedName~QueryExecutorTests|FullyQualifiedName~AsyncQueryExecutorTests"
    • 结果:通过,45/45 passed
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release
    • 结果:通过,1644/1644 passed
  • env GIT_DIR=... GIT_WORK_TREE=... python3 scripts/license-header.py --check
    • 结果:通过
  • git diff --check
    • 结果:通过
  • python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --json-output /tmp/current-pr-review.json
    • 结果:通过
    • 备注:确认当前分支对应 PR #334;仍有效的 latest-head review 已收敛到 legacy bridge 测试装配、运行时依赖契约、异步取消、XML 文档与兼容文档边界
  • dotnet build GFramework.Core/GFramework.Core.csproj -c Release
    • 结果:通过,0 warning / 0 error
    • 备注:修复新增 XML 文档 warning 后复跑,当前 GFramework.Core 三个 target framework 均已干净通过
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureContextTests|FullyQualifiedName~ArchitectureModulesBehaviorTests|FullyQualifiedName~CommandExecutorTests|FullyQualifiedName~QueryExecutorTests|FullyQualifiedName~AsyncQueryExecutorTests"
    • 结果:通过,48/48 passed
    • 备注:覆盖 legacy bridge 兼容入口、测试装配、执行器 runtime fallback 与相关模块行为
  • env GIT_DIR=... GIT_WORK_TREE=... python3 scripts/license-header.py --check
    • 结果:通过
  • git diff --check
    • 结果:通过
  • dotnet build GFramework.Core/GFramework.Core.csproj -c Release
    • 结果:通过,0 warning / 0 error
  • dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureContextTests|FullyQualifiedName~ArchitectureModulesBehaviorTests|FullyQualifiedName~CommandExecutorTests|FullyQualifiedName~QueryExecutorTests|FullyQualifiedName~AsyncQueryExecutorTests|FullyQualifiedName~LegacyAsyncCommandDispatchRequestHandlerTests"
    • 结果:通过,54/54 passed
    • 备注:覆盖 legacy 同步 bridge 的同步上下文隔离、bridge fixture 容器释放,以及 async void command cancellation 可见性
  • env GIT_DIR=... GIT_WORK_TREE=... python3 scripts/license-header.py --check
    • 结果:通过

下一推荐步骤

  1. 既然 RP-117 已把 notification publisher 的采用路径收口成显式策略矩阵,下一轮若继续留在 notification 线,优先评估是否需要补第三种仓库内置策略或更贴近示例代码的采用文档,而不是再重复翻写同一套边界说明
  2. 当前 benchmark 仍证明 TaskWhenAllNotificationPublisher 的价值主要在并行完成与异常聚合语义,而不是吞吐收益;若 notification 文档已经足够,下一轮再回到 request dispatch 常量开销时,应先避开“类型级 IContextAware 判定缓存”这条已验证无收益的热点假设
  3. 若 benchmark 对照需要继续贴近 Mediator 官方设计,再评估 Mediator 的 compile-time lifetime / stream 对照矩阵,或给 stream 引入 scoped host 基线,而不是回头重试已被 benchmark 否决的 GetAll(Type) 零行为探测方案

活跃文档

说明

  • PR #261PR #302PR #305PR #307 及更早阶段的详细过程已不再作为 active 恢复入口;如需追溯,以对应归档文件或历史 trace 段落为准
  • active tracking 仅保留当前恢复点、当前风险、最近权威验证与下一推荐步骤,避免 boot 落到历史阶段细节