Skip to content

Commit e537727

Browse files
committed
test(remote-connect): add runtime migration snapshots
1 parent 03fb59e commit e537727

7 files changed

Lines changed: 396 additions & 27 deletions

File tree

AGENTS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ and milestone verification gates.
155155
`bitfun-services-integrations`; tracker state and tracker event reduction
156156
belong in `bitfun-services-integrations`, while core still owns dispatcher
157157
assembly, session restore, terminal pre-warm, and product execution routing.
158+
Remote runtime owner migration must preserve the existing migration snapshots
159+
for command/response shape, restore, active-turn polling, cancel decisions,
160+
image context fallback/preference, tracker fanout, and RemoteRelay/Bot queue
161+
policy.
158162
`AgentSubmissionPort` still rejects generic attachments until
159163
image/multimodal equivalence tests and a runtime migration plan are reviewed.
160164

docs/architecture/core-decomposition.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ owner 边界,否则不要把一个 feature group 继续拆成更小的 crate
100100
- remote-connect tracker state 可由 `bitfun-services-integrations` 拥有;core 只保留
101101
`EventSubscriber` adapter、global dispatcher、session restore、terminal pre-warm 和实际
102102
dialog submission routing。不要把 tracker state 回写到 core。
103+
- remote-connect runtime owner 外移前必须保持迁移前快照:remote command/response
104+
shape、restore target、active-turn poll snapshot、cancel decision、image context fallback
105+
/ preference、tracker fanout 与 RemoteRelay/Bot queue policy。
103106
- `bitfun-core-types` 不得依赖 runtime manager、service crate、agent runtime、
104107
app crate、Tauri、network client、process execution,或 `git2``rmcp``image`
105108
`tokio-tungstenite` 等重集成依赖。

docs/plans/core-decomposition-plan.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,13 +976,14 @@ product-full = ["git", "mcp", "remote-ssh", "remote-connect", "announcement", "f
976976
- [x] 先完成 `remote-connect` contract slice:remote chat/image/tool/session wire DTO 与 relay/bot session/submission request builder 由 `bitfun-services-integrations` 拥有,relay/bot session 创建通过 `AgentSubmissionPort`
977977
- [x] 已补齐 remote runtime 迁移前的第一层 port baseline:`SessionTranscriptReader``AgentTurnCancellationPort``RemoteControlStatePort``RuntimeEventSink` 与 remote image attachment/request DTO;完整 `remote-connect` runtime 仍需后续单独迁移并补 queue/event/image 行为等价测试。
978978
- [x] `RemoteSessionStateTracker``TrackerEvent` 与 remote tool preview slimming helper 已迁入 `bitfun-services-integrations`;core 只保留 `EventSubscriber` adapter、dispatcher、session restore、terminal pre-warm 与实际 dialog submission routing。
979+
- [x] 已补齐 remote-connect runtime 迁移前快照:remote command/response wire shape、session restore target、active turn poll snapshot、cancel decision、legacy image fallback / unified image context preference、tracker completion/fanout 与 RemoteRelay/Bot queue policy 均有 focused regression。
979980
- [x] 已迁移的集成能力保持 core 旧路径 re-export。
980981
- [x] 产品完整 runtime 通过 `services-integrations/product-full` 启用已迁移集成能力。
981982

982983
**当前安全迁移状态(2026-05-15):**
983984

984985
- 已迁移到 `bitfun-services-integrations``service::file_watch`,通过 `file-watch` / `product-full` feature 启用,并保持 `core::service::file_watch` 旧路径。
985-
- `git` 已完成 DTO/params/graph/raw command output/text parser/arg builder、`GitError`、`GitService` runtime implementation 与 git utils 迁移;`bitfun-core::service::git::*` 仅保留 legacy facade re-export。`remote-ssh` 已迁移纯 contract/type、workspace path/identity helper 与 unresolved-session-key helper;SSH runtime manager / fs / terminal、password vault 与 PathManager-backed session mirror assembly 仍保留在 core。`mcp` 已迁移 tool-name / tool-info / protocol types / config location / server type-status、server config、cursor-format、JSON-RPC request builder、JSON config format/validation helper、config merge / remote authorization helper、OAuth credential vault / authorization bootstrap contract、remote auth error classifier、legacy remote header fallback helper、transport Authorization 归一化 helper、remote client capability helper、rmcp 到 BitFun protocol 的纯映射 helper、resource/prompt adapter、catalog cache、list-changed/reconnect policy、config service save-load orchestration、server process / local-remote transport lifecycle、dynamic tool descriptor / provider / result rendering helper,并用 owner crate contract test 锁定 wire shape、transport default、validation message、Cursor 兼容格式、config precedence / dedup 语义、OAuth vault 存储路径注入、NeedsAuth 分类、旧 env Authorization fallback、remote client capabilities、remote result metadata / structured content 映射、config load/save/delete contract、unsupported remote transport contract、context resource selection 和 dynamic manifest;`bitfun-core` 继续负责 core `ConfigService` store adapter、OAuth data-dir 注入、`BitFunError` 映射、legacy facade 和全局 tool registry / manifest 组装。`announcement` 仅迁移了纯 types contract,scheduler / state store / content loader / remote fetch 仍保留在 core;`remote-connect` 已完成 contract/request-builder slice,补齐 cancellation/state/event/image 第一层 port baseline,并迁出 tracker state / tracker event reduction / remote tool preview slimming helper,但远程消息执行、image context 真正接入、terminal pre-warm 与 workspace/session restore 仍保留在 core。它们涉及 SSH runtime、remote agent submission runtime、product tool manifest/exposure owner 化与 announcement config/path 边界,继续前需要单独确认端口方案与等价性测试。
986+
- `git` 已完成 DTO/params/graph/raw command output/text parser/arg builder、`GitError`、`GitService` runtime implementation 与 git utils 迁移;`bitfun-core::service::git::*` 仅保留 legacy facade re-export。`remote-ssh` 已迁移纯 contract/type、workspace path/identity helper 与 unresolved-session-key helper;SSH runtime manager / fs / terminal、password vault 与 PathManager-backed session mirror assembly 仍保留在 core。`mcp` 已迁移 tool-name / tool-info / protocol types / config location / server type-status、server config、cursor-format、JSON-RPC request builder、JSON config format/validation helper、config merge / remote authorization helper、OAuth credential vault / authorization bootstrap contract、remote auth error classifier、legacy remote header fallback helper、transport Authorization 归一化 helper、remote client capability helper、rmcp 到 BitFun protocol 的纯映射 helper、resource/prompt adapter、catalog cache、list-changed/reconnect policy、config service save-load orchestration、server process / local-remote transport lifecycle、dynamic tool descriptor / provider / result rendering helper,并用 owner crate contract test 锁定 wire shape、transport default、validation message、Cursor 兼容格式、config precedence / dedup 语义、OAuth vault 存储路径注入、NeedsAuth 分类、旧 env Authorization fallback、remote client capabilities、remote result metadata / structured content 映射、config load/save/delete contract、unsupported remote transport contract、context resource selection 和 dynamic manifest;`bitfun-core` 继续负责 core `ConfigService` store adapter、OAuth data-dir 注入、`BitFunError` 映射、legacy facade 和全局 tool registry / manifest 组装。`announcement` 仅迁移了纯 types contract,scheduler / state store / content loader / remote fetch 仍保留在 core;`remote-connect` 已完成 contract/request-builder slice,补齐 cancellation/state/event/image 第一层 port baseline,迁出 tracker state / tracker event reduction / remote tool preview slimming helper,并补齐 remote command/response、restore、active turn、cancel、image context、tracker fanout 与 queue policy 迁移前快照;但远程消息执行、image context 真正接入、terminal pre-warm 与 workspace/session restore 仍保留在 core。它们涉及 SSH runtime、remote agent submission runtime、product tool manifest/exposure owner 化与 announcement config/path 边界,继续前需要单独确认端口方案与等价性测试。
986987
- 最新主干的 Deep Review capacity / cost / queue、context profile、evidence ledger、session manifest、stream dedupe、search remote/fallback 与 session rollback persistence 仍属于 core runtime 或对应产品 runtime,不在本轮 `services-integrations` 迁移范围内;如果后续迁移 remote-connect / MCP / search / session,需要先定义运行状态 port 合约和等价测试。
987988

988989
**验证:**
@@ -1726,7 +1727,7 @@ git diff -- package.json scripts/dev.cjs scripts/desktop-tauri-build.mjs scripts
17261727
14. 已完成:remote-connect tracker owner slice:产品表面 DTO 已以 contract-only 方式进入 `bitfun-core-types``bitfun-services-integrations``remote-connect` feature 拥有 remote chat/image/tool/session wire DTO、relay/bot session/submission request builder、remote image attachment/request DTO、tracker state 与 tracker event reduction;relay/bot 创建 session 通过 `AgentSubmissionPort`,取消、远程状态读取和事件事实已有 `runtime-ports` 契约。远程消息执行、image context 真正接入、terminal pre-warm 与 workspace/session restore 仍保留在 `bitfun-core` product runtime assembly。
17271728
15. 已完成:agent tools + `tool-packs` owner 化低风险闭环;tool contract / DTO、runtime restriction、path resolution、generic registry / dynamic provider container 已归属 `bitfun-agent-tools`,core 保留产品工具列表、snapshot decorator、`ToolUseContext` 和 concrete tool implementation,后续外移需单独 port/provider 设计。
17281729
16. 已完成:关键语义回归 baseline,不移动 runtime owner。覆盖 MCP config failure / catalog invalidation / 既有 list-changed helper / dynamic manifest、tool manifest / `GetToolSpec`、product-domains adapter equivalence、remote workspace search fallback 的 focused tests 或 snapshots。
1729-
17. 下一步:remote-connect runtime 迁移前快照。先基于当前 port baseline 记录 remote session restore、active turn、cancel、image context、tracker event、queue/event fanout 的输入输出和验证命令;证明等价后再移动 runtime owner,不能把 generic attachment guard 当作已接入多模态行为。
1730+
17. 已完成:remote-connect runtime 迁移前快照。已基于当前 port baseline 记录 remote session restore、active turn、cancel、image context、tracker event、queue/event fanout 的输入输出和验证命令;后续只有在这些 focused regression 继续通过时才允许移动 runtime owner,不能把 generic attachment guard 当作已接入多模态行为。
17301731
18. 后续高风险单独审视:`product-domains` runtime + core facade finalization 的剩余 PathManager、process execution、Git/AI service、prompt template、host dispatch 执行与 worker/storage IO owner 迁移;不得与当前 PR2/PR3 混合。
17311732
19. 后续独立评估:`bitfun-core default = []`、per-product feature set、依赖版本收敛或构建收益优化;任何收益声明都需要记录 `cargo check -p bitfun-core`、workspace check 和目标 crate check 的前后数据。
17321733

scripts/check-core-boundaries.mjs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,6 +1837,28 @@ function runManifestParserSelfTest() {
18371837
'resolve_remote_agent_type',
18381838
],
18391839
},
1840+
{
1841+
path: 'src/crates/services-integrations/tests/remote_connect_contracts.rs',
1842+
contracts: [
1843+
'remote_connect_tracker_keeps_finished_turn_snapshot_until_persistence_finalizes',
1844+
'remote_connect_tracker_ignores_unrelated_direct_session_events',
1845+
'remote_connect_tool_preview_slimming_keeps_short_fields_and_drops_large_strings',
1846+
],
1847+
},
1848+
{
1849+
path: 'src/crates/core/src/service/remote_connect/remote_server.rs',
1850+
contracts: [
1851+
'remote_execution_prefers_unified_image_contexts_over_legacy_images',
1852+
'remote_cancel_decision_preserves_current_turn_boundaries',
1853+
'remote_restore_target_only_restores_cold_sessions_with_workspace_binding',
1854+
'remote_command_snapshot_covers_execution_poll_and_cancel_surfaces',
1855+
'remote_response_snapshot_preserves_active_turn_and_result_shapes',
1856+
],
1857+
},
1858+
{
1859+
path: 'src/crates/core/src/agentic/coordination/scheduler.rs',
1860+
contracts: ['remote_queue_policy_preserves_interactive_preempt_and_confirmation_boundary'],
1861+
},
18401862
{
18411863
path: 'src/crates/core/src/agentic/tools/registry.rs',
18421864
contracts: ['register_all_tools', 'GetToolSpecTool', 'get_collapsed_tool_names'],

src/crates/core/src/agentic/coordination/scheduler.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,7 @@ Status: {status}"
747747
if let Err(e) = self.dispatch_next_if_idle(&session_id).await {
748748
warn!(
749749
"Failed to dispatch next queued message after {}: session_id={}, error={}",
750-
status,
751-
session_id,
752-
e
750+
status, session_id, e
753751
);
754752
}
755753
}
@@ -817,4 +815,22 @@ mod tests {
817815
&completed, true
818816
));
819817
}
818+
819+
#[test]
820+
fn remote_queue_policy_preserves_interactive_preempt_and_confirmation_boundary() {
821+
let remote = DialogSubmissionPolicy::for_source(DialogTriggerSource::RemoteRelay);
822+
assert_eq!(remote.queue_priority, DialogQueuePriority::Normal);
823+
assert!(remote.skip_tool_confirmation);
824+
assert!(DialogScheduler::user_message_may_preempt(&remote));
825+
826+
let bot = DialogSubmissionPolicy::for_source(DialogTriggerSource::Bot);
827+
assert_eq!(bot.queue_priority, DialogQueuePriority::Normal);
828+
assert!(bot.skip_tool_confirmation);
829+
assert!(DialogScheduler::user_message_may_preempt(&bot));
830+
831+
let agent_session = DialogSubmissionPolicy::for_source(DialogTriggerSource::AgentSession);
832+
assert_eq!(agent_session.queue_priority, DialogQueuePriority::Low);
833+
assert!(agent_session.skip_tool_confirmation);
834+
assert!(!DialogScheduler::user_message_may_preempt(&agent_session));
835+
}
820836
}

0 commit comments

Comments
 (0)