GFramework/ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
gewuyou e3532fc2c8 feat(cqrs-benchmarks): 补齐request生命周期的Mediator对照
- 新增 RequestLifetimeBenchmarks 的 Mediator lifetime parity,并按编译期常量分支生成 Singleton、Scoped、Transient 宿主

- 更新 benchmark README 的 request lifetime coverage 与当前缺口说明,使其反映最新对照矩阵

- 修复 RequestBenchmarks 与 NotificationBenchmarks 的 XML 文档漂移,并同步 ai-plan 恢复点与验证结论
2026-05-12 15:44:54 +08:00

376 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
Copyright (c) 2025-2026 GeWuYou
SPDX-License-Identifier: Apache-2.0
-->
# CQRS 重写迁移追踪
## 2026-05-12
### 阶段request lifetime 的 Mediator parity 与文档漂移收口CQRS-REWRITE-RP-140
- 继续按 `$gframework-batch-boot 50` 推进,基线保持为 `origin/main @ 2b2bec65 (2026-05-12 11:49:39 +0800)`
- 本轮启动时重新测得当前已提交 branch diff 仍为 `14 files / 324 lines`,远低于 `50 files` 阈值;停止与否继续由 context-budget / reviewability 主导。
- 主线程结合两个 explorer 子代理的只读盘点后,接受以下结论:
- 不再继续按 benchmark XML `<returns>` inventory 机械扩批;粗糙脚本会把“注释位于 `[Benchmark]` 之前”的现有文档误判为缺口
- `RequestLifetimeBenchmarks` 的 NuGet `Mediator` lifetime parity 是当前仍然真实、且能保持 reviewable 的实现候选
- `NotificationBenchmarks.cs``RequestBenchmarks.cs` 仍有两处低风险 XML 文档漂移,均只涉及 NuGet `Mediator` 事实同步
- 本轮主线程实施:
- `RequestLifetimeBenchmarks.cs`
- 新增 `GeneratedMediator` 宿主字段、`SendRequest_Mediator()` benchmark 方法与 scoped `Mediator` request helper
-`BenchmarkRequest` / `BenchmarkRequestHandler` 扩为同时实现 `Mediator` 契约
-`Mediator` 宿主改用 `Singleton / Scoped / Transient` 三个编译期常量分支,规避 `MSG0007` 对运行时 lifetime 赋值的生成器限制
- `RequestBenchmarks.cs`
- 将 handler XML 文档说明补齐为同时实现 `GFramework.CQRS`、NuGet `Mediator``MediatR`
- `NotificationBenchmarks.cs`
- 将类说明与 handler XML 文档说明补齐为同时覆盖 `GFramework.CQRS`、NuGet `Mediator``MediatR`
- `GFramework.Cqrs.Benchmarks/README.md`
-`RequestLifetimeBenchmarks` 的 coverage 更新为包含 NuGet `Mediator` source-generated concrete path
- 删除“当前没有 request 生命周期下的 NuGet `Mediator` compile-time lifetime 矩阵”这一已过时缺口
- 验证里程碑:
- 第一次 `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
- 结果:失败
- 原因:`RequestLifetimeBenchmarks.cs` 中基于运行时变量写入 `MediatorOptions.ServiceLifetime`,触发 `MSG0007`
- 主线程修正:
-`CreateMediatorServiceProvider(HandlerLifetime lifetime)` 收口为 3 个常量分支工厂:
`CreateSingletonMediatorServiceProvider()``CreateScopedMediatorServiceProvider()``CreateTransientMediatorServiceProvider()`
- 第二次 `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
- 结果:通过,`0 warning / 0 error`
- 当前 stop decision
- 不继续开启新的实现波次
- 原因不是 branch-size 阈值耗尽;当前分支仍只有 `14 files`
- 停止原因是本轮已经完成一条真实 parity 收口和两处文档漂移修正,继续扩到 `StreamLifetimeBenchmarks` 会显著提高作用域与 review 成本
- 当前下一步:
- 主线程补跑 `python3 scripts/license-header.py --check --paths ...``git diff --check`
- 更新 active tracking / trace 后提交当前 benchmark 代码、README 与 `ai-plan`
### 阶段README startup coverage 精度同步并停在自然边界CQRS-REWRITE-RP-139
- 继续按 `$gframework-batch-boot 50` 推进,基线保持为 `origin/main @ 2b2bec65 (2026-05-12 11:49:39 +0800)`
- 本轮启动时重新测得当前已提交 branch diff 为 `14 files`,仍远低于 `50 files` 阈值;继续与否的主停止信号仍是
context-budget / reviewability。
- 本轮主线程先做只读盘点与抽样核对:
- README 一致性 explorer 结论成立:`GFramework.Cqrs.Benchmarks/README.md` 对 startup coverage / 边界的表述仍可更精确
- benchmark XML 缺口 explorer 结论未直接接受;主线程抽样检查 `NotificationBenchmarks.cs`
`RequestBenchmarks.cs``StreamingBenchmarks.cs``NotificationStartupBenchmarks.cs` 后确认,
其 class / benchmark 方法的 `<summary>``<returns>` 实际已存在不能继续按“14 个门面文件普遍缺 XML”
的假设扩批
- 因此本轮 accepted delegated scope 缩成单文件 docs-only worker
- `GFramework.Cqrs.Benchmarks/README.md`
-`StreamStartupBenchmarks` 明确写成 `MediatR``GFramework.Cqrs` reflection、
`GFramework.Cqrs` generated、NuGet `Mediator` 四组 initialization / cold-start 对照
- 补充 `RequestStartupBenchmarks``NotificationStartupBenchmarks``GFramework.Cqrs` startup 路径是
“单 handler 最小宿主 + 手工注册”模型不外推到程序集扫描、完整注册协调器、fan-out 或发布策略变体
- worker 回传验收结论:
- 改动文件未越出 ownership 边界
- README diff 与代码事实一致,且未引入无法从当前 benchmark 实现验证的表述
- 当前 stop decision
- 不继续开启新的 XML 文档波次
- 原因不是 branch-size 阈值耗尽;当前分支仍只有 `14 files`
- 停止原因是候选清晰度下降:继续追逐 explorer 误报会降低 reviewability并无谓增加当前上下文负担
- 当前下一步:
- 主线程更新 `ai-plan/public/cqrs-rewrite/**`
- 串行运行 benchmark 工程 build、license-header 与 `git diff --check`
- 提交 README 与 `ai-plan` 收尾
### 阶段benchmark XML 契约第 2 波收口CQRS-REWRITE-RP-138
- 延续 `$gframework-batch-boot 50`,基线保持为 `origin/main @ 2b2bec65 (2026-05-12 11:49:39 +0800)`
- 第 2 波启动前,当前分支相对基线的已提交 branch diff 为 `5 files / 177 lines`,明显低于 `50 files` 阈值;本轮继续与否的主停止信号仍是 context-budget / reviewability。
- 主线程本地盘点 `GFramework.Cqrs.Benchmarks/Messaging/*.cs` 的公开 `[Benchmark]` 方法后,确认当前仍有一批与既有收口模式一致的 XML `<returns>` 缺口:
- `StreamingBenchmarks.Stream_GFrameworkCqrs()`
- `NotificationBenchmarks` 的 3 个公开 benchmark 方法
- `NotificationFanOutBenchmarks` 的 5 个公开 benchmark 方法
- `StreamInvokerBenchmarks` 的 4 个公开 benchmark 方法
- `StreamLifetimeBenchmarks` 的 4 个公开 benchmark 方法
- 本波 accepted ownership
- 主线程
- `GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs`
- `GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs`
- `ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`
- `ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md`
- worker
- `StreamLifetimeBenchmarks.cs`
- `StreamInvokerBenchmarks.cs`
- `NotificationFanOutBenchmarks.cs`
- worker 回传验收结论:
- `StreamLifetimeBenchmarks.cs`
- 只补 `Stream_Baseline``Stream_GFrameworkReflection``Stream_GFrameworkGenerated``Stream_MediatR``<returns>`
- worker 自报 `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release` 通过
- `StreamInvokerBenchmarks.cs`
- 只补 4 个公开 benchmark 方法的 `<returns>`
- worker 自报同一条 benchmark 工程 build 通过
- `NotificationFanOutBenchmarks.cs`
- 只补 5 个公开 benchmark 方法的 `<returns>`
- worker 自报 build 遇到 `CS2012``obj/Release/net10.0/GFramework.Cqrs.Benchmarks.dll` 被并发进程占用;该失败被判定为并发构建噪音,而不是代码语义问题
- 主线程局部实施:
- `StreamingBenchmarks.cs`
-`Stream_GFrameworkCqrs()``<returns>`
- `NotificationBenchmarks.cs`
-`PublishNotification_GFrameworkCqrs()``PublishNotification_MediatR()``PublishNotification_Mediator()``<returns>`
- 当前下一步:
- 主线程串行执行 benchmark 工程 Release build消除 worker 并发写 `obj/Release` 带来的验证噪音
- 若串行验证通过,决定是在当前自然停点提交收尾,还是继续 request 侧 XML 契约的下一波低风险批处理
### 阶段request benchmark XML 契约第 3 波收口后停在自然边界CQRS-REWRITE-RP-138
- 第 2 波串行验证通过后,继续用 3 个 worker 扩展 request 系 benchmark 的同类 `<returns>` 收口:
- `RequestStartupBenchmarks.cs`
- `RequestBenchmarks.cs` + `RequestPipelineBenchmarks.cs`
- `RequestInvokerBenchmarks.cs` + `RequestLifetimeBenchmarks.cs`
- worker 回传与 acceptance
- `RequestStartupBenchmarks.cs`
- 只补公开 benchmark 方法缺失的 `<returns>`
- worker 自报 `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release` 通过
- `RequestBenchmarks.cs` + `RequestPipelineBenchmarks.cs`
- 只补公开 benchmark 方法缺失的 `<returns>`
- worker 自报 build 通过,并已提交:`555c7c07 docs(cqrs-benchmarks): 补齐 request benchmark 返回值文档`
- `RequestInvokerBenchmarks.cs` + `RequestLifetimeBenchmarks.cs`
- 只补公开 benchmark 方法缺失的 `<returns>`
- worker 自报 build 通过,并已提交:`ab422b05 docs(cqrs-benchmarks): 补齐 request benchmark 返回值注释`
- 第 3 波后主线程 stop decision
- 不再开启第 4 波 XML 契约批处理
- 原因不是 branch-size 阈值耗尽;当前分支相对 `origin/main` 仍只有 `9 files / 143 lines`
- 停止原因是 context-budget / reviewability剩余候选已不比当前波次更低风险继续机械扩批收益下降
- 当前下一步:
- 只做主线程未提交面的串行验证与收尾提交
- 将干净工作树作为下一次 `boot` 的默认恢复目标
### 阶段stream startup parity 与文档收尾CQRS-REWRITE-RP-137
-`$gframework-batch-boot 50` 恢复后,先重新执行 `$gframework-pr-review`
- 当前 GitHub 事实:
- `PR #349` 已关闭并合并到 `origin/main`
- 基线切换为 `origin/main @ 2b2bec65 (2026-05-12 11:49:39 +0800)`
- 当前分支相对新基线的已提交 diff 初始为 `0 files / 0 lines`
- latest-head open thread 本地复核:
- stale
- `StreamPipelineBenchmarks.Stream_Baseline``<returns>` 已存在
- `CqrsNotificationPublisherTests` 的 fallback 缓存安全网已收口
- trace 的当前 PR / 下一步已同步到 `PR #349`
- valid
- `StreamingBenchmarks.Stream_MediatR()` 仍缺 `<returns>` XML 文档
- 第 1 波 accepted delegated scope
- `StreamingBenchmarks.cs`
- worker 补 `Stream_Baseline()``Stream_MediatR()``<returns>` XML 契约
- 主线程验收时确认其中 `Stream_Baseline()` 属于额外收口,不是 latest-head 必修项
- `StreamStartupBenchmarks.cs`
- worker 在单文件 ownership 内补 `GeneratedMediator` 宿主字段、setup/cleanup、`Initialization_Mediator()``ColdStart_Mediator()`
- 同文件把 `BenchmarkStreamRequest` / `BenchmarkStreamHandler` 扩成同时支持 `Mediator` stream 合同
- worker 自主完成并提交:`f346110a feat(cqrs-benchmarks): 补齐 stream startup 的 Mediator 对照路径`
- `GFramework.Cqrs.Benchmarks/README.md`
- worker 只收口 `StreamStartupBenchmarks` coverage 与当前 gap 描述,不假设 `StreamLifetimeBenchmarks` 已补 parity
- 主线程验收结论:
- `StreamLifetimeBenchmarks``Mediator` parity 被判定为 hard slice需要 `BenchmarkHostFactory` 与 compile-time lifetime 配套,不再继续作为本 turn 的低风险并行切片
- 当前自然停点应落在:
- 已提交的 `StreamStartupBenchmarks` parity
- 未提交但已验收的 `StreamingBenchmarks.cs` / `README.md` 收尾
- `ai-plan` 同步到新基线与新恢复点
- 本轮权威验证里程碑:
- `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
- 结果:通过,`0 warning / 0 error`
- `python3 scripts/license-header.py --check`
- 结果:通过
- `git diff --check`
- 待当前未提交收尾切片与 `ai-plan` 一并提交前再次运行
- 当前下一步:
- 提交 `StreamingBenchmarks.cs``GFramework.Cqrs.Benchmarks/README.md``ai-plan/public/cqrs-rewrite/**` 收尾
- 如需继续 benchmark 波次,优先做 `StreamStartupBenchmarks` 的最小 smoke run而不是直接展开 `StreamLifetimeBenchmarks`
### 阶段PR #349 latest-head review 收口CQRS-REWRITE-RP-136
- 重新执行 `$gframework-pr-review`,按 GitHub 当前分支状态确认 `feat/cqrs-optimization``2026-05-12` 对应的是 `PR #349`,不再沿用 active tracking 中的 `PR #348` 锚点。
- 本轮 latest-head open AI thread 复核结论:
- `StreamPipelineBenchmarks``Stream_Baseline``Stream_GFrameworkCqrs``Stream_MediatR` 缺少 `<returns>` XML 契约,接受修复
- `StreamingBenchmarks.Stream_Mediator` 缺少 `<returns>` XML 契约,接受修复
- `CqrsNotificationPublisherTests` 的 fallback publisher 缓存回归测试用“第二次解析返回另一个 publisher”充当安全网和断言消息表达不一致接受收口为“首次后任何再次解析都直接失败”
- active tracking / trace 的当前 PR 锚点与下一步入口仍停留在 `PR #348`,接受同步到 `PR #349`
- 本轮主线程实施:
- `StreamPipelineBenchmarks`
- 为 3 个公开 benchmark 方法补齐 `<returns>` XML 文档
- `StreamingBenchmarks`
-`Stream_Mediator()` 补齐 `<returns>` XML 文档
- `CqrsNotificationPublisherTests`
- 把 fallback publisher 缓存回归测试改为“首次返回空数组,后续任何再次解析立即抛 `AssertionException`”,避免测试安全网与失败消息自相矛盾
- `ai-plan/public/cqrs-rewrite/**`
- 将 active tracking / trace 的当前 PR 锚点与下一步入口同步到 `PR #349`
- 本轮权威验证:
- `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
- 结果:通过,`0 warning / 0 error`
- `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsNotificationPublisherTests"`
- 结果:通过,`Passed: 9, Failed: 0`
- `python3 scripts/license-header.py --check --paths GFramework.Cqrs.Benchmarks/Messaging/StreamPipelineBenchmarks.cs GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.cs ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md`
- 结果:通过
### 阶段:多波 batch 继续收口CQRS-REWRITE-RP-135
-`$gframework-batch-boot 50` 恢复当前 topic并把基线固定为
`origin/main @ ef4d3d5d (2026-05-11 17:33:43 +0800)`
- 启动时确认当前工作树干净branch diff 为 `0 files / 0 lines`;旧 tracking 中“未提交收尾切片”已不再反映真实仓库状态。
- 第 1 波 accepted delegated scope
- `CqrsRegistrationServiceTests`
- 补空输入不触发 registrar、忽略空项后按稳定程序集键排序并去重、跨调用跳过已注册键时继续处理剩余新程序集
- `CqrsHandlerRegistrarTests` + `CqrsHandlerRegistrarFallbackFailureTests`
- 补 abstract registry 与缺少无参构造器 registry 在程序集级回退路径和 direct activation 入口的告警 / 抛错覆盖
- `StreamPipelineBenchmarks` + `GFramework.Cqrs.Benchmarks/README.md`
- 新增 `0 / 1 / 4` 个 stream pipeline 行为与 `FirstItem / DrainAll` 观测矩阵
- README 补齐 stream pipeline coverage、运行示例与 gap 说明
- 第 2 波 accepted delegated scope
- `CqrsNotificationPublisherTests`
- 补“容器未注册 publisher 时回退到 `SequentialNotificationPublisher`,且首次解析后缓存结果”回归
- `StreamingBenchmarks` + `GFramework.Cqrs.Benchmarks/README.md`
- 补 steady-state stream 的 `Mediator` 对照
- README 将 stream steady-state gap 收口为“lifetime / startup 仍缺 `Mediator` parity”
- 主线程验收与修正:
- 审核 5 个 worker 提交均未越出 ownership 边界
-`StreamPipelineBenchmarks.cs` 修掉 `git diff --check` 报出的 1 处 trailing whitespace
- 更新 active tracking / trace 到当前 branch 事实,避免下次 `boot` 继续落到过期恢复点
- 本轮权威验证:
- `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
- `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsRegistrationServiceTests|FullyQualifiedName~CqrsHandlerRegistrarTests|FullyQualifiedName~CqrsHandlerRegistrarFallbackFailureTests|FullyQualifiedName~CqrsNotificationPublisherTests"`
- `python3 scripts/license-header.py --check --paths ...`
- `git diff --check origin/main...HEAD`
- 当前停点判断:
- 当前 branch diff 约为 `9 files / 1111 lines`
- 明显低于 `50 files` 阈值
- 本轮停止信号来自 `context-budget / reviewability`,不是文件预算耗尽
- 当前下一步:
- 先按需要运行 `$gframework-pr-review`,确认 `PR #349` latest-head open thread 是否已随当前修复提交收敛
- 若继续扩 benchmark优先补 `StreamLifetimeBenchmarks``StreamStartupBenchmarks` 的单文件 `Mediator` parity
- 若切回文档收尾,把 `GFramework.Cqrs/README.md``docs/zh-CN/core/command.md``docs/zh-CN/core/query.md` 单独作为 docs-only 下一波
## 2026-05-11
### 阶段PR #348 latest-head review 再收口CQRS-REWRITE-RP-134
- 重新执行 `$gframework-pr-review` 抓取当前分支 `feat/cqrs-optimization` 对应的 `PR #348`
- 本轮 latest-head open AI thread 复核结论:
- `NotificationLifetimeBenchmarks.HandlerLifetime``[GenerateEnumExtensions]` 仍判定为泛化误报
- 仓库没有“产品/benchmark 枚举默认都启用该特性”的现行约定
- benchmark 项目也未接入 `GFramework.Core.SourceGenerators.Abstractions`,不应为局部对照枚举平白扩大 generator 依赖面
- `NotificationLifetimeBenchmarks``_scopedContainer` 释放缺口与公开 benchmark API 的 XML 契约缺口仍成立,接受修复
- `CqrsHandlerRegistrar` 中 generated descriptor 的“先去重后校验”缺陷仍成立,接受修复并补测试
- `CqrsHandlerRegistrar``MethodInfo` 使用 `ReferenceEquals` 的过严比较仍成立,接受修复
- active tracking / trace 的当前 PR 锚点仍停留在 `PR #347`,接受同步到 `PR #348`
- 本轮主线程实施:
- `NotificationLifetimeBenchmarks`
- `Cleanup()``_scopedContainer` 一并交给 `BenchmarkCleanupHelper.DisposeAll(...)`
- 为公开 benchmark 方法与公开 handler 方法补齐缺失的 `<returns>` / `<param>` XML 契约
- `CqrsHandlerRegistrar`
- request / stream generated descriptor 预热路径改为“先 `TryValidate...`,后写入 `registeredKeys`
- descriptor 对齐判断从 `ReferenceEquals(resolvedDescriptor.InvokerMethod, ...)` 调整为 `resolvedDescriptor.InvokerMethod.Equals(...)`
- `CqrsGeneratedRequestInvokerProviderTests`
- 新增 request / stream 两个回归用例,锁定“首条同键 descriptor 无效、后条有效时,仍应接受后条有效 generated descriptor”
- `ai-plan/public/cqrs-rewrite/**`
- 将 active tracking / trace 的当前 PR 锚点同步到 `PR #348`
### 阶段PR #347 latest-head review 收口CQRS-REWRITE-RP-132
- 使用 `$gframework-pr-review` 重新抓取当前分支 `feat/cqrs-optimization` 对应的 `PR #347`
- 抓取结果显示当前 latest-head 仍有 `CodeRabbit 6``Greptile 2` open thread但本地复核后只接受以下仍成立的结论
- `Program.cs` 只在命令行 `--artifacts-suffix` 下重启隔离宿主,未覆盖环境变量触发的隔离路径
- `Program.cs` 缺少“目标隔离宿主目录位于当前宿主输出目录内”的防守式校验
- `RequestLifetimeBenchmarks` / `StreamLifetimeBenchmarks``Scoped` 路径每次 benchmark 调用都会新建 runtime污染生命周期矩阵公平性
- `ScopedBenchmarkContainer` 的公共/关键成员 XML 契约说明不完整
- active tracking / trace 已经偏离“快速恢复入口”,需要归档瘦身
- 本轮实现选择:
- `Program.cs`
- 把“是否需要重启隔离宿主”统一收敛到 `ArtifactsPath != null`
- 为隔离宿主目录补充“不得等于或嵌套在当前宿主输出目录内”的校验
- `BenchmarkHostFactory.cs`
- scoped request / stream helper 改为复用单个 runtime只在调用边界进入和释放 scope
- `ScopedBenchmarkContainer.cs`
- 从“构造时绑定单次 scope”改为“可重复进入的作用域适配器 + `ScopeLease`
- 补齐只读适配器与作用域租约的 XML 合同说明
- `RequestLifetimeBenchmarks.cs`
- `Scoped` 路径改为 `GlobalSetup` 时创建单个 scoped runtime
- `StreamLifetimeBenchmarks.cs`
- `Scoped` reflection / generated 路径改为 `GlobalSetup` 时各自创建单个 scoped runtime
- 按语义阶段拆分 `Setup()`,同时清掉 `MA0051`
- `README.md`
-`RequestLifetimeBenchmarks` 的 scoped 语义更新为“复用 runtime仅每次创建真实 scope”
- `ai-plan/public/cqrs-rewrite/**`
- 将旧 active tracking / trace 复制归档到
`archive/todos/cqrs-rewrite-migration-tracking-history-through-rp131.md`
`archive/traces/cqrs-rewrite-migration-trace-history-through-rp131.md`
- 重写 active tracking / trace只保留当前恢复点、关键结论、风险与验证
### 本轮验证
- `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 -- --artifacts-suffix pr347-req-scoped --filter "*RequestLifetimeBenchmarks.SendRequest_GFrameworkCqrs*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1`
- 结果:通过
- 备注:独立宿主目录位于 `BenchmarkDotNet.Artifacts/pr347-req-scoped/host/...`
- 结果摘要:`Singleton 52.69 ns / 32 B``Transient 57.88 ns / 56 B``Scoped 144.72 ns / 368 B`
- `dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- --artifacts-suffix pr347-stream-scoped --filter "*StreamLifetimeBenchmarks.Stream_GFramework*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1`
- 结果:通过
- 备注:独立宿主目录位于 `BenchmarkDotNet.Artifacts/pr347-stream-scoped/host/...`
- 结果摘要:
- `Singleton + FirstItem`reflection `108.7 ns / 216 B`generated `110.1 ns / 216 B`
- `Scoped + FirstItem`reflection `266.7 ns / 792 B`generated `267.0 ns / 792 B`
- `Scoped + DrainAll`reflection `331.6 ns / 856 B`generated `332.2 ns / 856 B`
### 当前结论
- `Program.cs` 已不再依赖“命令行后缀”这一单一来源决定宿主隔离,环境变量生效路径也会进入隔离宿主。
- scoped benchmark 的公平性问题已经实质收口runtime 构造成本不再按每次调用重复计入生命周期矩阵。
- active tracking / trace 已恢复到可供 `boot` 和后续 PR review 快速进入的体量;历史细节仍可通过新的 archive 文件追溯。
### 当前下一步
- 推送本轮变更后,重新运行 `$gframework-pr-review`,确认 `PR #347` 的 latest-head open thread 是否已随着新 head 收敛。
### 阶段:多波 batch 收口与 benchmark / docs 扩面CQRS-REWRITE-RP-133
-`$gframework-batch-boot` 启动多波 non-conflicting subagent基线固定为
`origin/main @ 3b2e6899d5ffdcfb634b28f3846f57528fbf9196 (2026-05-11T12:25:00+08:00)`
- 启动前分支累计 diff 为 `0 files / 0 lines`;自然停点时累计 branch diff 约为 `12 files`
- 主线程把 stop decision 明确交给 `reviewability / context-budget`,没有在仍有文件预算时继续机械追到 `50 files`
- 本轮 accepted delegated scope
- runtime / tests
- `CqrsNotificationPublisherTests`:补“多 publisher 报错”与“publisher 缓存复用”回归
- `CqrsGeneratedRequestInvokerProviderTests` + `CqrsHandlerRegistrar`:补 generated descriptor 坏元数据、异常枚举、重复 pair 回退契约
- `CqrsDispatcherCacheTests`:补 request / stream pipeline presence、executor cache 与上下文重新注入组合分支
- `CqrsRegistrationServiceTests`:补稳定程序集键 fallback 到 `AssemblyName.Name` / `ToString()` 的回归
- benchmarks
- `RequestStartupBenchmarks`:补 `Mediator` startup 对照
- `StreamStartupBenchmarks`
- `NotificationStartupBenchmarks`
- `NotificationLifetimeBenchmarks`
- `GFramework.Cqrs.Benchmarks/README.md`:收口当前 coverage / gap / smoke 解释边界
- docs / recovery
- `GFramework.Cqrs/README.md`
- `docs/zh-CN/core/cqrs.md`
- `docs/zh-CN/source-generators/cqrs-handler-registry-generator.md`
- `docs/zh-CN/core/command.md`
- `docs/zh-CN/core/query.md`
- `ai-plan/public/cqrs-rewrite/archive/**` 顶部导航与跳转约定
- 本轮权威验证:
- `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
- `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release`
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release`
- `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsRegistrationServiceTests"`
- `dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- --artifacts-suffix notif-lifetime --filter "*NotificationLifetimeBenchmarks*"`
- 本轮 benchmark 结果摘要:
- `RequestStartupBenchmarks`
- `ColdStart_GFrameworkCqrs 61.648 us / 25336 B`
- `ColdStart_Mediator 110.867 us / 57872 B`
- `ColdStart_MediatR 679.103 us / 606256 B`
- `StreamStartupBenchmarks`
- `ColdStart_GFrameworkReflection 71.13 us / 25504 B`
- `ColdStart_GFrameworkGenerated 82.12 us / 28280 B`
- `ColdStart_MediatR 933.87 us / 678992 B`
- `NotificationStartupBenchmarks`
- `ColdStart_GFrameworkCqrs 85.09 us / 24752 B`
- `ColdStart_Mediator 136.08 us / 62512 B`
- `ColdStart_MediatR 1.379 ms / 719056 B`
- `NotificationLifetimeBenchmarks`
- `Singleton``GFramework 295.48 ns / 360 B``MediatR 77.99 ns / 288 B`
- `Scoped``GFramework 410.92 ns / 640 B``MediatR 213.49 ns / 632 B`
- `Transient``GFramework 311.21 ns / 416 B``MediatR 74.36 ns / 288 B`
- 当前收尾判断:
- branch diff 仍远低于 `50` 文件阈值,但 active 未提交面与 benchmark 运行输出已经足够构成自然 stop boundary
- 下一步不继续扩 batch先提交当前收尾切片并回到干净工作树再按 PR review 结果决定后续波次