Skip to content

fix(sessions): 启动期用户消息可靠投递 - #188

Merged
jh0904 merged 27 commits into
mainfrom
codex/fix-session-event-reliable-delivery
Aug 4, 2026
Merged

fix(sessions): 启动期用户消息可靠投递#188
jh0904 merged 27 commits into
mainfrom
codex/fix-session-event-reliable-delivery

Conversation

@jh0904

@jh0904 jh0904 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #189

问题

Cloud Session 在 sandbox 启动期间已经可以接收消息,但 Code Session 要到启动链路后半段才创建。

此前 Runner 在 prepare 阶段读取一次 session_events 快照。快照之后、Code Session 创建之前发送的消息虽然已经持久化,API 也返回成功,但它既不在旧快照中,也无法写入尚不存在的 code_session_inbound_events,因此 runtime 可能永远收不到。

修复方式

session_events 继续作为启动输入的唯一事实源,不新增临时 queue、watermark 或公开启动状态。

Send Events 和 Code Session activation 使用同一条 Session 行锁串行化:

  • Send 在同一事务中锁定 Session、写入公开事件,并提交可选的 outcome 更新;
  • activation 锁定 Session 和 initializing Code Session,读取完整公开历史,幂等写入 inbound,最后切换为 active
  • activation 完成后的 Send 继续使用现有 realtime 路径。

Session 对外状态仍为 idle,不新增公开 starting 状态。

启动消息交接流程

flowchart TD
    Start["Send 与 Activation 竞争同一条 Session 行锁"]
    Start --> Winner{"谁先获得锁"}

    Winner -->|Send| SendCommit["提交公开事件到 session_events"]
    SendCommit --> ActivationReads["Activation 获得锁并读取完整历史"]
    ActivationReads --> HistoryInbound["幂等写入可转发事件到 inbound"]
    HistoryInbound --> HistoryActive["Code Session 切换为 active 并提交"]

    Winner -->|Activation| ActivationCommit["读取历史并写入 inbound"]
    ActivationCommit --> CodeSessionActive["Code Session 切换为 active 并提交"]
    CodeSessionActive --> SendAfter["Send 随后获得锁并提交公开事件"]
    SendAfter --> RealtimeInbound["通过 realtime 写入 inbound"]
Loading

无论谁先获得锁,成功返回的公开事件最终都会进入该 Code Session 的 inbound:

  1. Send 先提交时,activation 会从完整历史中读取并回放该事件;
  2. activation 先提交时,后续 Send 会看到 active Code Session 并实时投递。

关键改动

  1. 移除 Runner 启动快照

    • prepareManagedAgentLaunch 不再读取或传递 InitialEvents
    • sandbox 准备耗时不再扩大消息丢失窗口。
  2. 分阶段激活 Code Session

    • Code Session 创建时为 initializing
    • 先写入 initialize inbound;
    • activation 按 created_at ASC, id ASC 读取完整 session_events
    • 只转换可转发事件,幂等写入 inbound;
    • inbound 交接完成后才切换为 active
  3. 保证原子失败语义

    • 历史转换、inbound 写入或状态更新任一步失败,activation 事务整体回滚;
    • Code Session 不会在历史交接不完整时变为 active。
  4. 限制批量查询和写入

    • activation 的幂等键查询和 inbound 写入均按最多 500 条分批;
    • 避免超长历史触发 PostgreSQL 绑定参数上限;
    • 多批次仍在同一 activation 事务中完成。
  5. 收紧 activation 锁范围

    • 锁定 initializing Code Session 时同时绑定 workspace_uuid 和 Code Session UUID;
    • 避免 activation 只依赖资源 UUID 建立租户归属。
  6. 统一 Deployment 初始消息

    • Deployment initial events 继续写入 session_events
    • activation 使用同一套公开历史回放,无需独立交接路径。

行为变化

场景 之前 现在
prepare 快照后、Code Session 创建前发送消息 API 成功,但 runtime 可能永远收不到 activation 从完整公开历史回放
启动期发送多条用户消息 可能只投递旧快照中的消息 全部接受并按历史顺序回放
超长历史 activation 幂等键可能展开为超大参数列表 查询和写入均按 500 条分批
activation 中途失败 可能留下不完整交接风险 inbound 写入与 active 切换整体回滚
activation 后发送新 batch realtime 投递 继续沿 realtime 路径追加
Deployment 多条 initial user messages 依赖 Runner 快照 initialize 后按公开历史顺序回放

回归测试

  • TestEnvironmentRunnerDeliversMessageAcceptedBeforeCodeSessionCreation:复现并覆盖 Cloud Session 启动过程中,已成功发送的消息可能到不了 agent #189
  • TestManagedAgentActivationReplaysStartupHistory:覆盖多条启动消息、顺序和 realtime cutover;
  • TestManagedAgentActivationPreservesLargeHistoryOrder:覆盖超过单批大小的历史顺序;
  • TestManagedAgentActivationRollsBackOnHistoryConversionFailure:覆盖 activation 失败不切 active;
  • TestListExistingActivationInboundEventsBatchesLookup:覆盖幂等键查询分批;
  • Deployment 子测试 success initial user messages replay in order:覆盖 initial events 顺序。

本地已验证以上启动期相关测试,以及 lint、dead-code、duplicate-code 和 complexity 门禁。

设计文档

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Managed-agent code sessions now start as initializing. Startup messages are stored in session_event_queue, then atomically delivered to inbound events before activation. Runner event snapshots are removed, and realtime delivery is limited to active sessions.

Changes

Session startup delivery

Layer / File(s) Summary
Startup queue contract and persistence
internal/db/migrations/..., internal/db/session_event_queue.go, internal/db/deployments.go, internal/db/sessions.go, internal/db/sessions_sqlx.go, internal/db/db.go
Adds the startup queue schema and transactional APIs for FIFO user-message queueing, startup-window validation, ownership checks, UUID tenant references, deployment enqueueing, and queue cleanup.
API normalization and delivery routing
internal/sessions/..., internal/codesessions/service.go
Persists normalized outcome evaluations with session events, returns startup conflicts as HTTP 409, selects realtime versus startup-queued delivery, and skips realtime forwarding for non-active code sessions.
Atomic code-session activation
internal/codesessions/managed_agent_code_session.go, internal/db/code_sessions.go, internal/environments/runner.go
Creates initializing code sessions, merges historical and queued events, converts them into inbound inputs, atomically delivers and removes queue entries, and retries activation when snapshots change.
Deployment, runner, and behavior validation
tests/..., docs/design/be/session-startup-message-delivery.md
Validates deployment ordering, startup delivery, queue cleanup, rollback, concurrency, runner delivery, and documented environment semantics.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SessionAPI
  participant session_event_queue
  participant EnvironmentRunner
  participant CodeSession
  participant InboundQueue

  Client->>SessionAPI: Send startup user.message
  SessionAPI->>session_event_queue: Persist event UUID
  EnvironmentRunner->>CodeSession: Create initializing code session
  CodeSession->>session_event_queue: Load FIFO queued messages
  CodeSession->>InboundQueue: Append history and queued messages
  CodeSession->>session_event_queue: Delete delivered queue rows
  CodeSession->>CodeSession: Transition initializing to active
Loading

Possibly related PRs

Suggested reviewers: arthur-zhang

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue [#189] by queueing startup messages, atomically delivering them after initialize, handling conflicts and concurrency, and preserving ordering.
Out of Scope Changes check ✅ Passed The implementation, migrations, tests, and design documentation are all directly related to reliable startup-message delivery and its transactional queueing behavior.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了修复 Session 启动期间用户消息可靠投递问题这一主要变更。
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-session-event-reliable-delivery

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.

@jh0904
jh0904 force-pushed the codex/fix-session-event-reliable-delivery branch from 3f1aaeb to 3a1a564 Compare July 29, 2026 12:36
@jh0904 jh0904 changed the title Ensure reliable delivery of code session events 确保 Code Session 启动窗口内已接收的消息可靠投递 Jul 30, 2026
@jh0904
jh0904 force-pushed the codex/fix-session-event-reliable-delivery branch 2 times, most recently from 71aabfb to 39a7942 Compare July 30, 2026 09:36
@jh0904 jh0904 changed the title 确保 Code Session 启动窗口内已接收的消息可靠投递 修复 Code Session 创建前消息丢失 Jul 30, 2026
@jh0904
jh0904 marked this pull request as ready for review July 30, 2026 10:45
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@jh0904

jh0904 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

cursor[bot]
cursor Bot approved these changes Jul 30, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff51cb6432

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/codesessions/managed_agent_code_session.go
Close the #189 startup window where accepted user messages were only written
to session_events and never reached code_session_inbound_events.

Record startup delivery responsibility in session_event_queue in the same
transaction as session_events, then atomically hand off the full queue,
clear it, and activate the Code Session under the same Session row lock used
by Send Events. Reject extra ordinary startup user messages with 409.
@jh0904
jh0904 force-pushed the codex/fix-session-event-reliable-delivery branch from ff51cb6 to d0ba785 Compare July 30, 2026 14:53
@jh0904 jh0904 changed the title 修复 Code Session 创建前消息丢失 fix(sessions): 启动期用户消息可靠投递 Jul 30, 2026
cursor[bot]
cursor Bot approved these changes Jul 30, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0ba785c67

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/db/migrations/00047_add_session_event_queue.sql Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@internal/codesessions/managed_agent_code_session.go`:
- Around line 135-171: Bound the retry loop surrounding
ActivateManagedAgentCodeSessionWithQueue with a finite attempt limit and return
a clear error when the limit is exhausted. Add a small backoff before retrying
when activated is false, while preserving immediate returns for successful
activation and existing errors; honor context cancellation during the backoff.

In `@internal/db/session_event_queue.go`:
- Around line 212-264: Update sessionUserMessageStartupWindowSQLX in
internal/db/session_event_queue.go:212-264 to derive startup eligibility solely
from the code_sessions lifecycle status, treating initializing sessions as
startup and excluding environment_work.state from the decision. Preserve
existing error handling and session/work matching behavior. The related sites in
internal/db/deployments.go:285-293 and internal/sessions/service.go:599-634
require no direct changes; they document the lifecycle behavior this query must
follow.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e923c6ed-f898-4e67-ac47-19d7a3dde314

📥 Commits

Reviewing files that changed from the base of the PR and between ff51cb6 and d0ba785.

📒 Files selected for processing (17)
  • docs/design/be/session-startup-message-delivery.md
  • internal/codesessions/managed_agent_code_session.go
  • internal/codesessions/service.go
  • internal/db/code_sessions.go
  • internal/db/db.go
  • internal/db/deployments.go
  • internal/db/migrations/00036_add_session_event_queue.sql
  • internal/db/session_event_queue.go
  • internal/db/sessions.go
  • internal/db/sessions_migration_sqlx_test.go
  • internal/db/sessions_sqlx.go
  • internal/environments/runner.go
  • internal/sessions/service.go
  • internal/sessions/service_helpers.go
  • tests/deployments_api_test.go
  • tests/environments_runner_cloud_test.go
  • tests/sessions_api_test.go
💤 Files with no reviewable changes (1)
  • internal/environments/runner.go

Comment thread internal/codesessions/managed_agent_code_session.go Outdated
Comment thread internal/db/session_event_queue.go Outdated
Drop overlapping startup-window cases (self-hosted, terminated CS, stopped
work, cross-session queue ownership) and fold post-activation realtime
assertions into the atomic activation test. Slim the #189 runner and
deployment multi-message checks without losing the unique paths.
cursor[bot]
cursor Bot approved these changes Jul 30, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2151cf7288

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/db/session_event_queue.go Outdated
Comment thread internal/db/migrations/00036_add_session_event_queue.sql Outdated
jh0904 added 2 commits July 31, 2026 00:02
Use samber/lo for small event filters, align the conflict sentinel with other DB errors, and keep activation checks to type match plus queue snapshot comparison.
Align the startup window with Runner managed Code Session activation so
self_hosted sessions keep accepting events without an undrained queue.
cursor[bot]
cursor Bot approved these changes Jul 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/environments_runner_cloud_test.go (1)

353-357: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert durable queue ownership before code-session creation.

The final inbound assertion proves eventual delivery, but not that the accepted event was persisted in session_event_queue during the no-Code-Session window—the regression this test is meant to prevent. Assert the sole queued ID immediately after sendSessionEvents.

Proposed test strengthening
 			acceptedEventID = sessionEventStringField(t, sent.Data[0], "id")
+			if queued := sessionEventQueueEventIDs(t, app, session.ID); len(queued) != 1 || queued[0] != acceptedEventID {
+				t.Fatalf("startup queue = %#v, want [%s]", queued, acceptedEventID)
+			}
 		},
🤖 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 `@tests/environments_runner_cloud_test.go` around lines 353 - 357, In the test
flow around sendSessionEvents, immediately assert that the sole accepted event
ID is present in session_event_queue before creating the Code Session. Reuse the
existing acceptedEventID and queue-inspection helpers or established database
assertion pattern, while preserving the current len(sent.Data) validation and
eventual delivery checks.
🤖 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.

Outside diff comments:
In `@tests/environments_runner_cloud_test.go`:
- Around line 353-357: In the test flow around sendSessionEvents, immediately
assert that the sole accepted event ID is present in session_event_queue before
creating the Code Session. Reuse the existing acceptedEventID and
queue-inspection helpers or established database assertion pattern, while
preserving the current len(sent.Data) validation and eventual delivery checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e245588-391f-42f6-9e57-a9021ec5288d

📥 Commits

Reviewing files that changed from the base of the PR and between d0ba785 and 112e515.

📒 Files selected for processing (8)
  • docs/design/be/session-startup-message-delivery.md
  • internal/codesessions/managed_agent_code_session.go
  • internal/db/code_sessions.go
  • internal/db/db.go
  • internal/db/session_event_queue.go
  • tests/deployments_api_test.go
  • tests/environments_runner_cloud_test.go
  • tests/sessions_api_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/codesessions/managed_agent_code_session.go
  • docs/design/be/session-startup-message-delivery.md

jh0904 and others added 2 commits July 31, 2026 08:38
Merge historical session_events with the startup queue on activation so
new sandboxes keep prior turns while still delivering startup-window
messages reliably.
cursor[bot]
cursor Bot approved these changes Jul 31, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/sessions_api_test.go (1)

3841-3878: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make queue ownership mismatches fail instead of disappearing.

This query does not require e.session_id = s.id; a queue row can therefore pair the requested session with another session’s event in the same tenant. Because the joins are inner joins, dangling or mismatched rows can also be silently omitted, weakening the tests for the documented ownership and rollback guarantees.

Use a left join with explicit session binding so malformed rows cause the helper to fail rather than appear as an empty queue.

Proposed fix
-       join session_events e
+       left join session_events e
            on e.uuid = q.session_event_uuid
+           and e.session_id = s.id
+           and e.session_external_id = s.external_id
            and e.organization_id = o.id
            and e.workspace_id = w.id
🤖 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 `@tests/sessions_api_test.go` around lines 3841 - 3878, Update
sessionEventQueueEventIDs to left-join session_events with an explicit
e.session_id = s.id binding, while preserving the tenant and workspace ownership
predicates. Make the helper detect a missing or mismatched event from the
nullable left-join result and fail the test instead of silently omitting the
queue row.
🧹 Nitpick comments (2)
tests/sessions_api_test.go (1)

688-1043: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reorder the new Go tests to put failure cases first.

The additions place activation success/realtime coverage before rollback, conflict, and rejected-batch scenarios. Reorder the new cases so failure scenarios precede success scenarios.

As per coding guidelines, **/*_test.go: 测试组织顺序先写失败场景,再写成功场景。

🤖 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 `@tests/sessions_api_test.go` around lines 688 - 1043, Reorder the newly added
test functions so failure scenarios come before success scenarios: place
TestSessionEventQueueDeliveryRollsBackOnInboundFailure,
TestSessionStartupRejectsSecondUserMessage,
TestSessionStartupRejectedBatchHasNoSideEffects, and
TestSessionStartupSerializesConcurrentUserMessages before
TestManagedAgentActivationAtomicallyDeliversSessionEventQueue. Do not change
test implementations or behavior.

Source: Coding guidelines

internal/db/code_sessions.go (1)

359-372: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Queue-delete statement exists twice. Both sites changed to the same organizations/workspaces UUID-join predicate in this PR, so a future change to queue tenant scoping must be applied in two places and can silently diverge.

  • internal/db/code_sessions.go#L359-L372: replace the inline literal with the shared deleteSessionEventQueueQuery constant.
  • internal/db/sessions_sqlx.go#L127-L136: keep this as the single definition of the queue-delete predicate.
🤖 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 `@internal/db/code_sessions.go` around lines 359 - 372, The queue-delete SQL is
duplicated across both call sites. In internal/db/code_sessions.go lines
359-372, replace the inline statement in the deletedResult operation with the
shared deleteSessionEventQueueQuery constant; retain
internal/db/sessions_sqlx.go lines 127-136 as the sole definition of that
predicate.

Source: Coding guidelines

🤖 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 `@internal/codesessions/managed_agent_code_session.go`:
- Around line 189-210: Update listSessionEventsAscending to populate
ListSessionEventsPageParams.Types with the forwardable event types consumed by
inboundInputsFromPublicSessionEvents, so filtering occurs in the database;
preserve ascending pagination and existing error/termination behavior while
using a larger page size to reduce round trips.

---

Outside diff comments:
In `@tests/sessions_api_test.go`:
- Around line 3841-3878: Update sessionEventQueueEventIDs to left-join
session_events with an explicit e.session_id = s.id binding, while preserving
the tenant and workspace ownership predicates. Make the helper detect a missing
or mismatched event from the nullable left-join result and fail the test instead
of silently omitting the queue row.

---

Nitpick comments:
In `@internal/db/code_sessions.go`:
- Around line 359-372: The queue-delete SQL is duplicated across both call
sites. In internal/db/code_sessions.go lines 359-372, replace the inline
statement in the deletedResult operation with the shared
deleteSessionEventQueueQuery constant; retain internal/db/sessions_sqlx.go lines
127-136 as the sole definition of that predicate.

In `@tests/sessions_api_test.go`:
- Around line 688-1043: Reorder the newly added test functions so failure
scenarios come before success scenarios: place
TestSessionEventQueueDeliveryRollsBackOnInboundFailure,
TestSessionStartupRejectsSecondUserMessage,
TestSessionStartupRejectedBatchHasNoSideEffects, and
TestSessionStartupSerializesConcurrentUserMessages before
TestManagedAgentActivationAtomicallyDeliversSessionEventQueue. Do not change
test implementations or behavior.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e18f4e05-2362-4958-b95a-b18c0e986c52

📥 Commits

Reviewing files that changed from the base of the PR and between 112e515 and 73b2d10.

📒 Files selected for processing (7)
  • docs/design/be/session-startup-message-delivery.md
  • internal/codesessions/managed_agent_code_session.go
  • internal/db/code_sessions.go
  • internal/db/migrations/00038_use_uuid_session_event_queue_tenant_references.sql
  • internal/db/session_event_queue.go
  • internal/db/sessions_sqlx.go
  • tests/sessions_api_test.go

Comment thread internal/codesessions/managed_agent_code_session.go Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,且存在未解决的人工评审线程,需继续人工跟进。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@duckpr duckpr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DuckPR reviewer: opencode
Model: anthropic/glm-5.2

✅ 增量复审未发现新问题。

Reviewed changes — 复审了自上次评审(c5a63a4)以来的增量改动,聚焦将激活事务编排从 DB 层上移到 Service 层的重构。

  • 上移激活事务编排到 Service 层 — 新增 DB.WithManagedAgentActivationTx / ManagedAgentActivationTx 事务句柄,Service.ActivateManagedAgentCodeSessionWithQueue 接管跨资源编排(锁 Session → 锁 initializing Code Session → 匹配 queue → 写 inbound → 删 queue → 激活),DB 层只暴露资源级 SQL 方法。符合 AGENTS.md 中"DB 层只承担数据访问、不编排跨资源业务流程"的边界规则。
  • 抽取 appendCodeSessionEventSQLXTx — 将 Commit() 从事务内 helper 移除,提交责任归还调用方;ManagedAgentActivationTx.AppendCodeSessionInboundEvent 复用该 helper,事务边界保持一致。
  • 改用 typed errorSessionArchivedErrorSessionStartupMessageConflictError 取代 sentinel error,writeSendEventsPersistenceError 通过 errors.As 精确分派 409 / 400。
  • 测试同步更新TestManagedAgentActivationAtomicallyDeliversSessionEventQueue、rollback 测试改为通过 codeSessionService.ActivateManagedAgentCodeSessionWithQueue 调用,验证 Service 层编排路径。

事务语义(加锁顺序、queue 匹配重试、inbound 幂等、queue 行数校验、状态推进)与重构前完全等价;go build ./internal/... 通过。上一轮提出的 environment type 过滤问题(review 4825644921)在本增量中未改动,保持 open。

Pullfrog  | View workflow run | Using anthropic/glm-5.2𝕏

jh0904 added 2 commits August 1, 2026 14:18
…doff

Use package sentinel errors for archived and startup-conflict cases, and map
Send Events failures with inline errors.Is handlers. Rename activation and
queue helpers for clearer handoff (shouldEnqueue, QueueMatches, shouldQueueForStartup),
batch queue insert/list with session ownership checks, drop the delete-row-count
precondition, and keep the design doc aligned with the code entry points.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,且存在未解决的人工评审线程,需继续人工跟进。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@duckpr duckpr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DuckPR reviewer: opencode
Model: anthropic/glm-5.2

Caution

新增的 *.gen.go gitignore 规则导致 yourbatis 生成的 mapper 实现无法提交,从干净 clone 执行 go build ./... 会失败。

Reviewed changes — 复审了自上次评审(3fa3cbe)以来的增量改动,聚焦将 Send / 激活路径的 SQL 从手写 sqlx 迁移到 yourbatis 生成的按表 mapper。

  • 迁移 Send 与激活 SQL 到 yourbatis mapper — 新增 SessionMapperSessionThreadMapperSessionEventMapperSessionEventQueueMapperCodeSessionMapperCodeSessionInboundEventMapperEnvironmentWorkMapper 七个 mapper 接口与对应 XML,通过 go generate 生成静态 builder 与 scanner。AppendSessionEventsForDeliveryWithManagedAgentActivationTx 改用 yourbatis.DB.Transaction 开启事务。
  • 共享同一个 pgxpoolnewDB 通过 yourbatis.NewDB(database.DB, ...) 包装 sqlx 底层 *sql.DB,不建立第二个连接池,符合 AGENTS.md 的 sqlx/pgxpool 共享要求。
  • 保留 sqlx 用于未迁移事务 — Deployment 创建和 Session 删除仍使用 sqlx 事务链,queue 操作通过 shouldQueueForStartupSQLX / enqueueSessionEventsSQLXTx / deleteSessionEventQueueSQLX 保持在同一 sqlx 事务内。
  • 重命名事件判定函数forwardPublicEventToWorkershouldForwardPublicEventToWorkerhiddenWorkerEventisHiddenWorkerEventpublicWorkerOutputEventisPublicWorkerOutputEvent,并在 shouldForwardPublicEventToWorker 中新增 user.tool_confirmation 类型。
  • 新增 mapper builder 单测yourbatis_mappers_test.go 覆盖动态 SQL 构建(IN 列表、批量 INSERT、CAST jsonb)、参数绑定顺序和无效 UUID 前置校验。

🚨 yourbatis 生成文件被 gitignore 排除,干净 clone 无法编译

新增的 *.gen.go gitignore 规则会排除 yourbatis 生成的 *.sqlmap.gen.go 文件(如 code_session_mapper.sqlmap.gen.gosession_mapper.sqlmap.gen.go 等),而这些文件包含了代码直接引用的 NewCodeSessionMapperbuildSessionEventMapperListSessionEventsByUUIDs 等符号。从干净 clone 执行 go build ./internal/db/...undefined: NewCodeSessionMapper

CI 的 lint workflow(.github/workflows/lint.yml)在执行 golangci-lint ./... 前没有 go generate 步骤,因此 CI 会直接失败。设计文档(docs/design/be/session-startup-message-delivery.md:209)明确写着"仓库提交生成文件",但 .gitignore 与该意图矛盾。

Technical details
# 生成文件被 gitignore 排除导致编译失败

## Affected sites
- `.gitignore:72` — 新增 `*.gen.go` 规则,排除所有 yourbatis 生成的 `*.sqlmap.gen.go`
- `internal/db/managed_agent_activation.go:27` — 引用 `NewCodeSessionMapper`,该函数仅存在于被 gitignore 的 `code_session_mapper.sqlmap.gen.go`
- `internal/db/session_event_queue.go:73` — 同样引用 `NewCodeSessionMapper``NewSessionMapper`- `internal/db/yourbatis_mappers_test.go:54` — 测试引用 `buildCodeSessionInboundEventMapperListExistingActivationInboundEvents` 等生成函数
- `.github/workflows/lint.yml:32-34` — CI 直接跑 `golangci-lint ./...`,无 `go generate` 前置步骤
- `docs/design/be/session-startup-message-delivery.md:209` — 明确声明"仓库提交生成文件"

## Required outcome
- 干净 clone(不运行 `go generate`)必须能通过 `go build ./...` 和 CI lint

## Suggested approach
方案 A(与设计文档一致):删除 `.gitignore` 中的 `*.gen.go`,把生成的 `*.sqlmap.gen.go` 提交到仓库。
方案 B:在 CI workflow 和 pre-commit hook 中添加 `go generate ./internal/db` 前置步骤(但这改变了"仓库提交生成文件"的约定,需要同步更新设计文档)。

## Open questions for the human
- `*.gen.go` 是否有意为其他生成工具添加?如果是,需要用更具体的 pattern(如 `*.sqlmap.gen.go`)避免误排除 yourbatis 文件。

Note: 1 inline comment(s) dropped because they did not anchor to lines inside the PR diff:

  • .gitignore:49 (RIGHT) — line 49 (RIGHT) is not inside a diff hunk

Pullfrog  | Fix it ➔View workflow run | Using anthropic/glm-5.2𝕏

jh0904 added 2 commits August 3, 2026 23:34
Move inbound/outbound append onto mapperDB.Transaction with table mappers,
keeping lock/epoch/idempotency/sequence semantics, rename activation entry
to ActivateManagedAgentCodeSession, and update tests and design docs.
CI and local quality gates failed on a clean checkout because
*.sqlmap.gen.go is gitignored. Run scripts/generate-go.sh before
lint, dead-code, complexity, tests, server restart, and Docker build.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,需人工复审。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

Resolve yourbatis init (#200) conflicts: adopt v0.1.1 with logger-aware
db.Open/newDB, drop the accidental local ybatis replace, and keep this
branch's session startup error sentinels.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3e211a5c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/db/session_event_queue.go Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,需人工复审。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@duckpr duckpr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DuckPR reviewer: opencode
Model: anthropic/glm-5.2

✅ 增量复审未发现新问题。上一轮提出的 *.gen.go gitignore 导致干净 clone 编译失败的问题已修复。

Reviewed changes — 复审了自上次评审(c8c0ed0,review 4841932066)以来的增量改动,聚焦 yourbatis 生成文件在干净 checkout 中的可用性修复,以及与 origin/main(yourbatis init #200)的合并冲突解决。

  • 在所有 Go 质量门禁前统一生成 yourbatis mapper — 新增 scripts/generate-go.sh(仅 go generate ./internal/db),在 CI(lint.ymldead-code.ymlcomplexity.yml)、pre-commit(pre-commit-go-lint.shgo-dead-code.shgo-complexity.sh)、justfiletest/lint 依赖 generate-go)、Dockerfilego buildgo generate)和 restart-server.sh 中统一前置调用。本地验证 ./scripts/generate-go.sh && go build ./... 通过,上一轮 undefined: NewCodeSessionMapper 已消除。
  • pre-commit hook 触发面扩大到生成器输入golangci-lintgo-dead-codego-complexity 三个 local hook 的 files 正则新增 internal/db/*.xmlscripts/generate-go.sh,使 mapper XML 变更能触发重新生成与对应 package 的 lint;pre-commit-go-lint.shgo.mod/go.sum/scripts/generate-go.sh 输入映射到 ./... 全量 lint。
  • 合并 origin/main(yourbatis init #200f65c999 解决冲突:丢弃本地 replace ybatis => ... 误提交,采用 yourbatis v0.1.1internal/logging 注入的 db.Open/newDB,保留本分支的 ErrSessionStartupMessageConflict 等 session 启动 sentinel error。go build ./...go vet ./internal/db/... ./internal/codesessions/... ./internal/sessions/... 均通过。
  • 设计文档同步session-startup-message-delivery.mddevelopment-quality-gates.md 更新为"仓库不提交生成文件,scripts/generate-go.sh 为统一生成入口",与本轮选择的方案 B 一致。

 Pullfrog  | View workflow run | Using anthropic/glm-5.2 | 𝕏

Pullfrog  | View workflow run | Using anthropic/glm-5.2𝕏

Bring in #202 (stop tracking generated Go mappers). Keep a unified
scripts/generate-go.sh entry point (go generate ./internal/db) for just,
CI, pre-commit, Docker, and local quality scripts.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,需人工复审。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@duckpr duckpr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DuckPR reviewer: opencode
Model: anthropic/glm-5.2

✅ 增量复审未发现新问题。

Reviewed changes — 复审了自上次评审(f65c999,review 4846232579)以来的增量改动,即 merge origin/main 引入 PR #202 "Stop tracking generated Go mapper sources"。

  • 合入 *.gen.go 不入库策略 — PR #202 确定了 yourbatis 生成文件不入库的最终方案:.gitignore 新增 *.gen.go,删除已跟踪的 admin_api_keys_mapper.sqlmap.gen.go / console_api_keys_mapper.sqlmap.gen.go。与本分支上一轮选择的方向一致。
  • 统一生成入口覆盖到所有门禁scripts/generate-go.shgo generate ./internal/db)在 CI(lint.yml / dead-code.yml / complexity.yml)、pre-commit(新增 go-generate hook + 三个 Go hook 的 files 正则改用 internal/db/*_mapper.xml)、justfilegenerate recipe,test / lint / dead-code / go-complexity / hooks-run 均依赖它)、Dockerfile(独立 RUN ./scripts/generate-go.sh)和 AGENTS.md 中统一前置调用。
  • 干净 checkout 验证通过 — 本地 ./scripts/generate-go.sh && go build ./... 成功,上一轮 review 4841932066 报告的 undefined: NewCodeSessionMapper 编译失败已彻底消除。

PullfrogView workflow run | Using anthropic/glm-5.2𝕏

Pullfrog  | View workflow run | Using anthropic/glm-5.2𝕏

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c7c4c908bc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +310 to +314
existing, err := listExistingActivationInboundEvents(
ctx,
tx.codeSessionInboundEventMapper,
codeSession,
inputs,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Batch the activation idempotency lookup

When activation replays more than roughly 65,533 distinct forwardable events, listExistingActivationInboundEvents expands every idempotency key into one IN parameter, plus the organization and workspace parameters, exceeding PostgreSQL's 65,535 bind-parameter limit. The later inserts are batched at 500 rows, but this preliminary unbatched lookup fails first, so a large-history session cannot activate and its managed-agent launch is cleaned up; split this lookup into bounded batches as well.

Useful? React with 👍 / 👎.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,需人工复审。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8819d8624e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

#{row.EventSubtype},
#{row.PayloadUUID},
#{row.RequestID},
CAST(#{row.Payload} AS jsonb),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Redact event payloads in mapper diagnostics

When YOURBATIS_DEBUG diagnostics are enabled, this binding treats the complete session event payload as an ordinary argument, so user prompts, tool results, or embedded credentials can be rendered into database logs; existing secret-bearing mapper parameters use sensitive=true for this reason. Mark row.Payload sensitive here and in the batch inbound and outbound insert bindings so diagnostics expose only redacted metadata rather than raw request content.

AGENTS.md reference: AGENTS.md:L62-L62

Useful? React with 👍 / 👎.

@duckpr duckpr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DuckPR reviewer: opencode
Model: anthropic/glm-5.2

ℹ️ 未发现关键问题——仅一处格式 nit 和一个 PR 描述同步建议。

Reviewed changes — 复审了自上次评审(c7c4c90)以来的增量改动。本轮提交是对整个投递机制的架构级重构:彻底移除 session_event_queue 表及其全部 mapper / SQL / helper,改为在 Code Session 激活事务中一次性读取完整 session_events 公开历史并重放入 inbound,通过 Session 行锁在 Send 与 Activate 之间串行化。

  • 移除 session_event_queue 全部代码与 migration — 删除 session_event_queue.gosession_event_queue_mapper.{go,xml}session_event_queue_sqlx.go 以及 migration 00047_add_session_event_queue.sqlAppendSessionEventsForDelivery 合并回普通 AppendSessionEvents,不再区分 startup_queued / realtime delivery。migration 00047 从未进入 main,整文件删除是正确的清理方式,不会产生孤儿表。
  • 激活改为完整历史重放ActivateManagedAgentCodeSession 锁 Session → 锁 initializing Code Session → 读取完整 session_eventscreated_at ASC, id ASC)→ 过滤可转发事件 → 幂等批量写入 inbound → 切 active,全部在同一事务。Runner prepareManagedAgentLaunch 不再读取事件快照。
  • 行为变化:不再限制单条启动消息 — 旧设计在启动窗口对第二条 user.message 返回 409;新设计接受多条启动消息,activation 按历史顺序全部重放。相应测试(TestSessionStartupRejectsSecondUserMessage 等)已删除,改为 TestManagedAgentActivationReplaysStartupHistory 验证两条启动消息的重放顺序。
  • 并发正确性验证 — Send 与 Activate 都通过 SELECT ... FOR UPDATE 锁同一条 Session 行;cutover 竞态由 inbound 幂等键去重(eventIdempotencyKey 基于 codeSessionID + direction + payloadUUID,两条路径对同一公开事件产生相同 key)。原 Issue #189 的消息丢失窗口已消除。

ℹ️ PR 描述与当前实现不一致

PR 描述(GitHub PR body)仍然详细描述 queue-based 设计(session_event_queue、409-on-second-message、startup_queued delivery outcome、单条限制),但代码已改为历史重放方案。分支上的设计文档 docs/design/be/session-startup-message-delivery.md 已正确反映新方案,建议同步更新 PR 描述的"方案"、"关键改动"和"行为变化"表格,使其与设计文档一致,避免后续维护者误以为仍有 queue 表和 409 限制。

PullfrogView workflow run | Using anthropic/glm-5.2𝕏

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using anthropic/glm-5.2𝕏

Comment thread internal/db/session_event_mapper.xml Outdated
deleted_at
</sql>

<select id="ListSessionEventsForActivation" resultType="sessionEventRow">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ 这一行的 <select> 标签使用了 Tab 缩进,而文件内其他所有行(以及同级 mapper XML 如 session_mapper.xml)都使用 4 个空格。建议改为 4 空格以保持一致性,避免 pre-commit 的 Prettier / XML 格式化检查报错。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

已在 4d76cdb 中改为 4 空格缩进。

Pullfrog  | View workflow run | via Pullfrog | Using anthropic/glm-5.2𝕏

Rename the locked code-session row variable to avoid confusion with
public sessions, document idempotent append branches, and fix mapper
XML indentation.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,需人工复审。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

未批准:Cursor Bugbot 首轮未出现,已跳过该信号;PR 仍为 CHANGES_REQUESTED,需人工复审。arthur-zhang 已在审阅请求中,未新增其他 reviewer。

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@jh0904
jh0904 merged commit c8ed2f1 into main Aug 4, 2026
8 checks passed

@duckpr duckpr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DuckPR reviewer: opencode
Model: anthropic/glm-5.2

✅ 增量复审未发现新问题。激活锁的租户范围加固和分批查重实现正确,编译与测试通过。

Reviewed changes — 复审了自上次评审(f65c999,review 4846232579)以来的增量改动,聚焦激活路径的租户范围加固与分批查重。

  • 为激活锁增加 workspace_uuid 租户谓词LockInitializingCodeSession 新增 workspaceUUID 参数,code_session_mapper.xmlLockInitializingCodeSession 查询从 WHERE uuid = #{codeSessionUUID} 改为 WHERE workspace_uuid = #{workspaceUUID} AND uuid = #{codeSessionUUID}SELECT FOR UPDATE 现在在 workspace 范围内锁定,符合 AGENTS.md 中多租户边界显式化的要求。
  • 分批查重避免大历史超出参数上限listExistingActivationInboundEvents 将 idempotency key 查重改为按 managedAgentActivationInboundBatchSize(500)分批执行,避免超长 session 历史触发 PostgreSQL IN 列表参数限制。每批仍保留 CodeSessionExternalID 交叉校验作为 data integrity guard。
  • 移除未使用的 GetLatestCodeSessionStatus — mapper 接口、XML 和生成代码中的 GetLatestCodeSessionStatus 已全部删除,无残留引用。
  • 新增覆盖测试TestTableMappersBuildDynamicQueries/activation_code_session_lock 验证锁定 SQL 包含 workspace_uuid 谓词;TestListExistingActivationInboundEventsBatchesLookup 验证 501 个 key 恰好产生 2 次查询调用。

go build ./internal/db/... ./internal/codesessions/... ./internal/sessions/... 通过;TestTableMappersBuildDynamicQueriesTestTableMappersBuildWritesTestListExistingActivationInboundEventsBatchesLookup 均通过。

PullfrogView workflow run | Using anthropic/glm-5.2𝕏

Pullfrog  | View workflow run | Using anthropic/glm-5.2𝕏

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.

Cloud Session 启动过程中,已成功发送的消息可能到不了 agent

2 participants