iter32 cluster-034: chat route policy 删 request-path projection priming#819
Conversation
…tion priming + 加 committed-state hook 违反 CLAUDE.md "禁止 query-time priming" + "命令骨架内聚":ChatRoutePolicyAdminEndpoints + VoiceDemoBootstrap 在 request path 调 EnsureProjectionForActorAsync 同步 priming。 变更(consensus minimal): - 新 ChatRoutePolicyCommittedStateProjectionActivationPlanProvider(committed-state hook 触发,匹配 ChatRoutePolicyUpdated) - 删 ChatRoutePolicyProjectionPort + EnsureProjectionForActorAsync request-path 调用 - DI 注册 ProjectionActivationPlanDispatcher + CommittedStateProjectionActivationHook + 新 provider - query_projection_priming_guard 加 ChatRoutePolicyAdminEndpoints / VoiceDemoBootstrapEndpoints 扫描 - 新 tests:provider tests / DI registration tests;modify endpoint tests removing port fixture Verification: 17 ChatRouting tests pass, architecture+priming guards green。 LOC: +166/-86 net +80。 Closes #818 ⟦AI:AUTO-LOOP⟧ Co-Authored-By: codex-refactor-loop <noreply@aevatar>
📊 状态卡片 — reviewer 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
📊 状态卡片 — reviewer 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
📊 状态卡片 — reviewer 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
🤖 Quality review approveTL;DR
详细说明这次改动把 chat route policy 的 projection activation 从请求路径移到 committed-state hook。 我打开了所有 touched files 全文检查。endpoint 和 voice bootstrap 的请求路径参数减少,测试里删除了 no-op activation fixture,guard 增量也只扫这两个相关 endpoint。cluster 要求的 📎 完整 codex 原始输出(存档备查)---
pr: 819
role: quality
verdict: approve
---
## Verdict
Approve: the PR is focused on moving chat route policy projection activation out of request paths, with readable naming, no introduced dead code, and clear mandated refactor self-docs.
## Evidence
- `agents/Aevatar.GAgents.ChatRouting/ChatRoutePolicyCommittedStateProjectionActivationPlanProvider.cs:13`: `ChatRoutePolicyCommittedStateProjectionActivationPlanProvider` is long but precise: it names the business scope, trigger boundary, and output responsibility; it also implements an existing multi-implementer abstraction rather than adding a one-off interface.
- `agents/Aevatar.GAgents.ChatRouting/DependencyInjection/ChatRoutingServiceCollectionExtensions.cs:70`: the new dispatcher/hook/provider registrations use existing projection activation plumbing and are covered by the service collection test, so there is no unreachable public surface.
- `src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:194` and `src/Aevatar.Mainnet.Host.Api/Voice/VoiceDemoBootstrapEndpoints.cs:153`: the modified request-path methods got simpler after removing projection priming parameters/calls; no new branchy control flow or oversized method was introduced.
- `test/Aevatar.Hosting.Tests/MainnetChatRoutePolicyAdminEndpointsTests.cs:175`: removing the no-op activation service fixture deletes now-dead test scaffolding and keeps the endpoint tests focused on dispatch/readmodel behavior.
- `tools/ci/query_projection_priming_guard.sh:43`: the added guard scan is scoped to the two affected endpoints and excludes only the required refactor self-doc text, so it is focused rather than a broad unrelated lint expansion.
- Refactor self-doc comments are present on the new provider, DI registration, endpoint removal sites, tests, and guard-related code; the Old/New wording is concrete enough for a non-audit reader.
⟦AI:AUTO-LOOP⟧⟦AI:AUTO-LOOP⟧ |
🤖 tests 评审:拒绝,voice demo bootstrap 缺少行为覆盖TL;DR
详细说明这次变更删除了 另外,cluster 明确引入了“chat route policy endpoint/bootstrap 禁止 request-path projection priming”的 no-regression 规则;虽然 📎 完整 codex 原始输出(存档备查)pr: 819
|
🤖 架构评审:comment-only,主链路合规,需补方法级 Refactor 注释TL;DR
📢 cc 原作者:@eanzhao 请 sanity-check chat-route-policy activation 的 ownership 表达是否符合预期。 详细说明我没有发现新的 CLAUDE/AGENTS 架构违规: 唯一评论项是 review checklist 的注释要求: 📎 完整 codex 原始输出(存档备查)---
pr: 819
role: architect
verdict: comment
---
## Verdict
comment-only - the PR removes request-path projection priming and moves chat-route-policy activation to the committed-state hook path, but several changed endpoint handlers are missing the required per-method Old/New pattern comment.
## Evidence
- `src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:71` and `src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:129` changed the write handler signatures/call path by removing `ChatRoutePolicyProjectionPort`, but neither method has the required review checklist comment: `Old/New pattern comment: each refactored type/method has // Refactor (iterN/cluster-XXX): Old pattern: … New principle: …`. The lower shared `DispatchAsync` helper is commented, so this is documentation compliance only, not a CLAUDE architecture violation.
- `src/Aevatar.Mainnet.Host.Api/Voice/VoiceDemoBootstrapEndpoints.cs:45` changed the bootstrap endpoint signature by removing `ChatRoutePolicyProjectionPort`, but the method itself lacks the same required Old/New pattern comment. `EnsureVoiceRoutePolicyAsync` has the comment at `src/Aevatar.Mainnet.Host.Api/Voice/VoiceDemoBootstrapEndpoints.cs:163`, so this is a narrow comment hygiene issue.
- No blocking CLAUDE/AGENTS regression found: `agents/Aevatar.GAgents.ChatRouting/ChatRoutePolicyCommittedStateProjectionActivationPlanProvider.cs:18` maps only committed `ChatRoutePolicyUpdated` state events to a durable materialization activation plan, satisfying CLAUDE: “持久投影 scope 的激活由 committed-state publication owner hook 触发…命令入口不得同步调用 projection activation facade,也不得新增 actor/lifecycle phase 来‘预热’读模型.”
- No blocking CLAUDE/AGENTS regression found: `src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:194` now builds and dispatches the command envelope without `EnsureProjectionForActorAsync`, aligning with CLAUDE: “命令骨架内聚:标准生命周期 `Normalize -> Resolve Target -> Build Context -> Build Envelope -> Dispatch -> Receipt -> Observe`;业务模块只负责目标解析与载荷/结果映射.”
- No blocking CLAUDE/AGENTS regression found: `agents/Aevatar.GAgents.ChatRouting/ChatRoutePolicyProjectionPort.cs` is deleted and no compat shim replaces it, aligning with CLAUDE: “删除优先:空转发、重复抽象、无业务价值代码直接删除,不保留兼容空壳.”
- Scope honesty is OK: the branch also changes `tools/ci/query_projection_priming_guard.sh:43`, which is outside the prompt's diff glob but inside the cluster's declared `scope_paths` and the implementation summary says no `SCOPE_EXTEND` was needed.
- No proto changes, no new `*WriteActor` / `*ReadActor` / `*Store` split, and no new NyxID / chrono-* external-repo dependency was introduced by the reviewed diff.
## What would change your verdict
Add the required `// Refactor (iter32/cluster-034-chat-route-policy-request-path-projection-activation): Old pattern… New principle…` comment to the changed endpoint methods themselves, or explicitly document that the class/helper-level comment is the accepted local convention for these thin handlers.
REVIEW_DONE:819:architect:comment
⟦AI:AUTO-LOOP⟧⟦AI:AUTO-LOOP⟧ |
📊 状态卡片 — fix 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
🤖 PR 819 round 1 fixes appliedTL;DR
📢 cc 原作者:@eanzhao 请 sanity-check voice bootstrap 的 route-policy upsert 行为断言是否贴合 demo 预期。 详细说明本轮修复集中在 PR 819 的两个 reject/comment 点: 同时新增 验证结果: 📎 完整 codex 原始输出(存档备查)# Fix report for PR 819 round 1
## Applied
- (A) src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:78: added per-method refactor Old/New comment to `HandleUpsertAsync` (addresses reviewer:architect's evidence #1).
- (A) src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:140: added per-method refactor Old/New comment to `HandleRemoveRuleAsync` (addresses reviewer:architect's evidence #1).
- (A) src/Aevatar.Mainnet.Host.Api/Voice/VoiceDemoBootstrapEndpoints.cs:56: added per-method refactor Old/New comment to `HandleBootstrapAsync` (addresses reviewer:architect's evidence #2).
- (B) test/Aevatar.Hosting.Tests/VoiceDemoBootstrapEndpointsTests.cs:35: SCOPE_EXTEND same logical refactor because reviewer:tests rejected missing `/api/demo/voice/bootstrap` behavior coverage; added endpoint behavior test that dispatches the demo init and chat-route-policy upsert, preserves non-`voice-demo` rules, replaces stale `voice-demo`, and does not register/invoke request-path projection activation.
- (A) test/Aevatar.Hosting.Tests/MainnetChatRoutePolicyAdminEndpointsTests.cs:174: added source-regression assertion that strips line comments and verifies `ChatRoutePolicyAdminEndpoints.cs` + `VoiceDemoBootstrapEndpoints.cs` contain no `ChatRoutePolicyProjectionPort` or `EnsureProjectionForActorAsync` in executable request-path source (addresses reviewer:tests evidence #2/#3).
## Rejected as false positive
- None.
## Blocked (cannot fix this round)
- None.
## Build status
- build: pass (`dotnet build aevatar.slnx --nologo 2>&1 | tail -20`)
- tests: pass (`dotnet test test/Aevatar.Hosting.Tests/Aevatar.Hosting.Tests.csproj --nologo --no-build --filter "FullyQualifiedName~MainnetChatRoutePolicyAdminEndpointsTests|FullyQualifiedName~VoiceDemoBootstrapEndpointsTests"`; `dotnet test test/Aevatar.GAgents.ChatRouting.Tests/Aevatar.GAgents.ChatRouting.Tests.csproj --nologo --no-build`)
- guards: pass (`bash tools/ci/query_projection_priming_guard.sh`; `bash tools/ci/test_stability_guards.sh`)
## Recommendation for next round
- expect unanimous
⟦AI:AUTO-LOOP⟧⟦AI:AUTO-LOOP⟧ |
📊 codex 进展 fix-pr819-r1 (⏳ 进行中; 已跑 8 min)
|
…egression assertion ⟦AI:AUTO-LOOP⟧
📊 状态卡片 — reviewer 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
📊 状态卡片 — reviewer 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
📊 状态卡片 — reviewer 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
🤖 Quality review approveTL;DR
详细说明我按三点差异读取了 touched files,并打开了分支上的完整文件上下文。 请求路径里的 📎 完整 codex 原始输出(存档备查)---
pr: 819
role: quality
verdict: approve
---
## Verdict
Approve: the diff is focused, the new names describe the chat-route-policy committed-state activation path, and I found no dead code, unjustified abstraction, or readability regression.
## Evidence
- `agents/Aevatar.GAgents.ChatRouting/ChatRoutePolicyCommittedStateProjectionActivationPlanProvider.cs:13` adds a concrete provider whose long name matches the existing committed-state activation provider pattern and states the business trigger/scope instead of a generic helper/manager role.
- `agents/Aevatar.GAgents.ChatRouting/DependencyInjection/ChatRoutingServiceCollectionExtensions.cs:70` registers the new dispatcher/hook/provider, so the new public surface is reachable from production composition and is not dead code.
- `src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:71` and `src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:132` remove the projection-port parameter from request handlers; the endpoint methods are simpler and keep their existing dispatch-focused structure.
- `src/Aevatar.Mainnet.Host.Api/Voice/VoiceDemoBootstrapEndpoints.cs:45` keeps the pre-existing bootstrap shape and only removes the projection-port dependency from the request path; the method was already near the size threshold, but the PR does not add branches or a new complex flow.
- `test/Aevatar.GAgents.ChatRouting.Tests/ChatRoutePolicyCommittedStateProjectionActivationPlanProviderTests.cs:17` and `test/Aevatar.Hosting.Tests/MainnetChatRoutePolicyAdminEndpointsTests.cs:175` exercise the new provider and the absence of request-path priming, so the added test fixtures have clear reachability and purpose.
- `tools/ci/query_projection_priming_guard.sh:43` extends the existing guard in a narrow way to the two affected endpoint files; no unrelated cleanup or drive-by file changes showed up in the touched-file set.
- Refactor self-doc comments are present with Old/New blocks in the new provider, DI registration, endpoint changes, tests, and guard-facing request paths; they describe the old request-path priming pattern and the new committed-state hook path clearly enough for a non-audit reader.
REVIEW_DONE:819:quality:approve
⟦AI:AUTO-LOOP⟧⟦AI:AUTO-LOOP⟧ |
🤖 tests review approve:测试覆盖足够TL;DR
详细说明我检查了三点:新增测试是否断言业务结果、是否引入 覆盖面满足这次 diff: 验证命令在 PR worktree 通过:ChatRouting focused tests 6 个、Hosting endpoint focused tests 7 个、 📎 完整 codex 原始输出(存档备查)pr: 819
|
🤖 架构评审:comment-only,生产路径合规,scope 记录需补齐TL;DR
详细说明生产代码层面我没有发现新的 CLAUDE/AGENTS 架构违规: 唯一评论项是 scope honesty:PR 新增了 📎 完整 codex 原始输出(存档备查)---
pr: 819
role: architect
verdict: comment
---
## Verdict
comment-only: production architecture moves chat route policy projection activation out of request paths and into the committed-state hook, but the PR has a scope-honesty drift in its internal implement summary.
## Evidence
- `test/Aevatar.Hosting.Tests/VoiceDemoBootstrapEndpointsTests.cs:1` is a new file in the PR, but the declared cluster scope only allowed `test/Aevatar.Hosting.Tests/MainnetChatRoutePolicyAdminEndpointsTests.cs` under `test/Aevatar.Hosting.Tests/`, and `.refactor-loop/runs/implement-cluster-034-chat-route-policy-request-path-projection-activation.md:24-33` says "No scope expansion was needed" / "None." This violates the review checklist item "Scope honesty: diff stays within the cluster's declared `scope_paths` (or has a documented SCOPE_EXTEND in implement summary)." I am treating this as comment-only because the added file is a targeted endpoint regression test, not a CLAUDE/AGENTS architectural regression.
- `agents/Aevatar.GAgents.ChatRouting/ChatRoutePolicyCommittedStateProjectionActivationPlanProvider.cs:13-38` maps committed `ChatRoutePolicyUpdated` publications to `ProjectionRuntimeMode.DurableMaterialization`; `agents/Aevatar.GAgents.ChatRouting/DependencyInjection/ChatRoutingServiceCollectionExtensions.cs:70-76` wires `ProjectionActivationPlanDispatcher`, `CommittedStateProjectionActivationHook`, and the provider. This aligns with CLAUDE.md "committed domain event 必须可观察:write-side 完成 committed event 后必须送入 projection 主链;禁止只落 event store 而不进入可观察流。" and "禁止 query-time replay/priming:`QueryPort/QueryService/ApplicationService` 不得在请求路径读 `IEventStore`、重放 events、临时重建 state mirror;不得在 query 方法内同步补投影或补跑 ES/materialization。刷新须通过正式 projection 会话、后台 materializer 或写侧预挂接 projection 完成。"
- `src/Aevatar.Mainnet.Host.Api/ChatRouting/ChatRoutePolicyAdminEndpoints.cs:71-231` and `src/Aevatar.Mainnet.Host.Api/Voice/VoiceDemoBootstrapEndpoints.cs:45-200` no longer inject `ChatRoutePolicyProjectionPort` or call `EnsureProjectionForActorAsync` before dispatch. This aligns with CLAUDE.md "命令骨架内聚:标准生命周期 `Normalize -> Resolve Target -> Build Context -> Build Envelope -> Dispatch -> Receipt -> Observe`;业务模块只负责目标解析与载荷/结果映射。"
- `agents/Aevatar.GAgents.ChatRouting/ChatRoutePolicyProjectionPort.cs` is deleted, so I did not find a new empty forwarding interface, compat shim, second projection pathway, `.proto` field churn, or new external NyxID/chrono-* dependency.
## What would change your verdict (only if comment or reject)
Document the `test/Aevatar.Hosting.Tests/VoiceDemoBootstrapEndpointsTests.cs` addition as an explicit `SCOPE_EXTEND` in the implement summary, or update the controller's cluster scope record to include this test file. No production architecture change is required from my angle.
REVIEW_DONE:819:architect:comment
⟦AI:AUTO-LOOP⟧⟦AI:AUTO-LOOP⟧ |
📊 codex 进展 review-pr819-architect-r2 (⏳ 进行中; 已跑 11 min)
|
📊 codex 进展 review-pr819-quality-r2 (⏳ 进行中; 已跑 11 min)
|
📊 codex 进展 review-pr819-tests-r2 (⏳ 进行中; 已跑 11 min)
|
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## auto-refact-dev #819 +/- ##
================================================
Coverage 83.07% 83.08%
================================================
Files 982 982
Lines 61782 61782
Branches 8061 8061
================================================
+ Hits 51328 51334 +6
+ Misses 6981 6978 -3
+ Partials 3473 3470 -3
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Summary
iter32 cluster-034 (high)。
ChatRoutePolicyAdminEndpoints+VoiceDemoBootstrapEndpoints在 request path 调EnsureProjectionForActorAsync同步 priming projection。违反 query-time priming forbidden + 命令骨架内聚。ChatRoutePolicyCommittedStateProjectionActivationPlanProvider匹配ChatRoutePolicyUpdated自动 activate;删 request-path port;DI 注册 dispatcher/hook/provider;guard 加 endpoint 扫描。违反 CLAUDE.md:
禁止 query-time replay/priming+命令骨架内聚。Scope
9 files changed (+166/-86 net +80)。17 ChatRouting tests pass,architecture+query_projection_priming guards green。
设计共识:issue #818 r1 consensus minimal
🤖 Auto-loop / codex-refactor-loop iter32
⟦AI:AUTO-LOOP⟧