Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/architecture/core-decomposition.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,17 @@ BitFun 的重构目标不是把 Desktop、CLI、Remote、Server 和 ACP 强行
产品形态时,`product-full` 才可以包含它们。
- 最终要么让 `bitfun-core/product-full` 显式聚合已经验证过的 owner crate capability feature,
要么持续声明它不是完整能力矩阵;不得用它证明未迁移 runtime 已经完成 owner 化。
- H5 已启动的第一步只允许补齐现有 optional feature 的编译边界。当前先让
`cargo check -p bitfun-core --no-default-features` 通过,并在 `ssh-remote` 关闭时保留
remote workspace identity/helper、让实际 SSH/SFTP/terminal/search runtime 返回明确
unsupported;这不是 remote-SSH runtime owner 迁移,也不改变 `product-full` 或产品发布形态。
- H5 后续推进只允许把 owner crate feature 传播显式化,保持
`default = ["product-full"]`、产品 crate `features = ["product-full"]` 和 release/CI
形态不变。no-default core 可以收敛为 runtime-surface-light facade;`tool-packs` 和
`product-domains` 可由 core feature 显式启用为 optional dependency,但这不代表整体
dependency graph 或构建收益已经完成优化。agentic runtime、MiniApp/function-agent、
Git/MCP/remote-connect/review-platform 等完整产品入口必须继续由 `product-full` 或对应
owner feature 打开。
- 拆解完成后不要自动移除或减轻 `product-full`。如果未来要用 per-product explicit
feature set 替代它,必须作为 P3 之后的独立评估,并且先通过完整产品矩阵。
- 不要把 feature 默认值变更和模块移动放在同一个变更中。
Expand Down
32 changes: 31 additions & 1 deletion docs/plans/core-decomposition-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,29 @@ owner-by-owner 迁移队列,不得把它们当作 H4 漏项补进当前 PR。
| HR3:service / agent runtime deep owner migration | 条件性高风险 PR | 当前已完成 core 内部 `service_agent_runtime.rs` 单一 owner 收口;remote-SSH manager / remote FS / terminal、remote-connect workspace-root source / response wrapping / `ImageContextData` concrete impl / concrete scheduler-session-restore-terminal adapter、agent registry / scheduler 继续显式 core-owned;后续若继续深迁移,只允许在单独评审后移动一个 owner 主题 | tool runtime、product-domain runtime、feature matrix 或产品逻辑变更 | 有 port/provider 设计、旧路径兼容、mode-scoped subagent visibility / background delivery / remote-connect dialog order / remote workspace guard / DeepResearch post-turn hook 等行为等价测试 |
| H5:feature/build-benefit evaluation | 可选评估 PR | `bitfun-core default = []`、per-product explicit feature set、依赖版本收敛、构建收益数据记录 | 任何 runtime owner 迁移、产品逻辑变更或构建脚本改造 | 有 feature graph baseline、`cargo check -p bitfun-core`、workspace check、目标 crate check 和必要 product check 的前后数据;若收益不清晰则不执行 |

**H5 start(2026-05-21):** 本轮先完成 feature graph baseline 的第一道编译门禁:
`cargo check -p bitfun-core --no-default-features`。当前结论是 `bitfun-core`
已有 `ssh-remote` optional dependency 边界,但源码仍曾无条件编译 remote-SSH
runtime;H5 的第一步只补齐 `ssh-remote` source gate 和 disabled diagnostic surface,
不迁移 remote-SSH runtime owner,不改变 `product-full`、产品 feature set、CI/release
脚本或任何产品行为。per-product feature matrix 仍需要在 no-default 编译闭环稳定后
单独评估。

**H5 follow-up(2026-05-21):** 在 PR #824 合入后,继续把 `bitfun-core/product-full`
改为显式聚合 owner crate feature group:`tool-packs`、`services-integrations` 和
`product-domains` 不再通过 dependency declaration 强制启用 `product-full`,其中
`tool-packs` 与 `product-domains` 在 core 中改为 optional dependency,由
`bitfun-core` 的 feature graph 显式启用。`services-integrations` 仍因 remote workspace
identity/helper 的纯 helper 需求保留 no-default 编译面,只启用 `remote-ssh` owner feature,
不启用完整 product-full。`default = ["product-full"]`、desktop/CLI/ACP
等产品 crate 的 `features = ["product-full"]`、release/CI 脚本和用户可见能力保持不变。
no-default core 当前只承诺 runtime-surface-light facade 可编译,不声明 dependency graph
或构建收益已经变轻:agentic runtime、MiniApp/function-agent、
Git/MCP/remote-connect/review-platform、snapshot/token/runtime usage 等完整产品入口继续由
`product-full` 或对应 owner feature 打开。remote workspace identity/helper 因为
session/workspace 路径稳定性仍保留在 no-default 编译面;russh-backed SSH/SFTP/terminal/search
runtime 仍由 `ssh-remote` 控制。

**HR 风险与优化清单:**

所有 HR PR 都必须满足以下共同约束:
Expand Down Expand Up @@ -2091,7 +2114,14 @@ git diff -- package.json scripts/dev.cjs scripts/desktop-tauri-build.mjs scripts
31. 已完成:H1 product provider plan closure。`bitfun-tool-packs::product_tool_provider_group_plan` 接管 product provider group id / feature group / tool-name order 计划,core `product_runtime.rs` 只按该计划物化 concrete tools 并继续注入 snapshot wrapper;不迁移 concrete tool implementation、`ToolUseContext`、runtime service handles 或 tool behavior。
32. HR1 当前闭环状态:工具 runtime 的 provider-neutral contract、manifest/catalog runtime facade、GetToolSpec facade、static-provider assembly、readonly filtering、provider plan 与 core product adapter 已收敛;core 内部 product runtime adapter 已统一到 `product_runtime.rs`。`ToolUseContext` 本体和 concrete tools 仍显式 core-owned;继续外移会触碰 workspace services、cancellation、Deep Review hooks 或具体工具 IO,必须作为后续高风险 owner 迁移单独确认。
33. H4 已完成:facade / boundary finalization。`scripts/check-core-boundaries.mjs` 的 regular check 和 self-test 已覆盖 remote-connect file/image/dialog owner anchor、core adapter/deferred owner anchor 与既有 duplicate-path required rule;root / core / services-integrations 文档与当前 H1-H3 代码状态一致,不声明 remote-SSH runtime、agent registry/scheduler、default feature 或构建收益已完成。
34. 后续独立评估:`bitfun-core default = []`、per-product feature set、依赖版本收敛或构建收益优化;任何收益声明都需要记录 `cargo check -p bitfun-core`、workspace check 和目标 crate check 的前后数据。
34. H5 已启动并完成当前闭环:第一步建立 `bitfun-core --no-default-features` 编译闭环,
证明 `ssh-remote` 关闭时不再编译 russh-backed runtime,并通过 disabled surface
返回明确 unsupported 诊断;第二步把 `bitfun-core/product-full` 改为显式聚合
`tool-packs`、`services-integrations`、`product-domains` 的 owner feature group;
其中 `tool-packs` 与 `product-domains` 已成为 core optional dependency,
同时保持 `default = ["product-full"]`、产品 crate feature set、release/CI 脚本和
用户可见能力不变。no-default core 当前只作为 runtime-surface-light facade,不声明
dependency graph 已变轻、per-product feature matrix、构建收益或 runtime owner 深迁移已完成。

冗余清理 PR 不进入上述主线序号。只有在满足 `0A.6` 的绝对等价要求时,才可以插入到相邻里程碑之间,并且不得与主线拆分 PR 混合。

Expand Down
288 changes: 288 additions & 0 deletions scripts/check-core-boundaries.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,191 @@ const forbiddenContentUnderRules = [
];

const requiredContentRules = [
{
path: 'src/crates/core/Cargo.toml',
reason:
'bitfun-core product-full must explicitly aggregate owner crate feature groups instead of forcing them through dependency declarations',
patterns: [
{
regex:
/bitfun-tool-packs = \{ path = "\.\.\/tool-packs", default-features = false, optional = true \}/,
message: 'bitfun-tool-packs dependency must stay optional and not force product-full outside the core feature graph',
},
{
regex:
/bitfun-services-integrations = \{ path = "\.\.\/services-integrations", default-features = false, features = \["remote-ssh"\] \}/,
message:
'bitfun-services-integrations dependency may keep remote workspace identity helpers but must not force product-full outside the core feature graph',
},
{
regex:
/bitfun-product-domains = \{ path = "\.\.\/product-domains", default-features = false, optional = true \}/,
message:
'bitfun-product-domains dependency must stay optional and not force product-full outside the core feature graph',
},
{
regex: /"dep:bitfun-tool-packs"/,
message: 'core tool-packs feature must explicitly enable the optional dependency',
},
{
regex: /"bitfun-tool-packs\/product-full"/,
message: 'core product-full must explicitly enable tool pack product features',
},
{
regex: /"bitfun-services-integrations\/product-full"/,
message: 'core product-full must explicitly enable integration product features',
},
{
regex: /"dep:bitfun-product-domains"/,
message: 'core product-domains feature must explicitly enable the optional dependency',
},
{
regex: /"bitfun-product-domains\/product-full"/,
message: 'core product-full must explicitly enable product-domain features',
},
],
},
{
path: 'src/crates/core/src/lib.rs',
reason:
'no-default bitfun-core must keep product runtime surfaces behind explicit features',
patterns: [
{
regex: /#\[cfg\(feature = "product-full"\)\]\s*pub mod agentic\b/s,
message: 'agentic runtime must stay behind product-full for no-default builds',
},
{
regex: /#\[cfg\(feature = "product-domains"\)\]\s*pub mod function_agents\b/s,
message: 'function-agent product domain facade must stay behind product-domains',
},
{
regex: /#\[cfg\(feature = "product-domains"\)\]\s*pub mod miniapp\b/s,
message: 'MiniApp product domain facade must stay behind product-domains',
},
{
regex: /#\[cfg\(feature = "service-integrations"\)\]\s*pub\(crate\) mod service_agent_runtime\b/s,
message: 'service agent runtime owner assembly must stay behind service-integrations',
},
],
},
{
path: 'src/crates/core/src/service/mod.rs',
reason:
'service integration and agent-runtime surfaces must not compile in no-default core builds',
patterns: [
{
regex: /#\[cfg\(feature = "service-integrations"\)\]\s*pub mod git\b/s,
message: 'git service facade must stay behind service-integrations',
},
{
regex: /#\[cfg\(feature = "service-integrations"\)\]\s*pub mod mcp\b/s,
message: 'MCP service facade must stay behind service-integrations',
},
{
regex: /#\[cfg\(feature = "service-integrations"\)\]\s*pub mod remote_connect\b/s,
message: 'remote-connect service facade must stay behind service-integrations',
},
{
regex: /#\[cfg\(feature = "service-integrations"\)\]\s*pub mod review_platform\b/s,
message: 'review platform facade must stay behind service-integrations',
},
{
regex: /#\[cfg\(feature = "product-full"\)\]\s*pub mod snapshot\b/s,
message: 'snapshot service must stay behind product-full until tool-runtime ownership is split',
},
],
},
{
path: 'src/crates/core/src/service/config/mod.rs',
reason:
'mode config canonicalization depends on product agent/tool registries and must stay out of no-default builds',
patterns: [
{
regex: /#\[cfg\(feature = "product-full"\)\]\s*pub mod mode_config_canonicalizer\b/s,
message: 'mode config canonicalizer must stay behind product-full',
},
],
},
{
path: 'src/crates/core/src/service/workspace/manager.rs',
reason:
'workspace metadata may omit git worktree enrichment when service integrations are disabled',
patterns: [
{
regex: /#\[cfg\(feature = "service-integrations"\)\]\s*use crate::service::git::GitService\b/s,
message: 'GitService import must stay gated for no-default builds',
},
{
regex: /#\[cfg\(not\(feature = "service-integrations"\)\)\]\s*\{\s*let _ = workspace_root;\s*return None;\s*\}/s,
message: 'no-default worktree enrichment fallback must remain explicit',
},
],
},
{
path: 'src/crates/core/src/service/workspace_runtime/service.rs',
reason:
'workspace runtime binding helpers may depend on agentic runtime only in full product builds',
patterns: [
{
regex: /#\[cfg\(feature = "product-full"\)\]\s*use crate::agentic::WorkspaceBinding\b/s,
message: 'WorkspaceBinding import must stay gated for no-default builds',
},
{
regex: /#\[cfg\(feature = "product-full"\)\]\s*pub async fn ensure_runtime_for_workspace_binding\b/s,
message: 'WorkspaceBinding runtime helper must stay behind product-full',
},
],
},
{
path: 'src/crates/core/src/service/remote_ssh/mod.rs',
reason:
'core remote SSH runtime must keep concrete SSH dependencies behind the ssh-remote feature while preserving lightweight workspace identity helpers',
patterns: [
{
regex: /#\[cfg\(not\(feature = "ssh-remote"\)\)\]\s*mod disabled\b/s,
message: 'missing disabled remote SSH runtime surface for no-default builds',
},
{
regex: /#\[cfg\(feature = "ssh-remote"\)\]\s*pub mod manager\b/s,
message: 'remote SSH manager must stay gated behind ssh-remote',
},
{
regex: /#\[cfg\(feature = "ssh-remote"\)\]\s*pub mod remote_fs\b/s,
message: 'remote SSH filesystem runtime must stay gated behind ssh-remote',
},
{
regex: /#\[cfg\(feature = "ssh-remote"\)\]\s*pub mod remote_terminal\b/s,
message: 'remote SSH terminal runtime must stay gated behind ssh-remote',
},
{
regex: /\bpub mod workspace_state\b/,
message: 'remote workspace identity helpers must remain available without ssh-remote',
},
],
},
{
path: 'src/crates/core/src/service/remote_ssh/disabled.rs',
reason:
'no-default core builds must expose explicit unsupported remote SSH stubs instead of compiling russh-backed runtime code',
patterns: [
{
regex: /Remote SSH support is disabled; enable the `ssh-remote` feature/,
message: 'missing explicit disabled remote SSH diagnostic',
},
{
regex: /\bpub struct SSHConnectionManager\b/,
message: 'missing disabled SSH manager compatibility surface',
},
{
regex: /\bpub struct RemoteFileService\b/,
message: 'missing disabled remote file compatibility surface',
},
{
regex: /\bpub struct RemoteTerminalManager\b/,
message: 'missing disabled remote terminal compatibility surface',
},
],
},
{
path: 'src/crates/runtime-ports/src/lib.rs',
reason:
Expand Down Expand Up @@ -2532,6 +2717,44 @@ const requiredContentRules = [
},
],
},
{
path: 'src/crates/core/src/service/search/mod.rs',
reason:
'remote workspace search must route to the real implementation only when ssh-remote is enabled',
patterns: [
{
regex: /#\[cfg\(feature = "ssh-remote"\)\]\s*mod remote\b/s,
message: 'missing ssh-remote gate for real remote search implementation',
},
{
regex: /#\[cfg\(not\(feature = "ssh-remote"\)\)\]\s*mod remote_disabled\b/s,
message: 'missing disabled remote search implementation for no-default builds',
},
{
regex: /#\[cfg\(not\(feature = "ssh-remote"\)\)\]\s*pub use remote_disabled/s,
message: 'missing disabled remote search export',
},
],
},
{
path: 'src/crates/core/src/service/search/remote_disabled.rs',
reason:
'no-default core builds must keep remote search unavailable with an explicit diagnostic',
patterns: [
{
regex: /Remote SSH search is disabled; enable the `ssh-remote` feature/,
message: 'missing explicit disabled remote search diagnostic',
},
{
regex: /\bpub struct RemoteWorkspaceSearchService\b/,
message: 'missing disabled remote workspace search service surface',
},
{
regex: /\bremote_workspace_search_service_for_path\b/,
message: 'missing disabled remote workspace search resolver',
},
],
},
{
path: 'src/crates/acp/src/client/manager.rs',
reason:
Expand Down Expand Up @@ -4254,6 +4477,63 @@ function runManifestParserSelfTest() {
path: 'src/crates/core/src/service/search/remote.rs',
contracts: ['remote_workspace_search_service_for_path', 'lookup_remote_connection_with_hint', 'allow_scan_fallback', 'fallback_query'],
},
{
path: 'src/crates/core/src/service/search/mod.rs',
contracts: ['mod remote_disabled', 'feature = "ssh-remote"', 'pub use remote_disabled'],
},
{
path: 'src/crates/core/src/service/search/remote_disabled.rs',
contracts: ['Remote SSH search is disabled', 'RemoteWorkspaceSearchService', 'remote_workspace_search_service_for_path'],
},
{
path: 'src/crates/core/Cargo.toml',
contracts: [
'bitfun-tool-packs = \\{ path = "\\.\\./tool-packs", default-features = false, optional = true \\}',
'bitfun-services-integrations = \\{ path = "\\.\\./services-integrations", default-features = false, features = \\["remote-ssh"\\] \\}',
'bitfun-product-domains = \\{ path = "\\.\\./product-domains", default-features = false, optional = true \\}',
'dep:bitfun-tool-packs',
'bitfun-tool-packs/product-full',
'bitfun-services-integrations/product-full',
'dep:bitfun-product-domains',
'bitfun-product-domains/product-full',
],
},
{
path: 'src/crates/core/src/lib.rs',
contracts: [
'feature = "product-full"',
'pub mod agentic',
'feature = "product-domains"',
'pub mod function_agents',
'pub mod miniapp',
'feature = "service-integrations"',
'service_agent_runtime',
],
},
{
path: 'src/crates/core/src/service/mod.rs',
contracts: [
'feature = "service-integrations"',
'pub mod git',
'pub mod mcp',
'pub mod remote_connect',
'pub mod review_platform',
'feature = "product-full"',
'pub mod snapshot',
],
},
{
path: 'src/crates/core/src/service/config/mod.rs',
contracts: ['feature = "product-full"', 'mode_config_canonicalizer'],
},
{
path: 'src/crates/core/src/service/workspace/manager.rs',
contracts: ['feature = "service-integrations"', 'GitService', 'return None'],
},
{
path: 'src/crates/core/src/service/workspace_runtime/service.rs',
contracts: ['feature = "product-full"', 'WorkspaceBinding', 'ensure_runtime_for_workspace_binding'],
},
{
path: 'src/crates/acp/src/client/manager.rs',
contracts: ['CLIENT_STARTUP_TIMEOUT_SECS', 'startup_timeout_error_message', 'formats_startup_timeout_error_message'],
Expand Down Expand Up @@ -4391,6 +4671,14 @@ function runManifestParserSelfTest() {
'FunctionAgentAiPort',
],
},
{
path: 'src/crates/core/src/service/remote_ssh/mod.rs',
contracts: ['mod disabled', 'pub mod manager', 'pub mod remote_fs', 'pub mod remote_terminal', 'pub mod workspace_state'],
},
{
path: 'src/crates/core/src/service/remote_ssh/disabled.rs',
contracts: ['Remote SSH support is disabled', 'SSHConnectionManager', 'RemoteFileService', 'RemoteTerminalManager'],
},
{
path: 'src/crates/services-integrations/src/remote_ssh/paths.rs',
contracts: [
Expand Down
Loading
Loading