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
5 changes: 4 additions & 1 deletion scripts/core-boundaries/checker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,10 @@ function checkClosedFeatureProfile(rule) {
}

const allowedLocalFeatures = new Set(
rule.requiredFeatureRefs.filter((reference) => features.has(reference)),
[
...rule.requiredFeatureRefs,
...(rule.allowedTransitiveFeatureRefs ?? []),
].filter((reference) => features.has(reference)),
);
for (const unexpected of unexpectedReachableLocalFeatures(
features,
Expand Down
22 changes: 22 additions & 0 deletions scripts/core-boundaries/rules/crate-rules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ export const dependencyProfileRules = [
forbiddenNonOptionalDeps: [
'aes',
'aes-gcm',
'bitfun-services-integrations',
'bitfun-product-capabilities',
'bitfun-product-domains',
'bitfun-relay-service',
Expand All @@ -431,22 +432,43 @@ export const dependencyProfileRules = [
'local-ip-address',
'mac_address',
'md5',
'notify',
'qrcode',
'rand',
'readability-js',
'rmcp',
'rusqlite',
'russh',
'rustls',
'rustls-native-certs',
'schannel',
'sse-stream',
'similar',
'serde_yaml',
'terminal-core',
'tool-runtime',
'tokio-tungstenite',
'win32job',
'x25519-dalek',
],
},
{
crateName: 'services-core',
profileName: 'default reusable service profile',
reason:
'services-core default profile must not compile capability-specific native or runtime implementations',
forbiddenNonOptionalDeps: [
'anyhow',
'async-trait',
'bitfun-runtime-ports',
'dunce',
'git2',
'notify',
'rusqlite',
'serde_yaml',
'zip',
],
},
{
crateName: 'core-types',
profileName: 'default DTO profile',
Expand Down
121 changes: 115 additions & 6 deletions scripts/core-boundaries/rules/feature-rules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ export const optionalDependencyFeatureOwnerRules = [
{
crateName: 'services-core',
reason:
'services-core workspace runtime dependencies must stay behind the explicit workspace-runtime feature',
'services-core optional implementation dependencies must stay behind their exact owner capability',
dependencies: [
{ depName: 'dunce', ownerFeatures: ['runtime-ownership', 'workspace-runtime'] },
{ depName: 'anyhow', ownerFeatures: ['dispatch-workspace', 'lsp', 'workspace-runtime'] },
{ depName: 'async-trait', ownerFeatures: ['permission', 'workspace-runtime'] },
{ depName: 'bitfun-runtime-ports', ownerFeatures: ['permission', 'workspace-runtime'] },
{ depName: 'dunce', ownerFeatures: ['runtime-ownership', 'workspace-identity', 'workspace-runtime'] },
{ depName: 'git2', ownerFeatures: ['session-git'] },
{ depName: 'notify', ownerFeatures: ['lsp'] },
{ depName: 'rusqlite', ownerFeatures: ['permission'] },
{ depName: 'serde_yaml', ownerFeatures: ['markdown'] },
{ depName: 'zip', ownerFeatures: ['lsp'] },
],
},
{
Expand All @@ -30,6 +38,21 @@ export const optionalDependencyFeatureOwnerRules = [
{ depName: 'bitfun-product-capabilities', ownerFeatures: ['product-capabilities'] },
{ depName: 'bitfun-product-domains', ownerFeatures: ['product-domains'] },
{ depName: 'bitfun-runtime-services', ownerFeatures: ['runtime-services'] },
{
depName: 'bitfun-services-integrations',
ownerFeatures: [
'announcement',
'canvas-runtime',
'file-watch',
'git',
'plugin-source',
'product-domains',
'product-full',
'remote-workspace',
'review-platform',
'ssh-remote',
],
},
{ depName: 'bitfun-tool-packs', ownerFeatures: ['tool-packs'] },
{ depName: 'chrono-tz', ownerFeatures: ['product-full'] },
{ depName: 'cron', ownerFeatures: ['product-full'] },
Expand All @@ -43,7 +66,11 @@ export const optionalDependencyFeatureOwnerRules = [
{ depName: 'md5', ownerFeatures: ['product-full'] },
{ depName: 'reqwest', ownerFeatures: ['ai-adapter-runtime', 'product-full'] },
{ depName: 'rmcp', ownerFeatures: ['product-full'] },
{ depName: 'rusqlite', ownerFeatures: ['product-full'] },
{ depName: 'serde_yaml', ownerFeatures: ['workspace-runtime'] },
{ depName: 'similar', ownerFeatures: ['product-full'] },
{ depName: 'terminal-core', ownerFeatures: ['terminal'] },
{ depName: 'notify', ownerFeatures: ['lsp', 'workspace-watch'] },
{ depName: 'tokio-tungstenite', ownerFeatures: ['product-full'] },
{ depName: 'tower-http', ownerFeatures: ['product-full'] },
{ depName: 'tool-runtime', ownerFeatures: ['product-full'] },
Expand Down Expand Up @@ -71,12 +98,12 @@ export const optionalDependencyFeatureOwnerRules = [
{ depName: 'bitfun-runtime-ports', ownerFeatures: ['git', 'remote-connect', 'remote-ssh', 'remote-ssh-concrete', 'script-tool-runtime'] },
{
depName: 'bitfun-services-core',
ownerFeatures: ['browser-control', 'git', 'hook-import', 'mcp', 'miniapp-runtime', 'process-tree', 'remote-connect', 'remote-ssh-concrete', 'review-platform', 'workspace-search'],
ownerFeatures: ['browser-control', 'git', 'hook-import', 'mcp', 'miniapp-runtime', 'process-tree', 'remote-connect', 'remote-ssh', 'remote-ssh-concrete', 'review-platform', 'workspace-search'],
},
{ depName: 'bzip2', ownerFeatures: ['speech'] },
{ depName: 'chrono', ownerFeatures: ['debug-log', 'git', 'miniapp-market', 'remote-connect', 'remote-ssh-concrete', 'review-platform', 'speech'] },
{ depName: 'dirs', ownerFeatures: ['browser-control', 'miniapp-runtime', 'remote-connect', 'remote-ssh-concrete'] },
{ depName: 'dunce', ownerFeatures: ['plugin-source', 'remote-ssh', 'workspace-search'] },
{ depName: 'dunce', ownerFeatures: ['plugin-source', 'workspace-search'] },
{ depName: 'fs2', ownerFeatures: ['plugin-source'] },
{ depName: 'futures', ownerFeatures: ['mcp', 'remote-connect', 'review-platform'] },
{ depName: 'futures-util', ownerFeatures: ['speech'] },
Expand Down Expand Up @@ -139,10 +166,16 @@ export const coreProductFullFeatureAssemblyRule = {
featureName: 'product-full',
requiredFeatureRefs: [
'announcement',
'dispatch-store',
'file-watch',
'git',
'lsp',
'remote-workspace',
'review-platform',
'ssh-remote',
'terminal',
'workspace-runtime',
'workspace-watch',
'product-capabilities',
'product-domains',
'tool-packs',
Expand All @@ -151,6 +184,78 @@ export const coreProductFullFeatureAssemblyRule = {
};

export const coreClosedFeatureProfileRules = [
{
manifestPath: 'src/crates/services/services-core/Cargo.toml',
featureName: 'default',
requiredFeatureRefs: [],
exact: true,
reason: 'services-core default profile must stay empty so consumers select capabilities explicitly',
},
{
manifestPath: 'src/crates/services/services-core/Cargo.toml',
featureName: 'session-git',
requiredFeatureRefs: ['dep:git2'],
exact: true,
reason: 'services-core session-git must own only the libgit2-backed memory workspace capability',
},
{
manifestPath: 'src/crates/services/services-core/Cargo.toml',
featureName: 'workspace-identity',
requiredFeatureRefs: ['dep:dunce'],
exact: true,
reason: 'services-core workspace-identity must own only canonical workspace path identity support',
},
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'dispatch-store',
requiredFeatureRefs: [],
exact: true,
reason: 'bitfun-core dispatch-store must expose only the durable dispatch index facade',
},
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'lsp',
requiredFeatureRefs: ['dep:notify', 'bitfun-services-core/lsp'],
exact: true,
reason: 'bitfun-core lsp must select only the LSP owner and its workspace watcher dependency',
},
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'terminal',
requiredFeatureRefs: ['dep:terminal-core'],
exact: true,
reason: 'bitfun-core terminal must select only the standalone terminal service owner',
},
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'workspace-runtime',
requiredFeatureRefs: [
'dep:serde_yaml',
'bitfun-services-core/markdown',
'bitfun-services-core/workspace-identity',
'bitfun-services-core/workspace-runtime',
],
exact: true,
reason: 'bitfun-core workspace-runtime must select only local workspace and runtime layout owners',
},
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'workspace-watch',
requiredFeatureRefs: ['workspace-runtime', 'dep:notify'],
exact: true,
reason: 'bitfun-core workspace-watch must extend only local workspace runtime with identity watching',
},
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'remote-workspace',
requiredFeatureRefs: [
'workspace-runtime',
'dep:bitfun-services-integrations',
'bitfun-services-integrations/remote-ssh',
],
exact: true,
reason: 'bitfun-core remote-workspace must add only the remote workspace service surface',
},
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'announcement',
Expand Down Expand Up @@ -191,10 +296,14 @@ export const coreClosedFeatureProfileRules = [
{
manifestPath: 'src/crates/assembly/core/Cargo.toml',
featureName: 'ssh-remote',
requiredFeatureRefs: ['bitfun-services-integrations/remote-ssh-concrete'],
requiredFeatureRefs: [
'remote-workspace',
'bitfun-services-integrations/remote-ssh-concrete',
],
allowedTransitiveFeatureRefs: ['workspace-runtime'],
exact: true,
reason:
'bitfun-core ssh-remote must select only the concrete SSH capability and must not pull product Dispatch assembly',
'bitfun-core ssh-remote must extend only the remote workspace surface with concrete SSH and must not pull product Dispatch assembly',
},
];

Expand Down
75 changes: 71 additions & 4 deletions scripts/core-boundaries/rules/source/required-rules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3791,9 +3791,9 @@ export const requiredContentRules = [
},
{
regex:
/bitfun-services-integrations = \{ path = "\.\.\/\.\.\/services\/services-integrations", default-features = false, features = \["remote-ssh"\] \}/,
/bitfun-services-integrations = \{ path = "\.\.\/\.\.\/services\/services-integrations", default-features = false, optional = true \}/,
message:
'bitfun-services-integrations dependency may keep remote workspace identity but must not force workspace-search or product-full outside the core feature graph',
'bitfun-services-integrations dependency must stay optional so local workspace profiles do not compile remote integrations',
},
{
regex:
Expand Down Expand Up @@ -8680,9 +8680,9 @@ export const requiredContentRules = [
],
},
{
path: 'src/crates/services/services-integrations/src/remote_ssh/paths.rs',
path: 'src/crates/services/services-core/src/workspace_identity.rs',
reason:
'services-integrations remote-ssh owns workspace path/session identity helpers that do not require concrete SSH runtime handles',
'services-core owns stable workspace path/session identity helpers without remote transport or concrete SSH runtime handles',
patterns: [
{
regex: /\bpub struct WorkspaceSessionIdentity\b/,
Expand Down Expand Up @@ -9962,4 +9962,71 @@ export const requiredContentRules = [
},
],
},
{
path: 'src/crates/assembly/core/src/service/mod.rs',
reason:
'bitfun-core service facades must compile only when their explicit capability profile is selected',
patterns: [
{
regex: /#\[cfg\(feature = "dispatch-store"\)\]\s*pub mod dispatch\b/s,
message: 'dispatch store facade must stay gated behind dispatch-store',
},
{
regex: /#\[cfg\(feature = "lsp"\)\]\s*pub mod lsp\b/s,
message: 'LSP facade must stay gated behind lsp',
},
{
regex: /#\[cfg\(feature = "remote-workspace"\)\]\s*pub mod remote_ssh\b/s,
message: 'remote workspace facade must stay gated behind remote-workspace',
},
{
regex: /#\[cfg\(feature = "workspace-runtime"\)\]\s*pub mod workspace\b/s,
message: 'workspace facade must stay gated behind workspace-runtime',
},
{
regex: /#\[cfg\(feature = "terminal"\)\]\s*pub use terminal_core as terminal\b/s,
message: 'terminal compatibility export must stay gated behind terminal',
},
],
},
{
path: 'src/crates/services/services-core/src/session/mod.rs',
reason: 'libgit2-backed memory workspace behavior must remain isolated from the reusable session profile',
patterns: [
{
regex: /#\[cfg\(feature = "session-git"\)\]\s*mod memory_workspace\b/s,
message: 'memory workspace implementation must stay gated behind session-git',
},
{
regex: /#\[cfg\(feature = "session-git"\)\]\s*pub use memory_workspace\b/s,
message: 'memory workspace exports must stay gated behind session-git',
},
],
},
{
path: 'src/crates/services/services-integrations/src/remote_ssh/paths.rs',
reason:
'remote SSH must preserve its public path while delegating stable workspace identity to services-core',
patterns: [
{
regex: /pub use bitfun_services_core::workspace_identity::\*/,
message: 'remote SSH path compatibility module must re-export the services-core owner',
},
],
},
{
path: 'src/crates/assembly/core/src/service/workspace/service.rs',
reason:
'local workspace profiles must use stable service-owned identity and fail closed for unavailable remote runtime behavior',
patterns: [
{
regex: /use bitfun_services_core::workspace_identity::\{/,
message: 'workspace service must consume the services-core identity owner directly',
},
{
regex: /Remote workspace support is not compiled into this product profile/,
message: 'workspace service must report an explicit unsupported state without remote-workspace',
},
],
},
];
Loading
Loading