Skip to content

cluster-025: voice host session state moves to actor; remote audio disabled until raw transport#706

Merged
loning merged 4 commits into
auto-refact-devfrom
refactor/iter15-cluster-025-voice-host-actor-lease
May 19, 2026
Merged

cluster-025: voice host session state moves to actor; remote audio disabled until raw transport#706
loning merged 4 commits into
auto-refact-devfrom
refactor/iter15-cluster-025-voice-host-actor-lease

Conversation

@loning
Copy link
Copy Markdown
Contributor

@loning loning commented May 19, 2026

Summary / 摘要

English

iter15 cluster-025-voice-host-session-state-actorization (severity:medium, rule_ids: AG-ACTOR-LIFECYCLE-01).

  • Old: voice host resolver RemoteActorVoicePresenceSessionResolver locks shared mutable lease state (_gate, _state, AttachmentState) outside actor lifecycle, and relays PCM audio chunks through EventEnvelope (VoiceRemoteAudioInputReceived / VoiceRemoteTransportOutput.AudioOutput).
  • New: actor owns remote session id and lease via existing VoicePresenceModule open/close handlers + EventEnvelope at function-call boundary only. Host-side lease state collapsed. Remote audio chunk envelope relay disabled until raw media transport exists; attach fails with remote_audio_transport_unavailable.

Violated: CLAUDE.md "## Actor 执行模型" — "回调只发信号" + "业务推进内聚"; also AGENTS architecture "no chunk-data through EventEnvelope" (per Phase 9 #701 unanimous consensus).

中文

iter15 cluster-025-voice-host-session-state-actorization(严重度:medium,规则 ID:AG-ACTOR-LIFECYCLE-01)。

  • Old: 语音 host resolver RemoteActorVoicePresenceSessionResolver 在 actor 生命周期外用 _gate/_state/AttachmentState 锁定可变 lease 状态;并把 PCM 音频 chunk 通过 EventEnvelope (VoiceRemoteAudioInputReceived / VoiceRemoteTransportOutput.AudioOutput) 中继。
  • New: actor 通过现有 VoicePresenceModule 的 open/close handler + 仅在 function-call 边界使用的 EventEnvelope 持有 remote session id 与 lease。host 侧 lease 状态被合并。remote 音频 chunk envelope 中继被禁用,直到 raw media transport 出现;attach 以 remote_audio_transport_unavailable 失败。

违反:CLAUDE.md "## Actor 执行模型" — "回调只发信号" + "业务推进内聚";同时违反 AGENTS 架构 "chunk 数据不走 EventEnvelope"(按 Phase 9 #701 3/3 unanimous 共识)。

Scope / 范围

7 files changed, +172 / -440 (net -268).

  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs
  • src/Aevatar.Foundation.VoicePresence/Hosting/CompositeVoicePresenceSessionResolver.cs
  • src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs
  • src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceSessionDispatch.cs
  • src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs
  • test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceModuleTests.cs

Validation: build pass; Aevatar.Foundation.VoicePresence.Tests 118/118 pass; architecture_guards.sh + test_stability_guards.sh pass.

No new actor type / envelope kind / pipeline phase / core abstraction. No proto removal in this patch (compatibility surface preserved). No external repo changes.

Phase 9 design source

Closes #681 after merge. Built on Phase 9 #701 round 5 consensus (architect+tests+quality solvers all propose:A). See implement summary in .refactor-loop/runs/implement-cluster-025-voice-host-session-state-actorization.md.

🤖 Auto-loop / codex-refactor-loop iter15 (Phase 9 consensus → implement)

…e audio disabled

Per Phase 9 #701 consensus (Auric architecture + Option A, 3/3 unanimous round 5):

- Collapse RemoteActorVoicePresenceSessionResolver from locked host-owned
  relay to setup/control-only bridge. Remove _gate, _state, AttachmentState,
  subscription handling, relay task, PCM-as-VoiceRemoteAudioInputReceived
  dispatch, and VoiceRemoteTransportOutput.AudioOutput forwarding.
- Remote media attach now dispatches Open + immediate Close with reason
  "remote_audio_transport_unavailable", disposes transport, throws
  NotSupportedException so callers fail explicitly.
- Keep remote setup/close/control envelope plumbing live through existing
  EventEnvelope + IActorDispatchPort (Auric pipeline: function-call boundary
  uses envelope, chunks never via envelope).
- VoicePresenceSessionDispatch: direct host envelopes no longer accept
  VoiceRemoteAudioInputReceived.
- VoicePresenceModule: actor still owns remote session open/close/control
  state; remote audio input inert; provider audio not republished as
  remote transport audio output.
- WebSocket/WHIP endpoints surface remote_audio_transport_unavailable.
- Behavior tests rewritten to assert setup/close/control remains and audio
  chunks never relayed through envelopes.

Diff: 7 files, +172 / -440 (net -268).
Build pass; VoicePresence.Tests 118/118; arch+stability guards pass.

No new actor type, envelope kind, pipeline phase, or core abstraction added.
Proto compatibility surface preserved (remote audio arms unused but reserved
for future raw-transport restoration).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

❌ Patch coverage is 87.50000% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.43%. Comparing base (03ecec0) to head (79ec5d3).
⚠️ Report is 13 commits behind head on auto-refact-dev.

Files with missing lines Patch % Lines
...on.VoicePresence/Hosting/VoicePresenceEndpoints.cs 81.48% 4 Missing and 1 partial ⚠️
@@                 Coverage Diff                 @@
##           auto-refact-dev     #706      +/-   ##
===================================================
- Coverage            82.44%   82.43%   -0.02%     
===================================================
  Files                  939      939              
  Lines                59722    59610     -112     
  Branches              7832     7818      -14     
===================================================
- Hits                 49240    49139     -101     
+ Misses                7112     7100      -12     
- Partials              3370     3371       +1     
Flag Coverage Δ
ci 82.43% <87.50%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...e/Hosting/CompositeVoicePresenceSessionResolver.cs 84.61% <ø> (ø)
...Hosting/RemoteActorVoicePresenceSessionResolver.cs 88.07% <100.00%> (+0.57%) ⬆️
...cePresence/Hosting/VoicePresenceSessionDispatch.cs 91.89% <ø> (+4.71%) ⬆️
...ation.VoicePresence/Modules/VoicePresenceModule.cs 88.21% <ø> (-0.30%) ⬇️
...on.VoicePresence/Hosting/VoicePresenceEndpoints.cs 93.90% <81.48%> (-1.54%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — architect — PR #706 round 1



pr: 706
role: architect
verdict: approve

Verdict

approve - no architecture compliance concerns found for the voice host session-state actorization changes.

Evidence

  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:11 documents the required old/new refactor pattern, and :119 repeats it at the changed attach path; the diff removes the prior host-owned _gate, _state, subscription, relay task, and AttachmentState rather than replacing them with another middle-layer registry.
  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:111 now reports remote host transport as never locally attached, and :123 dispatches setup/close only before failing explicit remote media attach. This aligns with CLAUDE.md: "Projection 运行态(会话、订阅、关联)必须由 Actor 或分布式状态承载;禁止中间层进程内注册表/字典持有事实状态。"
  • src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs:23 documents the actor-owned remote session principle; :461 keeps _remoteSessionId in the module/actor turn, and :486 makes stale remote audio input inert instead of forwarding PCM through envelopes. This aligns with AGENTS.md: "投影端口规范:禁止通过 actorId -> context 反查方式管理生命周期,改为显式 lease/session 句柄传递。"
  • src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceSessionDispatch.cs:60 removes direct host envelope support for VoiceRemoteAudioInputReceived, keeping setup/control only. This supports CLAUDE.md: "EventEnvelope 是统一消息包络... 但是否可持久化、可投影、可观察必须由消息契约显式定义,不因"都走 Envelope"混淆语义。"
  • Scope stays within the cluster's declared voice host/session files plus corresponding tests: changed production paths are all under src/Aevatar.Foundation.VoicePresence/Hosting and src/Aevatar.Foundation.VoicePresence/Modules; no SCOPE_EXTEND was needed.
  • Targeted added-line scans found no new actor.HandleEventAsync(, SubscribeAsync<EventEnvelope>, actor-state JSON serializer, production Task.Delay(, GetAwaiter().GetResult(), TypeUrl.Contains(...), middle-layer Dictionary<>/ConcurrentDictionary<>, raw HttpClient, disabled tests, external NyxID/chrono references, or technical *WriteActor/*ReadActor/*StoreActor split.
  • No .proto files changed, so field-number reuse/reservation rules are not implicated.

REVIEW_DONE:706:architect:approve

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — tests — PR #706 round 1



pr: 706
role: tests
verdict: reject

Verdict

Reject: the core resolver/module behavior has meaningful tests, but the PR adds new WebSocket and WHIP endpoint behavior for remote audio unavailability without endpoint-level coverage.

Evidence

  • src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:95 adds a WebSocket NotSupportedException("remote_audio_transport_unavailable") branch that closes the upgraded socket with WebSocketCloseStatus.PolicyViolation, but test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceEndpointsTests.cs only covers existing module-not-initialized, cleanup, and conflict paths; there is no test asserting the remote-audio-unavailable close status/description.
  • src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:199 adds a WHIP NotSupportedException("remote_audio_transport_unavailable") branch that disposes the unattached transport and returns HTTP 503 with the exact reason body, but test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceWhipEndpointsTests.cs only covers generic attach failure rethrow/dispose and existing 503 initialization behavior; there is no test for this new public response contract.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:17 and :141 do assert the new resolver behavior: attach dispatches open/close, throws remote_audio_transport_unavailable, disposes transport, and does not dispatch remote audio input. test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceModuleTests.cs also asserts remote audio is ignored while lifecycle/control behavior remains. These are behavior tests, not bump-only tests.
  • No new Task.Delay, Thread.Sleep, WaitUntilAsync, [Skip], or [Trait("Category","Manual")] additions were found in the touched voice presence tests; the only voice presence polling wait remains the pre-existing allowlisted VoiceTransportRelayTests.cs entry.

What would change your verdict

Add endpoint tests for both new public branches:

  • VoicePresenceEndpointsTests: a session whose AttachTransportAsync throws NotSupportedException("remote_audio_transport_unavailable"), asserting the accepted WebSocket is closed once with PolicyViolation and the remote_audio_transport_unavailable description.
  • VoicePresenceWhipEndpointsTests: a WHIP POST whose AttachTransportAsync throws the same exception, asserting HTTP 503, body remote_audio_transport_unavailable, and disposal of the unattached transport.

REVIEW_DONE:706:tests:reject

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — quality — PR #706 round 1



pr: 706
role: quality
verdict: comment

Verdict

Code is focused and substantially simpler, but the remote-audio-unavailable path is coupled through a duplicated exception-message sentinel that is brittle enough to warrant a quality comment.

Evidence

  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:18 and src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:21 each define their own RemoteAudioTransportUnavailable = "remote_audio_transport_unavailable", and VoicePresenceEndpoints.IsRemoteAudioTransportUnavailable at src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:303 classifies the condition by comparing NotSupportedException.Message. This makes the endpoint behavior depend on two private string constants staying identical across files instead of a shared typed contract or local exception type.
  • src/Aevatar.Foundation.VoicePresence/Hosting/CompositeVoicePresenceSessionResolver.cs:6, src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:11, src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:15, src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceSessionDispatch.cs:66, and src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs:23/:486 include clear Refactor (iter15/cluster-025-...) self-doc blocks with Old/New intent; no missing or placeholder refactor comments found in touched production files.
  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:92 keeps RemoteActorVoicePresenceSessionBridge as a small private implementation detail with no extra public abstraction, and the PR deletes the prior resolver-side lease state rather than adding new manager/helper layers.
  • Modified methods stayed within the preferred size/branch envelope; no new large method or obvious dead private member was introduced in the touched files.

What would change your verdict

Centralize the remote-audio-unavailable signal so the resolver and endpoints do not communicate by matching a private exception message, for example with an internal VoiceRemoteAudioTransportUnavailableException carrying the reason constant or an internal shared reason constant plus a typed exception filter.

REVIEW_DONE:706:quality:comment

@loning loning added the auto-loop-fixing Phase 8 fix codex round in flight (AI iterating to consensus) label May 19, 2026
Applied 7 fixes (FIX_DONE:706:round-1:applied-7:rejected-0:blocked-0):
addresses tests reviewer reject + quality reviewer comment.

Diff: 5 files, +158 / -14. Key additions: WebSocket/WHIP endpoint
behavior tests for remote_audio_transport_unavailable scenarios (covers
codecov/patch shortfall on new endpoint code paths).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Fix codex round 1 — FIX_DONE:706:round-1:applied-7:rejected-0:blocked-0

English

Round 1 addressed tests reviewer reject + quality reviewer comment. Key additions: WebSocket/WHIP endpoint behavior tests for remote_audio_transport_unavailable (also covers codecov/patch shortfall on new endpoint code paths).

Diff: 5 files, +158 / -14.

Next: re-dispatch 3 reviewers + codecov re-evaluates patch coverage.

中文

Round 1 处理 tests reject + quality comment。关键新增:WebSocket/WHIP endpoint 的 remote_audio_transport_unavailable 行为测试(同时补 codecov/patch 在新端点路径上的覆盖率缺口)。

Diff: 5 文件,+158 / -14。

下一步:重派 3 reviewer + codecov 重新评估 patch coverage。

@loning loning added auto-loop-reviewing Phase 8 reviewer codex round in flight and removed auto-loop-fixing Phase 8 fix codex round in flight (AI iterating to consensus) labels May 19, 2026
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — architect — PR #706 round 2



pr: 706
role: architect
verdict: comment

Verdict

comment-only: the PR removes the host-owned lock/state/subscription relay and stays within the cluster, but it leaves an explicit no-op compatibility handler for the stale remote-audio proto arm.

Evidence

  • src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs:486 adds HandleRemoteAudioInputReceived(...) as an explicit inert handler (_ = request;) with the comment "stale proto arm inert for compatibility"; src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceSessionDispatch.cs:66 already rejects direct host envelopes for VoiceRemoteAudioInputReceived, so this is dead compatibility surface rather than an active path. Clause: AGENTS.md says "删除优于兼容:重构以清晰正确为第一目标;无业务价值或重复层应直接删除,不为历史包袱保留空壳。" This is non-blocking because it does not introduce a second live media pathway or move facts back into host state.
  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:11 and :118 include the required old/new refactor comments, and the previous _gate, _state, SubscribeAsync<VoiceRemoteTransportOutput>, relay task, and host-owned attachment state are removed.
  • Scope check: changed files are limited to voice presence hosting/module code and matching tests; no .proto or docs/canon files are changed, and no NyxID/chrono references are introduced.
  • Added-line anti-pattern scan found no new actor.HandleEventAsync(, SubscribeAsync<EventEnvelope>, actor-state JSON serialization, production Task.Delay(, GetAwaiter().GetResult(), TypeUrl.Contains(...), cross-request Dictionary<,> fact map, raw HttpClient constructor, or disabled tests.

What would change your verdict

Remove the explicit no-op RemoteAudioInputReceived handler/case so the stale arm is not called out as a compatibility shim, or formally delete the proto arm with proper reserved field handling if the scope is extended to proto cleanup.

REVIEW_DONE:706:architect:comment

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — tests — PR #706 round 2



pr: 706
role: tests
verdict: approve

Verdict

Test coverage and quality are adequate for the voice host session-state actorization diff.

Evidence

  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:17 covers the new remote attach behavior with business assertions: open signal, close signal, shared unavailable reason, transport disposal, and no attached host state.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:141 covers the no-regression rule that transport frames do not produce RemoteAudioInputReceived envelopes and that the transport receive loop is never started.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:181 covers repeated unsupported attach attempts, ensuring no host-side attachment state blocks later attempts.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:205 and :219 cover the dispatch boundary directly: audio input payloads are rejected while remote control payloads remain supported.
  • test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceEndpointsTests.cs:206 covers the WebSocket endpoint response for unavailable remote audio with policy-violation close status and the exact reason.
  • test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceWhipEndpointsTests.cs:227 covers the WHIP endpoint response for unavailable remote audio with HTTP 503, exact response body, and transport disposal.
  • test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceModuleTests.cs:337 and :588 cover module behavior changes: remote audio is inert, provider audio is not republished as remote transport output, lifecycle close output still publishes, and remote control still advances drain acknowledgement.
  • The PR test diff adds no Task.Delay, Thread.Sleep, WaitUntilAsync, [Skip], or manual-category tests; bash tools/ci/test_stability_guards.sh passes without allowlist changes.

What would change your verdict (only if comment or reject)

N/A

REVIEW_DONE:706:tests:approve

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — quality — PR #706 round 2



pr: 706
role: quality
verdict: comment

Verdict

Comment: the production refactor is focused and readable, and the mandated refactor self-doc blocks are present, but the updated remote resolver tests leave small dead helper surface from the deleted stream relay behavior.

Evidence

  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:334: HoldingVoiceTransport.DisposedTask is no longer awaited or asserted anywhere in the PR version; it is set in DisposeAsync but has no reader after the attach flow was changed to fail synchronously.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:336: HoldingVoiceTransport.AudioFrames and its SendAudioAsync append path are no longer observed by any test in this file after remote output bridging was removed.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:379: ScriptedVoiceTransport.DisposedTask is also only written and never read in the PR version; Disposed and ReceiveStarted cover the remaining assertions.

What would change your verdict

Delete the unused DisposedTask properties and the unused AudioFrames storage/assertion support from the two local test transports, or add concrete assertions that still need those helpers.

REVIEW_DONE:706:quality:comment

@loning loning added auto-loop-fixing Phase 8 fix codex round in flight (AI iterating to consensus) and removed auto-loop-reviewing Phase 8 reviewer codex round in flight labels May 19, 2026
Applied 3 fixes (FIX_DONE:706:round-2:applied-3:rejected-0:blocked-0).
Diff: 2 files, +1 / -21 (net -20).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Fix codex round 2 — FIX_DONE:706:round-2:applied-3:rejected-0:blocked-0

Addressed v2 architect + quality comments. Diff: 2 files, +1 / -21. Next: re-dispatch 3 reviewers.

处理 v2 architect + quality comment。diff: 2 文件, +1 / -21。下一步:重派 3 reviewer。

@loning loning added auto-loop-reviewing Phase 8 reviewer codex round in flight and removed auto-loop-fixing Phase 8 fix codex round in flight (AI iterating to consensus) labels May 19, 2026
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — architect — PR #706 round 3



pr: 706
role: architect
verdict: comment

Verdict

comment-only: the PR does not introduce a blocking CLAUDE/AGENTS architecture violation, but one refactored method is missing the required Old/New pattern comment.

Evidence

  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:148 refactors DetachTransportAsync from state/transport-specific release semantics into a setup/control-only best-effort close path, but the method itself has no // Refactor (iter15/cluster-025-...): Old pattern: ... New principle: ... comment. Checklist clause: "Old/New pattern comment: each refactored type/method has // Refactor (iterN/cluster-XXX): Old pattern: … New principle: …. Missing or vague -> comment."
  • Scope and clause spot-checks were otherwise clean: RemoteActorVoicePresenceSessionResolver.cs:11 and :118 document the removal of host-owned locked lease state; VoicePresenceSessionDispatch.cs:66 rejects direct host remote-audio envelopes; VoicePresenceModule.cs:23 documents actor-owned remote session lifecycle. This aligns with CLAUDE.md: "Projection 运行态(会话、订阅、关联)必须由 Actor 或分布式状态承载;禁止中间层进程内注册表/字典持有事实状态."
  • The requested diff contains no .proto changes, no added actor.HandleEventAsync(, SubscribeAsync<EventEnvelope>, actor-state JSON serialization, GetAwaiter().GetResult(), TypeUrl.Contains(...), raw HttpClient constructor, disabled tests, external repo references, or new *WriteActor / *ReadActor split.

What would change your verdict

Add the required Old/New refactor comment directly above RemoteActorVoicePresenceSessionResolver.RemoteActorVoicePresenceSessionBridge.DetachTransportAsync, explaining the old host-held attachment-state release path and the new setup/control-only close semantics.

REVIEW_DONE:706:architect:comment

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — tests — PR #706 round 3



pr: 706
role: tests
verdict: comment

Verdict

Behavior coverage is mostly solid, but this cluster needs a source-regression assertion to lock out the old host-owned lease/subscription state pattern.

Evidence

  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:17 covers remote attach as a real behavior: open is dispatched, close uses remote_audio_transport_unavailable, the transport is disposed, and IsTransportAttached remains false.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:141 asserts transport frames are not consumed and no RemoteAudioInputReceived envelope is dispatched, which directly covers the new no-audio-through-envelope behavior.
  • test/Aevatar.Foundation.VoicePresence.Tests/RemoteActorVoicePresenceSessionResolverTests.cs:181 covers repeated unsupported attach attempts without sticky host attachment state.
  • test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceModuleTests.cs:337 and test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceModuleTests.cs:588 assert remote lifecycle/control still works while remote audio input and provider audio output are not relayed.
  • test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceEndpointsTests.cs:206 and test/Aevatar.Foundation.VoicePresence.Tests/VoicePresenceWhipEndpointsTests.cs:227 cover the new endpoint failure surface for unavailable remote audio.
  • No new Task.Delay, Thread.Sleep, WaitUntilAsync, [Skip], or manual-category traits were added in the PR diff. The only VoicePresence Task.Delay hit remains the pre-existing allowlisted VoiceTransportRelayTests.cs infinite-delay test double.
  • Missing: there is no source-regression test using source.Should().NotContain(...) for the cluster's central rule that RemoteActorVoicePresenceSessionResolver must not reintroduce host-owned lease/session state such as IActorEventSubscriptionProvider, _gate, _state, AttachmentState, or dispatching VoiceRemoteAudioInputReceived from the host bridge.

What would change your verdict

Add a source-regression test for RemoteActorVoicePresenceSessionResolver.cs/VoicePresenceSessionDispatch.cs that asserts the old host bridge tokens stay absent, especially IActorEventSubscriptionProvider, AttachmentState, _gate, _state, ReceiveFramesAsync, and direct host dispatch of VoiceRemoteAudioInputReceived.

REVIEW_DONE:706:tests:comment

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Phase 8 Reviewer — quality — PR #706 round 3



pr: 706
role: quality
verdict: approve

Verdict

Readable, focused deletion-heavy refactor; no dead code, over-engineering, unclear naming, or missing self-doc comments found.

Evidence

  • src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:91 keeps the private RemoteActorVoicePresenceSessionBridge reachable only from ResolveAsync; its methods are small and the deleted _gate/_state/subscription relay removes complexity rather than adding it.
  • src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:282 and src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:344 add a narrow helper and typed exception with direct callers in WebSocket/WHIP error paths; the names describe the business condition instead of generic handling.
  • src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceSessionDispatch.cs:66 documents the direct-envelope restriction at the switch case where remote audio input is intentionally no longer accepted; there is no commented-out code or filler comment.
  • src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs:128, src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs:329, and src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs:483 remain below the method-size/branching thresholds after the remote audio relay deletion.
  • src/Aevatar.Foundation.VoicePresence/Hosting/CompositeVoicePresenceSessionResolver.cs:6, src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:11, src/Aevatar.Foundation.VoicePresence/Hosting/RemoteActorVoicePresenceSessionResolver.cs:118, src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:15, src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceSessionDispatch.cs:66, src/Aevatar.Foundation.VoicePresence/Hosting/VoicePresenceEndpoints.cs:341, and src/Aevatar.Foundation.VoicePresence/Modules/VoicePresenceModule.cs:23 include clear Refactor (iter15/cluster-025-...) Old/New comments with no issue-only placeholders.
  • Touched tests stay focused on the cluster behavior and remove obsolete relay fixtures; the newly added RecordingCloseWebSocket is only a test double for the unsupported-remote-audio close path.

What would change your verdict (only if comment or reject)

N/A

REVIEW_DONE:706:quality:approve

@loning loning added auto-loop-fixing Phase 8 fix codex round in flight (AI iterating to consensus) and removed auto-loop-reviewing Phase 8 reviewer codex round in flight labels May 19, 2026
Applied 2 fixes (FIX_DONE:706:round-3:applied-2:rejected-0:blocked-0):
- (A) architect: add Refactor (iter15/cluster-025) marker on DetachTransportAsync
- (A) tests: add source-regression test asserting host-owned session state
  tokens (_gate, _state, AttachmentState, IActorEventSubscriptionProvider,
  VoiceRemoteAudioInputReceived) cannot return

Diff: 2 files, +38.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 19, 2026

🤖 Fix codex round 3 — FIX_DONE:706:round-3:applied-2

Refactor marker on DetachTransportAsync + source-regression test on host-owned state tokens. Next: v4 reviewers.

补 DetachTransportAsync Refactor 注释 + 加 source-regression test。下一步:v4 reviewer。

@loning loning added auto-loop-reviewing Phase 8 reviewer codex round in flight and removed auto-loop-fixing Phase 8 fix codex round in flight (AI iterating to consensus) labels May 19, 2026
loning added a commit that referenced this pull request May 19, 2026
…io surface (cluster-026)

Applied 9 fixes (FIX_DONE:707:round-4:applied-9:rejected-0:blocked-0).
Cross-PR note: also touches RemoteActorVoicePresenceSessionResolver
(PR #706 scope). Both PRs delete same dead code → rebase clean either order.

Diff: 7 files, +16 / -181 (net -165). Deletion-positive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@loning loning merged commit b862578 into auto-refact-dev May 19, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-loop-reviewing Phase 8 reviewer codex round in flight

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant