Skip to content

Feat/cqrs optimization#345

Merged
GeWuYou merged 9 commits into
mainfrom
feat/cqrs-optimization
May 9, 2026
Merged

Feat/cqrs optimization#345
GeWuYou merged 9 commits into
mainfrom
feat/cqrs-optimization

Conversation

@GeWuYou
Copy link
Copy Markdown
Owner

@GeWuYou GeWuYou commented May 9, 2026

Summary by CodeRabbit

发布说明

  • 新功能

    • 新增多Agent批处理入口,支持主Agent作为调度/审查者协调并行子Agent并跟踪进度与决策。
  • 文档

    • 补充并细化多Agent协同使用场景、边界与调用示例。
    • 更新 AI‑Plan 治理与迁移追踪文档及说明。
  • 测试 / 基准

    • 扩展流处理与派发缓存的测试覆盖与基准对照(含不同流观测模式),验证强类型绑定与缓存复用。

GeWuYou added 8 commits May 9, 2026 12:42
- 优化 CqrsDispatcher 的 CreateStream 热路径,按 dispatcher 实例缓存 stream pipeline behavior 的服务可见性

- 新增 stream presence cache 回归与最小测试桩,锁住同容器共享、跨容器隔离的缓存语义

- 更新 cqrs-rewrite 恢复文档并补充本轮 stream benchmark 验证结果
- 新增 request lifetime benchmark 的 generated registry,提供最小 generated request descriptor。

- 更新 RequestLifetimeBenchmarks 使用 generated-provider 宿主,并保留 Singleton/Transient 生命周期矩阵控制。

- 补充 dispatcher 缓存清理,避免生命周期矩阵之间互相污染 benchmark 结果。
- 拆分 GFramework stream lifetime benchmark 的 reflection、generated 与 MediatR 独立请求和 handler 类型

- 调整 generated stream registry 仅绑定 generated 口径,避免静态 dispatcher 缓存污染对照结果

- 验证 StreamLifetimeBenchmarks 在 Singleton 与 Transient 下均产出完整四方对照结果
- 更新 active tracking 的恢复点、branch diff 与 benchmark 口径。

- 补充 request lifetime 与 stream lifetime 的最新权威验证结果。

- 推进 trace 到 RP-125 与 RP-126,并记录下一推荐步骤。
- 更新 RequestLifetimeBenchmarks 的 generated-provider 宿主说明

- 更新 StreamLifetimeBenchmarks 的 reflection/generated/MediatR 对照口径说明

- 补充 benchmark 工程的最小构建与过滤运行示例
- 新增 gframework-multi-agent-batch skill 及其公开入口说明

- 更新 AGENTS.md 中主 Agent 协调多 worker 的职责与停机约束

- 补充 ai-plan-governance 主题的 public recovery 入口与验证记录
- 优化 generated stream dispatch binding 为按响应类型缓存强类型 invoker 与 pipeline executor,压缩 CreateStream 热路径桥接开销

- 保持 stream 异常契约与行为缓存语义不变,并补齐相关 XML 注释与必要内联说明

- 补充 generated stream binding 与 pipeline executor 复用回归,覆盖 generated invoker 与 stream pipeline 组合场景
- 新增 StreamLifetimeBenchmarks 的 FirstItem 与 DrainAll 观测模式,用于拆分建流瞬时成本与完整枚举成本

- 更新 cqrs-rewrite 恢复文档与 benchmark README,同步 RP-127 的验证结果、branch diff 与下一恢复点
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a0489bba-e98c-419a-badc-e57b1eef10a8

📥 Commits

Reviewing files that changed from the base of the PR and between 9ffe3ba and 6d5d4be.

📒 Files selected for processing (5)
  • AGENTS.md
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/README.md
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
✅ Files skipped from review due to trivial changes (1)
  • GFramework.Cqrs.Benchmarks/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • AGENTS.md
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (6)
!({.agents,ai-libs,third-party-licenses,scripts/license-header.py}/**)**/*.{cs,csproj,xml,yml,yaml,json,ts,js,ps1,sh,py}

📄 CodeRabbit inference engine (AGENTS.md)

Repository-maintained source and configuration files supported by scripts/license-header.py MUST include an Apache-2.0 file header

Files:

  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
ai-plan/**

📄 CodeRabbit inference engine (AGENTS.md)

If a task depends on observations from ai-libs/**, record the referenced path and conclusion in the active plan or trace when the work is multi-step or complex

ai-plan/ is split by intent: ai-plan/public/README.md for startup index, ai-plan/public/<topic>/todos/ for recovery documents, ai-plan/public/<topic>/traces/ for execution traces, ai-plan/public/<topic>/archive/ for archived artifacts, ai-plan/public/archive/<topic>/ for completed topics, and ai-plan/private/ for worktree-private artifacts

Never write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP addresses, proprietary URLs, or other sensitive environment details into any ai-plan/** file

Never record absolute file-system paths in ai-plan/**; use repository-relative paths, branch names, PR numbers, or stable document identifiers

Use ai-plan/public/** only for durable, handoff-safe task state; put temporary notes, local experiments, or worktree-specific recovery data under ai-plan/private/

When a topic is fully complete, move the entire topic directory under ai-plan/public/archive/<topic>/ and remove it from ai-plan/public/README.md in the same change

Files:

  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
ai-plan/public/**

📄 CodeRabbit inference engine (AGENTS.md)

Contributors MUST keep committed ai-plan/public/** content safe to publish in Git history

When a stage inside an active topic is fully complete, move the finished artifacts into that topic's archive/ directory instead of leaving every completed step in the default boot path

Files:

  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
ai-plan/public/*/todos/**

📄 CodeRabbit inference engine (AGENTS.md)

When working from a tracked implementation plan, contributors MUST update the corresponding tracking document under ai-plan/public/<topic>/todos/ in the same change

For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery document under ai-plan/public/<topic>/todos/ before making substantive code changes

Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next recommended resume step so another contributor or subagent can continue the work safely

Files:

  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
ai-plan/public/**/{todos,traces}/**

📄 CodeRabbit inference engine (AGENTS.md)

Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended recovery point

Active tracking and trace files are recovery entrypoints, not append-only changelogs; they MUST stay concise enough for boot to locate the current recovery point quickly

Completing code changes without updating the active tracking document is considered incomplete work

When completed and validated stages accumulate, contributors MUST archive their detailed history out of the active todos/ and traces/ entry files, keeping only current recovery point, active facts, active risks, immediate next step, and archive pointers

When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery document and the trace at each meaningful milestone before pausing or handing work off

If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in the active recovery document or trace before continuing implementation

Files:

  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
ai-plan/public/*/traces/**

📄 CodeRabbit inference engine (AGENTS.md)

Contributors MUST maintain a matching execution trace under ai-plan/public/<topic>/traces/ for complex work, recording the current date, key decisions, validation milestones, and immediate next step

Files:

  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Read `@.ai/environment/tools.ai.yaml` before choosing runtimes or CLI tools, and prefer project-relevant tools listed there instead of assuming every installed system tool is fair game
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: When working in WSL against a Windows-backed worktree, prefer Linux `git` with explicit `--git-dir` and `--work-tree` bindings over `git.exe` to avoid WSL path translation mistakes
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Every completed task MUST pass at least one build validation before it is considered done
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: When inspecting build warnings, establish a baseline from a non-incremental repository-root build by running `dotnet clean` and then `dotnet build`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: For Release builds on multi-project changes, prefer solution-level or affected-project `dotnet build ... -c Release`; otherwise use the smallest build command that proves compilation
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: When a task adds a feature or modifies code, contributors MUST run a Release build for every directly affected module/project and resolve all build warnings in the same change
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Commit messages MUST use Conventional Commits format: `<type>(<scope>): <summary>`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: The commit `summary` MUST use simplified Chinese and briefly describe the main change
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Commit `body` MUST use unordered list items, with each item starting with a verb such as `新增`、`修复`、`优化`、`更新`、`补充`、`重构`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Commit `type` MUST reflect release semantics: use `feat` for user-facing capability additions (minor version bump), `fix`/`perf`/`refactor` for patch bumps, `deps`/`security` for patch bumps, and `docs`/`test`/`chore`/`build`/`ci`/`style` for non-release categories
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Use `BREAKING CHANGE` in the commit footer or `!` after the type/scope header when the change should raise the next released version's major segment
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Keep technical terms in English when they are established project terms, such as `API`、`Model`、`System`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: When composing a multi-line commit body from shell commands, do NOT rely on Bash `$"..."` quoting for newline escapes; use multiple `-m` flags or ANSI-C `$'...'` quoting
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: If a new task starts while the current branch is `main`, first try to update local `main` from the remote, then create and switch to a dedicated branch before making substantive changes
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Branch naming rule for a new task branch is `<type>/<topic-or-scope>`, where `<type>` should match the intended Conventional Commit category
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Before committing changes that add or modify supported source/configuration files, run `python3 scripts/license-header.py --check` and resolve any missing or misplaced headers
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Prefer invoking `$gframework-boot` when the user uses short startup prompts such as `boot`、`continue`、`next step`、`按 boot 开始`、`先看 AGENTS`、`继续当前任务`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: The repository-maintained boot skill lives at `.agents/skills/gframework-boot/` and the multi-agent coordination skill lives at `.agents/skills/gframework-multi-agent-batch/`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: The boot skill MUST read `AGENTS.md`、`.ai/environment/tools.ai.yaml`、`ai-plan/public/README.md` and the relevant active-topic `ai-plan/` artifacts before substantive execution
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Use subagents only when the task is complex, context is likely to grow too large, or work can be split into independent parallel subtasks
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Use `explorer` subagents for read-only discovery, comparison, tracing, and narrow codebase questions
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Use `worker` subagents only for bounded implementation tasks with explicit file or module ownership boundary
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Every delegation to subagents MUST specify: the concrete objective, expected output format, owned files or subsystem, and constraints about tests, diagnostics, or compatibility
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Subagents are not allowed to revert or overwrite unrelated changes from the user or other agents; they must adapt to concurrent work instead
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Prefer lightweight models such as `gpt-5.1-codex-mini` for narrow exploration, indexing, and comparison tasks
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Prefer stronger models such as `gpt-5.4` for cross-module design work, non-trivial refactors, and tasks requiring higher confidence reasoning
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Public API changes must be covered by unit or integration tests
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Treat source code, `*.csproj`, tests, generated snapshots, and packaging metadata as the primary evidence for documentation updates
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Adding a new top-level module directory without a `README.md` is considered incomplete work
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Governance-only material such as XML audit snapshots, documentation remediation baselines, backlog status, and recovery metadata belongs in `ai-plan/**` or contributor-only artifacts, not in public docs
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: When implementation plans, traces, reviews, or design notes say 'reference a third-party project', prefer the repository-local path under `ai-libs/` instead of an unspecified upstream repository
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: If an existing documentation page no longer reflects the current implementation, fixing the code without fixing the documentation is considered incomplete work
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Use `cd docs && bun install && bun run dev` to preview documentation changes locally
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T09:31:33.190Z
Learning: Before considering work complete, confirm: required comments and XML docs are present, code follows repository style and naming rules, relevant tests were added or updated, sensitive or unsafe behavior was not introduced, user-facing documentation is updated when needed, and feature adoption docs under `docs/zh-CN/` were added or updated when functionality was added, removed, or refactored
🔇 Additional comments (1)
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md (1)

10-27: 过往评论问题已全部修复

本轮变更已解决先前 review 中指出的三个问题:

  1. ✅ PR 锚点已从 PR Feat/cqrs optimization #344 更新为当前活跃的 `PR `#345(Line 12)
  2. ✅ Branch diff 数字已统一为 21 files (1344 insertions / 194 deletions)(Lines 25 和 81 保持一致)
  3. ✅ Stream lifetime 数据已对齐为 FirstItem / DrainAll 双观测维度格式(Lines 22-23 和 92-93)

文档现已符合 coding guidelines 中关于恢复文档的所有要求:记录了当前阶段、活跃恢复点标识符、已知风险和下一推荐恢复步骤。


📝 Walkthrough

Walkthrough

新增 gframework-multi-agent-batch 技能与多 Agent 协作治理文档(README/AGENTS.md/ai-plan-governance),并将 CqrsDispatcher 的流分发重构为泛型强类型绑定与管道执行器,配套更新基准、生成器注册表与缓存验证测试。

Changes

多Agent协调治理

Layer / File(s) Summary
技能入口与 README
.agents/skills/README.md
在公开入口列表中添加 gframework-multi-agent-batch 并新增调用示例与推荐用法。
gframework-multi-agent-batch SKILL 文档
.agents/skills/gframework-multi-agent-batch/SKILL.md
新增 SKILL 文档,定义用途、启动步骤、worker 设计规则、主 Agent 协调循环、停止条件与 ai-plan 更新要求。
Boot/Batch 指南
.agents/skills/gframework-boot/SKILL.md, .agents/skills/gframework-batch-boot/SKILL.md
在 boot/batch skill 文档中补充何时切换到 gframework-multi-agent-batch(主 Agent 需持续协调/审查/维护 ai-plan 的场景)。
Agent 接口
.agents/skills/gframework-multi-agent-batch/agents/openai.yaml
定义 OpenAI 接口配置,包含显示名、简短描述与默认 prompt,指导主 Agent 维护 ai-plan 并协调 bounded parallel subagents。
AGENTS.md: 多Agent规则
AGENTS.md
更新技能路径并新增“Multi-Agent Coordination Rules”,定义主 Agent 职责、worker 启动/运行/验收约束与停止规则。
ai-plan 治理追踪
ai-plan/public/ai-plan-governance/*, ai-plan/public/cqrs-rewrite/*
新增 ai-plan-governance active topic 与跟踪/追踪文档,记录恢复点、验证里程碑、风险与下一步计划;更新 cqrs-rewrite 跟踪以关联基准/缓存阶段。

CQRS 流类型安全与基准测试

Layer / File(s) Summary
生成器基准注册表
GFramework.Cqrs.Benchmarks/Messaging/*.cs
新增 GeneratedRequestLifetimeBenchmarkRegistry 并更新 GeneratedStreamLifetimeBenchmarkRegistry 使用 GeneratedBenchmark* 类型映射与静态 Invoke 路径。
流类型合约与委托
GFramework.Cqrs/Internal/CqrsDispatcher.cs
引入泛型流委托类型(StreamInvoker<TResponse>StreamPipelineInvoker<TResponse> 等)并新增 _streamBehaviorPresenceCache 缓存行为注册存在性。
流分发绑定与适配
GFramework.Cqrs/Internal/CqrsDispatcher.cs
实现 CreateStreamDispatchBinding<TResponse>GetStreamDispatchBinding<TResponse>StreamDispatchBindingBoxStreamDispatchBinding<TResponse>;新增 GeneratedStreamInvokerAdapter<TResponse> 将弱类型 invoker 适配为强类型。
流管道执行器
GFramework.Cqrs/Internal/CqrsDispatcher.cs
将流管道执行器专门化为 StreamPipelineExecutor<TResponse>,并更新 StreamPipelineInvocation 存储强类型 StreamInvoker<TResponse>;移除热路径的 object -> IAsyncEnumerable cast。
流分发主路径
GFramework.Cqrs/Internal/CqrsDispatcher.cs
CreateStream 中使用 GetStreamDispatchBinding<TResponse> 解析绑定:当无行为注册时短路至直接 invoker,存在行为时解析行为并通过类型化管道执行器执行;新增 HasStreamBehaviorRegistration 使用实例缓存避免重复容器查询。
流基准测试
GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
引入 StreamObservationFirstItem/DrainAll),为 reflection/generated/MediatR 创建独立容器/类型;新增 ObserveAsyncConsumeFirstItemAsyncDrainAsync 与共享 EnumerateAsync<TResponse>,并拆分请求/响应/处理器类型。
请求基准与容器管理
GFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs
GlobalSetup/GlobalCleanup 中清理 dispatcher 缓存并在构建容器时注册生成器请求基准注册表,补充注册说明。
缓存验证测试
GFramework.Cqrs.Tests/Cqrs/*
新增/扩展测试以验证流行为存在性缓存、生成器流绑定与管道执行器的缓存复用;增加反射辅助工具以读取内部缓存并断言状态。
测试支持类型
GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.cs, DispatcherZeroPipelineStreamHandler.cs
新增零管道请求与处理器以覆盖“无流管道行为注册”场景并验证缓存/分发路径。
基准文档
GFramework.Cqrs.Benchmarks/README.md
更新文档,说明新的对比口径、FirstItem/DrainAll 观测维度、运行命令示例与优先复核方向。

预估代码审查工作量

🎯 4 (Complex) | ⏱️ ~45分钟

可能相关的 PR

  • GeWuYou/GFramework#307:与本 PR 在 CQRS 流调用器、生成器提供器与分发器绑定的变更有直接代码交集。
  • GeWuYou/GFramework#341:同一子系统(CqrsDispatcher 流/发送路径、生成器注册表、基准/测试)上的相关更改。
  • GeWuYou/GFramework#326:与基准注册表与基准对照/运行相关的变更有代码级关联。
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive PR标题「Feat/cqrs optimization」过于宽泛且缺乏具体性,无法清晰传达主要变更内容。变更涉及多个方面:AI规划治理入口、多Agent协调框架、CQRS流式派遣优化和基准测试增强,但标题仅用generic词汇「optimization」难以体现核心变更。 建议将标题改为更具体的表述,如「Refactor stream dispatch with strong-typed bindings and add multi-agent batch skill」或「Add multi-agent orchestration skill and optimize CQRS stream dispatch」,以清晰反映主要变更点。
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cqrs-optimization

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2343    ↑2 2343    ↑2 0 0 0 0 34.3s    ↓3.5s

Test Results

passed 2343 passed ↑2

Details

tests 2343 tests ↑2
clock 34.3s ↓3.5s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1100
pull-request Feat/cqrs optimization link #345

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2245 0 3 4.8s

Fail Rate

Fail Rate 0.00%
Test 📝 Results 📊 Passed ✅ Failed ❌ Fail Rate (%) 📈
CreateStream_Should_Throw_When_Stream_Pipeline_Behavior_Context_Does_Not_Implement_IArchitectureContext 12 11 1 8.33    ↓0.76
PublishAsync_Should_Stop_After_First_Handler_Exception_When_Using_Default_Publisher 30 29 1 3.33    ↓0.12
PublishAsync_Should_Throw_When_Context_Does_Not_Implement_IArchitectureContext 34 33 1 2.94    ↓0.09

build-and-test: Run #1100

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2343 2343 0 0 0 0 0 34.3s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 30 4.2s 4.8s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 45 1.4s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 45 2.2s 2.3s
Generates_Scene_Behavior_Boilerplate 45 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 45 1.1s 1.1s
Append_ShouldNotBlock 45 1.0s 1.0s
Context_Caching_Should_Improve_Performance 45 782ms 794ms
PendingCount_ShouldReflectQueuedEntries 45 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 45 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 45 401ms 402ms

± Comparison with run #1099 at 0141e3d | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 45 runs.

Github Test Reporter by CTRF 💚

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 9, 2026

Greptile Summary

This PR removes object-boxing from the CQRS stream dispatch hot path by making StreamDispatchBinding, StreamPipelineInvoker, StreamInvoker, and related types generic over TResponse. A StreamDispatchBindingBox pattern bridges the strongly-typed bindings to the weakly-keyed process-level cache, and a new per-instance _streamBehaviorPresenceCache avoids redundant HasRegistration calls for zero-pipeline streams.

  • CqrsDispatcher.cs: Generified stream binding chain eliminates all (IAsyncEnumerable<TResponse>) casts from the stream hot path; adds instance-level behavior presence cache mirroring the existing request-path cache.
  • Tests: New stream behavior presence caching test and generated stream binding reuse test, plus DispatcherZeroPipelineStreamHandler/DispatcherZeroPipelineStreamRequest stubs.
  • Benchmarks: StreamLifetimeBenchmarks splits into reflection, generated, and MediatR paths with a new StreamObservation (FirstItem / DrainAll) parameter; GeneratedRequestLifetimeBenchmarkRegistry extends the request lifetime matrix to the generated-invoker path.

Confidence Score: 4/5

Safe to merge after resolving the CS1998 warning in the new test handler.

The stream dispatch generification is logically sound and well-tested. The one concrete defect is in DispatcherZeroPipelineStreamHandler.Handle: declared async with yield return but no await expression, emitting a CS1998 build warning. AGENTS.md requires build warnings to be resolved in the same change, and the codebase consistently patches this pattern with await Task.CompletedTask.

GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs — async iterator without await needs the Task.CompletedTask fix.

Important Files Changed

Filename Overview
GFramework.Cqrs/Internal/CqrsDispatcher.cs Core stream dispatch path fully generified: replaces weakly-typed StreamDispatchBinding with StreamDispatchBinding, adds StreamDispatchBindingBox for unified cache storage, adds per-instance _streamBehaviorPresenceCache to avoid redundant container HasRegistration calls on the zero-pipeline path.
GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs New test handler for zero-pipeline stream cache path; async IAsyncEnumerable Handle() has no await expression, which will produce a CS1998 build warning.
GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs Adds stream behavior presence caching test and stream dispatch binding inspection helpers; AssertSharedStreamDispatcherCacheState has a symmetry gap for twoPipelineBehaviorType assertions.
GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs Adds generated stream binding and executor reuse test with correct identity assertions across two dispatches.
GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs Splits into Reflection/Generated/MediatR paths, adds StreamObservation param, extracts shared EnumerateAsync; two containers managed independently with correct cleanup.
GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.cs New hand-written generated registry for request lifetime benchmarks; correctly implements all required CQRS registry interfaces.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    CS["CqrsDispatcher.CreateStream<TResponse>(request)"]
    GSD["GetStreamDispatchBinding<TResponse>(requestType)"]
    WTC["WeakTypePairCache<StreamDispatchBindingBox>\n(process-level)"]
    HIT{"Cache hit?"}
    CREATE["CreateStreamDispatchBindingBox<TResponse>()"]
    GEN{"Generated invoker available?"}
    ADAPT["GeneratedStreamInvokerAdapter<TResponse>\nwraps WeakStreamInvoker"]
    REFLECT["CreateStreamInvoker<TResponse>\n(reflection, once per type)"]
    BOX["StreamDispatchBindingBox<TResponse>.Get<TResponse>()"]
    BINDING["StreamDispatchBinding<TResponse>\n(handler + invoker + pipeline executor cache)"]
    BPC["HasStreamBehaviorRegistration\n_streamBehaviorPresenceCache (per-dispatcher)"]
    ZERO{"Behaviors registered?"}
    DIRECT["Direct handler call"]
    PIPE["GetPipelineExecutor(count)\nStreamPipelineExecutor<TResponse>"]
    CS --> GSD --> WTC --> HIT
    HIT -- miss --> CREATE
    HIT -- hit --> BOX
    CREATE --> GEN
    GEN -- yes --> ADAPT --> BOX
    GEN -- no --> REFLECT --> BOX
    BOX --> BINDING --> BPC --> ZERO
    ZERO -- false --> DIRECT
    ZERO -- true --> PIPE
Loading

Comments Outside Diff (1)

  1. GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs, line 22-34 (link)

    P1 async iterator without await → CS1998 build warning

    Handle is declared async IAsyncEnumerable<int> but contains no await expression. The C# compiler emits CS1998 ("Async method lacks 'await' operators and will run synchronously") for this case, even for async iterators. The benchmarks in StreamLifetimeBenchmarks address the identical pattern by appending await Task.CompletedTask.ConfigureAwait(false) inside the loop; the same fix is needed here. Per AGENTS.md, build warnings in touched modules must be resolved in the same change.

    Context Used: AGENTS.md (source)

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs
    Line: 22-34
    
    Comment:
    **`async` iterator without `await` → CS1998 build warning**
    
    `Handle` is declared `async IAsyncEnumerable<int>` but contains no `await` expression. The C# compiler emits CS1998 ("Async method lacks 'await' operators and will run synchronously") for this case, even for async iterators. The benchmarks in `StreamLifetimeBenchmarks` address the identical pattern by appending `await Task.CompletedTask.ConfigureAwait(false)` inside the loop; the same fix is needed here. Per AGENTS.md, build warnings in touched modules must be resolved in the same change.
    
    **Context Used:** AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0cd0e33d-2941-4978-a8b6-a9a798ff17fd))
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs:22-34
**`async` iterator without `await` → CS1998 build warning**

`Handle` is declared `async IAsyncEnumerable<int>` but contains no `await` expression. The C# compiler emits CS1998 ("Async method lacks 'await' operators and will run synchronously") for this case, even for async iterators. The benchmarks in `StreamLifetimeBenchmarks` address the identical pattern by appending `await Task.CompletedTask.ConfigureAwait(false)` inside the loop; the same fix is needed here. Per AGENTS.md, build warnings in touched modules must be resolved in the same change.

### Issue 2 of 3
GFramework.Cqrs/Internal/CqrsDispatcher.cs:497-502
The `StreamInvoker<TResponse>` lambda is an unnecessary wrapper allocation. `adapter.Invoke` is already a method group with the exact signature matching `StreamInvoker<TResponse>`, so it can be assigned directly. Since the binding creation path is cached, the cost is amortized, but the lambda form allocates an extra closure object around the adapter on every first-use of a type pair.

```suggestion
            // generated stream descriptor 的公开契约仍以 object 返回值暴露异步流;
            // 这里在 binding 创建时只做一次适配,把后续 CreateStream 热路径保持为强类型调用。
            var adapter = new GeneratedStreamInvokerAdapter<TResponse>(weakInvoker);
            return new StreamInvokerDescriptor<TResponse>(descriptor.HandlerType, adapter.Invoke);
```

### Issue 3 of 3
GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs:846-874
**`AssertSharedStreamDispatcherCacheState` does not assert `twoPipelineBehaviorType` on `secondDispatcher` / `isolatedDispatcher`**

The helper verifies `zeroPipelineBehaviorType` on both shared and isolated dispatchers, but `twoPipelinePresence` is only checked as a bare value equality against `expectedTwoPipelinePresence` — it is never verified that `secondDispatcher` and `isolatedDispatcher` reflect the correct state for `twoPipelineBehaviorType`. The symmetry with the `zeroPipelineBehaviorType` assertions is missing, so a regression where the two-pipeline cache entry leaks across dispatcher instances could go undetected.

Reviews (2): Last reviewed commit: "docs(cqrs): 收口PR345评审反馈" | Re-trigger Greptile

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
⚠️ CSHARP dotnet-format yes 1 no 4.59s
✅ REPOSITORY gitleaks yes no no 8.51s
✅ REPOSITORY trufflehog yes no no 7.17s

Detailed Issues

⚠️ CSHARP / dotnet-format - 1 error
Welcome to .NET 9.0!
---------------------
SDK Version: 9.0.114

----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https

----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
Unhandled exception: System.Exception: Restore operation failed.
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
   at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
   at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)

See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
AGENTS.md (1)

138-170: ⚡ Quick win

建议明确"budget"相关术语的含义。

新增的多智能体协调规则结构清晰、职责明确,为并行工作提供了完善的治理框架。然而,文中多次使用了 "branch-diff budget"(第 154 行)、"reviewability budget"(第 154 行)、"context-budget posture"(第 158 行)和 "context-budget signal"(第 167 行)等术语,但在 AGENTS.md 中未见这些概念的定义。

如果这些术语在 $gframework-multi-agent-batch 技能文档中有详细说明,建议在此处添加交叉引用;否则建议在本文档中简要说明这些预算限制的含义,以便新贡献者理解何时应停止派生 worker。

💡 建议的补充说明示例

可以在第 138 行"Multi-Agent Coordination Rules"标题后添加简短说明:

 ### Multi-Agent Coordination Rules
+
+- **Branch-diff budget**: the maximum acceptable number of changed lines or files before the batch becomes difficult to review.
+- **Context-budget**: the main agent's remaining context window capacity for tracking active workers and integrating results.
+- **Reviewability budget**: the cumulative complexity threshold beyond which accepting more parallel changes would compromise review quality.

或者添加到技能文档的引用:

 - When a complex task uses multiple workers, the main agent SHOULD prefer the public workflow documented by
-  `$gframework-multi-agent-batch` unless a more task-specific skill already provides stricter rules.
+  `$gframework-multi-agent-batch` (which defines branch-diff, context-budget, and reviewability constraints) unless
+  a more task-specific skill already provides stricter rules.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AGENTS.md` around lines 138 - 170, The document uses undefined budget terms
(branch-diff budget, reviewability budget, context-budget posture/signal) inside
the "Multi-Agent Coordination Rules"; add a short glossary paragraph immediately
after the "Multi-Agent Coordination Rules" header that (1) defines each term in
one sentence (what it measures and its threshold intent), (2) states how they
affect worker-launch decisions, and (3) if detailed definitions exist in the
$gframework-multi-agent-batch skill, add a one-line cross-reference to that
skill (include the exact symbol $gframework-multi-agent-batch) so readers can
follow for full rules; update any nearby bullets to use the clarified terms if
wording becomes ambiguous.
GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs (3)

316-326: 💤 Low value

GetAsyncEnumerator() 未传入 CancellationToken

ConsumeFirstItemAsync 直接调用 responses.GetAsyncEnumerator(),没有显式把取消令牌穿过来。当前 baseline / MediatR / GFramework 路径在 benchmark 中都使用 CancellationToken.None,所以行为上不会有差异;但若后续把这个 helper 复用到带真实取消语义的场景,就会丢失 [EnumeratorCancellation] 的传播路径。建议显式接受并向下传递取消令牌,使 helper 自身保持取消可见性。

♻️ 建议修改
-    private static async ValueTask ConsumeFirstItemAsync<TResponse>(IAsyncEnumerable<TResponse> responses)
+    private static async ValueTask ConsumeFirstItemAsync<TResponse>(
+        IAsyncEnumerable<TResponse> responses,
+        CancellationToken cancellationToken = default)
     {
-        var enumerator = responses.GetAsyncEnumerator();
+        var enumerator = responses.GetAsyncEnumerator(cancellationToken);
         await using (enumerator.ConfigureAwait(false))
         {
             if (await enumerator.MoveNextAsync().ConfigureAwait(false))
             {
                 _ = enumerator.Current;
             }
         }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs` around
lines 316 - 326, ConsumeFirstItemAsync currently calls
responses.GetAsyncEnumerator() without a CancellationToken, losing cancellation
propagation; update the method signature of ConsumeFirstItemAsync<TResponse> to
accept a CancellationToken (e.g., cancellationToken) and pass it into
responses.GetAsyncEnumerator(cancellationToken). Ensure all internal awaits
still use ConfigureAwait(false) and that callers supply CancellationToken.None
where appropriate so the helper preserves enumerator cancellation semantics.

459-471: 💤 Low value

[EnumeratorCancellation] 可以改为短名引用

EnumerateAsync 的特性参数仍写成 [System.Runtime.CompilerServices.EnumeratorCancellation],而文件顶部并未把 System.Runtime.CompilerServices 列入 using,与本仓库要求"using 集中在文件顶部并保持一致"的风格不太一致。建议在顶部加入 using System.Runtime.CompilerServices; 后改为 [EnumeratorCancellation],避免方法签名出现一段长的内联命名空间。

♻️ 建议修改
 using BenchmarkDotNet.Order;
 using System;
 using System.Collections.Generic;
+using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Threading.Tasks;
     private static async IAsyncEnumerable<TResponse> EnumerateAsync<TResponse>(
         Guid id,
         int itemCount,
         Func<Guid, TResponse> responseFactory,
-        [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken)
+        [EnumeratorCancellation] CancellationToken cancellationToken)

As per coding guidelines: "Keep using directives at the top of the file and sort them consistently".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs` around
lines 459 - 471, The attribute on the EnumerateAsync method currently uses the
fully-qualified System.Runtime.CompilerServices.EnumeratorCancellation; add a
top-of-file using System.Runtime.CompilerServices; and change the method
parameter attribute to [EnumeratorCancellation] so the signature no longer
contains the long inline namespace; update any using ordering to match the
repository's sorted/top-of-file style.

26-30: 💤 Low value

类级 <remarks> 未提及新增的 Observation 维度

类摘要已经改为"对比 stream 在不同 handler 生命周期与观测方式下的额外开销",但 <remarks> 仍只解释 Scoped 维度的边界,没有说明本轮新增的 FirstItem / DrainAll 观测维度的取舍(为什么不再只 drain、为什么不引入 IgnoreFirstItem 之外的更多模式等)。建议在同一个 <remarks> 段补一行解释观测维度边界,避免后续维护者在阅读这个 benchmark 时只知道"有 enum"但不知道为何选这两种。

As per coding guidelines: "XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs` around
lines 26 - 30, Update the class-level XML <remarks> in StreamLifetimeBenchmarks
to explicitly document the new Observation dimension: mention the Observation
enum and the chosen modes (FirstItem and DrainAll), explain what each mode
measures (e.g., first-item latency vs. full-drain throughput/overhead), and
state why other observation patterns were omitted (to keep scope focused on
minimal per-item vs. full-stream cost and to avoid conflating additional
measurement strategies with lifecycle comparisons); reference the Observation
enum and the StreamLifetimeBenchmarks class so future readers understand the
intent, constraints, and usage of these two observation modes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Line 12: Update the recovery document (cqrs-rewrite-migration-tracking.md) so
the PR anchor reflects the actual active PR: change the current mention of "PR
`#344`" to "PR `#345`" (feat/cqrs-optimization) and ensure the RP-127 recovery point
is clearly tied to PR `#345`; additionally, verify the document includes the
required recovery metadata per guidelines: current phase, active recovery point
identifier, known risks, and the next recommended resume step so another
contributor or subagent can continue safely.
- Line 22: The document reports conflicting branch-diff totals: line 22 states
"21 files (1231 insertions / 181 deletions)" while line 78 states "10 files (556
insertions / 75 deletions)"; re-check the diff counts against the same baseline
commit id d85828c5 (origin/main) and update the "当前结论" and/or "当前活跃事实" entries
so they present the same reconciled totals (files, insertions, deletions)
derived from a single git diff run; ensure the baseline commit id d85828c5
remains referenced and that both the summary at line 22 and the detail at line
78 are consistent.
- Line 88: Update the outdated single-dimension stream lifetime statement (the
line starting "当前 stream lifetime benchmark 已补齐 ...") to the RP-127 validated
dual-dimension format (FirstItem / DrainAll) used in the "当前结论" block; replace
the old singleton/transient single values with the four-number matrix that
matches the authoritative validation entries found in the recent results (see
the validated numbers recorded around lines 162-164) so the "当前活跃事实" mirrors the
RP-127 FirstItem/DrainAll results exactly.

In `@GFramework.Cqrs.Benchmarks/README.md`:
- Line 64: Remove the governance recovery ID "RP-127" from the README and
replace the RP-127-dependent phrasing with a neutral, consumer-facing
observation: state the measured outcomes for StreamLifetimeBenchmarks (e.g.,
under Singleton generated slightly outperforms reflection for FirstItem and
DrainAll; under Transient reflection slightly outperforms generated for
FirstItem while generated outperforms reflection for DrainAll) and rephrase the
sentence about future work (“若继续沿 RP-127 收口 stream lifetime”) to describe the
capability/impact dimension (e.g., “如果继续优化 stream lifetime…”) rather than
referencing the recovery point; relocate any RP-127 audit or trace details into
the contributor-only ai-plan/public/cqrs-rewrite/** area.

---

Nitpick comments:
In `@AGENTS.md`:
- Around line 138-170: The document uses undefined budget terms (branch-diff
budget, reviewability budget, context-budget posture/signal) inside the
"Multi-Agent Coordination Rules"; add a short glossary paragraph immediately
after the "Multi-Agent Coordination Rules" header that (1) defines each term in
one sentence (what it measures and its threshold intent), (2) states how they
affect worker-launch decisions, and (3) if detailed definitions exist in the
$gframework-multi-agent-batch skill, add a one-line cross-reference to that
skill (include the exact symbol $gframework-multi-agent-batch) so readers can
follow for full rules; update any nearby bullets to use the clarified terms if
wording becomes ambiguous.

In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs`:
- Around line 316-326: ConsumeFirstItemAsync currently calls
responses.GetAsyncEnumerator() without a CancellationToken, losing cancellation
propagation; update the method signature of ConsumeFirstItemAsync<TResponse> to
accept a CancellationToken (e.g., cancellationToken) and pass it into
responses.GetAsyncEnumerator(cancellationToken). Ensure all internal awaits
still use ConfigureAwait(false) and that callers supply CancellationToken.None
where appropriate so the helper preserves enumerator cancellation semantics.
- Around line 459-471: The attribute on the EnumerateAsync method currently uses
the fully-qualified System.Runtime.CompilerServices.EnumeratorCancellation; add
a top-of-file using System.Runtime.CompilerServices; and change the method
parameter attribute to [EnumeratorCancellation] so the signature no longer
contains the long inline namespace; update any using ordering to match the
repository's sorted/top-of-file style.
- Around line 26-30: Update the class-level XML <remarks> in
StreamLifetimeBenchmarks to explicitly document the new Observation dimension:
mention the Observation enum and the chosen modes (FirstItem and DrainAll),
explain what each mode measures (e.g., first-item latency vs. full-drain
throughput/overhead), and state why other observation patterns were omitted (to
keep scope focused on minimal per-item vs. full-stream cost and to avoid
conflating additional measurement strategies with lifecycle comparisons);
reference the Observation enum and the StreamLifetimeBenchmarks class so future
readers understand the intent, constraints, and usage of these two observation
modes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 96c038a0-1be3-4309-bc5e-69b077c1467a

📥 Commits

Reviewing files that changed from the base of the PR and between d85828c and 9ffe3ba.

📒 Files selected for processing (21)
  • .agents/skills/README.md
  • .agents/skills/gframework-batch-boot/SKILL.md
  • .agents/skills/gframework-boot/SKILL.md
  • .agents/skills/gframework-multi-agent-batch/SKILL.md
  • .agents/skills/gframework-multi-agent-batch/agents/openai.yaml
  • AGENTS.md
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/README.md
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs
  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • ai-plan/public/README.md
  • 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/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (8)
**/README.md

📄 CodeRabbit inference engine (AGENTS.md)

Use the canonical filename README.md for module documentation; do not introduce new ReadMe.md or other filename variants

A module README MUST describe the module's purpose, the relationship to adjacent runtime, abstractions, or generator packages, the major subdirectories or subsystems the reader is expected to use, the minimum adoption path, and the corresponding docs/zh-CN/ entry points

If a module's responsibilities, setup, public API surface, generator inputs, or adoption path change, update that module's README.md in the same change

Files:

  • ai-plan/public/README.md
  • GFramework.Cqrs.Benchmarks/README.md
ai-plan/**

📄 CodeRabbit inference engine (AGENTS.md)

When implementation plans, traces, reviews, or design notes reference a third-party project, prefer the repository-local path under ai-libs/ instead of an unspecified upstream repository

If a task depends on observations from ai-libs/**, record the referenced path and conclusion in the active plan or trace when the work is multi-step or complex, or when an active tracking document already exists

Never write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP addresses, proprietary URLs, or other sensitive environment details into any ai-plan/** file

Never record absolute file-system paths in ai-plan/**; use repository-relative paths, branch names, PR numbers, or stable document identifiers instead

Files:

  • ai-plan/public/README.md
  • ai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md
ai-plan/public/**

📄 CodeRabbit inference engine (AGENTS.md)

Contributors MUST keep committed ai-plan/public/** content safe to publish in Git history

Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended recovery point

When a stage inside an active topic is fully complete, move the finished artifacts into that topic's archive/ directory instead of leaving every completed step in the default boot path

When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery document and the trace at each meaningful milestone before pausing or handing work off

If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in the active recovery document or trace before continuing implementation

Files:

  • ai-plan/public/README.md
  • ai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md
ai-plan/public/README.md

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/public/README.md MUST list only active topics; do not add ai-plan/public/archive/** content to the default boot index

When a worktree-to-topic mapping changes, or when a topic becomes active/inactive, contributors MUST update ai-plan/public/README.md in the same change

When a topic is fully complete, move the entire topic directory under ai-plan/public/archive/<topic>/ and remove it from ai-plan/public/README.md in the same change

Files:

  • ai-plan/public/README.md
**/Cqrs/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

Use CQRS (Command Query Responsibility Segregation) pattern with the Cqrs naming entry point instead of the historical Mediator alias

Files:

  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.cs
  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic

All public, protected, and internal types and members MUST include XML documentation comments (///) with <summary>, <param>, <returns>, <exception>, and <remarks> where applicable

XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax

Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds or compatibility constraints, and registration order or lifecycle sequencing

Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives

Generated logic and generator pipelines MUST explain what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior

Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling

Do not rely on implicit imports; declare every required using explicitly

Write null-safe code that respects nullable annotations instead of suppressing warnings by default

Use the namespace pattern GFramework.{Module}.{Feature} with PascalCase segments

Follow standard C# naming: types, methods, properties, events, and constants use PascalCase; interfaces use I prefix; parameters and locals use camelCase; private fields use _camelCase

Framework runtime, abstractions, and meta-package projects MUST NOT reference *.SourceGenerators* projects...

Files:

  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs
ai-plan/public/*/traces/**

📄 CodeRabbit inference engine (AGENTS.md)

Contributors MUST maintain a matching execution trace under ai-plan/public/<topic>/traces/ for complex work, recording the current date, key decisions, validation milestones, and the immediate next step

Files:

  • ai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
ai-plan/public/*/todos/**

📄 CodeRabbit inference engine (AGENTS.md)

When working from a tracked implementation plan, contributors MUST update the corresponding tracking document under ai-plan/public/<topic>/todos/ in the same change

Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next recommended resume step so another contributor or subagent can continue the work safely

Files:

  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Read `@.ai/environment/tools.ai.yaml` before choosing runtimes or CLI tools; prefer project-relevant tools listed there instead of assuming every installed system tool is fair game
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: In WSL environments against Windows-backed worktrees, prefer Linux `git` with explicit `--git-dir=<repo>/.git/worktrees/<worktree-name>` and `--work-tree=<worktree-root>` binding for every repository command
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Every completed task MUST pass at least one build validation before it is considered done
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: When inspecting or reducing warnings during project build, establish the warning baseline from a non-incremental repository-root build by running `dotnet clean` and then `dotnet build`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Commit messages MUST use Conventional Commits format: `<type>(<scope>): <summary>` with commit summary in simplified Chinese
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Commit body MUST use unordered list items with each item starting with a verb such as `新增`、`修复`、`优化`、`更新`、`补充`、`重构`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `feat` only for user-facing or consumer-facing capability additions; use `fix` for behavior corrections; use `perf` for observable performance improvements; use `refactor` only for non-feature code restructuring; use `deps` for dependency updates; use `security` for vulnerability fixes; use `docs`、`test`、`chore`、`build`、`ci`、`style` for their literal categories
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Documentation-only changes MUST NOT use `feat`, including new guides, refreshed examples, navigation updates, and adoption notes for existing capabilities
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: New task branches should follow naming rule `<type>/<topic-or-scope>`, where `<type>` should match the intended Conventional Commit category
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Repository-maintained source and configuration files that are supported by `scripts/license-header.py` MUST include an Apache-2.0 file header before the task is considered complete
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Before committing changes that add or modify supported source/configuration files, run `python3 scripts/license-header.py --check` and resolve any missing or misplaced headers
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: For files with shebang lines, keep the shebang as the first line and place the license header immediately after it
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Do not add project license headers to excluded or third-party areas such as `.agents/**`, `ai-libs/**`, `third-party-licenses/**`, generated snapshots, binary assets, lock files, and generated build output
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Prefer invoking `$gframework-boot` when the user uses short startup prompts such as `boot`、`continue`、`next step`、`按 boot 开始`、`先看 AGENTS`、`继续当前任务`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Prefer invoking `$gframework-multi-agent-batch` when the user explicitly wants the main agent to delegate bounded parallel work, track subagent progress, maintain `ai-plan`, verify subagent output, and keep coordinating until reaching a natural stop boundary
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use subagents only when the task is complex, the context is likely to grow too large, or the work can be split into independent parallel subtasks
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `explorer` subagents for read-only discovery, comparison, tracing, and narrow codebase questions
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `worker` subagents only for bounded implementation tasks with an explicit file or module ownership boundary
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Keep abstractions projects free of implementation details and engine-specific dependencies
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Preserve existing module boundaries; do not introduce new cross-module dependencies without clear architectural need
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use 4 spaces for indentation; do not use tabs
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Separate logical blocks with blank lines when it improves readability
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Keep line length readable, with around 120 characters as the preferred upper bound
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Public API changes must be covered by unit or integration tests
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Mirror the source structure in test projects whenever practical
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Every user-facing package or module directory that contains a `*.csproj` intended for direct consumption MUST have a sibling `README.md`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Adding a new top-level module directory without a `README.md` is considered incomplete work
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Governance-only material such as XML audit snapshots, documentation remediation baselines, backlog status, and recovery metadata belongs in `ai-plan/**` or other contributor-only artifacts, not in public docs
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: If a docs category appears in VitePress navigation or sidebar, it MUST have a real landing page or be removed from navigation in the same change
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: `ai-plan/` is split by intent: `ai-plan/public/README.md` for shared startup index, `ai-plan/public/<topic>/todos/` for repository-safe recovery documents, `ai-plan/public/<topic>/traces/` for repository-safe execution traces, `ai-plan/public/<topic>/archive/` for archived stage-level artifacts, `ai-plan/public/archive/<topic>/` for completed-topic archives, and `ai-plan/private/` for worktree-private recovery artifacts
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `ai-plan/public/**` only for durable, handoff-safe task state; put temporary notes, local experiments, or worktree-specific scratch recovery data under `ai-plan/private/`
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery document under `ai-plan/public/<topic>/todos/` before making substantive code changes
Learnt from: CR
Repo: GeWuYou/GFramework

Timestamp: 2026-05-09T08:23:08.382Z
Learning: Before considering work complete, confirm required comments and XML docs are present, code follows repository style and naming rules, relevant tests were added or updated, sensitive or unsafe behavior was not introduced, user-facing documentation is updated when needed, and feature adoption docs under `docs/zh-CN/` were added or updated when functionality was added, removed, or refactored
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs
🪛 LanguageTool
.agents/skills/gframework-multi-agent-batch/SKILL.md

[style] ~22-~22: Consider removing “of” to be more concise
Context: ...Use When Adopt this workflow only when all of the following are true: 1. The task is com...

(ALL_OF_THE)

ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md

[uncategorized] ~13-~13: 您的意思是“"不"齐”?
Context: ...E-RP-002 - 当前阶段:Phase 2- 当前焦点: - 已补齐ai-plan/public/README.md` 的 active-to...

(BU)

🔇 Additional comments (18)
ai-plan/public/README.md (1)

24-27: 变更方向正确,入口映射与 active topic 保持一致。

ai-plan-governance 的公开入口、追踪文件链接和 feat/cqrs-optimization 的优先级映射一致,符合当前恢复路径设计。

Also applies to: 47-50

ai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.md (1)

3-43: 追踪文档信息完整,可恢复性良好。

本次 trace 已覆盖日期、决策、校验结果和下一步,满足治理主题的恢复与交接要求。
As per coding guidelines, "ai-plan/public/*/traces/** 必须记录当前日期、关键决策、验证里程碑与下一步。"

.agents/skills/gframework-boot/SKILL.md (1)

12-13: 切换策略补充到位,规则边界清晰。

在 boot 语境下补充“何时切到 multi-agent-batch”很实用,且与委派策略段落一致。
Based on learnings, “Prefer invoking $gframework-multi-agent-batch when the user explicitly wants the main agent to delegate bounded parallel work...”.

Also applies to: 50-51

.agents/skills/gframework-batch-boot/SKILL.md (1)

14-16: 入口分流说明清晰,避免了 batch 与 orchestration 场景混用。

这里把“重复性批处理”与“主 Agent 持续编排多 worker”边界讲清楚了,方向正确。
Based on learnings, “Use subagents only when the task is complex... or the work can be split into independent parallel subtasks.”

Also applies to: 33-33

.agents/skills/gframework-multi-agent-batch/SKILL.md (1)

22-31: 新技能规范完整,职责边界与停止条件定义到位。

这份技能文档已经具备实际执行所需的关键约束,尤其是主 Agent 责任和 worker 边界定义。
Based on learnings, “Prefer invoking $gframework-multi-agent-batch when the user explicitly wants the main agent to delegate bounded parallel work...”

Also applies to: 53-68, 87-98

.agents/skills/README.md (1)

3-3: 公开入口文档更新准确,新增技能可发现性良好。

入口总览、适用场景和示例三部分对齐,阅读者可以直接判断何时使用该技能。

Also applies to: 69-91

.agents/skills/gframework-multi-agent-batch/agents/openai.yaml (1)

1-4: 接口配置与技能职责对齐,定义清晰。

default_prompt 对主 Agent 责任的约束表达明确,符合该技能定位。

ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md (1)

10-23: tracking 文档满足恢复要求,信息闭环完整。

恢复点、风险、验证和下一步都已覆盖,能够支撑后续无缝续作。
As per coding guidelines, "ai-plan/public/*/todos/** 必须记录当前阶段、active recovery point、已知风险和下一推荐恢复步骤。"

Also applies to: 45-67

AGENTS.md (2)

105-106: 路径更新合理且一致。

将技能路径从 .codex/skills/ 迁移到 .agents/skills/ 符合仓库维护的技能管理策略,两个技能路径更新保持了一致性。


109-111: 描述清晰,与下文协调规则对齐良好。

更新后的描述明确了 $gframework-multi-agent-batch 的使用场景和主要职责,与新增的"Multi-Agent Coordination Rules"章节形成良好的呼应。"natural stop boundary"这一术语在下文第 167 行的停止条件中有所体现。

GFramework.Cqrs/Internal/CqrsDispatcher.cs (2)

29-31: stream 零管道判定缓存补得很到位。

CreateStream(...) 的 behavior presence 判定下沉为 dispatcher 实例级缓存后,零管道 steady-state 不再重复打容器查询,而且和 request 路径保持了同一优化模型。

Also applies to: 194-214, 216-229


400-454: 强类型 stream binding / executor 链路拆分得很干净。

这里把 binding、invoker、pipeline executor 全部收口到 TResponse 维度后,缓存命中路径不再退化成 object 桥接;同时 generated provider 的适配也被限制在 binding 创建阶段,热路径更清晰。

Also applies to: 462-510, 579-1098, 1233-1313

GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs (1)

198-245: 这组回归把 stream 缓存边界锁得很扎实。

既覆盖了 dispatcher 实例级 presence cache 的隔离语义,也把新的 typed stream binding / pipeline executor 读取路径一起纳入了断言,和 runtime 改动是对齐的。

Also applies to: 765-790, 808-822, 849-910, 960-984

GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs (1)

225-266: generated stream 缓存复用回归补得很好。

这里不仅验证了结果不变,还把 binding 和 pipeline executor 的复用都显式锁住了,能很好地兜住这次 typed stream dispatch 重构。

Also applies to: 1005-1062

GFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs (1)

88-100: benchmark 变量控制做得很清楚。

先固定 generated descriptor 宿主,再单独覆盖 handler 生命周期,并在 setup/cleanup 两端清 cache,这样量到的更接近“生命周期差异”本身,而不是历史缓存或注册路径噪音。

Also applies to: 118-125, 160-163

GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs (1)

26-42: generated lane 的类型隔离保持得不错。

descriptor、匹配条件和静态调用桥都一起切到 GeneratedBenchmark* 类型后,stream lifetime benchmark 的 generated / reflection 两条路径不会再共用同一组请求响应合同。

Also applies to: 81-108

GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.cs (1)

1-112: LGTM!

GeneratedRequestLifetimeBenchmarkRegistry 作为 hand-written generated registry,接口实现完整、XML 文档齐全;Register(...) 仅做参数校验与诊断日志、不在此处注入 handler 生命周期,配合 benchmark 主体显式覆盖 Singleton/Transient 注册的设计意图清晰;InvokeBenchmarkRequestHandler 与 descriptor 元数据维护一致,不引入隐性副作用。

GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs (1)

32-209: LGTM —— 四方口径与双观测维度组织清晰

StreamLifetimeBenchmarks 把 reflection / generated 两条 GFramework 路径分别给独立容器与 runtime,再叠加 Observation 维度统一交给 ObserveAsync 消费,避免了原来"建流 + 完整枚举"被混在一起的对照口径;Setup / Cleanup 中显式调用 BenchmarkDispatcherCacheHelper.ClearDispatcherCaches()、按生命周期分别注册 reflection 与 generated handler 的拆分也是合理的实现。

Comment thread ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md Outdated
Comment thread ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md Outdated
Comment thread ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md Outdated
Comment thread GFramework.Cqrs.Benchmarks/README.md Outdated
- 更新 AGENTS 多智能体预算术语说明,明确 worker 波次停止边界

- 修复 StreamLifetimeBenchmarks 的取消传播、观测维度注释与枚举器特性写法

- 调整 benchmark README 与 CQRS ai-plan 恢复文档,移除过期 PR 锚点和旧 diff 统计
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2343 2343 0 0 0 0 36.7s    ↑2.4s

Test Results

passed 2343 passed

Details

tests 2343 tests
clock 36.7s ↑2.4s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1101
pull-request Feat/cqrs optimization link #345

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2247 0 3 4.8s

Fail Rate

Fail Rate 0.00%
Test 📝 Results 📊 Passed ✅ Failed ❌ Fail Rate (%) 📈
CreateStream_Should_Throw_When_Stream_Pipeline_Behavior_Context_Does_Not_Implement_IArchitectureContext 13 12 1 7.69    ↓0.64
PublishAsync_Should_Stop_After_First_Handler_Exception_When_Using_Default_Publisher 31 30 1 3.23    ↓0.10
PublishAsync_Should_Throw_When_Context_Does_Not_Implement_IArchitectureContext 35 34 1 2.86    ↓0.08

build-and-test: Run #1101

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2343 2343 0 0 0 0 0 36.7s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 31 4.2s 4.8s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 46 1.4s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 46 2.2s 2.3s
Generates_Scene_Behavior_Boilerplate 46 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 46 1.1s 1.1s
Append_ShouldNotBlock 46 1.0s 1.0s
Context_Caching_Should_Improve_Performance 46 782ms 794ms
PendingCount_ShouldReflectQueuedEntries 46 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 46 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 46 401ms 402ms

± Comparison with run #1100 at 1b93205 | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 46 runs.

Github Test Reporter by CTRF 💚

@GeWuYou
Copy link
Copy Markdown
Owner Author

GeWuYou commented May 9, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@GeWuYou GeWuYou merged commit 699d0b4 into main May 9, 2026
7 checks passed
@GeWuYou GeWuYou deleted the feat/cqrs-optimization branch May 9, 2026 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant