Skip to content

iter57 cluster-068: 扩展 #940 LarkCardOperation typed-signal 至 text streaming + Nyx relay (#946)#950

Merged
loning merged 2 commits into
auto-refact-devfrom
refactor/iter57-cluster-068-lark-extend-signal
May 24, 2026
Merged

iter57 cluster-068: 扩展 #940 LarkCardOperation typed-signal 至 text streaming + Nyx relay (#946)#950
loning merged 2 commits into
auto-refact-devfrom
refactor/iter57-cluster-068-lark-extend-signal

Conversation

@loning
Copy link
Copy Markdown
Contributor

@loning loning commented May 24, 2026

摘要

iter57 cluster-068(severity:high)— 扩展 #940 LarkCardOperationCompletedEvent typed-signal pattern 至 text streaming + Nyx relay

违反:CLAUDE.md「Actor 设计 / 生命周期 / 执行模型 — 回调只发信号」「业务推进内聚」

Phase 9 共识链路

Round Verdict
r1 escalate:philosophy(new operation owner)
reflector r1 retry-fix:扩展 ConversationGAgent + 已 deployed #940 pattern,无 new actor topology
r2 converge:narrow extension
r3 META_JUDGE_DONE:consensus:structural:3/3 propose same #940 typed-signal extension

Scope

  • ConversationGAgent.cs + NyxRelayStreaming.cs
  • conversation_events.proto(扩展 typed event)
  • ConversationGAgentDedupTests
  • architecture_guards.sh(覆盖新 signal-only text helper)

5 files changed, +976 / -133

closes #946

🤖 Generated with Claude Code via codex-refactor-loop iter57

⟦AI:AUTO-LOOP⟧

…nal 至 text streaming + Nyx relay (#946)

Phase 9 r3 consensus(reflector r1 救场 + r2/r3 converge):
- 扩展 #940 LarkCardOperationCompletedEvent typed-signal 到 ConversationGAgent text streaming + Nyx relay text 操作
- 删 unsafe execution shape(rich continuation 移到 actor handler)
- actor-owned in-flight text operation state + generation matching + timeout + stale rejection + coalescing
- 保留 CardKit/text behavior + CI guard 覆盖新 signal-only text helper
- 不引入 new actor / port / envelope / topology / docs/canon

closes #946
local PASS:architecture + test_stability + build + LarkCardOperationSignalTests + ConversationGAgentDedupTests

⟦AI:AUTO-LOOP⟧
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 状态卡片 — reviewer 派出

维度
阶段 派出 codex(role=reviewer)
codex log review-pr950-omnibus-r1.log
工作目录 /Users/auric/aevatar
timeout 5400s(~90 min 上限)
上下文 omnibus r1(架构/测试/质量综合)
下一步自动会做 1. 三 reviewer 完成 verdict marker 2. controller 计算 consensus 3. unanimous → auto-merge / reject → fix r<N+1>
是否需要人介入 ❌ 否(自动推进)

🤖 controller status banner

⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 状态卡片 — fix 派出

维度
阶段 派出 codex(role=fix)
codex log fix-pr950-r2.log
工作目录 /Users/auric/aevatar
timeout 5400s(~90 min 上限)
上下文 r1 reject(timeout payload 泄露 runtime-only reply_token 到 durable state)→ fix r2
下一步自动会做 1. fix r 完成 marker FIX_DONE:... 2. controller commit + push 3. 派 reviewer r<N+1>
是否需要人介入 ❌ 否(自动推进)

🤖 controller status banner

⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 review-pr950-omnibus-r1 (⏳ 进行中; 已跑 8 min)


codex
**Verdict: reject**

Finding:
- [ConversationGAgent.cs](/tmp/aevatar-pr-950-review/agents/Aevatar.GAgents.Channel.Runtime/Conversation/ConversationGAgent.cs:1114) schedules `NyxRelayTextOperationTimeoutFiredEvent` through `ScheduleSelfDurableTimeoutAsync` with `Chunk = chunk.Clone()`. That `LlmReplyStreamChunkEvent` includes `reply_token` / `reply_token_expires_at_unix_ms`, which the proto explicitly marks runtime-only and never persisted. The durable callback scheduler stores the trigger envelope in persistent scheduler state, so this leaks Nyx relay credentials into durable state. The timeout payload should be sanitized or carry only the typed fields needed for timeout reconciliation.

Verification run on PR worktree:
- `bash tools/ci/architecture_guards.sh` passed
- `dotnet test test/Aevatar.GAgents.Channel.Protocol.Tests/Aevatar.GAgents.Channel.Protocol.Tests.csproj --nologo --filter "FullyQualifiedName~ConversationGAgentDedupTests"` passed
- `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --filter "FullyQualifiedName~LarkCardOperationSignalTests"` passed

REVIEW_DONE:950:omnibus:reject
⟦AI:AUTO-LOOP⟧
tokens used
217,306
**Verdict: reject**

Finding:
- [ConversationGAgent.cs](/tmp/aevatar-pr-950-review/agents/Aevatar.GAgents.Channel.Runtime/Conversation/ConversationGAgent.cs:1114) schedules `NyxRelayTextOperationTimeoutFiredEvent` through `ScheduleSelfDurableTimeoutAsync` with `Chunk = chunk.Clone()`. That `LlmReplyStreamChunkEvent` includes `reply_token` / `reply_token_expires_at_unix_ms`, which the proto explicitly marks runtime-only and never persisted. The durable callback scheduler stores the trigger envelope in persistent scheduler state, so this leaks Nyx relay credentials into durable state. The timeout payload should be sanitized or carry only the typed fields needed for timeout reconciliation.

Verification run on PR worktree:
- `bash tools/ci/architecture_guards.sh` passed
- `dotnet test test/Aevatar.GAgents.Channel.Protocol.Tests/Aevatar.GAgents.Channel.Protocol.Tests.csproj --nologo --filter "FullyQualifiedName~ConversationGAgentDedupTests"` passed
- `dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo --filter "FullyQualifiedName~LarkCardOperationSignalTests"` passed

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

@codecov
Copy link
Copy Markdown

codecov Bot commented May 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.53%. Comparing base (f82a239) to head (a33bb0d).
⚠️ Report is 39 commits behind head on auto-refact-dev.

@@                 Coverage Diff                 @@
##           auto-refact-dev     #950      +/-   ##
===================================================
+ Coverage            82.83%   83.53%   +0.69%     
===================================================
  Files                  998      987      -11     
  Lines                63092    63583     +491     
  Branches              8161     8216      +55     
===================================================
+ Hits                 52261    53111     +850     
+ Misses                7304     6912     -392     
- Partials              3527     3560      +33     
Flag Coverage Δ
ci 83.53% <ø> (+0.69%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 70 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.

…Event payload(不泄露 reply_token)

PR #950 r1 reject blocker:
- timeout payload Chunk = chunk.Clone() 把 runtime-only reply_token / reply_token_expires_at_unix_ms 写入 durable scheduler state
- 泄露 Nyx relay credentials

修:
- timeout payload sanitize,只 carry typed fields needed for reconciliation
- 不带 reply_token / expires_at 进 durable payload
- 新增 NyxRelayTextOperationTimeoutPayloadTests:capture scheduled callback,验证 typed + serialized bytes 不含 credentials
- 826/826 tests pass

⟦AI:AUTO-LOOP⟧
@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 状态卡片 — reviewer 派出

维度
阶段 派出 codex(role=reviewer)
codex log review-pr950-omnibus-r3.log
工作目录 /Users/auric/aevatar
timeout 5400s(~90 min 上限)
上下文 fix r2 done → omnibus r3 验证 sanitization
下一步自动会做 1. 三 reviewer 完成 verdict marker 2. controller 计算 consensus 3. unanimous → auto-merge / reject → fix r<N+1>
是否需要人介入 ❌ 否(自动推进)

🤖 controller status banner

⟦AI:AUTO-LOOP⟧

@loning
Copy link
Copy Markdown
Contributor Author

loning commented May 24, 2026

📊 codex 进展 fix-pr950-r2 (⏳ 进行中; 已跑 10 min)

+
+        public Task<long> DeleteEventsUpToAsync(string agentId, long toVersion, CancellationToken ct = default)
+        {
+            ct.ThrowIfCancellationRequested();
+            if (toVersion <= 0 || !_events.TryGetValue(agentId, out var stream))
+                return Task.FromResult(0L);
+
+            var before = stream.Count;
+            stream.RemoveAll(x => x.Version <= toVersion);
+            return Task.FromResult((long)(before - stream.Count));
+        }
+    }
+}

tokens used
123,230
Implemented the PR #950 r2 fix.

Changed [ConversationGAgent.cs](/Users/auric/aevatar-wt-iter57-cluster-068-lark-extend-signal/agents/Aevatar.GAgents.Channel.Runtime/Conversation/ConversationGAgent.cs:1123) so durable timeout scheduling no longer clones the full `LlmReplyStreamChunkEvent`. It now builds a sanitized chunk containing only correlation, registration, durable-safe activity, accumulated text, and chunk timestamp. `reply_token`, `reply_token_expires_at_unix_ms`, and `TransportExtras.NyxUserAccessToken` are left out of the scheduled payload.

Added [NyxRelayTextOperationTimeoutPayloadTests.cs](/Users/auric/aevatar-wt-iter57-cluster-068-lark-extend-signal/test/Aevatar.GAgents.ChannelRuntime.Tests/NyxRelayTextOperationTimeoutPayloadTests.cs:1), which captures the scheduled `RuntimeCallbackTimeoutRequest`, unpacks the trigger envelope, and asserts both typed fields and serialized bytes do not contain relay credentials.

Verification passed:
`dotnet test test/Aevatar.GAgents.ChannelRuntime.Tests/Aevatar.GAgents.ChannelRuntime.Tests.csproj --nologo`
826 passed, 0 failed.

自动更新每 10 分钟;edit-in-place 不堆评论;codex 完成后此 comment 自动删除(per Auric "完成后删掉就好了 否则太占空间")。
🤖 controller progress reporter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant