#377: 删 IProjectionPortSessionLease,使用 typed session context + root_actor_id transport#1479
Conversation
…t + root_actor_id transport(Phase 9 r2 共识) per Phase 9 r2 hybrid-minimal-structural-delete 共识(judge-issue377-r2.md)。 删除 IProjectionPortSessionLease alias 层;projection session event transport 第一维 ScopeId → RootActorId/root_actor_id wire-rename;EventSinkProjectionLifecyclePortBase 直接使用 typed session context;移除 StreamingProxy/NyxID/Workflow/Scripting/GAgentService 的 lease 实现。 closes #377 ⟦AI:AUTO-LOOP⟧
🤖 quality review: reject,需修正 refactor self-doc markerTL;DR
详细说明质量角度唯一阻塞点是 self-doc 格式。评审清单明确要求 refactor self-doc 使用 具体例子:
建议改法:把本轮新增的所有 📎 完整 codex 原始输出(存档备查)---
pr: 1479
role: quality
verdict: reject
---
## Verdict
Reject because the refactor self-doc comments are clear but do not use the mandated `Refactor (iterN/cluster-XXX)` marker format.
## Evidence
- `src/Aevatar.CQRS.Projection.Core/Orchestration/EventSinkProjectionLifecyclePortBase.cs:9` adds `// Refactor (issue-377): ...`; the quality checklist requires `// Refactor (iterN/cluster-XXX):` Old/New blocks, so this major shared lifecycle refactor is not traceable in the mandated cluster format.
- `src/Aevatar.CQRS.Projection.Core/Streaming/ProjectionSessionEventHub.cs:10` repeats the same `Refactor (issue-377)` marker on the session hub rename documentation instead of the mandated cluster marker.
- `agents/Aevatar.GAgents.NyxidChat/NyxIdChatProjectionSession.cs:53` and `src/Aevatar.CQRS.Projection.Core/Orchestration/ProjectionSessionEventProjectorBase.cs:6` show the same pattern across feature and core projection files, so this is systematic rather than a one-line nit.
## What would change your verdict
Replace the newly added `Refactor (issue-377)` comments with the mandated `Refactor (iterN/cluster-XXX):` marker while keeping the current Old pattern / New principle wording, which is otherwise readable.
REVIEW_DONE:1479:quality:reject |
🤖 tests reviewer 结论:approveTL;DR
详细说明我检查了 PR diff、实际测试文件、 关键覆盖点包括: 📎 完整 codex 原始输出(存档备查)---
pr: 1479
role: tests
verdict: approve
---
## Verdict
Test coverage and test quality are adequate for the projection session lease refactor.
## Evidence
- `test/Aevatar.CQRS.Projection.Core.Tests/ProjectionHotspotCoverageTests.cs:17` covers `ProjectionSessionEventHub` input validation, stream keying, transport `RootActorId`, and protobuf payload handling.
- `test/Aevatar.CQRS.Projection.Core.Tests/ProjectionPortBaseCoverageTests.cs:50` covers `AttachLiveSinkAsync` routing through the session hub using `Context.RootActorId` and `Context.SessionId`.
- `test/Aevatar.CQRS.Projection.Core.Tests/ProjectionRuntimeRegistrationTests.cs:291` covers DI registration and attach-existing lease lookup with typed session context instead of the removed lease alias.
- `test/Aevatar.AI.Tests/NyxIdChatProjectionSessionTests.cs:24`, `test/Aevatar.AI.Tests/StreamingProxyCoverageTests.cs`, `test/Aevatar.GAgentService.Tests/Projection/*`, `test/Aevatar.Scripting.Core.Tests/Projection/*`, and `test/Aevatar.Workflow.Host.Api.Tests/WorkflowExecutionProjectionPortTests.cs` assert the affected production ports still attach existing sessions and route hub subscriptions by the root actor/session pair.
- No added `Task.Delay`, `Thread.Sleep`, `WaitUntilAsync`, `[Skip]`, manual category, or bump-only assertions were found in the PR test diff.
- `bash tools/ci/test_stability_guards.sh` passed, including polling wait allowlist enforcement and Python helper tests.
## What would change your verdict (only if comment or reject)
REVIEW_DONE:1479:tests:approve⟦AI:AUTO-LOOP⟧ |
🤖 architect review 通过TL;DR
详细说明我按 架构风险扫描结果:未新增 📎 完整 codex 原始输出(存档备查)---
pr: 1479
role: architect
verdict: approve
---
## Verdict
approve: no CLAUDE/AGENTS architecture regression found; the PR deletes the misleading projection session lease alias and keeps routing on the existing typed session context.
## Evidence
- `src/Aevatar.CQRS.Projection.Core.Abstractions/Abstractions/Ports/IProjectionPortSessionLease.cs` is deleted instead of kept as a compatibility shim, matching CLAUDE.md `删除优先:空转发、重复抽象、无业务价值代码直接删除,不保留兼容空壳。`
- `src/Aevatar.CQRS.Projection.Core/Orchestration/EventSinkProjectionLifecyclePortBase.cs:47` documents the old alias pattern and new typed-context principle; lines 51-58 route live sinks from `Context.RootActorId + Context.SessionId`, matching CLAUDE.md `身份与事实分离:稳定 ID 只负责寻址与复用键;可变绑定必须显式建模、显式读取。`
- `src/Aevatar.CQRS.Projection.Core/Streaming/ProjectionSessionEventHub.cs:38` and `src/Aevatar.CQRS.Projection.Core/Streaming/ProjectionSessionEventHub.cs:67` rename the hub API from `scopeId` to `rootActorId`; lines 52-60 and 81-85 keep one stream-backed route and do not introduce a parallel projection path, matching CLAUDE.md `统一投影链路:CQRS 与 AGUI 走同一套 Projection Pipeline,统一入口、一对多分发,禁止双轨实现。`
- `src/Aevatar.CQRS.Projection.Core/Orchestration/ProjectionSessionEventProjectorBase.cs:35` publishes only `ProjectionSessionEventEntry.RootActorId + SessionId` to the hub, so the projector entry, hub API, and typed session context use the same routing invariant.
- `src/Aevatar.CQRS.Projection.Core/projection_session_event_transport.proto:12` changes field 1 from `scope_id` to `root_actor_id` without renumbering or reusing a removed field number; no proto field was deleted, and existing reserved field 4 remains intact.
- Added-line anti-pattern scan over the PR diff found no `Task.Delay(`, `Thread.Sleep(`, `GetAwaiter().GetResult()`, `TypeUrl.Contains(...)`, JSON serializer for state/committed payloads, raw `HttpClient` constructor, `[Skip]`, `actor.HandleEventAsync(`, or host/application `SubscribeAsync<EventEnvelope>` additions.
- Scope matches the issue-377 consensus plan in `.refactor-loop/runs/judge-issue377-r2.md`: delete `IProjectionPortSessionLease`, remove the lease constraint from registration, move runtime leases to typed contexts, rename session-event routing to `RootActorId/root_actor_id`, and update matching tests. No unplanned external repository dependency or `*WriteActor` / `*ReadActor` / `*StoreActor` split was introduced.
REVIEW_DONE:1479:architect:approve⟦AI:AUTO-LOOP⟧ |
📊 状态卡片 — fix 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
🤖 Phase 8 fix r2 报告 — PR 1479TL;DR:已按 quality r2 reject 要求,只修正 refactor self-doc 注释格式。
FIX_DONE:1479:round-2:applied-73:rejected-0:blocked-0 |
…7/cluster-issue377) per Phase 8 r1 quality reject:73 处 refactor self-doc comment 用了 Refactor (issue-377) 格式,改为强制的 Refactor (iter367/cluster-issue377) 格式。 ⟦AI:AUTO-LOOP⟧
📊 状态卡片 — reviewer 派出
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
🤖 tests reviewer:PR 1479 测试质量通过TL;DR
详细说明我按三点 diff 检查了本 PR 的测试改动和对应生产文件。没有发现新增 覆盖面上, 📎 完整 codex 原始输出(存档备查)---
pr: 1479
role: tests
verdict: approve
---
## Verdict
Test coverage and quality are adequate for this refactor slice.
## Evidence
- `test/Aevatar.CQRS.Projection.Core.Tests/ProjectionPortBaseCoverageTests.cs:50` exercises `AttachLiveSinkAsync` through a runtime lease that carries `IProjectionSessionContext`, then asserts the hub receives `RootActorId` and `SessionId` from that context and forwards the event to the sink.
- `test/Aevatar.CQRS.Projection.Core.Tests/ProjectionHotspotCoverageTests.cs:17` covers the renamed hub API behavior: blank `rootActorId` validation, transport stream key selection, and `ProjectionSessionEventTransportMessage.RootActorId` population.
- `test/Aevatar.CQRS.Projection.Core.Tests/ProjectionHotspotCoverageTests.cs:58` covers subscribe-side filtering on `RootActorId` plus handling of empty and undecodable protobuf payloads without using timing waits.
- `test/Aevatar.CQRS.Projection.Core.Tests/ProjectionRuntimeRegistrationTests.cs:221` and `:271` cover the generic registration path for session-scoped runtime leases without requiring the deleted `IProjectionPortSessionLease` interface.
- `test/Aevatar.AI.Tests/NyxIdChatProjectionSessionTests.cs:24`, `test/Aevatar.GAgentService.Tests/Projection/ScriptServiceAguiProjectionPortTests.cs`, `test/Aevatar.Scripting.Core.Tests/Projection/ScriptEvolutionProjectionPortTests.cs`, and `test/Aevatar.Workflow.Host.Api.Tests/WorkflowExecutionProjectionPortTests.cs` keep behavior assertions on attach/subscribe routing for the touched concrete leases.
- Diff scan of changed tests found no added `Task.Delay`, `Thread.Sleep`, `WaitUntilAsync`, `[Skip]`, manual category, `Assert.True(true)`, or not-throw placeholder assertions; `tools/ci/test_polling_allowlist.txt` is unchanged.
REVIEW_DONE:1479:tests:approve |
🤖 quality review:comment,需统一两处 refactor self-doc 前缀TL;DR
详细说明
唯一需要改的是 refactor self-doc 格式不一致:
建议只做机械替换,不需要改代码逻辑。 📎 完整 codex 原始输出(存档备查)pr: 1479
|
🤖 architect review — PR 1479TL;DR
详细说明架构主线本身是对的: 唯一需要评论的是 self-doc 格式: 📎 完整 codex 原始输出(存档备查)---
pr: 1479
role: architect
verdict: comment
---
## Verdict
comment-only: architecture boundaries are preserved, but two refactored production runtime lease types still use the non-mandated `Refactor (issue-377)` self-doc marker.
## Evidence
- `agents/Aevatar.GAgents.NyxidChat/NyxIdChatProjectionSession.cs:53` adds the required Old/New self-doc, but the marker is `Refactor (issue-377)` instead of the checklist-required `Refactor (iterN/cluster-XXX)`.
- `agents/Aevatar.GAgents.StreamingProxy/StreamingProxyRoomSessionRuntimeLease.cs:6` has the same marker-format issue on the refactored runtime lease.
- `src/Aevatar.CQRS.Projection.Core.Abstractions/Abstractions/Ports/IProjectionPortSessionLease.cs` is deleted instead of kept as a compatibility shim, matching CLAUDE.md `删除优先:空转发、重复抽象、无业务价值代码直接删除,不保留兼容空壳。`
- `src/Aevatar.CQRS.Projection.Core/Orchestration/EventSinkProjectionLifecyclePortBase.cs:47` documents the old alias pattern and new typed-context principle; lines 51-58 route live sinks from `Context.RootActorId + Context.SessionId`, matching CLAUDE.md `身份与事实分离:稳定 ID 只负责寻址与复用键;可变绑定必须显式建模、显式读取。`
- `src/Aevatar.CQRS.Projection.Core/Streaming/ProjectionSessionEventHub.cs:38` and `src/Aevatar.CQRS.Projection.Core/Streaming/ProjectionSessionEventHub.cs:67` rename the hub API from `scopeId` to `rootActorId`; lines 52-60 and 81-85 keep one stream-backed route and do not introduce a parallel projection path, matching CLAUDE.md `统一投影链路:CQRS 与 AGUI 走同一套 Projection Pipeline,统一入口、一对多分发,禁止双轨实现。`
- `src/Aevatar.CQRS.Projection.Core/Orchestration/ProjectionSessionEventProjectorBase.cs:35` publishes only `ProjectionSessionEventEntry.RootActorId + SessionId` to the hub, so the projector entry, hub API, and typed session context use the same routing invariant.
- `src/Aevatar.CQRS.Projection.Core/projection_session_event_transport.proto:12` changes field 1 from `scope_id` to `root_actor_id` without renumbering or reusing a removed field number; no proto field was deleted, and existing reserved field 4 remains intact.
- Added-line anti-pattern scan over the PR diff found no `Task.Delay(`, `Thread.Sleep(`, `GetAwaiter().GetResult()`, `TypeUrl.Contains(...)`, JSON serializer for state/committed payloads, raw `HttpClient` constructor, `[Skip]`, `actor.HandleEventAsync(`, or host/application `SubscribeAsync<EventEnvelope>` additions.
- Scope matches the issue-377 consensus plan in `.refactor-loop/runs/judge-issue377-r2.md`: delete `IProjectionPortSessionLease`, remove the lease constraint from registration, move runtime leases to typed contexts, rename session-event routing to `RootActorId/root_actor_id`, and update matching tests. No unplanned external repository dependency or `*WriteActor` / `*ReadActor` / `*StoreActor` split was introduced.
## What would change your verdict
Change the two remaining `// Refactor (issue-377): ...` blocks in the NyxID chat and StreamingProxy runtime lease files to the mandated `// Refactor (iter367/cluster-issue377): ...` marker.
REVIEW_DONE:1479:architect:comment⟦AI:AUTO-LOOP⟧ |
📊 当前状态 — Phase 8 r2 review 完成,等 CI 完成(❌ 不需要人介入)
🤖 controller status banner ⟦AI:AUTO-LOOP⟧ |
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## auto-refact-dev #1479 +/- ##
===================================================
+ Coverage 83.08% 83.69% +0.60%
===================================================
Files 1008 1011 +3
Lines 67597 68209 +612
Branches 8795 8828 +33
===================================================
+ Hits 56166 57086 +920
+ Misses 7542 7232 -310
- Partials 3889 3891 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 28 files with indirect coverage changes 🚀 New features to boost your workflow:
|
摘要
closes #377(Phase 9 r2 hybrid-minimal-structural-delete 共识落地)。
Old
IProjectionPortSessionLease是只转发RootActorId + SessionId的 alias 层(src/Aevatar.CQRS.Projection.Core.Abstractions/Abstractions/Ports/);projection session event transport 第一维用ScopeId/scope_id实质就是RootActorId。New
IProjectionPortSessionLeasealias +EventSinkProjectionRuntimeRegistration的 lease 约束EventSinkProjectionLifecyclePortBase直接从 typed session context 读RootActorId + SessionIdProjectionSessionEventEntry/Hub第一维ScopeId/scopeId→RootActorId/rootActorIdprojection_session_event_transport.prototag 1 wire-renamescope_id→root_actor_id(protobuf field-number 不变)RootActorId+SessionId路由、projector entry rename invariant 覆盖违反:CLAUDE.md「权威状态 / ReadModel / Projection」:projection 端口不应通过 alias 转发已有 typed 字段。
范围
27 files changed (+201/-155)。
Stacked-PR
Base =
auto-refact-dev。🤖 Auto-loop / codex-refactor-loop Phase 9 r2 consensus #377
⟦AI:AUTO-LOOP⟧